gri/0000755000175000017500000000000013147560475010017 5ustar psgpsggri/config.guess0000755000175000017500000013036113147557614012344 0ustar psgpsg#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2013 Free Software Foundation, Inc. timestamp='2013-06-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD # # Please send patches with a ChangeLog entry to config-patches@gnu.org. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` ;; esac # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="gnulibc1" ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; or1k:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; or32:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: gri/debian/0000755000175000017500000000000013147560317011234 5ustar psgpsggri/debian/source/0000755000175000017500000000000013147557614012542 5ustar psgpsggri/debian/source/format0000644000175000017500000000001413147557614013750 0ustar psgpsg3.0 (quilt) gri/debian/gri.postinst0000644000175000017500000000175713147557614013642 0ustar psgpsg#!/bin/bash set -e ### Historic cleanup code, delete files like: # /usr/share/emacs/20.7/site-lisp/gri-mode.CompilationLog.gz # /usr/share/xemacs21/site-lisp/gri-mode.CompilationLog.gz clean_old_emacs_cruft () { rm -f /usr/share/emacs/$1/site-lisp/gri-mode.CompilationLog.gz rmdir --ignore-fail-on-non-empty --parents /usr/share/emacs/$1/site-lisp/ } clean_old_xemacs_cruft () { rm -f /usr/share/xemacs$1/site-lisp/gri-mode.CompilationLog.gz rmdir --ignore-fail-on-non-empty --parents /usr/share/xemacs$1/site-lisp/ } shopt -s nullglob for i in /usr/share/emacs/*/site-lisp/gri-mode.CompilationLog.gz; do i=${i#/usr/share/emacs/} i=${i%/site-lisp/gri-mode.CompilationLog.gz} test -e /usr/bin/emacs-$i || clean_old_emacs_cruft $i done for i in /usr/share/xemacs*/site-lisp/gri-mode.CompilationLog.gz; do i=${i#/usr/share/xemacs} i=${i%/site-lisp/gri-mode.CompilationLog.gz} test -e /usr/bin/xemacs$i || clean_old_xemacs_cruft $i done ### All done #DEBHELPER# gri/debian/control.unofficial0000644000175000017500000000505213147557614014765 0ustar psgpsgSource: gri Section: science Priority: optional Maintainer: Peter S Galbraith Build-Depends: debhelper, tetex-bin, texinfo, netcdfg-dev Standards-Version: 3.5.6 Package: gri-VSN Architecture: any Depends: ${shlibs:Depends} Conflicts: gri (= VSN), gri-VSNstatic Description: a language for scientific illustration (without extras). This is not an official Debian package. . Gri is an open-source language for scientific graphics programming. It is command-driven, as opposed to point/click. Some users consider Gri similar to LaTeX, since both provide extensive power as a reward for tolerating a learning curve. The output is industry-standard PostScript as output, suitable for inclusion in other documents. . Gri can make x-y graphs, contour graphs, and image graphs. Fine control is provided over all aspects of drawing, e.g. line widths, colors, fonts, etc. Greek letters and mathematical symbols are available in a TeX-like syntax. . This version-specific package exists to live alongside a newer release of the regular gri package, thus providing backwards compatibility for your old code that may depend on this version of Gri. To distinguish this package from the regular `gri' package, it is named as `gri-VERSION', e.g. gri-VSN. . This package does not contain an Info manual. Install the regular gri package to get that. Package: gri-VSNstatic Architecture: any Depends: ${shlibs:Depends} Conflicts: gri (= VSN), gri-VSN Description: a language for scientific illustration (without extras). This is not an official Debian package. . Gri is an open-source language for scientific graphics programming. It is command-driven, as opposed to point/click. Some users consider Gri similar to LaTeX, since both provide extensive power as a reward for tolerating a learning curve. The output is industry-standard PostScript as output, suitable for inclusion in other documents. . Gri can make x-y graphs, contour graphs, and image graphs. Fine control is provided over all aspects of drawing, e.g. line widths, colors, fonts, etc. Greek letters and mathematical symbols are available in a TeX-like syntax. . This statically compiled version-specific package exists to live alongside a newer release of the regular gri package, thus providing backwards compatibility for your old code that may depend on this version of Gri. To distinguish this package from the regular `gri' package, it is named as `gri-VERSIONstatic', e.g. gri-VSNstatic. . This package does not contain an Info manual. Install the regular gri package to get that. gri/debian/gri.doc-base0000644000175000017500000000042313147557614013421 0ustar psgpsgDocument: gri Title: Gri language for scientific graphics manual Author: Dan E. Kelley Abstract: Manual (info format) for Gri, a language for scientific graphics Section: Science/Data Analysis Format: info Index: /usr/share/info/gri.info.gz Files: /usr/share/info/gri.info* gri/debian/compat0000644000175000017500000000000213147557614012440 0ustar psgpsg9 gri/debian/gri-el.emacsen-startup0000644000175000017500000000065613147557614015465 0ustar psgpsg(if (not (file-exists-p "/usr/share/emacs/site-lisp/gri-el/gri-mode.el")) (message "Package gri-el is not installed. Skipping setup.") (debian-pkg-add-load-path-item (concat "/usr/share/" (symbol-name debian-emacs-flavor) "/site-lisp/gri-el")) (setq gri*directory-tree "/usr/share/gri/") (autoload 'gri-mode "gri-mode" "Enter Gri-mode." t) (setq auto-mode-alist (cons '("\\.gri\\'" . gri-mode) auto-mode-alist))) gri/debian/Makefile.in0000644000175000017500000002713113147560317013305 0ustar psgpsg# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # gri: src/debian/Makefile.am #srcdir = @srcdir@ #VPATH = @srcdir@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = debian ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS_TEMPLATE = @EXTRA_CFLAGS_TEMPLATE@ GREP = @GREP@ HAVE_CONVERT = @HAVE_CONVERT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PROGS = @PROGS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = rules compat changelog control control.unofficial\ copyright.template gri.doc-base\ gri-el.emacsen-install gri-el.emacsen-remove\ gri-el.emacsen-startup\ gri-html-doc.doc-base gri-html-doc.emacsen-startup\ gri-html-doc.preinst\ gri.man gri.postinst gri-pdf-doc.doc-base\ README.Debian.template\ README.Debian.unofficial source/format all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu debian/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu debian/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gri/debian/README.Debian.template0000644000175000017500000000411413147557614015115 0ustar psgpsggri for DEBIAN -------------- Here is how the packages are organized: gri: gri binary, manual in Info format, the Emacs mode (gri-mode.el), and one-page reference cards in PostScript format. For help about the software, see the Info manual: $ info gri gri-html-doc: HTML version of the manual (It's listed in dwww, dhelp and doc-central if you have the doc-base package installed). This manual is available on the web via: http://gri.sourceforge.net/gridoc/html/ Once you have installed this package, it's available at the URL http://localhost/doc/gri/html/ if you have a web server (like apache), or more simply at file:/usr/share/doc/gri/html/index.html gri-pdf-doc: PDF version of the manual suitable for printing or on-screen viewing. Once you have installed this package, it's available at /usr/share/doc/gri/gri.pdf.gz See also: The Gri cookbook (for real-world examples) on the web at: http://gri.sourceforge.net/gri-cookbook/ Packages available outside of Debian for older Gri versions: Some packages may be available outside the scope of Debian official packages that provide binaries for specific versions of Gri. This is useful if you write a complicated Gri command and find it no longer works after a Gri version upgrade. You may then want to install a version-specific package which contains only the binary and library of the Gri version you need. For example, if you currently use a package named gri_VSN-1.deb, and upgrade to gri_LATERVSN-1.deb, you could also install the package gri-VSN_VSN-1.deb (Note how the version number appears twice). The package name is thus `gri-VSN' instead of `gri'. This package would provide the version-specific command `gri-VSN', also accessible inside of Emacs' gri-mode (see the Emacs command `gri-set-local-version'). Statically compiled version are also available named like gri-VERSIONstatic. -- Peter S Galbraith , Wed, 31 Mar 2010 16:29:11 -0400 gri/debian/gri-html-doc.doc-base0000644000175000017500000000044413147557614015131 0ustar psgpsgDocument: gri-html-doc Title: Gri language for scientific graphics manual Author: Dan E. Kelley Abstract: Manual (in HTML) for Gri, a language for scientific graphics Section: Science/Data Analysis Format: HTML Index: /usr/share/doc/gri/html/index.html Files: /usr/share/doc/gri/html/*.html gri/debian/copyright.template0000644000175000017500000000116513147557614015012 0ustar psgpsgThis package was first debianized by Peter S Galbraith on Wed, 31 Aug 1998. It was downloaded from http://ftp1.sourceforge.net/gri/gri-VSN.tgz The Gri web page is: http://gri.sourceforge.net Copyright and License: Gri: The Gri programming languages, and all manuals and online help-files, are (c) 1991-2001 Dan E. Kelley . Gri is distributed under the GPL Version 2. See /usr/share/common-licenses/GPL Emacs gri-mode: Copyright (C) 1994-2001 Peter S. Galbraith gri-mode.el is distributed under the GPL Version 2. See /usr/share/common-licenses/GPL gri/debian/gri-pdf-doc.doc-base0000644000175000017500000000037213147557614014736 0ustar psgpsgDocument: gri-pdf-doc Title: Gri language for scientific graphics manual Author: Dan E. Kelley Abstract: Manual (PDF) for Gri, a language for scientific graphics Section: Science/Data Analysis Format: postscript Files: /usr/share/doc/gri/gri.pdf.gz gri/debian/copyright0000644000175000017500000000117113147557614013175 0ustar psgpsgThis package was first debianized by Peter S Galbraith on Wed, 31 Aug 1998. It was downloaded from http://ftp1.sourceforge.net/gri/gri-2.12.23.tgz The Gri web page is: http://gri.sourceforge.net Copyright and License: Gri: The Gri programming languages, and all manuals and online help-files, are (c) 1991-2001 Dan E. Kelley . Gri is distributed under the GPL Version 2. See /usr/share/common-licenses/GPL Emacs gri-mode: Copyright (C) 1994-2001 Peter S. Galbraith gri-mode.el is distributed under the GPL Version 2. See /usr/share/common-licenses/GPL gri/debian/gri.man0000644000175000017500000001307213147557614012523 0ustar psgpsg.TH GRI 1 .SH NAME gri \- scientific graphics language .SH SYNOPSIS .B gri [ .B OPTIONS ] [ .I CommandFile [ .I optional_arguments ]] .SH DESCRIPTION Gri is a programming language for scientific graphics. It can make x-y graphs, contour-graphs, and image graphs. In addition, Gri has a full suite of low-level graphical elements and sufficient programming capabilities (loops, subroutines, etc) to permit complex customization. Gri is not point-click. In some ways it is analogous to TeX. Extensive power rewards tolerance of a modest learning curve. .SH OPTIONS If a command file (CommandFile) is named, commands are read from that file; otherwise they are read from the keyboard. If a command file is named, then a file in which to store the PostScript output may also be named; otherwise it is stored in a file named by substituting the .ps extension instead of .gri in CommandFile. If no command file is named, the output is named gri-00.ps (or gri-01.ps if gri-00.ps exists, etc). There are 3 special forms that do no graphing: `gri \fB\-creator\fR postscript_file' .IP Extracts the Gri commands that created the Gri PostScript file. .PP `gri \fB\-help\fR' or `gri \fB\-h\fR' .IP Prints this help message. .PP `gri \fB\-version\fR' or `gri \fB\-v\fR' .IP Prints the version number of Gri. .PP In normal usage, where drawing is expected, Gri takes these options: \fB\-batch\fR or \fB\-b\fR .IP Stops printing of prompts and hints. .HP \fB\-chatty[N]\fR or \fB\-c[N]\fR .IP Let gri print info messages .HP \fB\-debug\fR or \fB\-d\fR .IP Turns debugging on (sets variable ..debug.. to value 1). .HP \fB\-warn_offpage\fR .IP Warn if any item is drawn far off a 8.5x11 inch page. (This is the default.) .HP \fB\-nowarn_offpage\fR .IP Don't warn if any item is drawn far off a 8.5x11 inch page .HP \fB\-directory\fR pathname .IP Specifies the directory where Gri looks for startup files; otherwise it looks in /opt/gri/lib or at whatever directory is defined in configure shellscript, at compile time. .HP \fB\-directory_default\fR .IP Reports directory where gri.cmd should be found, if not supplied by \fB\-directory\fR. .HP \fB\-no_bounding_box\fR .IP Make bounding-box be full page. .HP \fB\-no_expecting\fR .IP Prevent warning message if `expecting version .n.' command is missing. .HP \fB\-no_startup_message\fR .IP Stops printing of startup message. .HP \fB\-publication\fR or \fB\-p\fR .IP Sets the builtin variable ..publication.. to 1; normally it is 0. One might use if statements (`if !..publication..' ...) on drafts. .HP \fB\-superuser\fR or \fB\-s\fR .IP Used only by Gri programmers (who can check the value with the C function `superuser()'.) An optional value can be supplied without spaces (e.g. `-s2') to set the debugging level. Flags are listed below; add flags to get several actions at once .IP 1: print cmdline before/after substituting synonyms 2: print cmdline before/after substituting rpn expressions 4: print new commands being defined 8: print system commands and `open "... | "' commands before .IP they are passed to the system .IP 128: for author's use only 256: for author's use only .IP Note that all flags are equal to 2 raised to an integer power. Since the flag values are detected by a bitwise OR, you can combine flags by adding; thus specifying a flag of 5 yields flags 1 and 4 together; specifying 15 yields flags 1, 2, 4 and 8. .HP \fB\-trace\fR or \fB\-t\fR .IP Makes Gri print out command lines as they are executed. .HP \fB\-true\fR or \fB\-y\fR .IP Makes Gri think the answer to all `query's is RETURN. .SH "SEE ALSO" For more information, please consult online .I info and .I html manuals. The .I info manual included in the main .B gri Debian package is normally accessed by typing .B info gri (or from within Emacs' own info). There are also .I reference cards in postscript format. See .B /usr/share/doc/gri/*refcard.ps The Debian package .B gri-html-doc provides the .I html manual, which when installed is then located at .IP .B /usr/share/doc/gri/html/index.html .PP or, if you have a web server installed, at .IP .B http://localhost/doc/gri/html/index.html .PP The HTML manual is accessible via .I dwww and .I dhelp Debian help interfaces. The .I html FAQ is located at .IP .B /usr/share/doc/gri/html/FAQ.html .PP The .B gri-html-doc package also includes .I examples in .B /usr/share/doc/gri/examples/ which are described in the manual, and are included as a quick start primer. The .B gri-pdf-doc package is a .I PDF version of the manual suitable for printing. .SH GRI_MERGE AND GRI_UNPAGE COMMANDS Two Perl scripts are provided with Gri to manipulate the PostScript output. .I gri_merge is used to merge multiple Gri output files into a single PostScript file. See .B gri_merge -h and its man page for usage information. .I gri_unpage is used is split a multi-page Gri output file (in which the .B new page command was used) into separate PostScript files, one for each page. See their respective man pages. .SH EMACS SUPPORT An .I emacs mode is provided with Gri. It is documented in the gri Info or HTML manual. The mode is installed automatically in Debian by the elisp file: .B /etc/emacs/site-start.d/50gri-el.el The emacs mode itself is .I gri-mode.el and is installed on Debian as .B /usr/share/emacs/site-lisp/gri-mode.el Byte-compiled versions of this file are produced for every flavour of Emacs that is installed, and are located in places like .B /usr/share/emacs/23.1/site-lisp/gri-el/gri-mode.elc .SH "SEE ALSO" .B gri_merge(1), gri_unpage(1) .SH AUTHOR Gri (c) 1991-2010 Dan Kelley This manual page by Peter S Galbraith . gri/debian/gri-el.emacsen-install0000644000175000017500000000241413147557614015423 0ustar psgpsg#!/bin/sh # # emacsen install script for the gri package # - # This script is installed by the Gri package `rules' file to # /usr/lib/emacsen-common/packages/install/gri # It is run by Gri package `postinst' which calls # /usr/lib/emacsen-common/emacs-package-install gri # The Gri package `postinst' is installed as /var/lib/dpkg/info/gri.postinst set -e flavour=$1 package=gri files="gri-mode.el" ELCDIR=/usr/share/${flavour}/site-lisp/gri-el flags="-q --no-site-file -no-site-file --batch -l path.el -f batch-byte-compile" LOG=`tempfile -pelc_ -s.log -m644` if [ ${flavour} != emacs ] then echo install/${package}: Handling ${flavour}, logged in ${LOG} # link the source .el files into the ELCDIR directory install -c -m 0755 -d ${ELCDIR} cd ${ELCDIR} for i in $files do ln -fs /usr/share/emacs/site-lisp/gri-el/$i done # Byte-compile cat << EOF > path.el (setq load-path (cons "." load-path) byte-compile-warnings nil) EOF echo ${flavour} ${flags} ${files} >> ${LOG} ${flavour} ${flags} ${files} >> ${LOG} 2>&1 rm -f path.el egrep -s -e "While compiling|\*\*" ${LOG} || /bin/true echo install/${package}: Deleting ${LOG} rm -f ${LOG} else echo install/${package}: Ignoring emacsen flavour ${flavour} fi exit 0; gri/debian/gri-html-doc.preinst0000644000175000017500000000121513147557614015135 0ustar psgpsg#!/bin/bash set -e ### Historic cleanup code, delete files like: # /usr/share/doc/gri-html-doc/html/.dhelp if [ -f "/usr/share/doc/gri-html-doc/html/.dhelp" ]; then rm -f /usr/share/doc/gri-html-doc/html/.dhelp rmdir --ignore-fail-on-non-empty --parents /usr/share/doc/gri-html-doc/html fi ### Delete unedited potato /etc/emacs file because it wasn't a conffile if [ x$1 = xupgrade ] then if [ `md5sum < /etc/emacs/site-start.d/50gri-html-doc.el | cut -f1 "-d "` = 4b1366ce9d1e5de4670aba73f37b212a ] then mv /etc/emacs/site-start.d/50gri-html-doc.el /etc/emacs/site-start.d/50gri-html-doc.el.dpkg-old fi fi #DEBHELPER# gri/debian/control0000644000175000017500000000611013147557614012643 0ustar psgpsgSource: gri Section: science Priority: optional Maintainer: Peter S Galbraith Build-Depends: debhelper (>= 0), libnetcdf-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, texinfo, imagemagick, info, ghostscript, gsfonts Homepage: http://gri.sourceforge.net/ Standards-Version: 3.9.8 Package: gri Section: science Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, dpkg (>= 1.15.4) | install-info, perl Suggests: gri-html-doc, gri-pdf-doc, gri-el, gv Description: a language for scientific illustration Gri is an open-source language for scientific graphics programming. It is command-driven, as opposed to point/click. Some users consider Gri similar to LaTeX, since both provide extensive power as a reward for tolerating a learning curve. The output is industry-standard PostScript as output, suitable for inclusion in other documents. . Gri can make x-y graphs, contour graphs, and image graphs. Fine control is provided over all aspects of drawing, e.g. line widths, colors, fonts, etc. Greek letters and mathematical symbols are available in a TeX-like syntax. . Folks who write 1000-line Gri scripts usually start with something as simple as the following: . open file.dat # open a file read columns x * y # read the 1st column as x and the 3rd as y draw curve # draw the data and autoscale the axes . A full manual is also available in HTML (gri-html-doc package), in PDF suitable for printing (gri-pdf-doc package) and on-line by following links from the gri home page: http://gri.sourceforge.net/ Package: gri-el Section: lisp Architecture: all Depends: gri (>= 2.12.1-2), emacs | emacsen, ${misc:Depends} Recommends: gv Conflicts: gri (<= 2.12.1-1) Description: Emacs major-mode for gri, a language for scientific graphics Gri is an open-source language for scientific graphics programming. . This is the Emacs major-mode for gri. Package: gri-html-doc Section: doc Architecture: all Depends: ${shlibs:Depends}, ${misc:Depends} Suggests: doc-base Description: HTML manual for gri, a language for scientific graphics Gri is a command-driven application for making x-y graphs, contour-graphs, and image graphs. . This is the Gri manual in HTML format and can be accessed directly via file:/usr/share/doc/gri/html/index.html or http://localhost/doc/gri/html/ or via doc-central, dwww or dhelp interfaces (if you have the doc-base package installed). Note that the manual in info format (without graphics) is included in the gri package itself. This manual is available on the web via: http://gri.sourceforge.net/gridoc/html/ Package: gri-pdf-doc Section: doc Architecture: all Depends: ${shlibs:Depends}, ${misc:Depends} Breaks: gri (<< 2.12.23-2) Replaces: gri (<< 2.12.23-2), gri-ps-doc Description: PostScript manual for gri, a language for scientific graphics Gri is a command-driven application for making x-y graphs, contour-graphs, and image graphs. . This is the Gri manual in PDF format suitable for printing or viewing on-screen. The compressed file is located at /usr/share/doc/gri/gri.pdf.gz gri/debian/Makefile.am0000644000175000017500000000074213147557614013301 0ustar psgpsg## Process this file with automake to produce Makefile.in # gri: src/debian/Makefile.am #srcdir = @srcdir@ #VPATH = @srcdir@ EXTRA_DIST = rules compat changelog control control.unofficial\ copyright.template gri.doc-base\ gri-el.emacsen-install gri-el.emacsen-remove\ gri-el.emacsen-startup\ gri-html-doc.doc-base gri-html-doc.emacsen-startup\ gri-html-doc.preinst\ gri.man gri.postinst gri-pdf-doc.doc-base\ README.Debian.template\ README.Debian.unofficial source/format gri/debian/changelog0000644000175000017500000011112413147557614013114 0ustar psgpsggri (2.12.26-1) unstable; urgency=medium * New upstream release. * Bug fix: "ftbfs with GCC-7", thanks to Matthias Klose (Closes: #853434). -- Peter S Galbraith Tue, 15 Aug 2017 11:20:56 -0400 gri (2.12.23-10.1) unstable; urgency=medium * Non-maintainer upload. * Fix "FTBFS with perl 5.26 -- Unescaped left brace in regex is illegal": add patch perl-5.26.patch from Damyan Ivanov which adds the missing backslashes. (Closes: #865482) -- gregor herrmann Wed, 12 Jul 2017 21:50:06 +0200 gri (2.12.23-10) unstable; urgency=medium * Bug fix: "missing debian/copyright", thanks to Thorsten Alteholz (Closes: #795095). The previous code copied debian/copyright.template to the binary package copyright file while substituting the correct version number. Users will have to live without an exact version number. * Bug fix: "FTBFS: awk: cannot open gri.ky", thanks to Martin Michlmayr (Closes: #818449). Patch applied, thanks! * Standards-Version: 3.9.8 * debian/compat: 9 -- Peter S Galbraith Sat, 08 Oct 2016 16:37:57 -0400 gri (2.12.23-9) unstable; urgency=medium * Bug fix: "Fatal error occurred, no output PDF file produced", thanks to Martin Michlmayr (Closes: #790526). * Bug fix: "man page description of postscript output file", thanks to Kevin Ryde (Closes: #719033). -- Peter S Galbraith Sun, 26 Jul 2015 11:13:19 -0400 gri (2.12.23-8) unstable; urgency=medium * Bug fix: "please switch to emacs24", thanks to Gabriele Giacone (Closes: #754015). * Added debian/gri-el.emacsen-compat -- Peter S Galbraith Mon, 07 Jul 2014 22:06:18 -0400 gri (2.12.23-7) unstable; urgency=medium * Bug fix: "FTBFS: Can't locate getopts.pl in @INC", thanks to Andreas Moog (Closes: #735914). Fixed doc/texinfo2HTML here and upstream. -- Peter S Galbraith Wed, 29 Jan 2014 21:15:30 -0500 gri (2.12.23-6) unstable; urgency=low * Merge in updated config.guess and config.sub for arm64 on Ubuntu. * doc/examples/Makefile.am bug fix: "example png files black on transparent", thanks to Kevin Ryde. Added "-background white" to convert call (Closes: #719160). -- Peter S Galbraith Wed, 16 Oct 2013 10:34:27 -0400 gri (2.12.23-5) unstable; urgency=low * src/utility.cc: Merge in upstream fix for hurd PATH_MAX -- Peter S Galbraith Tue, 15 Oct 2013 10:06:03 -0400 gri (2.12.23-4) unstable; urgency=low * Bug fix: "FTBFS: Failed building docs", thanks to David Suárez (Closes: #724193). * Bug fix: "extra .gri$ auto-mode-alist entry", thanks to Kevin Ryde (Closes: #680701). * Undo bug #659422 Depends on libperl4-corelibs-perl and update scripts gri_unpage and gri_merge instead. -- Peter S Galbraith Mon, 14 Oct 2013 17:35:26 -0400 gri (2.12.23-3) unstable; urgency=low * These are the same bug; fixed upstream in git. * Bug fix: "FTBFS: manuals build fails against textinfo5 because some incompatibles changes wrt 4.13 and below (some warnings have turned into errors)", thanks to David Suárez (Closes: #712326). * Bug fix: "build from source fails on makeinfo 5.1", thanks to Kevin Ryde (Closes: #718821). -- Peter S Galbraith Tue, 06 Aug 2013 20:31:42 -0400 gri (2.12.23-2.2) unstable; urgency=low * Non-maintainer upload. * Add missing Breaks+Replaces Closes: #694275 -- Andreas Tille Thu, 06 Dec 2012 13:42:17 +0100 gri (2.12.23-2.1) unstable; urgency=low * Non-maintainer upload. * Add Depends on libperl4-corelibs-perl (Closes: #659422) -- Dominic Hargreaves Mon, 23 Apr 2012 18:53:37 +0100 gri (2.12.23-2) unstable; urgency=low * Move refcard.ps to gri-pdf-doc package. -- Peter S Galbraith Wed, 13 Jul 2011 21:01:53 -0400 gri (2.12.23-1) unstable; urgency=low * New upstream release Bug fixes: - Fix SourceForge bug https://sourceforge.net/projects/gri/forums/forum/16975/topic/4596628/index/page/1 (pgm: images grayscale was wrong) -- Peter S Galbraith Tue, 12 Jul 2011 14:46:23 -0400 gri (2.12.22-1) unstable; urgency=low * New upstream release Bug Fixes: - Fix github bug http://github.com/dankelley/gri/issues#issue/5 (`draw image' failed on some black/white images). -- Peter S Galbraith Tue, 23 Nov 2010 19:11:02 -0500 gri (2.12.21-1) unstable; urgency=low * New upstream release Bug Fixes: - Fix github bug http://github.com/dankelley/gri/issues#issue/1 (`convert grid to image directly' misplaced image ``patches'' by one patch width and one patch height.) -- Peter S Galbraith Mon, 07 Jun 2010 09:47:21 -0400 gri (2.12.20-1) unstable; urgency=low * gri-pdf-doc: New binary package replaces "gri-ps-doc" package. * Switch to Debian source package format 3.0 (quilt) * New upstream release - add `starting' option to `set x axis' and `set y axis'. - add `directly' option to `convert grid to image'. - gri-mode.el font-locking was broken since Emacs-22 Bug Fixes: - Fix SourceForge bug #2913919 (SVG: all symbols are ".") - Fix SourceForge bug #2913893 (svg segfault on draw label) - Fix SourceForge bug #2913841 (svg draw box filled not filled) - Fix SourceForge bug #2913840 (svg images are upside-down) - Fix SourceForge bug #2913838 (image postscript clip problem) * Various lintian fixes in debian/control -- Peter S Galbraith Thu, 01 Apr 2010 10:14:27 -0400 gri (2.12.19-3) unstable; urgency=low * Bug fix: "replacing libreadline5-dev build dependency with libreadline-dev", thanks to Matthias Klose (Closes: #553777). -- Peter S Galbraith Mon, 02 Nov 2009 17:13:32 -0500 gri (2.12.19-2) unstable; urgency=low * Bug fix: "FTBFS: Nonexistent build-dependency: netcdfg-dev", thanks to Lucas Nussbaum (Closes: #549756). Switched to libnetcdf-dev. Also switch gs to ghostscript. -- Peter S Galbraith Mon, 05 Oct 2009 21:31:45 -0400 gri (2.12.19-1) unstable; urgency=low * New upstream release Bug Fixes: - Fix SourceForge bug #2977816 (Fedora packaging requires more precise license declarations. - Fix SourceForge bug #3266884 (error in docs for strlen). -- Peter S Galbraith Fri, 17 Jul 2009 15:08:08 -0400 gri (2.12.18-1) unstable; urgency=low * New upstream release Bug Fixes: - Improve security when creating temporary files. - Fix SourceForge bug #1985862 (output had axis linewidth equal to curve line width). -- Peter S Galbraith Mon, 08 Sep 2008 20:46:30 -0400 gri (2.12.17-1) unstable; urgency=low * New upstream release New Features Add GNU readline support so that interactive mode will have history, command editing, etc. Bug Fixes: - Fix SourceForge bug #1913577 (superscripts did not end correctly, if preceeded by an inline { block). - Fix SourceForge bug #1761562 (y axis name printed upside down, for log axes in which user specified a high values at the bottom end of the axis) * gri-mode.el: minor fix for emacs-22 and license update to GPL V2 or later. * control: Added libreadline5-dev to Build-Depends. -- Peter S Galbraith Wed, 28 May 2008 20:48:14 -0400 gri (2.12.16-3) unstable; urgency=low * Bug fix: "gri-el: bashism ("&>") in emacsen install script", thanks to Aaron M. Ucko (Closes: #467639). Modernize gri-el byte-compilation. * Bug fix: "gri-el: Relies on gv, but does not recommend it", thanks to Javier Kohen (Closes: #470504). -- Peter S Galbraith Thu, 27 Mar 2008 21:02:21 -0400 gri (2.12.16-2) unstable; urgency=low * gri-el: Prefer emacs22 instead of emacs21. * Bug fix: "gri: Uninstallable, can't be binNMU'ed.", thanks to Kurt Roeckx (Closes: #466434). Rebuild for libnetcdf4. * Bug fix: "Confused by filenames with newlines", thanks to Trent W\. Buck (Closes: #446173). Use "\\.gri\\'" instead of "\\.gri$" in auto-mode-alist. -- Peter S Galbraith Mon, 25 Feb 2008 20:24:45 -0500 gri (2.12.16-1) unstable; urgency=low * Bug fix: "gri: landscape produces interdependent pages", thanks to Bernhard R. Link for outlining the fix (Closes: #130802). * Bug fix: "gri: 'set page landscape' requires 'set page size' first, but it should really default to something reasonable instead (Closes: #434010). -- Peter S Galbraith Fri, 20 Jul 2007 18:52:34 -0400 gri (2.12.15-5) unstable; urgency=low * Bug fix: "gri: FTBFS if built twice in a row", thanks to Bernd Zeimetz (Closes: #424371). -- Peter S Galbraith Wed, 16 May 2007 20:35:23 -0400 gri (2.12.15-4) unstable; urgency=low * Added texlive-latex-base to build dependencies for missing lcircle10 font. -- Peter S Galbraith Thu, 19 Apr 2007 20:03:20 -0400 gri (2.12.15-3) unstable; urgency=low * Build-depend (as well as Build-Depends-Indep) on texlive-generic-recommended instead of tetex-bin. Thanks to Kurt Roeckx (Closes: #419602). -- Peter S Galbraith Wed, 18 Apr 2007 22:06:17 -0400 gri (2.12.15-2) unstable; urgency=low * Build-depend on texlive-generic-recommended instead of tetex-bin. Thanks to Kurt Roeckx (Closes: #419602). -- Peter S Galbraith Mon, 16 Apr 2007 21:13:05 -0400 gri (2.12.15-1) unstable; urgency=low * New upstream release Bug Fixes: - Fix SourceForge bug #1700978 (html concept index mostly broken) - Fix SourceForge bug #1698924 (box plots show missing data) - Fix Debian bug #417217 (will not compile in GCC 4.3) (Closes: #417217) - Fix SourceForge bug #1698116 (poorly-positioned name of RHS y-axis) -- Peter S Galbraith Sat, 14 Apr 2007 22:04:29 -0400 gri (2.12.14-1) unstable; urgency=low * New upstream release Bug Fixes: - Fix SourceForge bug #1630768 (Fix to segfault in clipped images (a bug that may have developed after version 2.13.3)) -- Peter S Galbraith Fri, 19 Jan 2007 23:11:54 -0500 gri (2.12.13-1) unstable; urgency=low * New upstream release Bug Fixes: - Fix SourceForge bug #1591475 (Fix to compile in Solaris CC) - Fix SourceForge bug #1591062 (Fix to compile in OpenBSD) * debian/control: Standards-Version 3.7.2 -- Peter S Galbraith Tue, 7 Nov 2006 18:45:30 -0500 gri (2.12.12-1) unstable; urgency=low * New upstream release Bug Fixes: - Fix SourceForge bug #1523033 (Malloc error) - Fix SourceForge bug #1523032 (`create columns from function' bug, if there is an existing directory called `tmp') Thanks to Steve Cayford (Closes: #378277). - Fix SourceForge bug #1491105 (`set x axis labels' had no affect for log axes (same for y) -- Peter S Galbraith Wed, 19 Jul 2006 02:19:36 -0400 gri (2.12.11-1) unstable; urgency=low * New upstream release Bug Fixes: - Debian Bug fix: "Please update config.* (again)", thanks to Martin Michlmayr (Closes: #357181). - Fix SourceForge bug #1449546 (x axis limits not correctly inferred from `set x grid'; same for y). -- Peter S Galbraith Fri, 24 Mar 2006 21:46:59 -0500 gri (2.12.10-6) unstable; urgency=high * Bug fix: "gri: Please rebuild with current netcdf.", thanks to Daniel Kobras (Closes: #352219). * Set permissions to user writable on debian/changelog for binary-only rebuilds. * Switch to debhelper 4. -- Peter S Galbraith Fri, 10 Feb 2006 11:02:42 -0500 gri (2.12.10-5) unstable; urgency=low * Fix compilation bugs on ia64 and alpha, fourth attempt tested on a Debian ia64 machine. Thanks to Dan Kelley for the patch. (Really closes: #350467, I hope). -- Peter S Galbraith Wed, 1 Feb 2006 19:13:46 -0500 gri (2.12.10-4) unstable; urgency=low * Fix compilation bugs on ia64 and alpha, third try is the charm. Thanks to Dan Kelley for the patch. (Bug also reported by Kurt Roeckx, really closes: #350467). -- Peter S Galbraith Tue, 31 Jan 2006 23:24:18 -0500 gri (2.12.10-3) unstable; urgency=low * Fix compilation bugs on ia64 and alpha, second try. Thanks to Dan Kelley for the patch! (Bug also reported by Kurt Roeckx, Closes: #350467). -- Peter S Galbraith Mon, 30 Jan 2006 20:48:31 -0500 gri (2.12.10-2) unstable; urgency=low * Fix compilation bugs on ia64 and alpha. Thanks to Dan Kelley for the patch! -- Peter S Galbraith Fri, 27 Jan 2006 22:15:08 -0500 gri (2.12.10-1) unstable; urgency=low * New upstream release Bug Fixes: - Fix Debian Bug #348351 (PostScript file contained private information. This was fixed by adding new commandline arguments `-private' and `-no_private', the former of which (the new default) means to not include the user's name, the invocation arguments, or the command-file contents. Thanks to Falk Hueffner for reporting it (Closes: #348351). - Fix SourceForge bug #1285180 (NaN was mishandled. The bug may have arisen in version 2.12.7 or thereabouts.) - Fix SourceForge bug #1217273 (missing some version numbers within docs) - Fix SourceForge bug #1196613 (user-supplied x-axis labels can run offscale) - Fix SourceForge bug #1198341 (x-axis labels incorrectly rotated) - Fix SourceForge bug #1199280 (warning about `malloc' for RPN assignments) - Fix SourceForge bug #1101172 (`gri -help' incorrectly stated meaning of last argument(s)) (Closes: #290101) - Fix SourceForge bug #835711 (`draw gri logo' fails) - Fix SourceForge bug #1098269 (problem compiling on AMD64 machine. Solution provided by Andreas Jochens, a Debian user. This moves a fix into the upstream source, rather than patching in diff.gz) - Fix SourceForge bug #867515 (problem with junk appearing in images.) - Fix SourceForge bug #875881 (problem compiling with gcc 2.95.3 compiler) * debian/control: Standards-Version 3.6.2 without changes. -- Peter S Galbraith Sun, 22 Jan 2006 10:04:07 -0500 gri (2.12.9-3) unstable; urgency=low * Bug fix: "gri(GNU/k*BSD): FTBFS: out of date config.sub/config.guess", thanks to Petr Salinger (Closes: #342414). -- Peter S Galbraith Sat, 14 Jan 2006 16:19:19 -0500 gri (2.12.9-2) unstable; urgency=low * Bug fix: "gri-el: incompatible with new version of gv", thanks to Scott Webster for reporting this (Closes: #296692). -- Peter S Galbraith Tue, 1 Mar 2005 22:38:36 -0500 gri (2.12.9-1) unstable; urgency=low * New upstream release Bug Fixes: - Fix SourceForge bug #1094087 (`set path to' incorrectly parsed colon-separated paths) - Fix SourceForge bug #1085788 (`image *=', `image /=', `image ^=', and `image _=' all gave incorrect results) - Fix SourceForge bug #1084123 (does not compile in fink) - Fix SourceForge bug #676767 (on fink systems, `help' does not work) -- Peter S Galbraith Tue, 4 Jan 2005 20:08:02 -0500 gri (2.12.8-3) unstable; urgency=low * Bug fix: "gri: FTBFS (amd64/gcc-4.0): cast from 'FILE*' to 'int' loses precision", thanks to Andreas Jochens (Closes: #286921). * Remove another DEBUG printout. -- Peter S Galbraith Wed, 22 Dec 2004 19:11:47 -0500 gri (2.12.8-2) unstable; urgency=low * Remove DEBUG printouts. * gri-el: Adapt to new texinfo's "Index of Commands" which includes a line offset number. This fixes Info lookup for gri commands. -- Peter S Galbraith Thu, 16 Dec 2004 20:58:18 -0500 gri (2.12.8-1) unstable; urgency=low * New upstream release Bug Fixes: - Fix SourceForge bug #1019141 (draw arc' ignores the present pen color) - Fix SourceForge bug #997741 (PostScript broken on images with y-axis decreasing, and enclosed by PostScript clipping) - Fix SourceForge bug #978822 (documentation wrong on `set path to') - Fix SourceForge bug #932203 (misplaced labels caused by `set x axis labels') - Fix SourceForge bug #928277 (`draw polygon' should take `cm' and `pt' units) - Fix SourceForge bug #930259 (fix `draw arc's drawing of an extra line; thanks for the fix, Wolfgang Voegeli) - Fix SourceForge bug #923719 (`draw curve overlying' ignored the effect of `set dash') - Fix SourceForge bug #914125 (offpage points in axes were reported as having been drawn by `draw curve') - Fix SourceForge bug #877613 (`help' and other commands using temporary files do not work in OSX/Fink version.) - Fix SourceForge bug #874483 (`state save' doesn't keep track of `dash' settings.) - Fix SourceForge bug #873245 (inaccurate times are given in the warnings about slow operations on OSX platform) - Fix SourceForge bug #871477 (the `missing value' feature should not be the default. The solution involved adding a new command `set missing value none', which is now the default. * debian/gri-el.emacsen-install: Log byte compilation in temporary file in /tmp instead of e.g. /usr/share/emacs21/site-lisp/gri-mode.CompilationLog.gz -- Peter S Galbraith Thu, 25 Nov 2004 11:22:34 -0500 gri (2.12.7-1) unstable; urgency=low * New upstream release Bug Fixes: - Fix Debian bug #208589 (did not build on some Debian platforms because it was based on an old version of `automake' (Closes: #208589). -- Peter S Galbraith Wed, 3 Sep 2003 20:12:25 -0400 gri (2.12.6-1) unstable; urgency=low * New upstream version New Features: - Add `age' RPN function, for testing file ages. Bug Fixes: - Fix SourceForge bug 773850 (bounding-box is increased by `draw symbol' even if (rectangular) postscript clipping is active.) - Fix SourceForge bug 760130 (Solaris cannot compile with `C-l' in Makefile. - Fix SourceForge bug 743134 (bounding box not limited by 'set clip postscript') - Fix SourceForge bug 750561 (during compilation, `make' rebuilds HTML docs even if up-to-date) * debian/control: Standards-Version 3.6.1 without changes. -- Peter S Galbraith Mon, 1 Sep 2003 19:51:32 -0400 gri (2.12.5-1) unstable; urgency=low * New upstream version New Features: - Add hexadecimal colornames (Pen Color) Bug Fixes: - Fix SourceForge bug #739761 (`draw time stamp' named the command-file incorrectly). - Fix SourceForge bug #720607 (the emacs mode looked for html documentation files in an incorrect location on linux/redhat systems) * gri-html-doc.emacsen-startup, gri-el.emacsen-startup: Make sure packages are installed before doing elisp setup. -- Peter S Galbraith Tue, 20 May 2003 10:28:24 -0400 gri (2.12.4-2) unstable; urgency=low * Really work around compilation bug on m68k architecture by compiling rpncalc without optimization on m68k(closes: #183912) -- Peter S Galbraith Fri, 11 Apr 2003 20:55:14 -0400 gri (2.12.4-1) unstable; urgency=low * New upstream release Bug Fixes: - Fix Sourceforge bug #696073 (incorrect handling of \$() syntax) - Fix Sourceforge bug #715884 (mixup on quoted strings) - Fix Sourceforge bug #706202 (page orientation Postscript hint missing) - Fix Sourceforge bug #711354 (program name missing in Postscript hint) - Fix compilation bug on m68k architecture (closes: #183912) -- Peter S Galbraith Sun, 6 Apr 2003 9:40:10 -0500 gri (2.12.3-1) unstable; urgency=low * New upstream release Bug Fixes: - Fix SourceForge bug #685919 (Cannot understand .eps file extension on startup.) -- Peter S Galbraith Sun, 2 Mar 2003 13:56:18 -0500 gri (2.12.2-1) unstable; urgency=low * New upstream version Bug Fixes: - Fix SourceForge bug #675304 (Segmentation fault can occur on `read image pgm' if an image already exists, e.g. created by `convert grid to image'.) - Fix SourceForge bug #647234 (Source file draw.cc will not compile on MAC OS X 10.1.5 at optimization level 2, so drop the level to no optimization, as a temporary measure.) - Fix SourceForge bug #671022 (`flip image x|y' did not flip images correctly, except in special circumstances.) - Fix SourceForge bug #669603 (`skip backward .n.' erroneously skipped forward) - Fix SourceForge bug #667754 (`read image pgm' segfaults on memory if an image has already been created by `convert grid to image') - Fix SourceForge bug #664388 (`read image pgm' fails if an image already exists) - Fix SourceForge bug #654129 (ignoring ~/.grirc file) - Fix SourceForge bug #654127 (configure scripts are broken) - Fix SourceForge bug #649132 (removed unused LDFLAGS phrase from Makefile) - Fix SourceForge bug #649134 (tweak gcc optimization) - Fix SourceForge bug #649136 (examples 8 and 9 broken) - Fix SourceForge bug #641406 (RPN too aggressive on missing values) -- Peter S Galbraith Mon, 27 Jan 2003 15:01:03 -0500 gri (2.12.1-2) unstable; urgency=low * Create new gri-el package for Emacs major-mode instead of bundling it with the main gri package. * debian/control: Standards-Version 3.5.7, but I haven't done the optimization depending on DEB_BUILD_OPTIONS yet. -- Peter S Galbraith Fri, 18 Oct 2002 13:36:48 -0400 gri (2.12.1-1) unstable; urgency=low * New upstream version New Features: - n/a Bug Fixes: - Fix SourceForge bug #613075 (sin, cos, tan problem in RPN). -- Peter S Galbraith Wed, 25 Sep 2002 11:04:30 -0400 gri (2.12.0-2) unstable; urgency=low * gri-html-doc.preinst: recent versions of md5sum add a hyphen in the output, which leads to an error in my preinst test for an old config file. Patch from russell@coker.com.au (closes: #161154). -- Peter S Galbraith Tue, 17 Sep 2002 09:32:52 -0400 gri (2.12.0-1) unstable; urgency=low * New upstream version New Features: - Add 'sed' RPN operator, to work on strings. - Add 'skewness and 'kurtosis' RPN operators, to work on columns. Bug Fixes: - Fix SourceForge bug #606303 (web pages were not valid html) - Fix SourceForge bug #593958 (missing-values should be ignored if they occur as intermediate results in RPN calculations) - Fix SourceForge bug #600395 (won't compile with recently released version (3.2) of GCC compiler.) - Fix SourceForge bug #600233 (segfaults if some RPN operators are used on stacks that do not contain enough entries). -- Peter S Galbraith Fri, 6 Sep 2002 20:08:21 -0400 gri (2.10.1-1) unstable; urgency=low * New upstream version Bug Fixes: - Fix Sourceforge bug #562911 (won't build with gcc-3.0; closes: #148572) - Fix SourceForge bug #558463 (in HTML docs, the ``press'' margin tag was misdirected; this was patched into the 2.10.0-1 Debian package) - Fix SourceForge bug #562014 (won't build if 'popt' library is unavailable; closes: #148493). - Fix SourceForge bug #562017 (parser fails with DOS end-of-line) - Fix SourceForge bug #562113 ('new page' postscript error in 'gv' viewer) -- Peter S Galbraith Sat, 1 Jun 2002 10:32:38 -0400 gri (2.10.0-1) unstable; urgency=low * New upstream version New Features: - In the documentation, change the names of some variables to be clearer: `ll_x' is now written `xleft', etc. - Add RPN binary operators 'and', 'or' for logical operations, along with negation operator 'not' - Add 'draw arc' command. - Add 'set x axis labels' and 'set y axis labels' commands. - Permit specification of 'pt' units for 'draw label', 'draw box', 'draw symbol at' and 'draw line from'. - Add 'set clip to curve' command. - Add 'group' and 'end group' commands, in preparation for SVG output. So far these commands do nothing, and are basically just a signal that users should not create commands with these names since Gri will need them soon. - Add ..xinc.. and ..yinc.. builtin variables. - Make the 'open' command accept URLs as filenames. Removed Features: - Remove 'gri -repair old.ps new.ps' - Make the '-chatty' commandline option require a value. Bug Fixes: - Fix SourceForge bug #552009 ('rpn' can segfault if '!=' operator is written as '=!') - Fix SourceForge bug #546109 (bounding box wrong if postscript clipping used) - Fix SourceForge bug #514495 in which 'set clip to curve' failed to handle missing values in the curve. - Fix SourceForge bug #450465 ('create columns from function' was broken). -- Peter S Galbraith Thu, 16 May 2002 11:24:12 -0400 gri (2.8.6-2) unstable; urgency=high * debian/control: added imagemagick, info, gs, gsfonts to Build-Depends. They were in Build-Depends-Indep, but apparently the arch-independent stuff is needlessly built by the autobuilders anyway (closes: #140982). -- Peter S Galbraith Wed, 3 Apr 2002 09:50:14 -0500 gri (2.8.6-1) unstable; urgency=low * New upstream version - Fix SourceForge bug #513002 (minor error in docs for set clip) - Fix SourceForge bug #506592 (HTML docs had misordered indices) - Fix SourceForge bug #506534 (map axes give wrong minutes in negative regions) - Fix SourceForge bug #508088 (gri-mode.el: gv should update, not be relaunched) - Fix SourceForge bug #506490 (-v commandline option returned wrong version number). Note that this was already fixed in Debian release 2.8.5-2. * Various debian directory tweaks merged-in from CVS: * Updated to Standards-Version 3.5.6 (debian/rules uses build-arch and build-indep targets). * debian/rules: Use DH_COMPAT=3 (so that Emacs startup file under /etc/emacs get tagged as conffiles automatically) (closes: #132834, #132840); substitute /debian/tmp by /debian/gri/; * debian/gri.emacsen-install: Edit $(flags) such that XEmacs byte-compilation doesn't load Debian startup files under /etc/emacs. * debian/gri-html-doc.preinst: delete /usr/share/doc/gri-html-doc/html/.dhelp and move potato version of /etc/emacs startup file to .dpkg-old * debian/control: Depends on emacsen-common because of gri-mode install. * debian/gri-html-doc.emacsen-startup: /usr/doc -> /usr/share/doc -- Peter S Galbraith Thu, 7 Feb 2002 16:00:55 -0500 gri (2.8.5-2) unstable; urgency=medium * Gri had a internal version number mismatch, thinking it was version 2.8.4 instead. This confused gri-mode.el, which looked for 2.8.4 and couldn't find it (closes: #130246). -- Peter S Galbraith Mon, 21 Jan 2002 10:12:41 -0500 gri (2.8.5-1) unstable; urgency=low * New upstream bug-fix release: - Fix SourceForge bug #492472 (`inf' rpn operator caused segfault) -- Peter S Galbraith Thu, 13 Dec 2001 10:34:47 -0500 gri (2.8.4-1) unstable; urgency=low * New upstream bug-fix release: - Fix SourceForge bug #467973 (`gri -version' gave wrong version number, breaking the Emacs Gri mode.) - Fix SourceForge bug #468014 (`draw grid' disobeyed pencolor) -- Peter S Galbraith Thu, 4 Oct 2001 14:11:47 -0400 gri (2.8.3-1) unstable; urgency=low * New upstream bug-fix release: - Fix SourceForge bug #462243 (endian problem in Rasterfile images, plus a reading problem in PGM images). -- Peter S Galbraith Mon, 1 Oct 2001 08:53:50 -0400 gri (2.8.2-1) unstable; urgency=low * New upstream bug-fix release: - Really Fix SourceForge bug #454557 when netcdfg-dev present (wouldn't compile with the pre-release version 3.0.1 of the GNU c++ compiler; closes: #111093) -- Peter S Galbraith Mon, 10 Sep 2001 13:10:37 -0400 gri (2.8.1-1) unstable; urgency=low * New upstream bug-fix release: - Fix SourceForge bug #450465 (`create columns from function' was broken). - Fix SourceForge bug #454557 (wouldn't compile with the pre-release version 3.0.1 of the GNU c++ compiler; closes: #111093) -- Peter S Galbraith Thu, 6 Sep 2001 22:26:10 -0400 gri (2.8.0-1) unstable; urgency=low * New upstream version. New command syntax: - Add `unlink' command as a unix-familiar way to delete files. - Add `set page size' command to clip to a given page size. - Add `substr' RPN operator to permit extraction of sub-strings. - Add `default' for the `set x name' and the `set y name' commands. - Add Perl-like ability to put underscores in numerical constants (`.v. = 1_000' and `.v. = 1000' are completely equivalent). Emacs mode: - completes builtin variables and synonyms as well as commands. - "idle-timer help" displays defaults for builtin variables under cursor. - fontification of builtin variables _only_ if spelled correctly. Developer changes: - Add `make source-arch-indep' target in sources. This will build a source tar file in which all the architecture-independent material (documentation in HTML, postscript and Info formats) is pre-made. This makes it easier to install gri on a host that doesn't have TeX and ImageMagick installed. * Move gri-html-doc and gri-ps-doc documentation files to /usr/share/doc/gri * Complies with Standards-Version: 3.5.5 without changes. -- Peter S Galbraith Mon, 23 Jul 2001 20:54:15 -0400 gri (2.6.4-1) unstable; urgency=low * New upstream bug-fix release: - Fix SourceForge bug #435603 (`set dash' produced broken PostScript) - Fix SourceForge bug #435688 (`polar' column type not supported) * Close bug I submitted to keep 2.6.3 from entering testing because of #435603 above (closes: #103366). -- Peter S Galbraith Tue, 3 Jul 2001 15:05:42 -0400 gri (2.6.3-1) unstable; urgency=low * New upstream bug-fix release: - Use gri-mode.el from the 2.7.x stream. - Fix SourceForge bug #433250 (`draw symbol' ignored dashing state sometimes) - Fix SourceForge bug #432549 (contours sometimes unlabelled) - Tweak internal coding for compilation on AIX compilers. -- Peter S Galbraith Fri, 22 Jun 2001 09:15:27 -0400 gri (2.6.2-1) unstable; urgency=low * New upstream version (bug fixes only). - Fix SourceForge bug #425174 (synonym interpolation broken on e.g. show "[\syn]", i.e. if ended with a closing square-brace) - Fix SourceForge bug #425175 (`while !..eof..' acted ignored end of file) -- Peter S Galbraith Sat, 19 May 2001 21:46:10 -0400 gri (2.6.1-1) unstable; urgency=low * New upstream version (bug fixes only). - Fix SourceForge bug #420499 (gri-mode.el compatibility issues with emacs-21; Mostly bad old code.) - Fix SourceForge bug #421076 (byte-compiled gri-mode.el has broken IMenu support; Affects Debian package.) - Fix SourceForge bug #419599 (wouldn't compile under GNU g++ 3.x compiler) - Fix SourceForge bug #418065 (documentation mentions back-tic notation, which is not available) - Fix SourceForge bug #417333 (vague error message `RPN string operator') - Fix SourceForge bug #415277 (make fails on MSDOS) - Fix SourceForge bug #415149 (`file.cc' parse error on MSDOS) - Fix SourceForge bug #414520 (`draw symbol ... at' should automatically produces axes unless the location is in `cm' coordinates) - Fix SourceForge bug #414010 (items in the html concept index were in an odd order) - Fix SourceForge bug #413986 (`~username' was broken in `open') - Fix SourceForge bug #411904 (`/' was ugly in math mode) -- Peter S Galbraith Fri, 11 May 2001 10:48:25 -0400 gri (2.6.0-1) unstable; urgency=low * New upstream version. - Permit `rewind' to take a filename. - Make `open' set `\.return_value.' to the full pathname of the file that was opened. - Add `set path' command. - Remove functioning of `GRIINPUTS' environment variable, since this is more cleanly handled with the newly added `set path to' command. - Remove `\.awk.' synonym, which was deemed to be unhelpful. - Change the format of images in the PostScript output file, as a workaround for a bug in the `ps2pdf' program. - Add ``ampersand'' (`\&' and `\&&') syntax to permit newcommands to look up the name and nesting level of changeable arguments. - Add ``at-sign'' (`@') syntax for aliases. - Add ability to embed newlines in `show' commands with the `\<<' sequence. - Add ability to embed TAB characters in `show' commands with the `\>>'sequence. - Make various `read' commands able to decode synonyms as well as variables and simple numbers. - Add `strlen' RPN operator. - Add `default' option to `set x format' and `set y format' commands. - Add `new postscript file' command. - No longer remove comments from data lines that are read. - Let newcommands have changeable arguments. - Remove `-s' as an abbreviation for the commandline option `-superuser'. - Add commandline option `-output PS_file_name'. - Add `assert' command. - Add `sleep' command. - Permit indexing of synonym words with variables, in addition to constants. - Add `set colorname' command. - Add `source' command. - Add RPN operators `wordc' and `wordv' for accessing the words in the present Gri command. - Add RPN operators `argc' and `argv' for accessing the command-line arguments. - Add automatic support for gzipped compressed data files. - Add two new RPN operators, `file_exists' and `directory_exists'. - Reorganize parts of manual (e.g. changing the section about the Emacs `gri-mode.el' into a chapter, with screenshots). - Improve the HTML form of the manual (e.g. color-code the Gri syntax in examples, provide access to all the indices, use PNG format, etc.). - Numerous gri-mode.el enhancements (including new pull-down menu listing all Gri commands). * Use debhelper. * Info files have .info suffix now. * gri-html-doc suggests doc-base (otherwise it's not registered). * gri.emacsen-remove: delete ${destination}/gri-mode.CompilationLog.gz * gri.postinst: delete obsolete gri-mode.CompilationLog.gz files from prior versions. * Updated to Standards-Version 3.5.2 with DEB_BUILD_OPTIONS variable (Default build no longer complies with debugging symbols, -g) -- Peter S Galbraith Fri, 30 Mar 2001 14:27:29 -0500 gri (2.4.2-1) frozen unstable; urgency=low * New upstream version. ** Bug Fixes Only; No new features ** - Remove bug in which `convert grid to image' produced incorrect images, visible as a patchy appearance with coarse grids. - Remove bug in which `convert image to grid' failed to take note of the gri minimum and maximum, so that contouring of the grid was not possible for grids created from images. -- Peter S Galbraith Mon, 27 Mar 2000 10:46:36 -0500 gri (2.4.0-1) unstable; urgency=low * New upstream version. Introduces "set input data separator" to use TABs as column separators. We can now mix numerical columns with character strings in read commands. * Make gri-html-doc package redefine gri*WWW-page Emacs variable. * Quiet the byte-compiler in /usr/lib/emacsen-common/packages/install/gri * Updated to Standards-Version 3.1.1 with Build-Depends. -- Peter S Galbraith Wed, 5 Jan 2000 15:17:53 -0500 gri (2.2.4-2) unstable; urgency=low * Upstream source tar file changed without new version number to fix small buglet in HTML docs. * Fixed bug in description of gri-ps-doc package -- Peter S Galbraith Sat, 6 Nov 1999 21:25:57 -0500 gri (2.2.4-1) unstable; urgency=low * New upstream release. Includes support for iso-latin characters * Split package into gri, gri-ps-doc and gri-html-doc * Update to policy 3.0.0 (FHS issue of /usr/share/doc, etc) -- Peter S Galbraith Wed, 20 Oct 1999 14:39:19 -0400 gri (2.2.1-2) unstable; urgency=low * i386 package recompiled against g++ version 2.91.66-0slink2 -- Peter S Galbraith Mon, 05 May 1999 12:05:00 -0500 gri (2.2.1-1) unstable; urgency=low * Edited upstream configure script to enable netCDF compilation * Small upstream tweak to doc/Makefile * new license: GPL! -- Peter S Galbraith Mon, 29 Jan 1999 14:23:00 -0500 gri (2.2.0-1) unstable; urgency=low * Initial Release. -- Peter S Galbraith Mon, 22 Jan 1999 18:45:05 -0500 gri/debian/rules0000755000175000017500000001027213147557614012324 0ustar psgpsg#!/usr/bin/make -f # Made with the aid of dh_make, by Craig Small # Sample debian/rules that uses debhelper. GNU copyright 1997 by Joey Hess. # Also some stuff taken from debmake scripts, by Cristopt Lameter. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 #version=$(shell expr `pwd` : '.*-\([0-9.]*\)') #version := $(shell grep ^VERSION Makefile | cut -d" " -f3) version := $(shell perl -ne 'if (/AC_INIT\(gri, ([0-9.]+)\)/){print $$1}' configure.ac) somefutureversion=2.14.0 CXXFLAGS = -O2 -Wall ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS))) CXXFLAGS += -g endif ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) STRIPIT=1 endif ARCH := $(shell dpkg --print-architecture | perl -pe chop) build: build-indep build-arch # Build architecture-dependent files here (no need to be root). build-arch: debian/gri_merge.1 gri cd doc; make info gri: Makefile dh_testdir ifeq ($(ARCH),m68k) cd src; make CXXFLAGS="-O0 -Wall" rpncalc.o endif cd src; make CXXFLAGS=${CXXFLAGS} clean: dh_testdir dh_testroot [ ! -f Makefile ] || $(MAKE) distclean mv doc/FAQ.html doc/FAQ.html.KEEP -rm -f config.log config.status debian/Makefile doc/*.html -rm -f doc/gri.info* doc/*.dvi doc/*.ps doc/*.pdf doc/*.log doc/html -rm -f doc/screenshots/*.pdf doc/examples/*.pdf -rm src/gri.cmd src/startup.msg-tmp mv doc/FAQ.html.KEEP doc/FAQ.html -mv texinfo.tex.KEEP texinfo.tex -mv doc/texinfo.tex.KEEP doc/texinfo.tex dh_clean rm -fR debian/gri-$(version)static rm -f debian/README.Debian debian/gri.1 rm -f doc/gri_unpage.1 doc/gri_merge.1 chmod u+w debian/changelog install: gri dh_testdir dh_testroot dh_prep dh_installdirs cd src; make install_linux_debian debian=`pwd`/../debian/gri debian/gri_merge.1: #sed -e 's/VSN/$(version)/g' \ # debian/copyright.template > debian/copyright sed -e 's/LATERVSN/$(somefutureversion)/g;s/VSN/$(version)/g' \ debian/gri.man > debian/gri.1 sed -e 's/LATERVSN/$(somefutureversion)/g;s/VSN/$(version)/g' \ debian/README.Debian.template > debian/README.Debian cp doc/gri_unpage.1-skel doc/gri_unpage.1 cp doc/gri_merge.1-skel doc/gri_merge.1 # Temporary fix for 2.12.23-9 (Fixed upstream for 2.12.24) -mv texinfo.tex texinfo.tex.KEEP -mv doc/texinfo.tex doc/texinfo.tex.KEEP Makefile: # To test on g++-3.0 : # CC=gcc-3.0 CXX=g++-3.0 ./configure --prefix=/usr ./configure --prefix=/usr --enable-linux_debian # Build architecture-independent files here (no need to be root). build-indep: debian/gri_merge.1 Makefile cd doc; make refcard.ps cmdrefcard.ps gri.pdf html # Install (as root) architecture-independent files here. binary-indep: build-indep dh_testdir -i dh_testroot -i install -d debian/gri-el/usr/share/emacs/site-lisp/gri-el install -m 644 src/gri-mode.el debian/gri-el/usr/share/emacs/site-lisp/gri-el install -d debian/gri-pdf-doc/usr/share/doc/gri install -m 644 doc/gri.pdf debian/gri-pdf-doc/usr/share/doc/gri install -m 644 doc/refcard.ps debian/gri-pdf-doc/usr/share/doc/gri install -m 644 doc/cmdrefcard.ps debian/gri-pdf-doc/usr/share/doc/gri cd doc; make html-install DESTDIR=`pwd`/../debian/gri-html-doc/ rm -f debian/*debhelper dh_installdocs -i -A README debian/README.Debian dh_installexamples -i dh_installemacsen -i dh_installchangelogs -i dh_compress -i -X.jpg -Xlogo.gri dh_fixperms -i dh_installdeb -i dh_gencontrol -i dh_md5sums -i dh_builddeb -i # Install (as root) architecture-dependent files here. binary-arch: build-arch install dh_testdir -a dh_testroot -a (cd debian/gri/usr/share/gri/$(version) ; ln -fs ../../common-licenses/GPL license.txt) rm -f debian/*debhelper dh_installdocs -a README dh_installexamples -a dh_installemacsen -a dh_installinfo doc/gri.info* dh_installman debian/gri.1 doc/gri_unpage.1 doc/gri_merge.1 (cd debian/gri/usr/share/man/man1 ; ln -fs gri.1.gz gri-$(version).1.gz) dh_installchangelogs -a ifdef STRIPIT dh_strip -a endif dh_compress -a dh_fixperms -a dh_installdeb -a dh_shlibdeps -a dh_gencontrol -a dh_md5sums -a dh_builddeb -a source diff: @echo >&2 'source and diff are obsolete - use dpkg-source -b'; false binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary gri/debian/README.Debian.unofficial0000644000175000017500000000060513147557614015422 0ustar psgpsggri --- Comments regarding the Package: THIS PACKAGE IS NOT PART OF DEBIAN, but it is created from the same source, .diff and .dsc files. This package exists to live alongside a newer release of the regular gri package, providing backwards compatibility for your old code that may depend on this version of Gri. Peter S Galbraith , Sun, 10 Jan 1999 12:45:05 -0500 gri/debian/gri-html-doc.emacsen-startup0000644000175000017500000000031013147557614016557 0ustar psgpsg(if (not (file-exists-p "/usr/share/doc/gri/html/index.html")) (message "Package gri-htnl-doc is not installed. Skipping setup.") (setq gri*WWW-page "file:/usr/share/doc/gri/html/index.html")) gri/debian/gri-el.emacsen-compat0000644000175000017500000000000213147557614015227 0ustar psgpsg0 gri/debian/gri-el.emacsen-remove0000644000175000017500000000132613147557614015253 0ustar psgpsg#!/bin/sh # # emacsen remove script for the gri package # - # This script is installed by the Gri package `rules' file to # /usr/lib/emacsen-common/packages/remove/gri # It is run by Gri package `prerm' which calls # /usr/lib/emacsen-common/emacs-package-remove gri # The Gri package `prerm' is installed as /var/lib/dpkg/info/gri.prerm set -e flavour=$1 package=gri ELCDIR=/usr/share/${flavour}/site-lisp/gri-el if [ ${flavour} != emacs ] then echo remove/${package}: Purging byte-compiled files for flavour ${flavour} rm -f ${ELCDIR}/gri-mode.elc rm -f ${ELCDIR}/gri-mode.el rmdir --ignore-fail-on-non-empty ${ELCDIR} else echo remove/${package}: Ignoring emacsen flavour ${flavour} fi exit 0; gri/darwinport/0000755000175000017500000000000013147557614012211 5ustar psgpsggri/darwinport/Portfile0000644000175000017500000000243613147557614013725 0ustar psgpsg# $Id: Portfile,v 1.8 2008/06/05 22:34:47 dankelley Exp $ PortSystem 1.0 name gri version 2.12.17 categories science graphics platforms darwin maintainers dan.kelley@dal.ca j.stalnaker@neu.edu description A scientific graphics programming language long_description Gri is a language for scientific graphics programming. \ The word "language" is important: Gri is command-driven, \ not point/click. \ Some users consider Gri similar to LaTeX, since both \ provide extensive power in exchange for patience in \ learning syntax.\ Gri can make x-y graphs, contour graphs, and image \ graphs, in PostScript and (someday) SVG formats. \ Control is provided over all aspects of drawing, e.g. \ line widths, colors, and fonts. A TeX-like syntax \ provides common mathematical symbols. homepage http://gri.sourceforge.net master_sites sourceforge checksums md5 235c32be7dca8db9ab56cb8ee9162f39 depends_build port:ImageMagick \ bin:tex:texlive \ port:ghostscript \ port:perl5.8 configure.args --infodir=${prefix}/share/info gri/darwinport/files/0000755000175000017500000000000013147557614013313 5ustar psgpsggri/darwinport/files/patch-gritexi.diff0000644000175000017500000000074113147557614016717 0ustar psgpsg--- ./doc/gri.texi.orig 2006-07-16 10:32:04.000000000 -0300 +++ ./doc/gri.texi 2006-07-16 10:32:26.000000000 -0300 @@ -16252,7 +16252,7 @@ you would have put the cursor over either the word `lower' or `upper', and invoke @code{gri-kill-option} (@kbd{C-C C-k}) instead. -@strong{NOTE:} you might want to practice using this example to learn +You might want to practice using this example to learn how to do it. If you make a mistake, note that the normal Emacs undo works. gri/darwinport/files/patch-doc-examples.diff0000644000175000017500000000045113147557614017623 0ustar psgpsg--- ./doc/examples/Makefile.am.orig 2006-07-15 21:02:01.000000000 -0300 +++ ./doc/examples/Makefile.am 2006-07-15 21:02:19.000000000 -0300 @@ -62,7 +62,7 @@ cp $< $@ chmod +w $@ %.png : %.ps - convert $< $@ + -convert $< $@ %-tiny.png : %.png -convert -geometry 90x999 $< $@ %.pdf : %.ps gri/darwinport/files/patch-startup.diff0000644000175000017500000000076213147557614016751 0ustar psgpsg--- ./src/startup.msg.orig 2006-07-16 09:15:39.000000000 -0300 +++ ./src/startup.msg 2006-07-16 09:15:58.000000000 -0300 @@ -4,7 +4,7 @@ Type `help' to view list of commands. Type `show license' to view license. - Examples at: PREFIX/share/doc/gri/examples - Manual at: PREFIX/share/doc/gri/html/index.html + Examples at: PREFIX/share/gri/doc/examples + Manual at: PREFIX/share/gri/doc/html/index.html Info Manual at: gri Resources at: http://gri.sourceforge.net gri/darwinport/files/patch-doc.diff0000644000175000017500000000255413147557614016015 0ustar psgpsg--- ./doc/Makefile.am.orig 2006-07-15 21:16:52.000000000 -0300 +++ ./doc/Makefile.am 2006-07-15 21:18:22.000000000 -0300 @@ -132,26 +132,29 @@ # cp gri.info* $(INFO_DIR_SOLARIS) # chmod 644 $(INFO_DIR_SOLARIS)/gri.info* +TEX=/usr/local/teTeX/bin/powerpc-apple-darwin-current/tex +PDFTEX=/usr/local/teTeX/bin/powerpc-apple-darwin-current/pdftex + refcard.ps: refcard.tex - tex $(srcdir)/refcard.tex + $(TEX) $(srcdir)/refcard.tex dvips -o refcard.ps -t landscape -t letter refcard.dvi cmdrefcard.ps: cmdrefcard.tex - tex $(srcdir)/cmdrefcard.tex + $(TEX) $(srcdir)/cmdrefcard.tex dvips -o cmdrefcard.ps -t landscape -t letter cmdrefcard.dvi gri.ps: gri.texi cd examples ; ${MAKE} eps cd screenshots ; ${MAKE} eps cd tst_suite ; ${MAKE} texi - tex gri.texi + $(TEX) gri.texi texindex gri.cp texindex gri.fn texindex gri.ky texindex gri.pg texindex gri.tp texindex gri.vr - tex gri.texi + $(TEX) gri.texi dvips -o gri.ps -t letter gri.dvi #ps-install: gri.ps @@ -163,14 +166,14 @@ cd examples ; ${MAKE} pdf cd screenshots ; ${MAKE} pdf cd tst_suite ; ${MAKE} texi - pdftex gri.texi + $(PDFTEX) gri.texi texindex gri.cp texindex gri.fn texindex gri.ky texindex gri.pg texindex gri.tp texindex gri.vr - pdftex gri.texi + $(PDFTEX) gri.texi # Add to some of the automake-created targets. all-local: refcard.ps cmdrefcard.ps gri/README0000644000175000017500000000332713147557614010705 0ustar psgpsgWhat Gri is =========== Gri is a language for scientific graphics applications. By 'language' I mean that it is a command-driven application, as opposed to a click/point application. It is analogous to latex or tex, and shares the property that extensive power is the reward for tolerating a learning curve. Gri output is in PostScript, suitable for incorporation in documents prepared by various text processors. Gri can make x-y graphs, contour-graphs, and image graphs. In addition to high-level capabilities, it has enough low-level capabilities to allow users to achieve a high degree of customization. Control is extended to all aspects of drawing, including line widths, colors, and fonts. Text includes a subset of the tex language for letters and mathematical symbols in labels. Compiling and Installing Gri ============================ The normal case is to have received the Gri source as a so-called "tarball". If that is how you got Gri, then you should type ./configure make make install at the shell to create and install Gri. If there is a problem in these steps, trying typing aclocal autoconf automake --add-missing first to create some configuration files, and then you type ./configure make make install as usual. Copyright restrictions ====================== The Gri programming languages, and all manuals and online help-files, are (c) 1991-2017 Dan E. Kelley . Gri includes a pared-down form of the popt library which in its original form is (c) 1998 Red Had Software and distributed under the X license. The Gri Emacs mode (gri-mode.el) is (c) 1994-2017 Peter S. Galbraith Gri and gri-mode.el are distributed under GPLv3 license or later; see COPYING. gri/ChangeLog0000644000175000017500000003326413147557614011602 0ustar psgpsg2008-05-29 Dan E. Kelley * this file has not been updated in years; consult the official documentation instead. 2003-07-19 Dan E. Kelley * src/gr.cc (gr_drawsymbol): Fix SF 773850 bug (bbox increased by 'draw symbol' even if ps clip) 2003-05-19 Dan E. Kelley * startup.cc (start_up): Fix SF bug 739761 ('draw time stamp' broken) 2003-05-03 Dan E. Kelley * README-linux-redhat: had wrong directory for docs (patch provided by Kawamura Masao) * utility.cc (tmp_file_name): fix bug that would prevent compilation if the HAVE_TEMPNAM flag were set (patch provided by Kawamura Masao) 2003-04-14 Peter S Galbraith * Makefile.in: Fix HTML manual link in gri-mode.el installed on RedHat. Fixes SF bug 720607. 2003-04-06 Dan E. Kelley * doline.cc (sub_dollar_paren): fix SF bug 696073 2003-04-05 Dan E. Kelley * doline.cc (remove_comment): fix problem in scanning double-quoted strings 2003-01-08 Dan E. Kelley * read.cc (read_pgm_image): fix SF bug 664388 ('read image P5' broken) 2002-11-23 Dan E. Kelley * rpncalc.cc (do_operation): fix SF bug 641406 (RPN too aggressive on missing values) 2002-09-07 Dan Kelley * Gri version 2.12.0. 2002-08-28 Dan Kelley * variable.cc (put_var): catch assignment to ..missingvalue.., and set the missing value if so 2002-07-21 Dan Kelley * CHANGE definition of kurtosis used in "column statistics", to be the more basic of the two common definitions (i.e. the one without 3 subtracted) * rpncalc.cc (do_operation): Add rpn operators for column skewness and kurtosis 2002-06-16 Dan Kelley * rpncalc.cc (do_operation): add hex2dec and dec2hex RPN operators 2002-06-08 Dan E. Kelley * doc/texinfo2HTML (sub_refs): add ability to handle uref texinfo item, which makes cross-referencing urls a lot easier. 2002-06-05 Dan Kelley * rpncalc.cc (do_operation): Add 'sed' binary operator (do_operation): use GriString and string objects, instead of C character array, for safety 2002-06-01 Dan Kelley * Fix Sourceforge bug 562911 (won't build with gcc-3.0) * Fix Sourceforge bug 562558 ('draw title' confusion with log axes) * Fix Sourceforge bug 562014 (won't build if popt library is unavailable) * Fix SourceForge bug 558463 (in HTML docs, the ``press'' margin tag was misdirected) * Fix SourceForge bug 562017 (parser fails with DOS end-of-line) * Fix SourceForge bug 562017 ('new page' postscript error in gv viewer) 2002-05-16 Dan Kelley * gri.cmd, doc/gri.texim, and some code: rename variables such as .ll_x. as .xleft., thus increasing uniformity and ease of understanding 2002-05-07 Dan Kelley * configure.in (PROGS): remove the check for popt, which won't be used in the 2.x series (but remains, commented-out, for the 3.x series) 2002-05-04 Dan Kelley * rpn.cc: Fix SourceForge bug #552009 (`rpn' can segfault if `!=' operator is written as `=!') 2002-04-21 Dan E. Kelley * set.cc (set_clipCmd): move the postscript clipping work to gr.cc, isolating the control of the PS file to smooth the road for SVG. 2002-04-04 Dan Kelley * set.cc (set_x_axisCmd): Add user-supplied axis labels (same for y axis) * graxes.cc (gr_drawxaxis): Add user-supplied axis labels (same for y axis) 2002-03-18 Dan Kelley * draw.cc (draw_labelCmd): Permit 'draw label' coordinates in pt 2002-03-16 Dan Kelley * regress.cc (regressCmd): Fix Sourceforge bug ##482120 ('regress' ignored data weights. * grstring.cc (gr_DrawChar): Fix Sourceforge bug #508657 (drawing of strings containing undefined synonyms was missing the backslash that should have been present). 2002-03-12 Dan E. Kelley * draw.cc (draw_box_filledCmd): permit 'draw box' coordinates in pt (draw_symbolCmd): permit 'draw symbol' coordinates in pt (draw_line_from_toCmd): permit 'draw line' coordinates in pt * GriPath.cc (stroke_or_fill): permit coordinates in pt (bounding_box): permit coordinates in pt * gri.cmd: permit 'draw box' and 'draw symbol' to have coordinates in pt * draw.cc (draw_boxCmd): allow 'draw box' to specify coordinates in pt 2002-02-27 Dan E. Kelley * set.cc: Fix Sourceforge bug #523450 (log axes detect non-positive values too late) 2002-02-21 Dan E. Kelley * Fix Sourceforge bug #513002 (minor error in documentation of 'set clip'). * Fix sourceforge bug #521045 (install problem, function prototype problem). * Fix Sourceforge bug #509592 (doc HTML indices misordered). * Fix SourceForge bug #506523 (map axes give wrong minutes in negative regions). * Fix SourceForge bug #508088 (grimode: gv should update, not be relaunched). * Make RPM install/uninstall run silently. * Fix SourceForge bug #506490 ('-v' commandline option gave wrong number) * Add `set clip to curve'. (Not reliable yet, for long curves, and also I've not finalized the winding convention yet.) 2001-12-13 Dan E. Kelley * rpncalc.cc: insert a missing 'return' statement, to fix gri.sf.net bug number 492472 (i.e. that the "inf" RPN operator was broken). 2001-10-18 Dan E. Kelley * startup.cc (interpret_optional_arguments): examine the commandline argument "-output NNN" for various file types, e.g. GIF and SVG files, but (so far) only actually _handle_ postscript file types. I think SVG output would be nice, since I think that's where free vector-graphics editors are going. 2001-10-14 Dan E. Kelley * variable.cc (put_var): update the _xinc and _yinc values, if the variables named ..xinc.. or ..yinc.. get modified * scales.cc (create_y_scale): keep ..xinc.. and ..yinc.. up to date as scales are changed * startup.cc (set_defaults): store ..xinc.. and ..yinc.. * doc/gri.texim: update the history sections to account for versions 2.8.3 and 2.8.4 * startup.redhat: rewrite to shorten and clarify; also, put in a pointer to the SourceForge website. 2001-10-13 Dan E. Kelley * startup.cc (start_up): prevent segfault if no command-file name is supplied * set.cc (set_line_widthCmd): make 'set line width rapidograph' (that is, with no pen-width name) give a more informative error * utility.cc (show_words): this will help in debugging 2001-10-09 Dan E. Kelley * Makefile.in (check): add 'make check', to run the 'check.pl' Perlscript (see next item) * check.pl: add this new feature, which checks version numbers in the various files, and will (I hope) eventually check other aspects of a release. 2001-10-01 Dan E. Kelley * Release as gri-2.8.4 on SourceForge.Net site. * Fix SourceForge bug #467973 (`gri -version' gave wrong version number, breaking the Emacs Gri mode.) * Fix SourceForge bug #468401 (`draw grid' disobeys pencolor) 2001-10-01 Dan E. Kelley * Release as gri-2.8.3 on SourceForge.Net site. * Fix SourceForge bug #462243 (endian problem in Rasterfile images, plus a reading problem in PGM images). 2001-09-10 Dan E. Kelley * Release as gri-2.8.2 on SourceForge.Net site. * Really fix SourceForge bug #454557 (wouldn't compile with the pre-release version 3.0.1 of the GNU c++ compiler). This closes SourceForge Bug #111093. 2001-09-06 Dan E. Kelley * Release as gri-2.8.1 on SourceForge.Net site. * Fix SourceForge bug #450465 (`create columns from function' was broken). * Fix SourceForge bug #454557 (wouldn't compile with the pre-release version 3.0.1 of the GNU c++ compiler). Closes Sourceforge bug #111093) 2001-07-24 Dan E. Kelley * Bump up version number to 2.8.0 2001-07-23 Dan E. Kelley * Release as gri-2.8.0 on SourceForge.Net site. * Add `unlink' command as a unix-familiar way to delete files. * Add `set page size' command to clip to a given page size. * Add `substr' RPN operator to permit extraction of sub-strings. * Add `default' for the `set x name' and the `set y name' commands. * Add Perl-like ability to put underscores in numerical constants (`.v. = 1_000' and `.v. = 1000' are completely equivalent). * In Emacs mode, change so that it completes builtin variables and synonyms as well as commands. * In Emacs mode, add "idle-timer help" to display defaults for builtin variables under cursor. * In Emacs mode, make fontification of builtin variables apply only if spelled correctly. * To Makefile, add `make source-arch-indep' target in sources. This will build a source tar file in which all the architecture-independent material (documentation in HTML, postscript and Info formats) is pre-made. This makes it easier to install gri on a host that doesn't have TeX and ImageMagick installed. * Move gri-html-doc and gri-ps-doc documentation files to the /usr/share/doc/gri directory * Ensure that package compiles with Standards-Version: 3.5.5 without changes. 2001-04-19 Dan E. Kelley * Rename the RPM spec file as gri.spec, without the version number embedded in the filename. Upgrade to version number 2.6.1. Change url to point to sourceforge site (but leave ftp as it is, for now anyway). 2000-06-1 Dan E. Kelley * Triv changes here; code changes are to read compressed files, and manual improvements. 2000-05-30 Peter S. Galbraith * doc/gri.texi: Added Emacs gri-mode chapter. * doc/gri.texi: Example images are not in example directory anymore. * doc/screenshots: new directory. * doc/gri2html: Colorize .gri file in HTML manual. * index.html: Now first page instead of gri1.html * doc/HTML_subdivide: Now has better navigation tags. * doc/examples: All examples are jpg instead of Gif. * doc/texinfo2HTML: skips a few more @if constructs. * doc/Makefile: Updated for above things. * Makefile.in: Updated source target 2000-05-12 Dan E. Kelley * Compress info files for linux-redhat. 2000-05-11 Peter S Galbraith * Change info files to .info file extension. * Tweaked install-info rules. I hope they work. * Patch texinfo2HTML to skip over the @dircategory line and the @direntry block. * Uncomment them in gri.texi * Make gri.texi produce .info extensions (@setfilename gri.info) * Patch gri-2.5.1.spec, Makefile.in and doc/Makefile targets to use .info extension. 2000-05-07 Dan E. Kelley * VERSION 2.4.4 * Make it report a warning, rather than an error, if mathematical operations are tried on empty columns (e.g. 'y += 10'). * The Makefile doesn't automatically link to the math library; instead it uses "./configure" to figure out whether a math library exists. This is because BeOS doesn't use the math library. * Some other changes to Makefile, which I think/hope affect only "make install", not "make install_linux_debian" or "make install_linux_redhat". * I no longer use "popen()" subroutine, which BeOS does not have, unless I REALLY need it. (utility.cc) * Clean up a few things in the configure script, mainly by renaming variables to be more readible, and by removing tests for architectures that never have any affect on the code. 2000-04-01 Dan E. Kelley * Fix spec-file error in the install-info command. However, to my great frustration, this is still broken or install-info is broken) since the command doesn't install an entry for gri. After hand-editing to insert a Gri entry, I uncovered another bug, and so I have added a chmod of /usr/info/dir file so folks other than root can use info. * Update the version number in gri.cmd to match the number compiled into gri. * Update the startup message from the old form to the new form. * Call this release 3 to match Tim Powers' convention (although I think it should be called release 1, when it works!) 2000-03-31 Dan E. Kelley * applied Tim Powers' patches directly to the sources, updating them so that the patches Tim had made in this spec file are no longer needed. Note: I didn't apply Tim's patch to the documentation, since visual inspection indicated that I had already repaired the errors he found (each of which which involved my having used an incorrect name for the example gif files.) * renamed Tim's spec file from gri.spec to gri-2.4.3.spec since otherwise I'd get too confused as versions develop. 2000-01-30 Dan E. Kelley * Changing to e.g. /usr/share/info instead of /usr/info. Same for manpages. I know, I should be using the fancy macros that are defined in /usr/lib/rpm, but these seemed contradictory, with respect to where things are in my Redhat 7.0 setup ... and I had a hard time figuring out how to use these macros anyway, so I just gave up and hard-wired them in, using the new directories as used in Redhat 7.0, as opposed to the (different) directories in all the other Redhat versions I've had. Someday I'll switch to using macros, but it means changing both this spec-file and various Makefiles, and I need to be sure that changes to the Makefiles don't hurt the distributions for Debian linux, for solaris, etc. gri/Makefile.in0000644000175000017500000005751213147560317012071 0ustar psgpsg# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope am__DIST_COMMON = $(srcdir)/Makefile.in AUTHORS COPYING ChangeLog \ INSTALL NEWS README THANKS compile config.guess config.sub \ depcomp install-sh missing mkinstalldirs DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print VPATH = @srcdir@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS_TEMPLATE = @EXTRA_CFLAGS_TEMPLATE@ GREP = @GREP@ HAVE_CONVERT = @HAVE_CONVERT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PROGS = @PROGS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ # gri: Makefile.am srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src doc debian DIST_SUBDIRS = doc src debian EXTRA_DIST = ChangeLog README README-linux-redhat README-SunOS5\ license.txt copyright.txt gri.spec grilogo.gif THANKS missing all: all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ distcheck distclean distclean-generic distclean-tags \ distcleancheck distdir distuninstallcheck dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gri/developer-helper.pl0000755000175000017500000000463113147557614013626 0ustar psgpsg#!/usr/bin/perl -w $gri_version = "2.12.2"; $prompt = "\t>> "; $debug = 1; $snippet_separator_top = "+++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++\n"; $snippet_separator_bot = "--- --- --- --- --- --- --- --- --- --- --- ---\n"; sub document_bug_fix() { print "Give version number (ENTER for $gri_version):\n$prompt"; $_ = <>; chop; $gri_version = $_ if (!/^$/); print "Give bug number at SourceForge.Net:\n$prompt"; $_ = <>; chop; while (/\D/) { print "Error: bug numbers may not contain non-numeric characters.\n"; print "Give bug number at SourceForge.Net:\n$prompt"; $_ = <>; chop; } $bug_number = $_; # one-liner print "Give one-line description of bug (for use in changelogs)\n$prompt"; $_ = <>; chop; $description_short = $_; # long description print "Give multi-line description of bug (html is okay), ending with blank line\n"; $description_long = ""; while (1) { print $prompt; $_ = <>; last if (/^$/); $description_long .= $_; } if ($debug) { print "Bug number: $bug_number\n"; print "Short description: $description_short\n"; print "Long description: $description_long\n"; } # print "\nSNIPPET for gri.spec, after the line '%changelog':\n"; print "$snippet_separator_top"; $d = `date '+%a %b %d %Y'`; chop($d); print "* $d Dan Kelley \n"; print "- fix SourceForge bug $bug_number ($description_short)\n"; print "$snippet_separator_bot"; # print "\nSNIPPET for debian/changelog (at top of file):\n"; print "$snippet_separator_top"; print "gri ($gri_version) unstable; urgency=low\n"; print "\n"; print " * New upstream version\n"; print " Bug Fix:\n"; print " - Fix SourceForge bug #$bug_number ($description_short)\n"; print "$snippet_separator_bot"; print "\nSNIPPET for doc/gri.texim (after the line '%comment ADD-NEW-BUG-FIXES-HERE'):\n"; print "$snippet_separator_top"; $d = `date '+%Y %b %d'`; chop($d); print "\@subsubsection Version $gri_version [$d]\n"; print "\@strong\{Bug Fixes\}\n"; print "\@itemize\n"; print "\@item\n"; print "Fix SourceForge bug\n"; print "\@uref\{http://sourceforge.net/tracker/index.php?func=detail&aid=$bug_number&group_id=5511&atid=105511,#$bug_number\}\n"; print "\@dots\{\} $description_long\n"; print "$snippet_separator_bot"; } document_bug_fix(); gri/fix-tar-ball0000755000175000017500000000126513147557614012234 0ustar psgpsg#!/bin/bash # Usage: # ./fix-tar-ball gri-2.12.10.tar.gz # TARBALL=$1 if [ -z "$1" ] ; then echo "Usage: ./fix-tar-ball gri-2.12.10.tar.gz" echo " Missing argument" exit 0 fi DIRECTORY=$(echo ${TARBALL} | perl -ne 'if (/(gri-[0-9.]+).t/){print $1}') # extract TARBALL into DIRECTORY tar zxf ${TARBALL} # fix permissions chmod -R u+w ${DIRECTORY} # fix debian/changelog if broken if test -e "${DIRECTORY}/debian/ChangeLog"; then echo "Fixing debian/ChangeLog" mv -f ${DIRECTORY}/debian/ChangeLog ${DIRECTORY}/debian/changelog fi # rebuild tar ball tar cf ${DIRECTORY}.tar ${DIRECTORY}/ mv -f ${TARBALL} ${TARBALL}.old gzip --best ${DIRECTORY}.tar rm -fR ${DIRECTORY} gri/AUTHOR-NOTES0000644000175000017500000000502413147557614011634 0ustar psgpsgGri release procedure ===================== The list below is the typical procedure leading up to a release, where "DEK" is the primary author, and "PSG" is the debian packager. 1. DEK fixes a bug or adds a feature, and then indicates this by updating ``configure.ac`` and ``doc/gri.texi``. (The latter file needs updating both near the top, where the new and old versions are numbered explicitly, and also at the History section.). Then he does a ``git-push``, and asks PSG to ``git-pull`` it. 2. PSG updates various debian files, does a ``git-push``, and asks DEK to do a ``git-pull``. 3. DEK verifies that the build works. Then he makes a tarball and sends it to PSG for testing. 4. PSG tests it. Steps 1--3 are repeated if there is a problem, otherwise he tells DEK that the tarball is OK. 5. DEK uploads the tarball to SourceForge and makes the release. 6. PSG does the debian release. Working with issues and branches ================================ Suppose we want to fix issue3 on github (http://github.com/dankelley/gri/issues/#issue/3). We want to be able to work from two machines, so we need a remote branch. Here's what we do: 1. Do ``git branch issue3`` to create a local branch. Note that the branch name matches the issue name. 2. Do ``git push origin issue3`` to put this branch on the remote repo. Total 0 (delta 0), reused 0 (delta 0) To git@github.com:dankelley/gri.git * [new branch] issue3 -> issue3 3. Do ``git branch -d issue3`` to remove the local branch. 4. Do ``git checkout --track origin/issue3`` to track the remote branch. 5. Fix the bug in this branch. (If working on several machines, be sure to always do a ``git checkout issue3`` and then ``git pull`` to update the branch before editing anything.) 6. Do ``git checkout master`` to return to the master branch. 7. Do ``git merge --no-ff issue3`` to merge this in. (The ``no-ff`` is important, because it preserves the branch record cleanly.) 8. Do ``git push`` to push this newly-updated master back to remote. 9. Do ``git push origin :heads/issue3`` to remove the remote branch. 10. Do ``git branch -d issue3`` to remove the local branch. (Note that the syntax is quite different to the removal of local branches.) Building from git source ======================== We no longer have ``configure`` in the repository, so the procedure is three step: 1. Do ``autoconf`` 2. Do ``automake`` 3. Do ``./configure && make`` (Note: I don't know whether the order of steps 1 and 2 matter, so I do them twice -- DK.) gri/INSTALL0000644000175000017500000000174513147557614011060 0ustar psgpsgIf you are reading this file, it means you are trying to build and install Gri. The method for this depends on how you got the Gri source. CASE 1 ------ If the gri source is a "tarball" from http://gri.sourceforge.net (or another source), do as follows. :: ./configure make make check make install If you wish to control the location in which Gri is installed, use a "prefix" command at the configure stage, e.g. :: ./configure --prefix=/opt There are also some special flags; read the ``configure.ac`` file to learn about them. One that the author is working on lately is exemplified :: --enable-OSX_BUNDLE which is used to cause Gri to look for gri.cmd in the same directory as the executable, which is useful in an OSX bundle application. CASE 2 ------ If the gri source is from the "git" server at http://github.com/dankelley/gri, do :: automake autoconf to create the ``configure`` file, and then follow the same procedure as in Case 1. gri/config.sub0000755000175000017500000010535413147557614012013 0ustar psgpsg#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2013 Free Software Foundation, Inc. timestamp='2013-08-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches with a ChangeLog entry to config-patches@gnu.org. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 \ | or1k | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or1k-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: gri/install-sh0000755000175000017500000001124313147557614012025 0ustar psgpsg#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" tranformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 gri/configure0000755000175000017500000063632013147560121011724 0ustar psgpsg#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for gri 2.12.26. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='gri' PACKAGE_TARNAME='gri' PACKAGE_VERSION='2.12.26' PACKAGE_STRING='gri 2.12.26' PACKAGE_BUGREPORT='' PACKAGE_URL='' ac_unique_file="src/gri.cc" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS OS_IS_SOLARIS_FALSE OS_IS_SOLARIS_TRUE OS_IS_LINUX_DEBIAN_FALSE OS_IS_LINUX_DEBIAN_TRUE OS_IS_LINUX_REDHAT_FALSE OS_IS_LINUX_REDHAT_TRUE OS_IS_FINK_FALSE OS_IS_FINK_TRUE OS_IS_FREEBSD_FALSE OS_IS_FREEBSD_TRUE OS_IS_OSX_BUNDLE_FALSE OS_IS_OSX_BUNDLE_TRUE OS_IS_APPLE_OSX_FALSE OS_IS_APPLE_OSX_TRUE OS_HAS_POPT_FALSE OS_HAS_POPT_TRUE HAVE_CONVERT EXTRA_CFLAGS_TEMPLATE AM_CXXFLAGS EGREP GREP CXXCPP am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE ac_ct_CXX CXXFLAGS CXX am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC PROGS RANLIB host_os host_vendor host_cpu host build_os build_vendor build_cpu build AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_dependency_tracking enable_OSX enable_OSX_BUNDLE enable_FreeBSD enable_FINK enable_linux_redhat enable_linux_debian enable_solaris ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CXX CXXFLAGS CCC CXXCPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures gri 2.12.26 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/gri] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of gri 2.12.26:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-OSX Build for OSX --enable-OSX_BUNDLE Build for an OSX BUNDLE --enable-FreeBSD Build for FreeBSD --enable-FINK Build for FINK --enable-linux_redhat Build for Linux/redhat OS --enable-linux_debian Build for Linux/debian OS --enable-solaris Build for Solaris OS Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CXX C++ compiler command CXXFLAGS C++ compiler flags CXXCPP C++ preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF gri configure 2.12.26 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp # ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES # --------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_cxx_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_mongrel # ac_fn_cxx_try_run LINENO # ------------------------ # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_cxx_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_run # ac_fn_cxx_check_header_compile LINENO HEADER VAR INCLUDES # --------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_cxx_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_compile # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link # ac_fn_cxx_check_type LINENO TYPE VAR INCLUDES # --------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_cxx_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_type # ac_fn_cxx_check_func LINENO FUNC VAR # ------------------------------------ # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_cxx_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_func # ac_fn_cxx_check_decl LINENO SYMBOL VAR INCLUDES # ----------------------------------------------- # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR # accordingly. ac_fn_cxx_check_decl () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack as_decl_name=`echo $2|sed 's/ *(.*//'` as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 $as_echo_n "checking whether $as_decl_name is declared... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { #ifndef $as_decl_name #ifdef __cplusplus (void) $as_decl_use; #else (void) $as_decl_name; #endif #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_decl cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by gri $as_me 2.12.26, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am__api_version='1.15' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='gri' VERSION='2.12.26' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi PROGS="gri" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for old C++ subroutine called string::remove" >&5 $as_echo_n "checking for old C++ subroutine called string::remove... " >&6; } if ${gri_cv_have_old_string+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _POSIX_SOURCE 1 #include int main () { string s("hi"); s.remove(0,1); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : gri_cv_have_old_string=yes else gri_cv_have_old_string=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gri_cv_have_old_string" >&5 $as_echo "$gri_cv_have_old_string" >&6; } if test $gri_cv_have_old_string = yes ; then $as_echo "#define HAVE_OLD_STRING 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc compiler" >&5 $as_echo_n "checking for gcc compiler... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined(__GNUC__) yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then : GCC=yes else GCC=no fi rm -f conftest* if test $GCC = yes; then EXTRA_CFLAGS_TEMPLATE="$AM_CFLAGS -Wall" AM_CXXFLAGS="$AM_CXXFLAGS -Wall" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GCC" >&5 $as_echo "$GCC" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler with new headers as of August 2002" >&5 $as_echo_n "checking for C++ compiler with new headers as of August 2002... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined(__GNUC__) #if __GNUC__ >= 3 yes #endif #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then : Cplusplusnew=yes else Cplusplusnew=no fi rm -f conftest* if test $Cplusplusnew = yes; then AM_CXXFLAGS="$AM_CXXFLAGS -DCPLUSPLUSNEW" # AM_CXXFLAGS="$AM_CXXFLAGS -fno-strength-reduce" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $Cplusplusnew" >&5 $as_echo "$Cplusplusnew" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DEC cxx compiler" >&5 $as_echo_n "checking for DEC cxx compiler... " >&6; } if ${gri_cv_is_deccxx+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __DECCXX yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then : gri_cv_is_deccxx=yes else gri_cv_is_deccxx=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gri_cv_is_deccxx" >&5 $as_echo "$gri_cv_is_deccxx" >&6; } if test $gri_cv_is_deccxx = yes; then AM_CXXFLAGS="$AM_CXXFLAGS -D_ANSI_C_SOURCE" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DEC alpha computer" >&5 $as_echo_n "checking for DEC alpha computer... " >&6; } if ${gri_cv_is_dec_alpha+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __alpha__ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then : gri_cv_is_dek_alpha=yes else gri_cv_is_dec_alpha=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gri_cv_is_dec_alpha" >&5 $as_echo "$gri_cv_is_dec_alpha" >&6; } if test $gri_cv_is_dec_alpha = yes; then $as_echo "#define IS_DEC_ALPHA 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BeOS environment" >&5 $as_echo_n "checking for BeOS environment... " >&6; } if ${gri_cv_is_beos+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __BEOS__ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then : gri_cv_is_beos=yes else gri_cv_is_beos=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gri_cv_is_beos" >&5 $as_echo "$gri_cv_is_beos" >&6; } if test $gri_cv_is_beos = yes; then $as_echo "#define OS_IS_BEOS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FreeBSD system" >&5 $as_echo_n "checking for FreeBSD system... " >&6; } if ${gri_cv_is_freebsd+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __FreeBSD__ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then : gri_cv_is_freebsd=yes else gri_cv_is_freebsd=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gri_cv_is_freebsd" >&5 $as_echo "$gri_cv_is_freebsd" >&6; } if test $gri_cv_is_freebsd = yes; then $as_echo "#define IS_FREEBSD 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OPENBSD system" >&5 $as_echo_n "checking for OPENBSD system... " >&6; } if ${gri_cv_is_openbsd+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __OpenBSD__ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then : gri_cv_is_openbsd=yes else gri_cv_is_openbsd=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gri_cv_is_openbsd" >&5 $as_echo "$gri_cv_is_openbsd" >&6; } if test $gri_cv_is_openbsd = yes; then $as_echo "#define IS_OPENBSD 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for HPUX environment" >&5 $as_echo_n "checking for HPUX environment... " >&6; } if ${gri_cv_is_hpux+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef hpux yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then : gri_cv_is_hpux=yes else gri_cv_is_hpux=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gri_cv_is_hpux" >&5 $as_echo "$gri_cv_is_hpux" >&6; } if test $gri_cv_is_hpux = yes; then $as_echo "#define OS_IS_HPUX 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for NetBSD system" >&5 $as_echo_n "checking for NetBSD system... " >&6; } if ${gri_cv_is_netbsd+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __NetBSD__ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then : gri_cv_is_netbsd=yes else gri_cv_is_netbsd=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gri_cv_is_netbsd" >&5 $as_echo "$gri_cv_is_netbsd" >&6; } if test $gri_cv_is_netbsd = yes; then $as_echo "#define IS_NETBSD 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for for Sun Microsystems computer" >&5 $as_echo_n "checking for for Sun Microsystems computer... " >&6; } if ${gri_cv_is_sun+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef sun yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then : gri_cv_is_sun=yes else gri_cv_is_sun=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gri_cv_is_sun" >&5 $as_echo "$gri_cv_is_sun" >&6; } if test $gri_cv_is_sun = yes; then $as_echo "#define IS_SUN 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for for IBM AIX computer with IBM compiler" >&5 $as_echo_n "checking for for IBM AIX computer with IBM compiler... " >&6; } if ${gri_cv_is_aix_with_ibm+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __IBMCPP__ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then : gri_cv_is_aix_with_ibm=yes else gri_cv_is_aix_with_ibm=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gri_cv_is_aix_with_ibm" >&5 $as_echo "$gri_cv_is_aix_with_ibm" >&6; } if test $gri_cv_is_aix_with_ibm = yes; then $as_echo "#define IS_AIX_WITH_IBM 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for for mingw32 system" >&5 $as_echo_n "checking for for mingw32 system... " >&6; } if ${gri_cv_is_mingw32+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __MINGW32__ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then : gri_cv_is_mingw32=yes else gri_cv_is_mingw32=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gri_cv_is_mingw32" >&5 $as_echo "$gri_cv_is_mingw32" >&6; } if test $gri_cv_is_mingw32 = yes; then $as_echo "#define IS_MINGW32 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see whether this machine is big endian or little endian" >&5 $as_echo_n "checking to see whether this machine is big endian or little endian... " >&6; } if ${gri_cv_endian_type+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test "$cross_compiling" = yes; then : gri_cv_endian_type=unknown else # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-""} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { /* Figure out endian-ness, from Harbison & Steele */ union { long l; char c[sizeof (long)]; } u; u.l = 1; exit(u.c[sizeof (long) - 1] == (char)1); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : gri_cv_endian_type=little else gri_cv_endian_type=big fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gri_cv_endian_type" >&5 $as_echo "$gri_cv_endian_type" >&6; } if test $gri_cv_endian_type = big; then $as_echo "#define GRI_IS_BIG_ENDIAN 1" >>confdefs.h else $as_echo "#define GRI_IS_BIG_ENDIAN 0" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_cxx_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in unistd.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default" if test "x$ac_cv_header_unistd_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UNISTD_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for netcdf library" >&5 $as_echo_n "checking for netcdf library... " >&6; } for d in /opt/netcdf /usr/local /usr; do if test -f $d/include/netcdf.h; then AM_CXXFLAGS="$AM_CXXFLAGS -I$d/include" EXTRA_CFLAGS_TEMPLATE="$EXTRA_CFLAGS_TEMPLATE -I$d/include" DEFS="$DEFS -I$d/include" LIBS="$LIBS -L$d/lib -lnetcdf" if test $gri_cv_is_sun = yes ; then LIBS="$LIBS -lnsl" fi $as_echo "#define HAVE_LIBNETCDF 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi done { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } #AC_SUBST(EXTRA_OBJS) # Extract the first word of "convert", so it can be a program name with args. set dummy convert; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_HAVE_CONVERT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$HAVE_CONVERT"; then ac_cv_prog_HAVE_CONVERT="$HAVE_CONVERT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_HAVE_CONVERT=""yes"" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_HAVE_CONVERT" && ac_cv_prog_HAVE_CONVERT=""no"" fi fi HAVE_CONVERT=$ac_cv_prog_HAVE_CONVERT if test -n "$HAVE_CONVERT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_CONVERT" >&5 $as_echo "$HAVE_CONVERT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test $HAVE_CONVERT = "no" ; then echo " **WARNING: Cannot make proper HTML manual without Imagemagick." echo " **WARNING: It is needed to make PNG images from PostScript files." echo " **WARNING: Expect broken image links in the manual!" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_cxx_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for poptReadConfigFile in -lpopt" >&5 $as_echo_n "checking for poptReadConfigFile in -lpopt... " >&6; } if ${ac_cv_lib_popt_poptReadConfigFile+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpopt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char poptReadConfigFile (); int main () { return poptReadConfigFile (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_popt_poptReadConfigFile=yes else ac_cv_lib_popt_poptReadConfigFile=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_popt_poptReadConfigFile" >&5 $as_echo "$ac_cv_lib_popt_poptReadConfigFile" >&6; } if test "x$ac_cv_lib_popt_poptReadConfigFile" = xyes; then : if test 1=1; then OS_HAS_POPT_TRUE= OS_HAS_POPT_FALSE='#' else OS_HAS_POPT_TRUE='#' OS_HAS_POPT_FALSE= fi else if test 0=1; then OS_HAS_POPT_TRUE= OS_HAS_POPT_FALSE='#' else OS_HAS_POPT_TRUE='#' OS_HAS_POPT_FALSE= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 $as_echo_n "checking for readline in -lreadline... " >&6; } if ${ac_cv_lib_readline_readline+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lreadline $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char readline (); int main () { return readline (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_readline_readline=yes else ac_cv_lib_readline_readline=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 $as_echo "$ac_cv_lib_readline_readline" >&6; } if test "x$ac_cv_lib_readline_readline" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBREADLINE 1 _ACEOF LIBS="-lreadline $LIBS" fi ac_fn_cxx_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" if test "x$ac_cv_type_pid_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define pid_t int _ACEOF fi for ac_func in isnan isinf acosh getcwd popen mkstemp tmpnam tempnam gethostname access lstat stat strerror do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_cxx_check_decl "$LINENO" "getenv" "ac_cv_have_decl_getenv" "$ac_includes_default" if test "x$ac_cv_have_decl_getenv" = xyes; then : $as_echo "#define HAVE_GETENV 1" >>confdefs.h fi ac_fn_cxx_check_decl "$LINENO" "drand48" "ac_cv_have_decl_drand48" "$ac_includes_default" if test "x$ac_cv_have_decl_drand48" = xyes; then : $as_echo "#define HAVE_DRAND48 1" >>confdefs.h fi # Check whether --enable-OSX was given. if test "${enable_OSX+set}" = set; then : enableval=$enable_OSX; case "${enableval}" in yes) OSX=true ;; no) OSX=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-OSX" "$LINENO" 5 ;; esac else debug=false fi if test x$OSX = xtrue; then OS_IS_APPLE_OSX_TRUE= OS_IS_APPLE_OSX_FALSE='#' else OS_IS_APPLE_OSX_TRUE='#' OS_IS_APPLE_OSX_FALSE= fi # Check whether --enable-OSX_BUNDLE was given. if test "${enable_OSX_BUNDLE+set}" = set; then : enableval=$enable_OSX_BUNDLE; case "${enableval}" in yes) OSX_BUNDLE=true ;; no) OSX_BUNDLE=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-OSX_BUNDLE" "$LINENO" 5 ;; esac else debug=false fi if test x$OSX_BUNDLE = xtrue; then OS_IS_OSX_BUNDLE_TRUE= OS_IS_OSX_BUNDLE_FALSE='#' else OS_IS_OSX_BUNDLE_TRUE='#' OS_IS_OSX_BUNDLE_FALSE= fi # Check whether --enable-FreeBSD was given. if test "${enable_FreeBSD+set}" = set; then : enableval=$enable_FreeBSD; case "${enableval}" in yes) FreeBSD=true ;; no) FreeBSD=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-FreeBSD" "$LINENO" 5 ;; esac else debug=false fi if test x$FreeBSD = xtrue; then OS_IS_FREEBSD_TRUE= OS_IS_FREEBSD_FALSE='#' else OS_IS_FREEBSD_TRUE='#' OS_IS_FREEBSD_FALSE= fi # Check whether --enable-FINK was given. if test "${enable_FINK+set}" = set; then : enableval=$enable_FINK; case "${enableval}" in yes) FINK=true ;; no) FINK=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-FINK" "$LINENO" 5 ;; esac else debug=false fi if test x$FINK = xtrue; then OS_IS_FINK_TRUE= OS_IS_FINK_FALSE='#' else OS_IS_FINK_TRUE='#' OS_IS_FINK_FALSE= fi # Check whether --enable-linux_redhat was given. if test "${enable_linux_redhat+set}" = set; then : enableval=$enable_linux_redhat; case "${enableval}" in yes) linux_redhat=true ;; no) linux_redhat=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-linux_redhat" "$LINENO" 5 ;; esac else debug=false fi if test x$linux_redhat = xtrue; then OS_IS_LINUX_REDHAT_TRUE= OS_IS_LINUX_REDHAT_FALSE='#' else OS_IS_LINUX_REDHAT_TRUE='#' OS_IS_LINUX_REDHAT_FALSE= fi # Check whether --enable-linux_debian was given. if test "${enable_linux_debian+set}" = set; then : enableval=$enable_linux_debian; case "${enableval}" in yes) linux_debian=true ;; no) linux_debian=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-linux_debian" "$LINENO" 5 ;; esac else debug=false fi if test x$linux_debian = xtrue; then OS_IS_LINUX_DEBIAN_TRUE= OS_IS_LINUX_DEBIAN_FALSE='#' else OS_IS_LINUX_DEBIAN_TRUE='#' OS_IS_LINUX_DEBIAN_FALSE= fi # Check whether --enable-solaris was given. if test "${enable_solaris+set}" = set; then : enableval=$enable_solaris; case "${enableval}" in yes) solaris=true ;; no) solaris=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-solaris" "$LINENO" 5 ;; esac else debug=false fi if test x$solaris = xtrue; then OS_IS_SOLARIS_TRUE= OS_IS_SOLARIS_FALSE='#' else OS_IS_SOLARIS_TRUE='#' OS_IS_SOLARIS_FALSE= fi ac_config_files="$ac_config_files Makefile debian/Makefile doc/Makefile doc/examples/Makefile doc/tst_suite/Makefile doc/resources/Makefile doc/screenshots/Makefile src/Makefile src/popt/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${OS_HAS_POPT_TRUE}" && test -z "${OS_HAS_POPT_FALSE}"; then as_fn_error $? "conditional \"OS_HAS_POPT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${OS_HAS_POPT_TRUE}" && test -z "${OS_HAS_POPT_FALSE}"; then as_fn_error $? "conditional \"OS_HAS_POPT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${OS_IS_APPLE_OSX_TRUE}" && test -z "${OS_IS_APPLE_OSX_FALSE}"; then as_fn_error $? "conditional \"OS_IS_APPLE_OSX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${OS_IS_OSX_BUNDLE_TRUE}" && test -z "${OS_IS_OSX_BUNDLE_FALSE}"; then as_fn_error $? "conditional \"OS_IS_OSX_BUNDLE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${OS_IS_FREEBSD_TRUE}" && test -z "${OS_IS_FREEBSD_FALSE}"; then as_fn_error $? "conditional \"OS_IS_FREEBSD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${OS_IS_FINK_TRUE}" && test -z "${OS_IS_FINK_FALSE}"; then as_fn_error $? "conditional \"OS_IS_FINK\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${OS_IS_LINUX_REDHAT_TRUE}" && test -z "${OS_IS_LINUX_REDHAT_FALSE}"; then as_fn_error $? "conditional \"OS_IS_LINUX_REDHAT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${OS_IS_LINUX_DEBIAN_TRUE}" && test -z "${OS_IS_LINUX_DEBIAN_FALSE}"; then as_fn_error $? "conditional \"OS_IS_LINUX_DEBIAN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${OS_IS_SOLARIS_TRUE}" && test -z "${OS_IS_SOLARIS_FALSE}"; then as_fn_error $? "conditional \"OS_IS_SOLARIS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by gri $as_me 2.12.26, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Configuration commands: $config_commands Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ gri config.status 2.12.26 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "debian/Makefile") CONFIG_FILES="$CONFIG_FILES debian/Makefile" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "doc/examples/Makefile") CONFIG_FILES="$CONFIG_FILES doc/examples/Makefile" ;; "doc/tst_suite/Makefile") CONFIG_FILES="$CONFIG_FILES doc/tst_suite/Makefile" ;; "doc/resources/Makefile") CONFIG_FILES="$CONFIG_FILES doc/resources/Makefile" ;; "doc/screenshots/Makefile") CONFIG_FILES="$CONFIG_FILES doc/screenshots/Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/popt/Makefile") CONFIG_FILES="$CONFIG_FILES src/popt/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi gri/AUTHORS0000644000175000017500000000031013147557614011062 0ustar psgpsgDan Kelley wrote Gri, and Peter Galbraith wrote the Gri Emacs Mode. They can be contacted at http://gri.sourceforge.net on the web, which is also the place to look for new releases, bug reports, etc. gri/missing0000755000175000017500000002403613147557614011424 0ustar psgpsg#! /bin/sh # Common stub for a few missing GNU programs while installing. # Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch]" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing 0.4 - GNU automake" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. You can get \`$1Help2man' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then # We have makeinfo, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; tar) shift if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 fi # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequirements for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 gri/install-SunOS50000644000175000017500000000564013147557614012510 0ustar psgpsg#!/usr/bin/sh # Set defaults for file locations. bindir_default="/usr/local/bin" libdir_default="/usr/local/share/gri/VSN/lib" docdir_default="/usr/local/share/gri/VSN/doc" emacsdir_default="/usr/local/share/emacs/site-lisp" echo "Please enter the full pathname of the directory in which the Gri executable" echo "is to be stored." echo " [Press ENTER to get the default of $bindir_default]" read BINDIR if [ -z "$BINDIR" ] then bindir="$bindir_default" else bindir="$BINDIR" fi echo "Please enter the full pathname the directory in which the Gri library" echo "files are to be stored." echo " [Press ENTER to get the default of $libdir_default]" read LIBDIR if [ -z "$LIBDIR" ] then libdir="$libdir_default" else libdir="$LIBDIR" fi echo "Please enter the full pathname the directory in which the Gri documentation" echo "files are to be stored." echo " [Press ENTER to get the default of $docdir_default]" read DOCDIR if [ -z "$DOCDIR" ] then docdir="$docdir_default" else docdir="$DOCDIR" fi echo "Please enter the full pathname the directory in which the Gri" echo "Emacs editing mode should be stored. " echo " [Press ENTER to get the default of $emacsdir_default]" read EMACSDIR if [ -z "$EMACSDIR" ] then emacsdir="$emacsdir_default" else emacsdir="$EMACSDIR" fi # Install the files, creating directories if needed. echo "Installing Gri executable in $bindir" mkdir -m 755 -p $bindir cp -f bin/gri $bindir/gri # Create a shellscript to run this, named "Gri" (note upper-case) cat > $bindir/Gri < # Created: 1993-05-16 # Public domain errstatus=0 dirmode="" usage="\ Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." # process command line arguments while test $# -gt 0 ; do case $1 in -h | --help | --h*) # -h for help echo "$usage" 1>&2 exit 0 ;; -m) # -m PERM arg shift test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } dirmode=$1 shift ;; --) # stop option processing shift break ;; -*) # unknown option echo "$usage" 1>&2 exit 1 ;; *) # first non-opt arg break ;; esac done for file do if test -d "$file"; then shift else break fi done case $# in 0) exit 0 ;; esac case $dirmode in '') if mkdir -p -- . 2>/dev/null; then echo "mkdir -p -- $*" exec mkdir -p -- "$@" fi ;; *) if mkdir -m "$dirmode" -p -- . 2>/dev/null; then echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" fi ;; esac for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case $pathcomp in -*) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr else if test ! -z "$dirmode"; then echo "chmod $dirmode $pathcomp" lasterr="" chmod "$dirmode" "$pathcomp" || lasterr=$? if test ! -z "$lasterr"; then errstatus=$lasterr fi fi fi fi pathcomp="$pathcomp/" done done exit $errstatus # Local Variables: # mode: shell-script # sh-indentation: 2 # End: # mkinstalldirs ends here gri/README-linux-redhat0000644000175000017500000000267013147557614013307 0ustar psgpsgWhat Gri is =========== Gri is a programming language for scientific graphics. It can make x-y graphs, contour-graphs, and image graphs. In addition, Gri has a full suite of low-level graphical elements and sufficient programming capabilities (loops, subroutines, etc) to permit complex customization. Gri is not point-click. In some ways it is analogous to TeX. Extensive power rewards tolerance of a modest learning curve. For the rest of this document, the symbol "N.N.N" will be taken to stand for the Gri version number, e.g. N.N.N might represent the version numbered 2.6.0, say. Obtaining Gri for RedHat ======================== Follow the links at http://gri.sourceforge.net to get an RPM package, and then install it by doing rpm -U gri-N.N.N-1.i386.rpm The source is also available as a gzipped tarfile and as an RPN source file. The package provides a cursory manpage, available by typing man gri at the unix prompt; the main documentation is available in "info" format, by typing info gri at the unix prompt (or through access by emacs or other facilities). Many users will find it easier to study the HTML version of the documentation, available at the local URL /usr/share/doc/gri-N.N.N/html/index.html Copyright restrictions ====================== The Gri programming languages, and all manuals and online help-files, are (c) 1991-2009 Dan E. Kelley , and covered by the GNU icense GPLv3 or later. gri/Makefile.am0000644000175000017500000000045013147557614012053 0ustar psgpsg## Process this file with automake to produce Makefile.in # gri: Makefile.am srcdir = @srcdir@ VPATH = @srcdir@ SUBDIRS = src doc debian DIST_SUBDIRS = doc src debian EXTRA_DIST = ChangeLog README README-linux-redhat README-SunOS5\ license.txt copyright.txt gri.spec grilogo.gif THANKS missing gri/doc/0000755000175000017500000000000013147560320010551 5ustar psgpsggri/doc/gri_merge.1-skel0000644000175000017500000000274713147557614013555 0ustar psgpsg.TH GRI_MERGE "1" "2009" "gri_merge " .SH NAME gri_merge \- merge multiple Gri output files into a single PostScript file. .SH "USAGE (style 1):" .IP gri_merge [OPTIONS] CxR a.ps b.ps ... > merged_file.ps .PP Merges the files onto one page, in 'C' columns and 'R' rows. The CxR files are given in the order of words on a page. The page is presumed to be 8.5x11in in size, as are all the input files, and the input files are sized to fit, and kept in natural scale. .SH "USAGE (style 2):" .IP gri_merge [OPTIONS] xcm ycm enlarge a.ps [b.ps ...] > merged_file.ps .PP Where `enlarge' is a scale factor applied after offsetting `xcm' to the right and `ycm' upward. .SS "EXAMPLE (style 2):" .IP The following .TP gri_merge 2 12 .5 a.ps \e .IP 12 12 .5 b.ps \e .IP 2 2 .5 c.ps \e .IP 12 2 .5 d.ps > all.ps .PP produces 4 panels from gri plots done using margins and sizes as specified in the following lines in a gri commandfile .IP set x margin 2 set x size 15 set y margin 2 set y size 15 .PP The OPTIONS, available if your 'perl' has 'getopts' library, are: .HP \fB\-u\fR graylevel \fB\-\-\fR set graylevel for underlay beneath panels, by default 0.75. .IP Values range from 0 (black) to 1 (white), although a value of precisely 1 means do NOT draw underlay. .HP \fB\-b\fR graylevel \fB\-\-\fR Set value for background under individual panels, again 0 .IP for black to 1 for white, with 1 meaning no drawing. .TP \fB\-h\fR \fB\-\-\fR Print this help message and quit. .SH "SEE ALSO" .B gri(1), gri_unpage(1) gri/doc/HTML_subdivide0000755000175000017500000002031313147557614013314 0ustar psgpsg#!/usr/local/bin/perl # # Special features: # 1) The item # # if it occurs on a line all by itself, causes # this perlscript to chop files here. The filename # will be as specified. The other_words # will be used as the title. If neither the # filename nor the other_words are present, then # this script makes up filenames using numbers, e.g., # gri1.html, gri2.html. If the filename is ".", # then this same naming scheme is used, but the titles # are used. # 2) If the item all # by itself is encountered. This is a kludge because # xmosaic refuses to skip comments if a
 item is
#    contained within them.
#
$debug = 0;

$num_files = 1;
die "Need 2 arg (eg chop_into_subfiles gri.hml \"The Gri graphing language\")" if ($#ARGV != 1);

$basefile = "gri";
#$file = "$basefile$num_files.html";
$file = "index.html";
$basetitle = $ARGV[1];
$title = $basetitle;
$marginnote[0] = "Gri";
$#ARGV = 0;			# Dumb way to ignore
print STDOUT "$file " if $debug;
if (open (OUT, ">", "$file")) { #|| die "Cannot open $file";
$file_list[$num_files++] = $file;

$name_of_top_node = "index.html#Top";


print OUT "\n";
print OUT "\n";
print OUT "\n";
print OUT "$title\n";
print OUT "\n";
print OUT "\n";
print OUT "\n";
print OUT "";
print OUT "\n";



#$body_start = "";
#$body_start = "";

# Colors below from Mozilla page as of 2001-mar-05.
$body_start = "";

print OUT "$body_start\n";

while(<>) {
    # Skip comment blocks (kludge; see above)
    if (/^\s*\s*$/;
        }
	$_ = <>;
    }
    if (/^\s*$/) {
        $file = (length($1) > 0 && $1 ne ".")
	    ? $1 : "$basefile$num_files.html";
	if (length($2) > 0) {
	    $title = $2;
	} else {
	    $title = $basetitle;
	}
        if (length($3) > 0) {
	    $marginnote[$num_files] = $3;
	}
        $titleList{$file} = $title;
        print OUT "
\"navigation
";
	close OUT;
	open (OUT, ">$file") || die "Cannot open $file";
	$file_list[$num_files++] = $file;
        print OUT "\n";
	print OUT "\n";
	print OUT "\n";
        print OUT "$title\n";
	print OUT "";
        print OUT "\n";
	print OUT "$body_start\n";
        print "Creating $file\n" if $debug;
    }
    print OUT;
} 
close OUT;

for ($i = 1; $i < $num_files; $i++) {
    $file = $file_list[$i];
    $ofile = "$file.pass2";
    open (IN, "$file") || die "Cannot open $file";
    open (PASS2, ">$ofile") || die "Cannot open $ofile";
    print "$file " if $debug;
    $node_parent = "";
    $need_to_find_parent = 1;
    while() {
        if (/\s*href\s*=\s*"#([^"]*)/i) {
            $key = $1;		# suck out key
	    $key =~ s/ //g;	# despace key
	    s,href\s*=\s*"#[^"]*,href="$ref{$key},;	# replace key with what is keyed to
            s,="#,=",;
        } elsif (/
	    $key = $1;
	    $key =~ s/ //g;
	    s,"[^"]*","$key",;
       }
       if ($need_to_find_parent && /a href="([^"]*)">parent/) {
           $need_to_find_parent = 0;
           $node_parent = $1;
       }
       # Do not print those 'Navigation' things
       if (!/^Navigation<\/b>:/ 
	   && !/next<\/a>,/
	   && !/previous<\/a>,/
	   && !/parent<\/a>/) {
	   print PASS2 if (!/href=""/);
       }
    }
    print "." if $debug;
    close IN;
    close PASS2;
    open (PASS3, ">$file.pass3") || die "Cannot open $file.pass3";
    open (PASS2, "$file.pass2")  || die "Cannot open $file.pass2";
    $need_table_cmd = 1;
    while() {
        if (/^<\s*a\s*name="(.*)"\s*>/ && $need_table_cmd) {
            $need_table_cmd = 0;
            print PASS3;
	    $this_chapter = $marginnote[$i];
	    if ($this_chapter eq "") {
		$this_chapter = "Gri";
	    }
	    #print STDERR "[$file]\n";
	    print PASS3 "
\"navigation

Chapters:
  1: Introduction
  2: Simple example
  3: Invocation
  4: Finer Control
  5: X-Y Plots
  6: Contour Plots
  7: Image Plots
  8: Examples
  9: Gri Commands
  10: Programming
  11: Environment
  12: Emacs Mode
  13: History
  14: Installation
  15: Gri Bugs
  16: Test Suite
  17: Gri in Press
  18: Acknowledgments
  19: License

Indices:
  Concepts
  Commands
  Variables
"; print "file $file\n" if $debug; if ($file ne "index.html") { print PASS3 "\n"; print PASS3 "\"$name_of_top_node\"\n"; if ($node_parent ne "") { print PASS3 "\"$node_parent\"\n"; } print PASS3 "\"$titleList{$file_list[$i-1]}\"\n"; print PASS3 "\"$titleList{$file_list[$i+1]}\"\n" if $file_list[$i+1] ne ""; print PASS3 "\n"; print PASS3 "\n"; print PASS3 "\"$name_of_top_node\"\n"; print PASS3 "\"$titleList{$file_list[$i+1]}\"\n\n" if $file_list[$i+1] ne ""; } } else { print PASS3; } } close(PASS2); print PASS3 " "; close(PASS3); rename("$file.pass3", "$file"); print ".\n" if $debug; } } gri/doc/screenshots/0000755000175000017500000000000013147560320013111 5ustar psgpsggri/doc/screenshots/Makefile.in0000644000175000017500000003050413147560320015160 0ustar psgpsg# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # gri: doc/screenshots/Makefile.am VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/screenshots ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS_TEMPLATE = @EXTRA_CFLAGS_TEMPLATE@ GREP = @GREP@ HAVE_CONVERT = @HAVE_CONVERT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PROGS = @PROGS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = gri-screenshot-1.png gri-screenshot-1-tiny.png\ gri-screenshot-2.png gri-screenshot-2-tiny.png\ gri-screenshot-3.png gri-screenshot-3-tiny.png\ gri-screenshot-4.png gri-screenshot-4-tiny.png the_eps_files = gri-screenshot-1.eps gri-screenshot-2.eps gri-screenshot-3.eps gri-screenshot-4.eps the_png_files = gri-screenshot-1-tiny.png gri-screenshot-2-tiny.png gri-screenshot-3-tiny.png gri-screenshot-4-tiny.png the_pdf_files = gri-screenshot-1.pdf gri-screenshot-2.pdf gri-screenshot-3.pdf gri-screenshot-4.pdf DISTCLEANFILES = $(the_eps_files) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/screenshots/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/screenshots/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am .PRECIOUS: Makefile all: eps png png: $(the_png_files) eps: $(the_eps_files) pdf: $(the_pdf_files) %.pgm : %.png -convert -geometry 500x999 $< $@ %.eps : %.pgm -convert $< $@ %.pdf : %.eps convert $< $@ # ps2pdf $< $@ # This was good for color; # now let's put them in grayscale for the PostScript manual #%.eps : %.png # -convert -geometry 500x999 $< eps2:$@ %-tiny.png : %.png -convert -geometry 999x120 $< $@ # OLD STUFF, PROBABLY SHOULD BE REMOVED. old_clean: rm -f *-tiny.png *.eps *.pgm *.pdf *~ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gri/doc/screenshots/Makefile.am0000644000175000017500000000221213147557614015156 0ustar psgpsg## Process this file with automake to produce Makefile.in # gri: doc/screenshots/Makefile.am EXTRA_DIST = gri-screenshot-1.png gri-screenshot-1-tiny.png\ gri-screenshot-2.png gri-screenshot-2-tiny.png\ gri-screenshot-3.png gri-screenshot-3-tiny.png\ gri-screenshot-4.png gri-screenshot-4-tiny.png the_eps_files = gri-screenshot-1.eps gri-screenshot-2.eps gri-screenshot-3.eps gri-screenshot-4.eps the_png_files = gri-screenshot-1-tiny.png gri-screenshot-2-tiny.png gri-screenshot-3-tiny.png gri-screenshot-4-tiny.png the_pdf_files = gri-screenshot-1.pdf gri-screenshot-2.pdf gri-screenshot-3.pdf gri-screenshot-4.pdf DISTCLEANFILES = $(the_eps_files) all: eps png png: $(the_png_files) eps: $(the_eps_files) pdf: $(the_pdf_files) %.pgm : %.png -convert -geometry 500x999 $< $@ %.eps : %.pgm -convert $< $@ %.pdf : %.eps convert $< $@ # ps2pdf $< $@ # This was good for color; # now let's put them in grayscale for the PostScript manual #%.eps : %.png # -convert -geometry 500x999 $< eps2:$@ %-tiny.png : %.png -convert -geometry 999x120 $< $@ # OLD STUFF, PROBABLY SHOULD BE REMOVED. old_clean: rm -f *-tiny.png *.eps *.pgm *.pdf *~ gri/doc/screenshots/gri-screenshot-2.png0000644000175000017500000011300313147557614016724 0ustar psgpsg‰PNG  IHDR<MÃ!€ |PLTE    $!!!%$"(&#((&++*''(/0.0.,10.<6.443786863886==<H?@>)HF,LJ@>>@@>NB5WJ‚Hb\ã•+ØŠ@ÍÃÿú婃ÛG$µËó—pÜ_]EcBÞ@8r¾ö”óê'Ø‚]ùèêÇüë_„ïpÄHš\Bhàü}~õ“kŸ]Ãñæ¯ÒÂ]!@9>"E¿|iîÒå+ð?Gš 5‘W_á?tþÕ¯®¢–¸‚«|ùŠGФW â•q}æ.CÃx ?Wð#"ž zH(臿ž‡¼ T¸%¯ vþˆ4n…ççýÊZùãÆFMÿkðë+ìa\¥ Žjù««¨˜¸)>šÿè³zî¬5GžO€ç>¼‚Þ‡s@—çàùÍ}xynþÊÜ<´?Â:ÎÁÓÁ!æ.8æpã£Ç·W.Ï!Oâ 't Ò !'i_ag”0D»|ùC +~8ÿá8ÎA,ôÄæ(!7(ׇBvsÀ4ssó—¯àLÁ…þ¦Š p i!/ãø¬—/ãœÀáÂ.ïÜÜEx Ìq¦š=?; íqéâyäŒ~çÑÅy8Sºpþ< ÃoÐíù‹!Âwá½Ãaf±/ÐÜ4r¢1.¡Ô/]Bnòâ%|DŽs J—f/ÑRàD/ñœgÁÎ@¿øàêƒ÷ffÞÿÅ/Þ}f]#‡‹àzþ} â]8qÇDQqeHPYP òs¸uÑ#@µæ%Únð ¼(Ä^è0þðËì ÆÐ¯.¿Wð…@À)84ú¿Œ/Îçv9µæñèÀ3û<„÷߇ßûïϼžÄ/>€ëÙôXÐÿ{çÀŸÜ,yøIS†š½tqîü 󸵡aã2~î qÛÅ9ø'ô!†pÙs™›‡‹Ë—çæ(2X8ê͹q.àû³ïãÒþ‚°òTLT+ Ìw”‰.‡ Ä“1?*z3£×5Aÿ%öòðÊp ×3ºº,.øwÞ,ð—/_æE‡·Ã<¼ È늼‰³$QHõ+aöKøþ)²Ÿç(DBmzé". ‹r‰µªö¸à )¢„P¤W.b\AÂÂcùWé€ylp‘òfŽ÷ ^ñúÿàƒÙ÷Î>cð\@L5;3qéwËîûSSé›·ÓD{cƒ½€~iô··aܠ۽༧aÏp¡dº ¢ÈaÏž½(Å={ö Ä÷¡Ìðý^t ¹4Yí¡yÓØ=³‡Ú­]‚+û Þ{ùÁXøç4=Ô ÚÝ –à»á`÷3@ øøÌ³Ï<ûì³»ñ§Ý»ŸA¡vã@Ïáp$Ê3Ï=óÜsÏá ⌠XƒÝ43º¥•xṄŠÛhozOKî güú¼rc¥tþüÎÌì•ß­”f/NÍb|_¼²~ÀìùÁ1ÏGpœ¸öŸ?ý§þðŸÆsè t¿yÎ_ìlÈ:544::<2:2<::ŠN##ÃÃCÃ#C##Cè tzè4ú{hxè4rB.#CœÞ†D†ˆ;Ü tjè†N²[Åq ÛááQ¼OB7¸,oCfP ÓøÃpyzø4.Á02CÉI5à.È„$5 ±·áÑ(TUlN£˜&F'Æ&Fóc£ccc£ù1¸gˆf¡‘SGáóù<üàD»MäGqˆò(åQt;:ÎãÁÝøxÀÝØ(¤Dühú( >>ìåίFÔ²Œ’”ùyÜ‹3|z˜jhÚaÜ#ø44Ôut‚öÙw¯—~÷á»SSSïà»ÏÑÝ{S?Ÿ}a Ý-þùý|QîQçb­™<:ð =ñËÿéÏþýgÿWÓÕ:ûÑZ.t6Å4 -< =ô€ÇóÀ¤éá¡ñç2>NŸÂèr£ÌÇ1Ä!èñ#˜gì8âã!YŒá°Ø{l Ý¡ûñqôì–¿1à>Hb"¿Ñ±‰ eG$ðÔGBš·áÞä,±ùî‡å*1WîL =êG [üÆ`/ˆaü?4B^à¨0(‘Ìœ˜ÉË`]ðWÆiˆ<Œ~(8Üqه黀ä9ŠÞ#è=ï°Ó(aò ÃÙ ÃïôèihòF ¸ò*EÜGXs¨ð›À'&†‡Y‹(`MpêJiöÇ?þé \œ›š¿øöwßxã»GÞx{àÒ‡Só¥Ù·üλºÞîE*L.ÎjÛoQ[¼ûŸÿò￾öË}íÏZ²oŸÇÝ—K£ ]¬Y›:nO8yMœ—Þ´ yEÂKÒAœ. À8‹«ïé ãÝ K¯púàOs®•¸§ ¿{ RÆh¬,¬¼ÔÑæMä:2ŒÙ˜³=\c6&2tÿFÿãß°W"Ч‰q^$Lưl‚7üÁ{c^ yôB‡¼cðË¿.p¹¸x C¸„¸ DšbTÈ42NÛá~\À v‚7‘ZðŽ·ü8‘ ^¨ñ ö6óR…w4‘Ç]ÛÙÒ%üJ{çwF/Í–v=Jhªoôâlé⣾7þò×}käâÅž›jÍãÑç3 þé¿üçýîÚÏÿæOÿø›YÜA¾x±33 /@*³á™rJˆ‡œá’ƒÞ#ÃD“ÂJ(I8œSÂü4ÌÞç(:áwf5ü¸Gúæ4ÄïAO††Guš2‘Ç!cc\axbdæ±Ê“Ÿ~˜Ù5" ð‹¤úÙBo 1,áY@8Ü¢¿1* ‰äŽÇšÖ8fy¸µ*OT*#ŸŸà4>¹GÅ×yœñÕêPáaŽuö‚?- 2,L¤*ýè;"÷R12:&½ ”w4ôi lÔvø ê)ÖD Ü!‰22¬Àn*ŒULܘy¬0båÔtŒ¼ÏÌ{\ûüFo>ísÎ×}ô‘Ÿ¿ýÝÙkŸ¢›ü×þ£Ù“o\¼8ðõKžxþë‡?ýåâï®ýô/ÿô«O?zé LaÌ7pÅœéæN Ý¡DÜ9ç"°ˆoþ1t?Fßk˜7ñ5âìÒØÕÚGˆê¹,qD%ƒÞbEÕÈ1ÌŸãÀØü%îõ+FI1…^¦s@g½cÿŸ=wölý;wæì9&Ÿ?#GÓîÇpŒ‡!ÌŽˆ¨ŠÃžØŸõnP$üNŸ@‘'ÈKt\üf0‚N<)Sc&ö*)_ X£ÅÇR½LÆI¿ Îã¼UÎÐzœƒó«ÓYz: ÿÖçóç¿Ì¯L½õÖ?Ÿ| Ó¾Ùå©íï;nêíÿúÖ¾÷—§ÞúîWwìØñÕóï¼Õ8s¡gGŒÁóÙùÙÙßÿý?ýû¯ù³¿û‹×¾¶c{÷y>h8…5)ià§á_ þªD~ ÉA˜Ñ1|Dž8 C ‰€Å©ï(u'ÝR¬SA.£U‚ÈàÄü>:?~oøÇau§! Ö¯H¿ÉLÜC@J¼îO“|X·"€ÐÁ½,q¯cذ C Ãðþ¦£лÀa¨ÜÅC'êiZ§Ó„p‡q±à¡ï^Xá­?†5<ÀÏ8Á?Àƒôô¼·˜:ä@ù0ýYÀÿYü@'Ї³øÌ^!ø'YH)É8Áj&‘´cXÝɌԶós¥·ôÏo½uòŸOž|kð…³¥··ŸGw'm|þ\éí·N¾ñÈŽSÈo÷¹Ë}±–<—çæþëÿ}íûÿòý×þâµ~íÁ…>8ÿÁì{N¾t´’ àÀ)trJΈƒø…vN—àýJCøzÈBÇ{Ûy» OÝcWÜ F^´syqt«m9o1ý†ªƒXõ@ñð%è@qI‡å4·;ÿO!ÊÁ0:ŸÈ åë)†‡L”Ë¡À(ø›'PÄŸBÒðÃü|ƒg†v‡ÉðF*ê! Û¨&¥Þ!ãìeÀºbD'Æ™€÷K™ª·t‘v¾N z0~3 áTÁû46êÆˆfFõÍQÖYŲ KU‚\,Ô8¢ææçç>\~‹Ów÷Í®¼µý=¸|uûøw÷ͬ¼õÖËÛ·ïØ¾I }3ñÏgss—þóoþüÏÿâ/ÿêïþñïï¿÷3—?š_˜_8š?ƒT§?r$¿³N©„NØlÉÁç°„É;RççLéÌY ­èwȽ‰®.DåÃêŸþ eïBüÂÃ/^ôäÆÙõxžŽ¿á®ÕGp˜Qª¾€îDu9áQÜS&ú%¼ä1ïŒ%ÐA.%¯W¤‘hŒt~ò˜ãÆi{\&|MX—eðQ.¹ûvw[Fé@4cƒø%0"B:‡ß§N°}@ô)r>e&AFðа8Ì<2ì©ÀtRr‚è>¤ªX%&'ª%B£AãæG ó0©;ÿƒ7Äô¯ß}¡eê×½Ž~ó•W¾ùüƒo=ÿ2º{ñÁ·ÿìÁïŸx¾ej6·+Æ¿»8wæG/þÙkßÿÇïÿÝýw}ù›˜"½xqôØ0èb%PÅÈégè<î”0‘þ!ùƒÕ6hA/‰ôŽt°ºWU…ôvðƒž`}jz`ÿðö$Ì0DE }†Ùª5è4 'L QÖËa!t O V$R(GXò” e3ž$N'OåN½‰¥‘T蟊›aª­15‘Xî p:)0„?6ÁXÉ’nL~ŒbåCwæèPŒ†Ð÷ ô"¡ÆGñœÓ8ðçœ2yOàQ %2N†@Æ`N õ‡&èÀǛȓR½^Hä‡ÃŒ²_KŠ÷ßùîÖ·Þÿàýg_|²{jö-÷m¹ÿ»Oö¼ûÞ;ßÜúà™×ÿÇýÛÞúFÏÌùÜ®/ԚǣÑÌýôù¯ýñ_üù×îþÂ]Oþè<5âÀ|IeÈô^ND°Îï8Üý!Ã÷‹HŸ‡A©&?`+šy¶èw°†ñÀ"}à‰hA‘¤Úå ¢A oÉ_Ð7 S%‡p?Îk\ï EU´Q6÷J]F}çÜÂÇðf=ÿó–G^XX$¶„…ñW[Z¾ùâ“;öž<7;{nüÕÿöß¾ùâ7ÝûÖÙ©©‰wÐÝ+/þÑŽsgäy*Æ}ž¥ùùùÏOýè•¿¼eǾO}€€?Àž…Q&vÌ)•Nãc ½,K À%’2ÈKÔe˜\ÃK$š@øàPðL3í·’™D6%B4‡±¡ ïV1¡bÒ¹³g ù ËŸ-äÙóòÆŽ” €‚3b%A'CF©Ã<™'ÀâsžLoót·q2¸­§g&ðkà,{œ;g(›5 e¡’ÇCÑ,šÁ˜ØVÆf““+æG‹>ÁPcçoÞ„êù+W.Nåôƒo<½÷»ã³ûLœì}ì/z{jîÃK³¹<úÄ‹‡ß.\œ»œ‹³mÛ'óó£Hèê|ãήÞxsèÊÜüÍÕ j¥“PíhåæÕ+t:{dh û Ä1Ý'q¿Ý!½íÈÀ·áÓ'ÞxãÈ‘žSÈk¾g{ŒmÛ®ÏíÏf3™ææý™æLf¨)Ã(‹­€Ð±­­ ®Ú訽9A2™l¦%CÎY–þGéФ³,ƒfÈ•eÔÌ2nif·Íܧ9ã…kÎ?’Fü5517845Ã}£Ætº(Méô¾ô>tLwvB‡&tnJ£p-ÒKM¡¨9DT®f(a3›påö7eHmÀ­¹‰µ ¾Ëd”t_zé¥&Z:tõ*s•]£#rxix:±š§÷¢§Ñá\qLìLiùíÁáöAƒ¤I pD™¼D’'mJÛ¥ñ%(ªCó~TÜýì‘7ïÇíæJÿÛ.Æ=Ε\S­ßh ؆⬶}6”©uû&[,]‰3x–‡‘fæ&”P4ˆÁW­í¼ãgð$ ö–®Æ<ŸjJÀ“P4„$Ï…8«m×ð$!ðÌÅ<¥Ñ¶<1¦ÕwúW‘yooéòc1Ïo‡šðĘV?`¶ŠÌ‘ä¹gÉs}(QÛâL«}¸ƒ«ÏÜã1Ïos xbL«}¸½«Oï`éBœÃ}’K$Oœ©Ö’çÊNg®ÖLx>“À“„/è­©Mx(ÎÊM£[ëÈ÷>ű•MO \`¿¤«R^’æêúZ+‚ü ”HäájíiHÁœ)O@( öÆÛÂàÆé¬ùÂÆsò%cmËs•#…•º„Î1diÌ…rmà)¿„zÊB­CÊàQã÷ö† e¡¸Ïó,ì5Ç· f‰r^Çæ¨!Sˆ<Á‘« ž²[ʵƒ'l ¡$OxðÄZò\HÀ#ieš¾"„"šòn´§âbÁ¼$GsTé©ñ“_T¥Ì)žŸkÌÞñRÊ[z¥ëë×6bZz:ÿª5³'dŠê %‚Gy¦Ì]Wy˜ x,¡,ÔwðœÎ¨}™SŒl$³—¯Ú¦2¢˜¤Ä’Œƒ€¨Æ l™ \(¯lá‹î½@¼Õ[ÊÇõIÈKc©µž”Ör ¶–ê Ê‚wЀÄâ––2Æ1V׎hE/ä¼y‹î§V^Rµ¡jK(xúKÅzÀ j ƒÀN(JªìázÍÏ <½¥ù8ƒ§”€'ÖT[ð –>гÚ¹äI¨¦´jÛ¶ÞUE.]}"ÆË°¯çÒ xbL¥Òàà`/þƒ r„~Ï®Máà™#És5ÎjÛdIBœ©Ä¡ÀáA/ØÉóÕÃÁa™ÇÒÒ5d¿Ao ¦—9ò{çÞÁÁAÝÉ7¼v*¾Ps)Ê/Ÿµs¹|¾)-,|¶„“[Àa®“ðBÜ–þÒÒç( 8b—š&) \àTÄð&.ÏuⳄc}N®?ÃéðrC$õk8-ˆƒ£]_¢å#Ù|B¢__"åäùó|–®Ñz.à¶YúŒ•’¶ *ÑçŸòùg$ϯáÀêÒ/.':|NJ„ ²DÚã“RF„[ò Ïç:+#Iâ3RÞë4&q§àQ,J}¬¡ëÆœ*Ò‚VöRs)Eê%à¹uàqw¡Àhý¦èå½ý&¹äE_rš®1 <šèLoÐarZò˜Ä"MM‰¹ÀqzrzR ï•ÞsòõR’«EýŠÜ™Ãóš¤9@1…ü ¢/)Ë$ §äWd­ Æ+Û$»/ =Éj=Éó˜¤í?IÓšÚa’§3h)ÍàqËO¥œ¼ D žÀåH²Ÿ¶–æ“AmËîÀc¦éBxš±ÞéMÛ\' 4Äž±U™ÑËΟÀyUÙ}ö/4!iFV€µÏJ©²xå¤:$,C “¹"yJoìðLû±m–.̬5©y¸&¸p“œ±HÒ“Óe¦eÇÊ´Ÿsp“ÍØïìyúy“ÓžÐVÀã·‡´$H^½d )úmÖWPYr𢋋ôôÜ£ÐZáÌà· Àst—&y¤'Ï׌åÁ½cÕ×èô¤ &~)Y¥…5k ÷Uý%`¡ˆò™¬Dœqð„ÚÀúR6ôšZ¿x›• òZJߺуǢ¨)~xÚVêzÆ]˜”ù“óûŒÀ Õâ;Lš³¡/Ó²öÑÀŠåj‡j>QÈ¿ ~‚cw²äñÝÀôÿ‰<2†DGÛþ(¥5ž¶\¹&à1.‹5׆»ƒ - }Î] |l!ÔíUrÓͦ%6 ©Íð3šK¹dα¼j¢þ:í°WT†å¬Õf’4—R(ÇH*xDæÐ_¶œQV*ô®ˆ‡O%»àŠ=–~åNŠ3hÎ;7ºþ«mEßç©2 lb L‡çÓ'tШHÓeÉÕ´ãßO+Ðñ²cjx®¨»O³wÌ´ –'äèOÉcÊ’(yT5Ÿómi³ Į̀ ˆW ©õE­pþwÌ f¡‘ÚvãØž Ñ¶iåQM:ÎÊá[/òLØ€XÆiN™‚oÚî>%ô:÷óž„öù‰3H,МMjeÄ›båQ4¥ì•ZçLÁ<¬»~›­xj”+uî7»ÊÌñ[Ù,o+"úáŸ%œ6¯0ŽôJ¦îÅõ<.¿V8ïn³Z‚›çAjÛ‚ñz6)q‚Î|ž©BRx™á<ü™ø×É¥{¡WC~Èuœ¹‹s)¼±¦t>ýÍŽwiNɈ͗–ìœ*:ÎÕ«Ä[ }Ói¬Òœ8 Ž<ö÷o •VÌîË+•Å« (ÿòŠ?X?!µíV_Zíóp}™=/ÙóGÿ£GcÛ)!˜ÿlƒ´|Öa¸0FÀþûÔ0¦p¾4]ÈÐ++ÙLѹ‹<Åâ o!5‚"‡M,‚,]ÿüóÏ—v8Î&CN:ó ó 8içß¼Øspþç'ˆ#x0-`èÁB¨ àIH'*ynHjðŸsõÚ'×®]C¯·×蛎BGPÜ4žE\õ½ïYÐC˜Âà9ù ±ˆã,å–rŽê+¤þÙ‰¥7 Øs°”LIÖäšÉžÎØÀÐù'=:7ç ¥Ñ÷~ƒé'Ž:èAï§ÏÒõagJOÀùxaçc€óo-ä@ænœ>ûäôÓ+ïìpôƒ'¡J lná#d´MäçÚµ«W<Ú{ÓI7Pì|úiZ}x3“9ßû^©D;Ó2 a…‹²Ü“Â.Ó:K ¹œEqÃþÅ%ÀPÔhI ƒh™Œ§“=:<|î,öÉf´¸:s{.ŽîÙsñ¢ƒ¥“ŽÝ Ÿ¾èùô7Ÿî°LìÀ‚çstÐJê8 W>FØù·?vDìÐ1Èi;ÿµ ¸Àã Ρ‹O4Cv¾na@0åîí• » «.„už·t0ÌËysyX!³^é¿WʯwP,ºçÛkuá56­1ìðàí™Âc]àà‘žÁÕ«W?¹ú p¡¬·O:Ÿ¦v>5t{@Þä¸%—IŸi…“Q²ö.7’*9°¦\Z2ËÄ'–¦—f;fùà|ô¿ÌÉËX´ÈÂÀp>?œ-f²ùáÌLAy©ÌŸK¦Ó¨ÓsÑØ¡Ÿq~ó(“<¨}&M³»›œá%<ˆT¹ã à|<ÿ×Hk›?¼pU–;$ægõš>ùLÓ›1x>¦è!8"CÕÛöJ,,ñ›Êô,Œ¾··WÁC¯€ƒ^–K¯Õ_NßVœ¯ÇÖRaýR¯S™Rr/¼G¸“à4(µ€zÄϹ ¢–ïü­óÉ5@Æ‚H,|úé†Oâh€ó=†F ˆjÝ8-Ì*êŽðü‘&tbÙJç NŽ3´„€¾„Ç y8˜ŒmM;Ÿ ó¿ÿ­½Ë…-zr‡¥1CÀst8_8—éΟÕû>=é?C‚^”É´ó›ßìxï=Ô6¿Áí#RLMMƒ\ý|h¨áóÏävœ)ÑÀüóÿõÉk‡<ϰ£ ôvIò Tî ºÊe€§Ö*N< /†+ÁP5µ'&ÃûßQ§Çq®QîàÏn$ϧéŸ0ð|êhf<::?š-Ê PÀ£çÏã!gnTÌ‚¾>ýtÇëïýd‡ãìx·hU>=… Bg¤a÷ÈéÏ—iІܜ«ó ½pèÚÕÀN‘§, ®McñóÉÿåëi< É &›Öæ¤stÍÂg §âVÔüvÈõ‰4ˆžiͦk›Ž’P¦@ú:r‘ͨ%È¢Ϲb!sîØðÙ|Á$z.Î9Îè(RÝ„¡R=h„Ÿ¼÷Þë;ÞûÍ§Žˆî©‚34r}akl# Û¶ïPÁóñÂ_ŸDjêñ ì,›‰`çœéIÅ I“@ x"#,yVŽ6€äÁèñÀƒ´¶«ŽA²À`ÇΧÿ¡Œ¸¡÷þ÷ºý½ïÉà)£vL¼™Ø¢èœðšårCŽÇ¼ÄÔÌð@e[ZxóDΓŒÓü\`ãy&ÑC0¨ÁGC$xÎ΂ÊŠÃb°|(:Hê`¥ õ}æ.RÑC –ÎOÞûtÇO>ýô½Ÿ¼¾å2l!àãvDêd©³0ÿ×=?åq+b‡æƒ±#?¤ÍÕ%?<¿_ë É$iç“|À€«m×®^»zMé™àqÒôˆàÑÃÀó=W@s$u‰å¢c'—K§s{Íh¡0„ CüÓݺþ6iÄ'À¦£´Ï£ÎÓ±s>ƒ”¶s…|qXM0àv~ƒç"™+RAÕ߃z;Î{“ïýä'?q`ºGè—¡^þé¡ôw} +o€GÅzÎÁcm;HlüÛa‡¥/Õÿ•;ÂpF.íå`íêÏšSoï…YžÊhÛß:×P¯ûÚUûÉ‚çÓOÿ‡#,˜¡è‘$Ϥ`܃NècÛ³ì)bÑ‚žø ô›éœ>›[(ätÒoîÉqµH°MàA¥ÈÂÀÙ4>Ò«\¤,ˆ@…â¹Â¹¢<ç>ΟvæÆÉàUî'¿ð|аó:ϧ¯³BLaµ­aäôÈÐÐÐÛC=Û x4Åp~þãùÿaàßNž<ù£×l–”ÉêĪî°ÎÕß>vðèÔ6®XÓ™ÓšMÓŠHF~‹)§}ž´¡êkWôÑ6ÝNÌŒr¡¢ç:RÈÒ¹Ï`9Õ¨‹tDà‚^Àþ’©Â´ÝÂ!#Mñ(²ijÃ(@±€°S8k=E'=Ÿ‹xÌ@4Ÿtxv¼ØÙ½ãÓßÁ™]\½é™í §‡~<<<4ÔðÈ6ŒýõƒÍH;> „Õ6ïµ0=ME·:”C$¯€]mS--ËOD\^+ðX–3É «{<'ž®gdð 7ä5j¢ ý‰%± YjÏ£¢’+s1£££c`§úˆžéi¡¦Ó{À2g‡ã<ºÛ¤õnjhhx œ†ÝDîL)Ó¤3Xô€iÛÂüU<?i˜Œ¥#9tfkš]3ð@§‡«o*xª» ;¥™×ÏRë@옌ʭàQ–ax`%é‘Ýî”øˆ&EÃP­OÏÅ<ÖIIiƒíoàÑ2±Ãõtörf–Ÿ>‹¤”-Á¨–+E 9Äÿòå-m•†Ô D°.¾æ¦Ë9ÙáLÆœ¸36ê8EguyÎ:Ž*Mj^𞃡­õÄ69ÛŸk€qêí;›¦¦¦õÆpÀÊ`+Í|4Z*)L ‘è`}ÑSÛñÇÁSÅeØÆ_¦êa©u¹à ·ºÇ[”Ð{á¼óÛîG¬k¹zlëyðè÷<=Sª© ’løу¤Ê;• üßD¢ûû­¿³¬E›Æ#mBôpY2ÿ“±& 33Stæ.Mh6“¤×ƒÍB'g ‚“Äß´Àãà¾oy^ä·¦†Ö#Gž†ó?ÿi{^é¡á>$ù-)’§:˰ý–L«kâj¶Ô:4x¬Ë°YÁ7›ÀC6=Dàû<ªE3ï ^φg:8ÏÕÂEaŠ\š“ãðEÔ3=é…!DZ-ªÁþ'4è£Ó†×yèÕ Å– P°®¢ž."* ÑÕ,z9²6ƒ·ÿØáÌLâ…7†¦ÁÒI È¢8¥×²è¨c5“Êã kEXŽ“FÒP5ý]ÕÀ#²¿Ìð_†<µ[-ˆ.Z]²®G[IÊú<|÷œp æÈbÇë8¨sýÓd¤I¾t˜[N³'/Ù•y¬á8Ž}Eg'ˆ4…Õ´²Ùƒ‚N ÃÓÓËFŽ·?›,¾œßp£?ûpù´ßbA/U†ííÌ;<“…ÞçQÕ6ë2ìË©õUŸáQSà VÔ¤;ωض}&pÓC¿g+?XyŸŠ¢Â¾Þö›>*׌83ì0ãY}iI…ØÖÐ:Í#W‹••H2‚pUQ3­uó_e éØÑÞXb’pY4lÇÚ™ô2Y¶– @¤Ç/¨Oá—aÓ³R4‚Ÿëed€™tµA> â užg¥«Aß='`û +Ÿ*Xáãkxè`’]yîÅð`)ŸB&=]…4Ê+M1Ôæ(ÕªebÛ QÉãÇ3bÖž‰åõðì¼]ÿ«Ç bX­œE[@ñ.PÛ [†b™åõ©H5R1Ržh¨Ð÷ á+ E‘…Šª„°>é¢Á¡(ßNà ÌSôI.0?̓_ˆoûéÉ"(5è8©”®è—~Qi›¨*¾EË–ubkT°<ÑÞàôÆ.w!C¨™[²ìš ž¯2³?ÛŒoÈ*™¦ [,ÓDƒdÉ©¥@‚7 ‘›Y _hbÍJNä² {dÅ4D©Yˆ×VŸ&ê˜mæ5„c^(Ëþbé¸)‹Ü>^v*œ³R/Ïl¡Ek[/!VÆf9p³Ü¾äІIÀ óÏ‚°ˆj‰Ÿ—Ø'ΖøgÒØ÷ÊØgËø'ш¬òÂÇ%á(Æ2£Ÿ\ó‚xB©„^h‚²}8ޤsÝ+µWüïûtÂÒo1í¥‹¿P913½ Ôz¥›’„ø\š—áY.I E²]ò.ÄæÛ™·0k²<Ñù /RÛ>#‚E_(CA©É âU¾Œî”Ö9š®¬LžŒ‹ýÚ“®ã5' ûŒ|J’€'"+s’ÔBSUë>ûñâ*Ê&P5¾W²šü×ðDCôËp»Œà©Öã^m:aÍ£.GPòAãyAã’Q•/O4„w Å‹áx´YWÞP€Ô#nö~â}³Ð³mâ;6FåÞ^—ŽSH™¿²_톳š¤$…¤š•¬…®¸R³f9|³R¹¯F–Ëé5QÆ?e€Dº†Vô˜rVZ‹ÉÕ–—$pòY€\/ž‘Ä`ž£ø{†L¢Àù·¨Ë²OvËÚí-7€øK/0¤OFzüå ù嫸(Ijok{–м‹Ë-k„p-rK޶RUX]T»hßÜKprÉšZXŠ<–åL¶ VÃÐöîMNÑ7¡Ú<62x­TÀÉ+٠̾ì±&à Ä žAX ·ò:ÏbžX’ Eÿ· {s¨¯aËñ6ËŽR>~ ­5©àáüîšô–U,†« ^Í–h›À£fé½lÄwÑË>%/‚§C@ @ÀækÈ%´¶dÀ=ÊJœ¿†]GK´%ð˜7…“<ÕO‡æ—P )ÀøÁzs« Ý()±m‹†è¦‡éJÁ8iä7‰m[]Ržh¨×4`=Ø€º‘ ´¥]—YU¯'ɳ(O4D Cû¬†¡ßrÅi£…Ašµ5’ë„êŽðDCd’4×d7 e?;á©Qª«%vÕuH x¢!¬¶­¨àmÛBêpiÖßI¨î(O4D rMËáÀó-«±N£×çYcÚÃe«¤<Ñq£wW4 –<¬³ÓXŠ ;•$£<Ñ“<êg¿¥,ˆó%ØŸ7ŒÒ¶¾€bv௄tÂ{¬(·J(^j¶' xd*IB\’< x¢£ß:DG¡–a'8 A¥’ŸÞ<ñ§P˰ÙQY$-Ùök2•J"|¨ä©ŠÚ–tKë”B-Öýü70à öâ;xäÁißÄÒ¾mdãÐĶ­î(Ôb8ð¸n‚—€ga‡©m•ƒ'ÏÔžšÌó4Æaªt}§ùS•À“Àµ$BÎ »ì½0ë”öY CýÁçFÓä^¾K(*Ø€Gì%j§R©wлÃjÛJ×îÕ†zËÒµ®\B& µ [0#$œJƒâÝ·m·lžÃ- ¾Eltt·…MS²{N]RÙ$ሮ$}A7 å’Ç ÖÝ<™“vbT7ݦ<ÑÙÃÀ´c(–8*xÌëy™}N²$¡.)±m‹†ˆÚÖmÜ1ô[ß §¶‘BKi¸ŠÁ8[í©Ú"+O4ÔKû<ð“<``¥´›ìZ·”€'"’§W\’p‹ø”³.¡º¦<ÑÙà‡J~Ñ3Ï Þ£:¡õA x¢!òYE<‰ah )O4DÔ¶ã»ðĘðDC<=»+Üô°‘X„¢¿F¼žX'û¶Õ%à‰†Èî9~àñ…R#ß&”±6H» Õ1ð(ö5Ò:R~°S°uNý|?$ Ú­L'’çgí;†ú‚ ™´xïÆÄªÚ‡êÆr ,qÛ6ógM~FŠx ßç1ÖÆÞ dÓÃ×w-kàá¶m☛É „w ÅϧƠYw\½F$€ÇF– @Ô@!¬?ð”Y]ñËpøûn%‡WâÐ[=a5 ¿c¨xJ¨žÈô17‹Úfä~[„_e¬S2G¯ÉO¨m‡Ÿ°††Ý14-Ö3ÅOù“û<üÙ›ÀcüVµú9h%1íÓƒúÇãë$ X¿†-û%O×3.ÛòP5 ³Ñ;9À‰X‡&T_<~§˜ÇÔçñ¿Ó^!½úJRlÛÆ C݆¡ìÃpëÂ04~’%ˆÖ<ëGm3¶ùßià!’çõ'ô­§ÃÐØ8ÏÃÁ#Ë£Úæ ‰<¦@ÝÈA>Õ-æy|ïHe´yž£» û¶%†¡q¡Ä "†¡G ÏÃ:=µ.RBÕ¦<Ñ5 }&Ùn7Æ”€'"àiß™€'Æ”€'"j[û xbL x¢!²’´3Oœ)O4DGÛv¹|vžº¢jÌJ%à‰†ˆaè»6„äÙxÓ£„ðDCDòô§7x6*%à‰†{ᛤú×°Š%à‰†z/?%ŸPŒHüJ¹ÐÃTׄ³Ö¡¡²/¶b­§ ˆû¶%´:ª°‡AÇL]†md—rÙ=` fPr!„á*&j˰†¡]‰…Áª©ŽG#,{ÈŠUWVB…‘ÖJ`ˆ5OøDŒà9š€'Τ€GúƵ¢Ë™l¥ÇÍ)ÙÒÚÁ5ä &¶Yúš˜=ž—Ÿ¸ÀBO%<å.Ã6h½|£÷dÓÃø’Qm³.Ö ¹JGò×—¾r°'”ƒ!žºJ¢ìeDUX†MÀÓÓ€'ˆêX- "sŸÇ;JŽ)ÿ¤ kË_^´EP½?ó‚g Íž!G¤Ê‘iìÔˆÏéô‹û\äP?ú}™]ªèz` xÌ˰=?oBJ‘Q²]³¸lÀ¸ZIz³R^-j›îTCo=k”…mRźŸ²n QÉ’‚«Õ@ I@ÄQeNiå°Öź<ìi)ˆN5 ¢ÀiL63Õ6ë’3yÙÍ/ÄBhu=LiE÷“×Ë(ª”¼îÈ´¸FZ8äA'x %ò‹CÔ¶c’Uµ÷bJéÜ/·µwôBRð˜£SJ«×šäqݦe| ßö@á…“:Mé’?Éç„Ídîóèëvô5h*xÄ Á ¡M}+sOZ¸á° ÞøV( p¤¤±ŒÂÒ'í&d Û€AëW|ù'ðäÚØ].š„4°¶xWPkï§D!˰sj›ÔËQ»@vð¤´è„Ò08–†§Ê€ƒoÉÓèOCOy,‹Aøe‰¨{ ¿…ठHAj›¦©XÁ5~š–MM´J­,Bt­bþÈÑòbN¥Íšn¨Ü‰à 0{)~p…+±ïãu}R|à@-6Ÿæ¡ý6ÐØØèT¯F&]Ü&Ò#¢iL§¥ñî2f…6‰Ë°eM‹:{Ak³%?!ˆÃBhã¢fãRk©dªbh$RáuÝ+Œäq%.÷’]Ñ2ñîdUôyTµmÍ(½–™­1ÕýBx ƒ ŽBí¨ì’‘‘޽Ïó$´î© óœú]j]vÉPøÍщªmM xbL‰m[4DlÛðÔU[áKÀ «j<‹kbÚè†zO´†¡‚yN2æ¦Pžh«m+~~èHøëÞi20Væn¨¾+‘[2–vÕøòFïX ‰”€' m Oi࡜žœ\ÍÌÀåѾb„0ǦVol)!ðDC <·jl ‡¿r=BT—ÃÇt ›‰–èä["Ôè& ›™ðDC†yƒ…'<«0 5‡,åa3Ÿì,-Ö1†bë4U­›³>)O4D$dUígj”<† ÃpðlÖÒÔ¹$Èž4ìáÚY‰˜…º‰m›ðDCô›¤ ! C[ºJ C}ÃÑQ¸t#ƒBZ , /¸L¥“€—D Þ¥aÃjøF^I*† ¯å{9näT?¶7!È÷ƒ¾fæ·CBMeƒÇ°cè²a(¦U†ÂúÏ4\°õ¡CiÖyQ¨‘÷„`ˆàEGf„6ˆä©´U]†½Á¢Ò`ï…Y§ÔóÏ¢ÿ$©ÒçY5¥ËŽ‘¨ïå“ Ùê8¥Œ­j¶Îê©¶|mらJžÝaÍsê×p0!+Ác\Ž–ò0AãšÖ分ÿY‘¡êîÊöªÞ(´®:8²IÁÕ.œL‹ÚÄT7"Qɳ/OœÉIr¨‹?ÅõÍÆEœ x˜ä¬Éb¸jw ²<Úæ·Z_íººÚ–€‡$Ýçވȶ-(öÆmúµ#ežÇ¸ [Y\m\°í¥"|Çz÷‚É ½{ì½'àY÷”XDC½x1\£(yB†Ê¶m)éæ…ÍDýv Më½ÿ¾æ”€'"j[¿¨¶ù†úm=E¤™¿ f¢â\*½O$Oô”€'"àée€,†*ýC<ô¤ìW$š‰*‚+ÏÚPžhˆŒ¶õî]펡)YòˆAR"°\IëÛÐc5kG x¢!jU½§òC¹íÐÕ6¾HN5ôHÀ³TB¹ÿ«¿^|Aï|ý¥ø½ÌCðawƒ^ѹ·W $C*W L¼ìïÔÓŠÐ+x+U’ ¥T#©á{Éh[ÿ‹•í*øy"Gbð%R2Ú¶FTò¸‘r¯Š½!üv‚C?å¦>6*«ñ$¦DAÿÁC ÑûrH–N?ÎŽ8bŸ—*úõ÷ Ü Ð×ß;8¨ãGF3G¦ KxLx’ôÅÕL’Š¢*DÈ„âEðeä‡îœBar²€èÝÉ©Âd©à‚ÖøÒ¦ó]ÀÇYáh#ò tá‚öÂììva–…Àç bÙ…\]8¯‡¿@¯Äráüxžzxê€À³:ó¿5£rÀZ?脪Oø»4ä‡î Î$''¡·U*5ß)CBÁù4{~vV ˆÙYEÞ…ÙYáÇâI0£N³¢ï¬ÙÇÏUØÃàFbÛ–P™tC2Nq :„˜äi¾= BÖ%Õp£÷ú¡*̼nÐÉÛëœBÑCOJžM«çÒ:%}¨zm(0GuÊ›7eÉ#•ÏK¾†¡ÊwQÃЄ #yî¨5Gi¯jµqJÞ‡éÍüž†nhº)¬£Ü}ž—VµchbZ)Åa$„äÉÄ<'’¯a'T)…m‹³…ÁHKž„*$«ä™)7‚mÛH6:ð4²¯¤ký”ÃQ4©5%?É3µú<§š*³m Cü3VÉCcI·¬’gƒôy†"O#ûz[žxÒF·08ÙT™a¨l *Ù€&´QH“<3šä‰÷JÒtHÃPÙAù˜¢ü%ß„4ŠgwŠMòè’§È%ÏԚǣO£üMRh“;†r|ñºahBq'AòÜÚˆêJÒ;†j2*ÎÐ ¡8gœEë™8ƒ§¯²C…©Dm[…âhm›Ù{œÎV´c¨ ¶ 0K´¶X“†¿ >Ú¶2”I, ª ’G]IcðÈ£mµ~ ­/ !y6ì$iB5¥úÞ–—$˜wω3xN%àI¨R !yb žÓÍÑ'½Î C+¥úQÛ¶ýqOŽJžÅĶ-¡ri£K¿•¤«ϋ䔮õSN(²Jž™Ñ瑇ªÃЄʠ >ÏÃÕ¶@ÃPu»]71 Ýðt#¸Ï³qöm ¿chbZMZ¯#]ò x“¤‹eìºÃÐõÊ* ©b´-Ö¶mAëy,;†&†¡ ÖóÌè’'ÎàÁ_IXôÔ6«a(¦Ä04!Äïó¬lÄ>Ï@Øo’&b%!•<ÎYtm}ž ³’Ô·¥±‚6VNïóL«ëyöÇx1ÜJ®i9$xJH¡>Ú–K CªT`šFÛ´õ<ÓsµæòÈÀ³VK’9 ÒF—<~Ÿ©œ×Se9'´N)Ä<ÏŸÄ<Ý Ñ†ª”`'ªå…6ϳÑ$ÏbY†¡æïħRÞ¼©ò!E7ÁNü(Œ…ÁíkÍä‘g¥oo¥Ÿ’¾ïzô•>ôkùc m¬ßõKzŸgZ•<éÛç¦kÍåQGÞ·­¬OÉ ß‰!#_>EZ÷”@7,ù¬çaßçIa:®¢Ç)õï ËÝr>%ŸÒe.ë< …%¿Ñ6ò}ž¥†Ûçâ ž®]•~J^øN¼ o\~e^ð¡)f2-Ä÷yþ$ζmGw…Ü1“Á0Ô‹Gt9m„!™æ©"Õƒçyâ ž®gªgšH—uF«EàMÁ ß(yVn¾ë¡êÐ;††‰tÙX$y–K+é8¯ç9úœø}žZ?„ÖÝ”Ðcêó¬ì5xªm ­)ÕEŸ&ˆdÉSdè™öú<1WÛÃÐz§º’:Ú6£IžÒ¾8ƒ§+Û¶Ú†Ö-ÃʼnBXUÿIœÕ¶®†åÀc¦DðÄŒÉSÔû<7ÓwÄÕ:Ô¶½íš†&Fò¬¤oëZ8X’°'¤a¨â©ahBëƒä% ÆÑ¶tœû<ÇB†Ê_ÃŽ³ahBa鿢AòÌH}žXÏó¨!?%Ÿ†&¤~JÞ¸ž'Ö’Gšçñ7 5¨mµ1 MFÒê„BŒ¶Åz¨º¯!¤a¨¶ž'1 ÝðlUoð„ßô0˜ÃÐ`Š•ÔÜèó<Òv»·VÙ˜‰tÙXBò¤7Åu-Üšç$C2K<Ü6ImÛÒ1ÞnWTÛ#O݉¥º+Ðz#ÉC÷0¸¹/ÎàX³ívkʨ)Ë¢X[¡:øAºAâ)Rê°”¬CéZñ"ɵZ=é’gFëóÄzÀ )¬ahÊìì%¬—‘¾­]øò§Í+–êˆn_ŸuT¸#(€²!²ìpíà18t¸ê;aÕ´h—<Ì 1Ö’'´Uõj%GÅà©¥4ððÙ\oàšƒg•Txªš¿+(üÖѶÆ8ïa€À#l=ågÊî<ÝÓ›æ1|'n¾ã~ç;ßQOFú6"z!ÝJžøøío“[9ˆNð¤Ü•ÎS"\:0–ˆcS1¿#=?<,ºÏ ØáÚÒt;X’BF’.ØÁÊÙ¡£C‰ œª¡ÇÞçaßçYNÇ<Ò÷y‚ C½ ›ù€`Ù£›a}Ç%˜Of’Ô¶ok.²Ó·Õ :-¼S›Enù«£ÃƒA‡Iéawn‡ ïÚ bä]{šž“‡ Uå@¦¦ÒáºZ‘èE£UõÞ8÷yN4…5 ÕÁ#ø)æp¢’øŽËßa'3éàü¾-™Ì«#¤.,yÈ8vxBB!4h‡Ò•ÁÓáI.!#ñBad•Áe¤'c–\x×]SÉ#Ÿ'ÞVÕ'šÂ†ú‡3§pTƒx’Çå’ÇsÑÉ<>Â1¼ÊfüèPù«C8;ü½ß¡Ë 1BxðTtUø‚«CòÔuŸÇ$yŠÀªšÏó,†0 õPá«¶™$‡õy\<‚ ‘µ5_µíÛ&G M¾{7zLeëÓø«mûZÔ6WJÛ2þeäw‹ÚæeI„ŒkOÇ‚GÂÎäF°ªÎ5…Þ1T´ú4P‹Pó€ ïô/NÆÑ€o‹~ê€|âåK™ 4ÏC˜RÔƒ„0¼sᱯÐÇRDW ¢¤É´EŸ†\½+#ÞUtÇæy|FÛâ ž*†À¾ß±Ñe†âÿí !µ0© T!Õ‹™çªço*«ˆ§³}Û„)ÒéÒ¤‹GÛâ<Ï“ ½ch5é;k–Ó!M*­ jÛ²"y¦§éh[œ‡ª%†¡ UJÖ>Ï´7ÚgÉÓ•€'¡J)xž'Þ£m|£÷è¿Ö£¾¨^:4õKÁëy–c=I*®çIÀ³î¨¶–<·b=ÚÖ½7QÛª‚%ÏJúöïÚ½û÷ xªŒÌ’gZÚ1ôŽ‹q]‡í”ºvËôM(¡ÐFòÄy¨º/QÛª”|ú<|ƒ8ƒgà¥< UH>’‡îa°²'Îx¢Þ$¡¸Qˆõ•ôyª”BXUǹÏsk¸åVž„*£}ž8ƒ§tª)Ù«:¡ i1Pòü6ÖCÕC xª”|$Ï$“<1Ï­¡¦dß¶„*£åà>ÏÍXäš’ƒ„*$Mò”Ä?†ª6Ê2ìd’4¡²H•<5“äìnð,,- B‡%Dør‰°ûÒ þ ר×ÒýQ/êÍÝD–\_“â,éi- þKzú(%!/¯˜‡W–‹œ&¾ã¹ËY_»ºp'äå+´\váz‰%¿$×D,ìÒ'× ý¥…ëJ9…g`H_,ƒÐªK¸¬B èùÐò_—ë.–_zž^zùšÓ—ýºTw/¯ØˆÜÒg±mëÛë.Ê¢Éò‚W9>‹=³ªTjGÅÕ'QcšR¬4VÕqîóô” Ç‘Î>ÕÆ¶ÇðI åãHÊ!n( 9’Ç–-§è¨F.ÄŒ)¼”œÑ‰–Óœ´Ã[’t]OœÍsFÚV`„| @à]Ô\ìa q!£1:‡ ÷Ã.^GF’âXdIHiJ's } Çƃ Á jÕpà©o9–uKWž‰±ÚöI®I{ŠŽwšñ{Bú›Ü/œ¿K09òs™/xd´9FGÇ" ‚ÊÚÏÑOŽ)ˆC+dÆW¨X±gKžùY­±è"‹ÀÃÄWRX`Ç‘-Mîçû¼0c8A_Ù—ÁQT:îõTU‡å.´Y¬¨å40Ÿ#6Q9ýsk&qš…¤DB)Ð8&w&nÍE!Nýû~ÐL‚c¶`Ê/ÓœUDçBF ×ä%/ÄËdiº™, Ó$6†•:«ú5g²ÑA¸oöÊí5^3oô¬‰gÃËï%'§'Ü7Óò7‹þÊCmœ2j¸f{ú<´×ž†FQÈ-ÍÅ/p3çÁ¹œƒ«3,h>ŸgO?ÿú#1–<í;|çίï|ýíÜùÄÎ'w>MÏOž@8cg—®'.=F]Ã?r|ü 9Öã;#ÿèG“ _î{üq8?fʈ§ó„Û‰c?þ8ö§Gþ?îõBC‚O<¡Õ ÑÓ;YOœì“Þý“Ø“µ ûNáé»v¡#r5áÓO )áë]8 Ií)⸠_>Mnpø§hò;Ÿ~ yú âû4/ÈãyPË>Ž/Çÿ¤¹YÀ÷±¯£'Åð“{ÒA‡¯?çǃ4} žðN”´=|ìë4}æ">á)m{äöƒç „nÇDèøDÎä@ÃÝqÇpüFþh ^žÖí4eŒÇTé ü,úZÂÔI* ±Hñïø­ØBâH}è™ÐüH›H¤;‰÷w¢Ómw2×M4Òí›îÜt±Ëè9lºýß¶I#âM|îD—·m‚ØwÂõíØ÷Nâ}'p' Š. ÇMðƒˆ‚Þ?¸%qà–€Ü!ý;!A(×&Rð…(·ÙJÇŽwR'\¶Ûø-'çö8ƒ'¯ÑáLô„äì„w,“¼8$Ÿ³ÂQÎ_ÍÝï³rÒgò~tV v&(Šñ½õq?› 3á vÆrmyFHv" áŠÄšàé{jÍãÑçÌ`O¢žž¾ã}½}=袧¯;õöÃ%¢~tÛ|»»Ž ô£ÛA¾·o°¯»èwÕ70€¼€Ðý@?>çrÔ]è?ÑŸË<•Ë¡ÿ¡èx2‡îápâüÐ!‡ÝrÌJÐJ!wb9çsƒ' xÿ éGÈû„ËåN€ó t=pòÔ©SÈùöé‡PÙrý' ßSè¢A\^„@§NæP\è.Ñ)ZД¤Í _æ°ëЩ“44ÊõäMùq¨2¨]PÓ ¢–íÅ­† ¼pÙqiQ ûIÒý0„ɡȕ…§•é'.}øØ½ð{zûûŽï?~¼çx_ÿñÛÓá ΃4:<È¥ŠKí|¢Ÿ¶.¸ã[ø Ú}›¤ƒþYkœÊ5Æx¨úátÄõ}”í©>@ 0 èÜ7 Q€ãà€ìn`€§A¢åP¹~Ä÷^žvަB½sƒý}}RJý<ä C..FŸ˜`ÿ€à°ONpÛ}¬½ŽuG¯‚núº8Ö„ŽÈ zKtõuëC·=ÝÇ ü±®cþø1ôÊA‘q|@tù „Ža'ï&ü²AÀýXJ N(9¤·¸9@²}8pOÏq”ʳûx)G—@ǵkäŠÕ};  òÕè8úG%ìÁ9ÑÛPz¤Ô=G€30@áÓŸ{3/‚|èÏ)qá¾»i›Sk<]2ëÆOâ{*Ýø)Ð;ôÑNèqwuÁcE €Ø¤g€qjÚ;ÇÚ{€Ág`€1ëß1Êm}noõ1Fïüúû…çh¦‰"fëî9†9ºK%`Ðî¾cØ£Õ úÔ¦›z ƒ7B@â$TS¨ ºéÅ•ÂÔ œ6@'½.¬w¤Ê+õ °ªrz‹U…¾bú„Fê>†žãX@—  ²‚ ÷=€Äî>N,7vÂo²~ü6ëïçÅÃj@U-þ fQŠpA¡O’í“êHônN=Þ%à»7ijbÜêÇ»›î‹1xúqO]ú¯[˳SGðë½ ñókoøú¶Û¾‚hûöí;¾ò0ÆøÑÃ<òÈÃÛydÇÃ_}„ºm‡{Dèü(ú}‡'ˆ×_ù ЇÎÛ¡¤iú<ü0¶“04-Hça”öã? ¿í¢{äø(ÎRÙ±ŸPnÛñá+Ûv<ü•¯<¼Ò$ù¢´¶‘ü¶oÃ)ãÜP11Ñ@ýám_Ù†ÂP÷¯(à¾c*ðŽm(Æ£Û!%R ¼ ÒÚAîÙõþ ‹IëÁ.!•‡qK €Ðtè÷UHýaÜ’æƒÐ¨Y mچ顯l ûCÛ¡ßCÛ¶ÉžFú Æï˜š4ºyx9Óg9lÇÏ U]?üÈÃ_}îå£HNöÉ–žÈ÷vAïô¶éËÿ ç $ѺA…ž8‹Þ³ˆ‰rÇ›ˆ1xN Õãø®ýò§ÿôÃþËxîóÀk§»gÏÿùTöÞjÊfÑáÕ¶ì«­Ùlë«™–VtÎd[²­m¯¶dÚ²û3™ÖÖL œmEQö£ËV¼ÇWuBWÈ5‹wþjÝ/îÖôÍýû[À¥Û ‘[ l¶­¥ç EÀée³°+Ê%mƒ²dÛPHž.[¦¥ ‡k%E5ÛŽJÝÖŽ®ZÛÛ[²” ‰Ò!Q[3¢GÅÈ´½Ú†ÙvN‡^E¿öƒèÏ£l{þµã–‚¼½Š£j‡?ry¸½óàÁƒíÈ¡óÐ!’"N¿í`Ûv…d…|  mÂ];-YÎy¢;¸DÙ¶6úÔˆx¶µSˆ¤€½Ú¡ÝPSfÛ²¡ZQû´áFδ5ïMêÆšÉñ#Cù¡®7Ž¼Ñ ºº;=ÐuäÈ‘lWWß±#Cg‡Ž ¿6$Ú¶Ä<=}G~ùóŸþìßö÷õ7]-¨e@êîkØþy6ìAj$üäx@Ê0pöÛvýÑëÖ,pÐVÎ>ímRþ²ØFÓnÞÕmíZ²K´µ·‚tÂR%·Ÿ±¦]ÞøK¤,fúŒÇ˜}I1²í¼íí‚|Pþp['’9 ô[`Á¤Jœ6œ ðp+G6Ãþ9—3ÙÂjKÚŒ·&ź'g¬¯/웕Ýöó”Å‚ƒ¾O÷Ùn$U_}Õ¢)ÛÓ“ß¶e+üÝÿÆKÙ¾î³Ç¶lé~õÉ-[{^nïhŒ³äÊårWÿå§¿¼þ»k?íO¿öò }}9è6<…x%‹§Î8ù3y'›u²p˜W2=G'ãdчt²TÇâïxú¶o#ÌÆÀ,óGÌÚÒ†Ù‚i‡„_p*íäuy€§ÝØø89¶2iѪBj=su+{PÚ)&‚¡Øz@ÓhxÌâø× oal ©Å'¥ÇR§µm vÏ¡wD&fÉ9ËÊJ)µb½ œÚÚZZ²è”Ú Í†ä…ß:¸qq¶W¼È‡Y3©çÔyÆ5††Ú^}õÕ6„ŸÖÖ†î“C[(}ÝjC@:´e˃]- Çûb ˜ÿ¯þô×ׯ_û׿üÓí»¾ÚGFoêìl?àœsòðsÚóXær<‚»pä삞œôbËŠœN]³˜°ž@5)ü¶mo—ù©¥ââ·°¿C ‡^@·¢N> [ôï>|èðáÎCG;Ñï(:=zôõöÃȽõõNJ‡!ØÆyö`{ !ôÀÚÊ€AÞê!ø0âýNÂÿ¡=pK@[´ÓÊ ‘›Œû /w†*Ym-&ƒqç†ö¸K0ªÁ¹bÙ™ƒ„×Û1ü±íyp€ñ'ÃûÑNÂä`'…„=€EçA‚;âÔ @;ÔŽÞ&ømsè†Í Ücv2”âÙ«|ÛþWZZ^nAèùæö7ò™/w·¼üÊþçï=ôòöÃù¶—_yaçÈËû_Þñú@ãÖ8ƒ©°ÿõÚkßÿ§ï#ì|ÿÜ~¤OÆíÀ]TÜÛÁý™6,VØðwÏ2wøfºÚ¿Ÿ°cK†÷^_á|‡ö{wŒs=.õôÞ¿åDX–i#Ù  Î ]‘Q3Âþ­­ÂÖÿû½íþÑ\´4ˆd³…²â#~Í€öÝ[` @‹OÚu’ëA1•a*+Ä­í´WGу….ïB±$Zh- ıÀ¤÷—mmõÞ7ìU€K -¿ThçÌN¸ü:ÀðÊÁ @;L ‹gFG_~…Šž—ŸG²æå{—»¿ÜöücGÆ_~ùÙ/ù„žW¾~ôxó¶[xþóµ?ÿó¿ø«¿ú»üÿî¿÷]¹7‡rC Ú_ý(îÛ¼Žû8ñ ÁY'ß™§}žNvÄ’ÌÐh?$¼ûP罓½ù:qó ÚÁÃäíFˆÎÎø| ¼ý ï§ðËGàâ7ì jº1ô=È«”xèÛˆ e!>@ûû&v¦ý^ >0ŒÇ TÚiw†ƒ šÛþv:’Á[(S“3{À¨àšÀq?ÅŒ€êfáˆ?ìá}CËÍ,rã#lx È9:C:`B…yGQÔ³EõV{8x²o ×—k|ánL¯¾°ýÉ#¹}w·}ãßø£íw¿¼ýé#oíÛqÏÝ_þî]wß}è«O9ÖôPŒ?è{z §gðÇög¯}ÿøÚö»îyùõcØF­= o*¬¶zæ þO>VTÒ°šæ)oã¨Ê–%|ʾ½Ï+´Òþ@«×cÅÃÈ-¸£3Bl<¼Û)[½‚_óxަëO-üÝî)€û³YQ’ÐAüG?|ÃÆ÷{\¸?f½’-ûñ|öi Çkñx5Kز%CçI{ü|¸Íž`È cDw%ovÔo;t@í«ˆ U^üÜÙn%{OPy3”¯:é(ÃX*BGN½9Ð?p´ýù»¿øÅ/"|<öо#ÝíIwÝýüƒûŽtµ}ãî»?ÿü]÷ì°±k gɃ͓Þyþüöµ»ï¼k'‹Ŷ xT2rt²ÎÙlÆáÊ›è ½"€¼pɸåªÖ6¦‹´3-Ex—{#qôœIst8̤™¬§µµÓ CoÌÔ°a+ÂmZqxªöeÉTFkχ’‰FI­A˜iw«­M;D^ÃܾɽY$a*)+LWâ¾ ¯€ûªï1}µNÌбH®×²—A ½ð©¬ŒQñÌò‹,~U´° "2°Žûq+qo12ÐÎFoDÿ£C9l±÷ÆÓ-û÷·¶¼¼oËcm]Ýo¼¸ïÅö¾ðâö-¶u÷¼ño¶<ýGϾ𣶠ƒ µfòÈÀ3„”ؾ®<ûÈýwÝqÇÝ_Ûß•cvhíílüL ó
ûôί=øåG_>täH;Ü=¹ù5uhŽó€Ìó ;úFË‹÷nÙ±·õcǰeð±cÝÇŽmÏäñë $LŽè>X¾ Ïó`wôŒà¹µ±I¼€š B«ÀãÍ€,”“žÊ pA²å°Ç減DÔ ÄÕ<^ÇÌ.Ó×…—à~¸ýàÖ÷"¿í,ÔâŠÔùƒ€ÆÎ¬vGãüáÜey“#Ù²‹ªv¡{A5‚ThlÞJñ:ôµ’Óò´³°xؽF&nt˜™”“½;hqhÛÛÛyÇ“]@ÊlÀšyÁýëí, 6œÙ}B;mA p~"¨N[äÏ*¸ª¼5Î’çDú^Ø_Ëú©[ìQ2;­˜ý]ÉŸÆð ¶zŠðƒ»<éÕ|xÖÛLË6W“Ç™8ƒçTz«ð5ìT*ùGBáIÙ1´ˆþ”¯aÄy=ÏXÓVõãVÉÓ …$úy¾Wµ„¼Wõ©8Kž!¤¶…O…2)µºè Õ/ïU=gðäý$þå*ýÃó7Dô„ÖÙ¾’€¿5’çf¬Á3š¾o¹ ðh"ˆ› =¡uFÖo’ΰïóäâíkØü+k«þ¶àì]úVùüaJO%¡º£à¯aÇzÀ`4½U–<.ûv5¿†ò.~%ÑO2j^÷ü5ì‘8ƒg¨Q0H¥¼OÞÂyeeY¸‹<ž#—< Õ3-Kž·ã¬¶©m›ySUð5lÑÃ'ºò­êDm[/Üç‹óv»c{îS- ø€Áª¿†-Åõ‰.¨m ­­î‰ÍZ%ÏÊhœÕ¶·÷„Ÿ$M(!™‚%ÏDœÕ¶üž{o%¶m UF7=ûœ[¢ä™a’çæXœÁ3´çáýQfà Õ/Jž›£qÏhÃ½î ±J(4޶­ÄÚª:Ïú<‹ x*—%Ï­XKž±§þšàw‰äI¨| ”<‹±ÏèÛܛ‰Ú–PE(yb=`0úì$àI¨Bâú¾Mò\õ’„±Ç¿ ‚‡Y—%Ö1§ßW%•`Ékµ-ú<‹‰äI¨"⌳h‘< ù‡b ž‰§þ ™çI¨B ”“?¶ åäWuð˜ ;"]ýâ˜É:Ï3Íû<±Oý’gƒ‚§¢²Õx"¦@ÉsíL¬û<Òî9ËlÊÏ6¸®aî'åÍ/(ÏLœÝPì.eËGãôÄfÑhT b˜`Ô¬LmI—oj4â”&©”ÉS5-YxV‚)ßÚ*ñ\×ú|íJµ©µªa+تzl{œÁ#/Ãf͵9}ÙÂÀ4n´n´ûéf+)Ÿ &ðˆæ ®T2ƒ…+•Z- ĘŸ¹‚•„”ƒb àºö&Kf5APŸKÅR1¡")S‘VIÁ}ž3Æ<»d«j7en|¹L&VîÐü$›LÍz3åÄaæ^ÈÝ 5Šóø6ð(%• óm5ý"ÕO3•jëÅåvñ¯˜c‘ª “ä9kɳëÿ(<º‡‰¹ ~jb¹q…;KîG¹]ü+–Ò3ª&|%ÏXïaæ‹¡À£ªžGJy*»KããõÕÂ,’ e‹@³5«'Zá C]Á7¸€)S5Sj›ÐÔ†Äð¤Ôr[I«˜ µ~Uiß¶x¶í’‡ªS"G1uÁ`p)€G|ÊrÚbªä p‰%ˆ à¥lRk¯Þ0ÔŠ›r 4ªmz!Ô.{ʵ%¦¨³²£6ì`«XНª5ä^qƒ@ɳïyž†Õm=UE:tvkœçú¥_ßêHžE_ɳXˆwŸg}íšX‹–A¥Õ'áKËÉ#ïÛ¶x.Ö’'Ùô0¡Š)°Ïsë\¬'IåѶõM‰LZc⌳hÛ·-ÞRŸG™w)Ÿª¨SU’Rpœ «WA³ØÃ óQ>aÄS5Û¨š(ynÆ{Àà)ŸM+ U¦Ò/«—¢«N[ƒCø ¡Ü–H¹õJ§Roà1Hž•™Xƒ§á‹õCJ)®¬„KÆ'±à©bKÄ<·‚%O¼ $«jΰ&ãO˶®RœQP´E(ŸO&B{’ª6 ®»¼Ùœ‘ÑøSž;òßõt³¶ë›ÒFÒT(ÅÎsÚmGeð˜,IÝ`Õ/z²Kºo[ÜÁó%¥Ïã øFt„cs!€YÉa§Î㻜Åè)—§™2¤Â#ùd䚢Kõ3æÀfW´º“Ö*B¨³ËÆ:¤”,å¤c‚šR äYŽwŸG<‹7e&Ñ/å=2n‚(Û5§ÄŽà|k°ueð˜ áu¤­Ö©óK¥¾øbAJn(ðpws~’¬¤ìà±o¶Zb|cïób½HÚ ¶™Áã=_Ãu]™ûü"¿7%OÙ–2e+Í>àí+2q¥à‘«ìúÆ+]6xL­äúG YCºé¡ç–Qò¬Lnñ7Ia¨úFxð¤„iPi¹¿ÐmÛþãžêæ þº#ÏÝ ÷Ût+Ï38ˆ¿I§Ww)Š¡Í\ §´4Eà©KµÍ ynÍ<gðì±h“Á¶R`5×Ó夞´-ºà™òSjHÓ¨…ˆƒÚf7€L™Êb²õ_êÕ]«tJ+Œé$H¨)-!¶§«¢¦dìóˆû¶­ÄÛ¶­áÞ*|J>U†k¸ÄBk?5g 0eŒ+Jž›ñO:x`ª.‡„ŸÎOÌDkKÁó<3ñîóT< mLÚè’g×kžøIŒøÕ(ø@µÝ¶-Öàa˰é`ýÚéA|6¦’xkGePiäÑ+j—:©QY%Ï4“<3±Ï®/¶žZ«ÇÐãO…v¬´¸Cå6ˆ–`ʦòúUNþ3q¼$ÁðMÒ…X÷yžÑÀÙãL…p©$•Õ&»£¥FaÁSâW±¶å’_Ÿ§ˆwÏ™yĹWô8ùgMà1Nj{a*“Ú¬ˆjùhPRJ×g\C\j.®–˜d[iÜÕb ko{¤0.ÏÖ²Ÿ§©}ê§ÚÆNK©íxL{l µÍÏpRÛ”R™îÖ MÔ¹z«ä±Íø«3÷áD„lE2%-÷Nd.—2 °$5ÔHµ<*¢!¨$¿úm#yÔú‰¹›Û³š½ÚÀѶñ0Øe<†Æw•çãr«œ”igLÁFÒh&*3Ÿ1?áa\ªV¦zš)©ÔšÝkÍȧAì5Í=Eð¨9ˆ8õi%m#*ÁÑ{*rcÊ–<¿ð”<× Û7Í֚ɣÏ|ß¶¡Àã9Š»{JOÏÏÕÀ#õaX9Q¦Z of×<ÆŒ*–@ʃ,Ë­é?a+Å6Ö”2-ˆ»ð‘·ó”Uò<gÉóĆ’<«H«Ú摟˜Em«ÈàR5ê­«,©ã©XwD5gäÓ ~}]'L¹ZtñB©ƒOýäÖ`{U<ËVÉSd’g2ÖKžýCáýÁ߃ÃIAm{–þªðÐ| VcpéjùéŒ'›¬ \'å`Ú‚Sâ7sƒ¨/{‰?…ЉÂAl ¥~j¬õ“"(ù™›UnϪaÇÖçËÐIºoÛL¬Á³†Ÿ’¯âc NJÓŸêº>k˜t5é¦Ä:¦½ªã½’t힪ÿžMH¥ÀѶÅwc-yž©‘m[B1 àyžxƒçñ*~ ;¡Š›4Hy¯êOâ åSòU5 -+­aQ1FeI§‚½Õ1¯2óQ'„´q¸5¤@«ê¥™Gâ iÀÀÕ‡›Võ<*O*8wÐÆb+-™iüºìÚ‡}Ô6à—²†]sðøöy®Ç{÷œ†{"4 ­¢ä)­Øa]†IùÜU^ ûh¶_VA3ËužE×bÛkðì¼#¤a(DfûP7¥ÆsM¯oÃ<ˆkžäÐö+ÝìÍyÊ3²¥¥úy:S©M6§ª½¦Xã<–\>ÎVÊPhª¶£)ctŸí@ªjÎfMòÄ[m{æÅ­§üí …'­MÙ‹ö¦)tctËôºçR]ÄI?aæS'¿Ÿµ‰x¿jʳ¾æ:ˆ?1ÅPÓÒO[•í¨2a+Ø;ø°y4豎¶Íð/Ãíp.՚ɣ7 ] 0 •Ÿ‚/xL,ê*ñø+Õ´û¥O<uµM„„œ¤jŽŸÒs·¨?z7PŽÑ’Ùέ³ÚŽšà髱¥"=ÁVÕ¿ˆ·ä kU->úrÁcR™¿ð¨P2ÅSFž2•¤†RÍ ð¸’À“å—\?3/ ­äŠée0å.–³ðøku´Ñçyž kjxô¡À#«ãJaÔ6‰$ð(àÓ”1+ÃC¦ÔLSþe™žÖHÔ¦¼<ªo;jO8»ÒªR°…Áì×ã ž]"x–Mĵp€¹÷êÔñ”ÜqðkJKEëÜë;òªF£Ò‹Z°´s·–Zì—+ÕT4B¥/%&–E‘ÙŽzÖ¬›å º–*7]äà1ìaóÑ6<‹‘XD¨5Ô([cÒ){Ðh¨äóU¯µjn?ÉS$VÕ±îó4Dþ5ìèFJk•­)éZT±ætóæEß>ÏÊùÇâ ž8} ;¡5¦À>ÏÍÙGã žg"—Ö}ž]wø€Ç-<¡¸Ö2£bŽ^~SVR¦ÕÊ(:¤ìòå5rùÕ Mó<+çc-y¾´\MðRJ» žàä¶´Ù'B„àñO©ªà© UÊ&Ù0Ô°žgq6Ö’ú<‹xd³FÃ,§:¥hpÉãö×ÐædRz~6’õDŽà¦ôxæðJ¥õ)Sóh\Ÿ,lEÒ&\ÑO³–ÐÓ—Ë):ší{«BÁ’ç_ó^ÕÒ÷yŒfÊ µÄÁíC]ÑQeÆÕØHú¿cù̼ßΦ²‹VÉÛ–»ÁŽO{‘R †ÄiWËKÇ^ö½Õ¡à>ÏÌÛjÍã‚Gÿv€ÝTÊ{ØâD¼äëÃx&ÉS±¤… œÊ'âíáÕ©~©<wÊ!iÉ6›m\CIitfõdIÓ,y”w€ú"ïJÒ•‹±ªnøR™àq-ŒÞ+<ÚS7æ ñ ,¯y±œz ,²á¿ž®äP (YP‘Rr!üå¥EvÖ<¾’çÖÅX÷yÊVÛÖN)IfÃ2Á#¿¿¦_Ÿ'¼Ú¦T3¨rHKÉÊ,’¨ZIàIYÁãcüiO•díó°õ<7ãmž“¾6Á }ÀÀltÈÔu7J)‚öÖ3`P®¤¯&­~ñ0`Ì'¨JAJH½deIm ~g€¼ª*»Z¶ÒSñ^U1”<+3xÖõ}#ÐDÖ ÕCÝGÛn¡>OŒGÛö¬gð$T[ aaëƒgîò&IoÔúa$´®h9PòÜœ‹µÚ¶[°m[à©Ý%Nå,“‚%ÏÆÚVÁÓ_Y)?NÙ$30·ð…MÙo«oZi9«l4ZEº)|Æ,yâ=`°«|ð„|@˛Å[5ù΃¤LŽ–ªøÝ@`¼¯ œ³Zþ…ˆ”Bôybmºû^ñ³ŠA¦,Šæ9†`®ðH¯CðX’¯Sðp³HÛzž·×šÇ£Ïu ßí9ä}9=7e~H›"Q¦ÄŒŒ{oZMO5öPJ-MÉv¥šá«ý¢³­´œÚSqõæQk±Và ²0˜ÛgÛ¶=÷XÍsl“æÞü¾ }_žMi~†-F…;cH#sˆ}Í$@R‡4 ÛyóŠ®!‚x§^ÛÚl5嬆Ñh4Ä$X÷mûàÉ (yøÃµŸ§ W~!KÜâ™{¦„ŒxÏ ÷„–<åöBÃ4 áW÷$«Å¼w¶…yCS¸êðHuë¶Fãk2…°ªŽ5x,}c7ÄþxR¾Î!kÊ÷6êèeÄ `L—Gò£(RªìX«¥E»ä!ßç¹uþ©X[„—<ƒ§2YàI…ŒŸÝ#Où±VK~’Ÿg9ÞCÕiužG˜MI Vüa˜ …‰ݬ ôÖÊ— ÕÅ/òÔ“”˜+LµÍRY„ÍFcS¹b5å‰/uïM³ªdh%<>†¯rF~Pín]-Û2µæÊÀð}žxU¿p¯Ù<Çe )=vïQÉz¹Ú¼R2ÚŠ‰§ì=W Ž4(0ð¤¤UÅÿÁçÔ¼jÌsü)/‰”’´;‚¯g"-M÷ºIJ(5²å¡å/æé¡2öyJñîó𭧨äQ™UjÈ(¯naÛ&}Š ©œ˜ %xc¤ëIDATsSZÒrçÞ»:þ)ñÖR2#C›"È­¡˜ÁÊ…°´§Ü š‡ F@xÌëybu÷œ”òTðXXÛü°-’‡>|#ÛÙ½n–/ÈóË[LÛC¤jº®+¿ÑC0¥Ü|)× ÃI”r¼ ~ÝÉ:k”<Ëç7xB¨mìêœg7ñõQÛäž÷“L%l‘²Ý£ÛÁ¬¶y•–•*cŸG õyÔr¡$"±=UQFòD  ÀyžR¼GÛ¤½ªÅn«×øšå£á­fPõ¼”+wŒå«ÐwÖyS0såýyÑåÜ¥4õ´r*V˜>FªR+É‚D·óT”MW- «\¦äœ4É£äùäÇ9–ïó”â=`ðÒÖZšçD®XT£|)?Ï(«gTÍꉂ­ªãÝçI×ahÓê†{WËîÑ6¯Ž‚GÛâÝçi¬©äIh]“·"ÁÖ牷äÙsïòÆO]¿Ö×[UÇ<û ’§Rž2Ç“gS|Ó«¤ø+C×á#A9HF¡RÖR°ÝUªšÕFgíóÌx£mq0T½¨ƒÇð|Œ,e÷rõ±#ûSÉ¢ ƒê• ïW²PŽaf•Ê£”åzí(XòÄ|=ÏÝeJžÕ'`î®’ÇŸ•Se†WÂ3i9ੌê <϶­Á`êÍÒiË P>;0ÝãªàQÍDé‘Ep5sOW< !õ‰‘жœòL®Ë¦±Œ%33±±î))Me_û ßä–T2©Yå§b46bèn£¶I¶mË䙤$ŽRfíL³ó"Óí’¨ñyÊ|­þ(ƒŠ'5i‰á¤~’G»¤ˆUªâÇwB+ɼ\Ř e)®¬Ä ´’)u—žŠÑØ4°åSˆïóÄ[mS CñkQ²5ãÄÇQ6¸äÌÅyTWY$›L![8š¥Ì@®¥,sùñ¿Â¢¦Œì‘åüŒŽ¼]à®dkO]b»æ’éÍêÝ)Ï ]ëCa#˜%OÌÁ#õy¼‡­pqyà±2—kÆ¢\mÓ’¶¾ßU–«<©hÁãy¬¬<ºä‘S1•E†OÕ¾œt3ðû<Ä<Ϩ{U †øVð¤|ýÔ6EÅ’ùVǬ\m7Ñ`t«ê­Ï“ò:&!Ô6CŸÎ*SFµm³œ½xt™hìU€EmK¥ªöᤒçñXƒçKúŽ¡;¥t,»ŸªÉ£ L‹#å.´f*«mòËÛÕBJÜh±‘4®#’ÔTƆZg[j%ºÑÀ3%VLö3H_Í"TÎÝ•âju—‡U´²¸bÈja‡qHi=Ï —<3ÇÙªú™zݷͨ,­ö¹§¼Â¥_=î«nÖ¼ð‹A’g1¿-Î’g׺7ê<¡&þ£Î¯©žÊ8Ú¶˜$Î’§áž lÛ–Ðê(°Ï³Tx$Ö’çÿ¨Sµ-¡ú§`ÉSˆ÷€A¸¯aûS媄2²PõÅ3z§)e¹«r_Â0„Ô«PRCF£ìÛ¶Å[ò<÷Ê å5Ÿ4¿ðܹ;e zÌÀˆƒ5OÐØFTÈuѬRÈÍ¥PÁªLËl¨Í>ÏSØ(£m‹HžrÀèJv”—ÏZ€Ç8Êì‹à@)S.xRAÓž5’<7ã-yµÍhi©Îq3 F‹PS%i£Á¥2Cc˜ÃqM¶ªÊÔŒ”Qʨ š¹×ÇšRª‘6¯$ÖD1 5jÊ•6@Ï×ÐÖïPÚ¬×4ûVMð,Ú$ÏÌ£<¦){ùNž«p¡N…ËA If_Źú”]LEWr,“&™ Öˆó¤}ZÞb³ÃË-§(ÌÌj…&lŰk@­Yƒ¥Ó^\eÌc…¦A’gñƒX4ÜkèóhÝø”öìdƒD<ó09ˆÈÓbš–QùVgz#;¥\Wmê3ex ËuP¢+;”jš lÄŠ©Uñü4 YÕ6ÍÐÖçP*™°žJU_ô[UÏÆ<_4èïF3§êün bãéZ€ÇÏQŒ§Ç lÔjSjÅŒÒLY e¬¦±Yƒ€1ˆ9•ªPˆ>O¬ L’G~œ Ôã­›³*9òÒ:™Ê~–ñðÕŽŠ‚çyf¿gµ­ážµOÕ¨<ðDZ–ÈÀSI¾’oÍ%ÏLÁ™d’'ÎàÙýEÃŽ¡Þ¦¶çÀ æ—š¤!¤éÎhª$m1D5Úk꩘+– [uòØOá]só¸ú¤‘2Û£Ä+ Øšg­Àc<7b¾î.Ã7Iýu‰‹½ê›à6…ä~Ò›b¾Ö¦ÊV¦æŒL©¸¦ròÌ…ÐÍä:ˆFiš’<µ+6œÕRVy0ZÉ"¤à>O¼Á# ¤ÄëÛîêܹÁSIÌt'2:aff‰ûeCMÍ~Ò ÏI*®]ME+§?è ÆÑÆx¢R[4.Ìmmz0JóDGò’ózž8<{—`X.?´Õ‚'øNžHxIÊ7^ TªÖäÑPô¯òÀÜ}Öœ‚GÛòÛc-yîIÌsBSä¯rßÌk]{GÛ–ã ©ÏS뇑Ðú¢@És+î}žš.I¨Ã×iB¡É&y¦yŸçL¬Ã醡jï\%s?µR}Æ4vT~Z kBÞxMòœùJ¬%Ï=vðèãh^}|-°Ckåp-A[¦ÖTðÔ„û<+gb=Úöü½þà1<æpa¨,ðØSHh­)تúL¬¿Ï£}J^œ?!M¤NVè³!jH££ÝØT›—ð²áir/1•šŽ~%,ynœy8Îæ9ÒJRyB]¶4Sì \„ÞëS‹K£§Œ9øíþ¦NZ&´æ(yÜx«mx\qçOLVÖöÈj £2AÈÙÊà‘Ë"w¯"·|LÈ—|$YÏsë\œ C'^Újü”¼K®ø±jà1ÁGÉÖKNHÄžÚÎø'd’<ÿÉS:ëyž´]m ‘MŠÅ %+xÔŽ‘Ym“ãéàÛ,G0u½Z#ÒmÛì€ä)ÅZmãàYô0LŠS^gÝkE?+L×ó³+ì< i†“RÈÀi©„¢#Mòˆ„%O¼- ÖÛÖS¾Ÿ@K°³¶¤÷yÄ?ätk2Öà©pë©„Ò$B̤€, b žgîv–àø„.––Øy‰¸/-|¾À‚`'×X^D–ÚÒgK<Öæ L/Ð}*tÒÜѯݵð!Ÿ·)Ë'㮌Æ<'Ò[%ð„#Ç!?~+w}x¦Œ,”DÂŒƒ {9“¤{êˆ1”øª£Á‹çS^§‘_Ò¢¯ÍÉ‹æ ŸªÛ¾U!\Ž¢µL·4gð 5V<&vªüaáZLÕqø=åTÁ2ƒÕRKéÙjZ0 Ã<Ž-‹‹cF–¶€Ñ#©òô›xŠñ$i©mK~OÙø\}ÁãX“™ñ¹Óó‘¸Ñ)€Gæ\ÇèèXyÕ·eÇ^£‹‰«}5M¯2~…©MÅ]m;$'X„à 9ŽAUZ9¼H³äŽ2* <4‚ZNÇ¿üÀ5I§ÀË"Òtx©e¢$lɽêà©‘Ú6üPŒÁ“Û{RÛ<¾gÞÀ >W¡×!¼ûED9†xr¯rÆì¬‘S`ºÃçZÇ)€G„™àh‚U xhm¥xŽSP Ës*!6«cÈBòÓ (?•õqrKCqÏО{ËéóȨá8 O0 YÉ<¬):Y#÷$KùUZò8RCXð@‘—‘ã2„&ÞP0¸ºYZ)Ý*¡à%¸Y! ” þÊ-üOR$÷7qLrO·–KpD¾7!ViåV %ˆ¯P²õB·pinAÅq¥Q±—¡Q–ic“‡À.nxíëHèrñ!t±xsÝ¡óïñrB·HbãŸ÷ððóÆž }väi-—náVÇEƒÂ.Ó`¥\œGÛºÒé½éôPú#Ô××Ó‡îúúzñ?ö€vG¿žž¾îÞî¾îžî¾>ôßwüxww÷±žî®¾®c]]Çñíq8G§®®îcÝ}]Ý]ÇÁèX§î.qÇãø¿ %‚DÝÝÝ¡äúº!ŸîžTŽîtÛÝK†œÁíxow/* òêFu@N}½Pú¾cèx.zpÕú¡^ø×?0ˆ¯úqC R¿þ>H·GÜP §^|ìáÎý8±þN,$I©ß‹ ©¢’ãrCCÂ×·lOWÜô@;vá–†œzH–,)=‘c]}ÝÇúºpŠýÇ£_<„ã=ÐǺQ‚èÜà¿Òì9ÞÍÊÙ#ÿ®c¨qŽ¡Ž÷ôƒ¶:Ö‡ž´5z¾Ðòðºà‰CYu·nœÜñ¸ðž#<ž†{c,yžÙ*Ñ ÿ‡ØöànÝ ÿm}`ëƒ<ðàƒàµ»¡vÞŠ8õ$·,ó÷èÁ­U!)Ùîߺõ~Åë­zÞÜ÷¨#>’‘ÀJÅ{ð¨à²ðˆ‚P­ô÷{à|~è¡Ð?õ|ˆœØ‘¸<à• ]B`–:>y"LJ ³‡h"qjm…ŠõÀC8$)ÔC¬Ì÷ ÝBoE·­÷Š7÷áß}´Y¶H®< ¥@Clñr¡gzuÿV•î¹oSŒÁsÛ¦MwÂÿíè_rº}Óm·á‹Û¸Ëí(Ôw’øÞ‰#Ñx$>KyÝI¯ï¼_£ Cï6yéßé%$•a‰{;- O‘„DŽ·‘X”ümwâÌ!ÛP™q*¼ŽwòIEND®B`‚gri/doc/screenshots/gri-screenshot-4.png0000644000175000017500000016444313147557614016744 0ustar psgpsg‰PNG  IHDRGíå|õyPLTE   $!!!$#"(&#((&++*''(/0.0.,10.<6.443786863886==<H?@>,LJ0ON@>>@@>NB5WJcSôFR7;är0Ü(››³7{q-u­JÍŠ½´³ 6K4y¨îFa@“rbŒJPbɦt,ùPt $AÑ­gwUwÏ`>@Pó#1Óªêêžß·úկ侢 çþ/úRra0õ;¾| ÝdÃC]h³ n#Ýàü&ë§6US¡¾·õ6­#ÜÛ댤ÆvsþmÆÑ…Çr~ê‰'žxꞟOHzêðU:,χKåõöOyOòÖž”çóKäçŸÌË–ÛS×RµwØ?z¹¼éÏÎv¹}}ù¼å:·‹òÉ«ÙϤÚߺç{Ø®lÝç÷WÔ€œM€¬D/öÃÔ-@í~ÃÑéæXÎ俺ýô©/óÀŸØrC·ÔÁ[»ô]íjrk]U0<ì¼+ž²0û”Z Ö~X®¼kW±_Û¾Õ¶>b_[í¾ÿpôO.äL~YÐKšÔV±Ÿ/ÿýÌ.i>vù'ùñ'~e.ñÔ¯jÊ–þÊ--<ñ«—œrnO«Gô§UYµöR¥…ÛEüñ=¥¯Vô¾Oëžoý}¾?ëwyâö¼1îÆkç¾ÃÑ£ÿÈÅÑÏÀÔñŠÍ’/íßó²ùésLÚ8Râ¶mxûòK%Î(¶U /Züµ ¨ÊIQùN’¹Ù§~uÙÜCßþÖ•Ó [¼Ï—^zêWÎC¶zÕïØ§â†-߯}ÍêèåâS•ºßp„ý'&ß,ëlT¢ÀÑá_m‘ŸøÕ-tð [BÜq²¡pwïSWOnñNo±ªïÌý†£SûÿIš+][zN?ùÙF%ly´qéÛþÛ>u×qtË¿ÅkßS8ª§û Gç¿§í£tëòhÃOY8ÚŒ¦r{~[G¯»ótK¼<ÂÑ¥ èàØÝÒë’[ÁQz‹8ºãŒáÞìØÛ‚£-ê·©CÒ}‡£Ç†ÆQÃØTÃÐåËß²üuvc›ÿmµš÷c¨ë;Ö÷µ6Ó¹ú®Þzeç6‡ºç[yÝÜžšF8Ú<ŽÄ/£ûžü•Û”Þ©\hðoÛØÄå_Ü6•ºivË©«ìÜæP÷¼Cݙ۷rÿf7(cÔ÷³Ýœ›qtfÿ?GƒvÐSe¿wÁµ õÁQrøWÎùaôÄ6Ê#—÷ (TÒ¿«¦Â÷<Ž6¾/ÇœÌ/7àºÃ”)®ÜÐpÞnοÍ8:}pt¸Š#»‰-È£Mõ`p”Ú]µqT=æìÖvÕÆÑKw Gn;Žò¸?q4óØÿl9Ó>àÚß~õÊñ×éJVSFUt^ÕnÓpd¿ÎåV¥_}qdË„¢B]#5Âî²ÁÕj^@uØzi8²»Ñ§ºzÌ µQþ¹/™‡Ÿ·ZÒëö·)ç´ã–1?§¹h¥Ðý‰£Ó·†£¡ì”Â_÷¤í)p˜¹ø9+Àz©Žœ*ES•~õÑUµR³ŠèòÕ¬r]­ÄºîÍmˆ#§€ëupo¢ò˜Ìe3pé·*0š€£†ÕªeðØe¥CÖ¥ìnÜw8ÚD<ƒÃa®LTMøLHñ“¿úÙe«±òoixÑ6J=©~nü’/_¬á\·a½(ìUŠ«%qTBæÀ®V jžY©f=†¾í‡#÷CÐá¾8ª¶X-óRß‹åWQÛÍù·•^½p¾y7pTø½rÙnÏb¶ËÅ‘aqTáͼ¹¡pT©j±¤£{Uô²M^­¤KZ·X­œÚ6~˜,_{€Nisôð8*ëu¦V£®Åj™â¡”/–_Eml7ëß^ºpv3òÈÙ,Ô“~8R‘ª?³pt؇-i6®ªã4í¼ä+ï÷*w•*´/ÙÌ\i¤|ã[¸ZñåÇ8ò—-¸9Ø+}½44ŽlDº.ºuÓ8’m¨}—-J—ÛnοÍ8:¯q„·ˆ£AÄÜ ¦'-?ÃÏ.WZ,«I/•™·ŸŸá%·^(éÇœµU+,ª¹­¨³µ«•ë¿d‚©†áØGOÕáè²ÙØPÕõa³8*Nq]._ª@ðý†£ÓþÑ-É£ÁUT°¼úyÓ""¡x¹æŸ®h’Ö¯0G¥&dE»Äå¡ì£z-ßeÝÕ6£†Óì­àè²ÝHÎ[ÔëL^tiX0)m (S½Ö•Õå¶›óo7޽55^ziš¤^÷[]vì 2[öPÃáȪgW¾|ØŽ:ÛGN#/•?êû·AWË0¬iœèã÷n”vú€ÿòÙ(ýT ûC}WÀ˜cÄù„£Fã¥>—*.·Ýœ›qtãèü–qdÙ (·^¬õ(Z³¿iÔmz½ÎªçnÊ"Oõq‚YU]|4ì¼d·æT©9oºZºÑ~m7œ"/õó×5Ê;/9Ç‹W)Þ[>×ü÷ÃÑåŸ4„%« >Ðp×åæº$r‰¹Ÿùqq±Ÿ5ê/uãè<ÇÞ:Ž,­b¹ag®ºã2tÃmÚ ‘så_©^£Ò¯Ë}ÉEUWª™FŠ6Ϋ¸ç›­Ä×Õ}på:äÔtÈz"53­6üq„+’¨gÅÕ…oY}øÙP3ˆ/ÿ¤´YÔ|åû G›Ðë¶L58ÚB /Y»Œë;4o¢ßëcƒ« fË[šLÛÏ>ÚL ?+帼•y.W—_ù¾ÃÑþ‚£!f…¿/?u/áèvÜg*rC¨æ›hâ'?ù™Ó‡Ë[™¿,õ¼ ®|¿áè‡;Fm< ÐÑ|Š_õž’GÃÝg¿ó?ûÉåaª¯ºìãåŸÙjW)sÑOÜìIyô³¾Oü²Ê Usâgƒ~%sî~ÃÞ>Ú2óî¬<ªúZå/wáh=˲ìüi*—ã6ÌQÑþ†z]‘ Éä„*å 2ÇòºÅ5þÖôá¾ÃÑ]ÒëĘİÎæùk ݽîŽtuó8rrž=ñ«4U8R®¬¼h—/ë$XÖ¢bÛ|«>üÁ¯ª9Õì>Xíínx½âø}†£ÏìÛsgqtùîÙG}:p÷ó3$wL¯«òµ%_.›Ó'žzâ©'‹ü¥òÿaqŒÿãÛO>i>ñGzCŸ‘åu#y™ºÌòŒ¨óÔð¿o=eçK}2¿ž<ô¤9’ÿý¸Ïptá´£¡sY?¹©3ö8lµÌSÕÚÕFd OþJý,Ã÷FÓô}*=YÓÆ“ƒ[~rС_Õ?Ë'ë9rÃÊ‚W¿U÷¼ªù„Ÿ09V†¦k·U6Y}“×ã8zYràË7¾\á/àÞAçÓÆWÚ\_.\(æÃ>yç²Ð8º•¶\ûßÝíîªSys¼za0m1±}:Ô¡MQƒôF4¢;J¿þ§·È¤·Æñƒ–tÙúZ9©Û£«¯¿qõ×_õuþGÈ«¯ª­Wõ?“ï¾úêËüŸ<üúëWŹWÕ¶úTôÆëWøß¼žø»"¾Þà—à×ôºÜ¾zõç?ÿùÕw¯¾[Ð/8½ËPú‹wåÖ/øö»Wý‚Š¢W¯Ò«ýœïþüê/~aöeÉŸ¿®Îý\ý9•uÞ½ZÒ+Zâý’Ÿê¼¤Ÿóðmªjü‚ÿ»ú ]ïQWl\½úŽØâø?CTôü]y ”oÀ7?àÿTwM/xúsªîV^ç7Ô³ãÿÅŽéPq³êAÈòêôêV ýdeUþÿMþŒ¯¾¡[3?Žü|õeùKÊ_óuñã¼*~¤Ÿ‹%ž“øMìÇyU?rªú,7~.»ñ‹wäþÏ­>Ò¼"rï¼£žÆUþNþƒ;¡Ð…oùriÍT|p½Ë‚+o¾ùÆo^yóŠøÏéÍ7¯\½òÆ•7ÄÁ+WÞ{r÷ Lj,¡¾_¿òêëâSTáe^¿ÒŸ^×'ß0ûòó*¿è›ü7Çy oò~ˆ¶Þ¸rU—{óªî“¸¶,~Un_U½|Sn˜6ßЛo:ÇDá«Îµ¯¼Êûýªì¾x;\yõµW_•ú¢ø||õµ×?L^#â¿<\³÷ê«úO$¼¡WM)~r…7#þ›c¢iòoýµWÅ'?ÿ:¯øêkV‹¯©+˜«¼¬þò¯—-.¾Üí.ò/ñÍ·ºò«ËÏEÂÿó²ß™7ÄÿÄ)ÑÀ«¦aþ{ˆn¼öºùÁù³ýÍ‚;PÁüñ]}“ÿPy3Ç Õ¸áEø¯KÅþ›’ø—غ*XæM·Ñ—« ¾ÜŠdpp‘ ¨tÃ})éW‘ãHü(úgà¿Ë¢øYÄÀœWÄ/$v»‹êGáÒÈøE‰ú]åïóúkœigr>S<Ä+êu…cäªDFÁÃêO~ &"²f‰$@^½b€-ÚTÀ³J¼Z´)Ó0žâ EÅn/wsÌ{®».Y« }ôЉê+y Ôñõϼ;L×Þw|UBüMõæy³­xSˆŽ_}S¾,ä½yU‚þû²Eý÷ªú|õuÝ©—_çÏ÷5ÂÕ…×ä8_ï%މ×D‰‚ì•+5/2¢½y5Ãèr¯ó#¼&-Þ¯¿–c\¼K^{ÍzÚº²x$êí¢ìÔ—Í·~¶/+žP~¹û2¿Ý’KS‡[“Z†Ý >ú¿­‹ó¥ G¯¿Â1séÅ¿cŸ~ºxé’bÇ×Ô3FÖÜ_¢GÝÝû›üoó€9ðµúr}hÒÝ)Uúšj·)¯²ßü;E'6$·å‡kJ<\ükξ¶ó4 Žs½‡ÿÅß䤸|èá‡ï!þù{“=ôÐï=4É¿æÿÄÇÃòÁ=$ ñ"|ã!þµOn<üðÓ¿·ïá}“|W’(!ªÉöUQFì«ç/·ê‰ûó|­¹ß‡‹ :‹‹äå7Y¯÷òË—äj±+÷È¥—% ÉU¶Þ#dsÑU}µq l›öÙÞéÖýy=ƒel_«Ft¦B¯/½äÝ¿ûïÿíÿßÿë9(ëêu öú«™™^8sA‚ø·Ø<Ï ™™3gfΜž93súô 3œÎ̼0szf>->gÄ6ÿ8ÃÏŠ#âïÌYPœyAþ?5#ÿ~03åç)yä…SüÜÑ„l@\ŧ‘høÌŒ"$âGc„ĵxOòñ?$jŸ9#ŽÊo„ò÷À‰:#«~AT‘UÅÖ g$©ZœÎ™ZçÏ¡óçÏž?ž):‹Îž={Ž… :'ò:çx)¾Îž?{Ž×¹pî‚^mÖ,9{^ý;þ\Þ¼(ˆÎæžãx çΞÓ’{¥ë‰c[!§þÔÄË?b$ž*Àò0±|D3ð¯À-y>è}øæÂå…… ù½p½Ç®üôÒ¥Ëgù^÷¾×½|);'ÎÁ¯6*\ï0x·ßÑÕ\Kݸ ór]å˜yñï.ÿ÷Ÿ\þÉÿçß?õÝ?ìEç;ûÃüsváÁ¬ š—Ĭ~¾óÖ?óËp\¡¸î‚ü@g/L(6ÏŠƒç/pÅ‘¬ÀYS@çUÛró‚ä-SU‘õx·T‘³’™dO%j8œF±ÉgÄ~ì´ÂF|æ´üRlr¦–¿b}×òvÊLjØÙfAqX]W úõº8Í·Õ«#ÿã8–íÎ Ù'ѹÓê5# ‰ƒ/œž1‹§eIùnoñZÑÿ$ƒŸ‰ó—‚dô3æý#·ygNËbqé6ÏVîÖ¼iJ=›ÿø†~IM%£½—øã :ùÚ•…«¯ýðÛßþîÓO?ýÃèõ7/½Ó#?üá ?üîwxòå×®|ocÃE›‡aú[ÂͰ.†­^ãèï¹Æ{éïþÛåwÞù?ÿÿðoþýá¸z,L¤a—­Ã@FÃz)ž•X3ø:{V"álÁˆçëÞšgÏ6xMÕN ‹jš)×âbñœÓŠªvþœó³ç@9+Ä916»¢³gäýq†ïa¤¤à%_cÉǧõ1)mcë·tùÁ¸ÜiîZ þœfê]P¼.\ot]P/'õÏH¹¼ÿâ *qÇ!(öêܬÐyñ¦+ N?Xóº§Å¥Î/&ûd~qªsg‹¿ / 3éåÞßãôãs?þñ÷Ñk¯õö}å+_ùmþÿòIôÚ˽W¿ò•îŸøí¯¼Ì÷^ý˽·¢×•©·C¢ô§¤ÜýšÛzÝ»ôwÿÛÿ»?~÷ò¿ÿ×ÿúñÃÒ6zíÊâªÔ œ[ÄOwZjUœwO+]H±×Lc¦×kýIªC ¥É·QüÌgœ_ÚÚ¥Os^môDC‚oEÌ¡sH 9d”,#ã87Ê]ÉÀç5')†E’SÏž¿ t'Y—³+—œ‡…H$qþœ¬.ŽœÓ²‘—8«/y^êv’ëå%H¥–%¹ó¬>,ŽËîɃçJoÿâ•pZÞ¤8}Ú}Fg5Îk%À”`ó³ùŽûÔþ@õU¤º+ômñvï ýÐëÀ§|öì…èò±¨Gu^óŽ½Øìqý"E?xš\¿ñA_ùòå~çåë7ÎñäË_ù/ÿð;äÊsfó±¦EÅÞc̓j§©7ø×Á|KV8˜—h6q0UšQ-<¢Êªƒª€)óØcEqÕÐAÕ„êÿ|ì`ÞêA³gš“ULÇ‘e9˜Ÿ{L<Øä8ú}÷ÿë?ÿ÷¿»ñá»?ù£ÿ烿û•ׯR-ú@ãŠW½^<¯Õø œ÷.Èw©Ôí½óòï‚â¤ÞùB\õò×¢âjÃMç´Fh1H£'þç5êA'Û0hqr^¿/5Ÿ_°´?c…ˆÿ/^à·ÀïáÂ…_TÇSE/¾˜^Hµ©/¾(GÒ´4Òö¢þ>ïš6 UêÂæ–ʸ1*dñÜ;:/цÌkA±íÙóçÎÕØÍ?9“Ÿ5<~^s¼xœ57ë7‚ùsPçùœç!¿qû¢þ–[å÷ûy÷ÕKèUJW/?§o¼üéå/½¼péÒ<÷ýov?½üýoÿ³¿üå/¿ü|¿Ù%'ŽÚ0QŒhcȰi~è ÁÁR^·À‡÷ÜcÍÇòú|çÿQ*q0ÇßÐÐ¥Z};Xn\cì1ëBVß9Ž> ‹/üÿþ¯—ßù»Ÿü§?úÿüËjÌ~(ôf¥¹ñ?!.Ķ>¢s4zùYñ¡þôv^R0™à †n®ÁEÜùGŽŒ–¨Ì|Q†‹8ñYQê,y&‹K­LU“²S¨iÜ<š95#.¡_Ä\Q;-Õº˜[H§ÅëYjh3FwÓtZ8;^˜9¥-›ü\QD>Òu"u-!Šg¤. 1~méà¶ ?®ÅÀŒòˆÔ¼”¶$_ ç”xVÀÂ25@.¨—C®ï ©hHþ—¯ýŽH ð˯óLü…Âð·Š|¥”0â G^ïìy½qAK¤³Dø½{gNýõ÷O’8ÚŸô~ø ùþþúûþà9øð…Þðý§9Œ¾êäÃÉ›ÏïmÜQµk3T«¡¶mHB¯ãbúÃÿôþóýÏÿáþÃþ×_úò%,²ØÝ/ØéLqͳ9ÿã?¾ÜVŸgòã=ùɵ”F³Wc†ŸšºÚLChk§§yɤM­¶{R”Æó §åvO€Ik‰ÚWW‘W<£ßéâãL¡ßH®=sZ[õÂ"?mlwqì…S’éOþÞÌ©S§ r~/ßRÞBóù‚õ™•®DÈëÈÍS¦^ŽªÎØµ¤æ+ —™3RbÓsi›ißWÙà,>ÕéX=‚3úE!îM{(•‡Déü ®eËlõF‘~ iï ߥöF½Î•†Â†Uv¥Ñ%%ª¥zwV*¼\9k‰ø³®Ð7¯¾ùi!޾ý òé÷\›üà¿ý.?÷øƒÿìË_þg—ø¹î›\¯š¥‡!KXÖøÿn«©4DcIŽ£^¿òúß=õ¿ýoôïÿýúÏÿéKÿè·/]¥×9³BÛ‘S2{êß‹z›Wî%Æ‹/öÖ?ÞXO¼êI¿ùö‹^ï‚9£ÞŠüû¼:r¡'ìqä¼øãEÅÇù'~4qü‹Œrf>Ïñ?‰šóú˜:§Ê¶Òõä¡¢¼yÅ3òåªyLOI­êtþÚŽ6΋†û,23¹DúždÁïÍ8bè”86£´8ñ å0ß|r¹5+6øÇ÷ffra¤ô³ÓÚ‚Îôó—)è)/¢ý9«Þþç$“j÷â…óÚÄ޳Ò#’óíY^i¤¬$_ Êú7¶ *FÄ“w×ÕþRq]qQ¥0J?àÙóÊoR¼•.hM¹ôÕ›A:´Ý&=°‹ï uüç¿9ö¥ßüâ—Îó_>{éåéK_ûҗƾôíù——º?þƒ/~)ùó?ÿâƒ?øÝ ¯Â}ŸÛ€»$·…îèTõbbüˆÓ•ÿþ¿ø×ôoþù?üÜ?ü§L”ްNKÞFF朖òHèg\/“Ç9£#GÊVÊ1!-¨†jEY@²ì¹ÿ¹6ŽÎÈoq½3ÒÓ×ö—p@Vã)ò­j¹'W2Õ9ÍX¶â¸t-óäŒ|YŸ‘9õ1Ä,xH^:{vаgœ«P¹*%Ûå]4ãO/4D1Îtºð¢q=L8ݵ=V(›J©w‚s*/ò‚úSãäõ3ÂF“*^uä)\1Ft^)uÅ3+Ü:úøy”]÷ÊkW^{ùÒÜ8âÿÿòËßøq—\ú®¢ßŸøÆ Ý—/ýÁÉ>ùäß~æÀ7^È®œÚ÷·ƒW·¬ÞzÝÕ«o^I¾û{_þGÑ?üW?쪨Î×^»rV{„Ä‘¡ u-¥q!…”ŸmH ¢ü K½ü¬µ­œ7~yüláÇ0WcñÙ“k‰—Þ^Íôäq^œ_µ§¥NÌ5Dù›(dq‘„ÔÙ‚¨ÎB±)<é=$·ù/Ì?zÚgk<ÍÚoe8_”)Uª<Ö9i?î‹}…¼òÿ–VçÏj—¶›zº ½WÖЊ`:¯ìu($ÇΞãPR¹:§ãxä¶0²ŒûùBîn;Ÿ¿'^Ì?¤ï-ß1à‚x8k 5ª#ŽŸ3=»{õŒÇ-÷z«/ÚGM»úHñ&)Ž™fÎ󇏸æ*£’®’…Oøêï~íÏÎ-^¥o¾véÅïŸø¿»ÿ(Â^~ñ<üîoósg.qÝæ{_mdYÊÿeÜÜÆ)NÄÿÂI’% Dz4Á™ØäÇq*%²´.(¶ñÍ?äñD”S¥D‹ª õ™—ç'äžÃxîEÑËáãSœ½(ÛõÕ˜G¦ZJÄyyYyñLôGŸ—×ÑWâͧa1ÇJÈ#Jù‹ Âg¿óíï|ûÙH™œfg®¼ymu½·~«ó¸„À±w·{^Ùˆ¶Jë«×¯ÌhÅ)øìÓßyúÛÏB!Y9Ë<ûL>srF¼ Ï xâéo?óí§¸°¥ÏM4¦,jßêlLó5tQе‹ËЦo™ÒâÉH½ù¾çy½ƒ‡ø—Øô¼Cæ¿!_’ç>|ã°¸¤ŽùVÏ4äóëørS6y¨'ΉC‡Ôò__µ¸î¡|ï)rP<¨Žäð¿C‡tQ±{ðq~'üv45>&‡ÏŠ¡3AߨŽß©qp^ºùØA‡“­ØtHÿ‰Çõ‘C‡ö¥Çu©o:ø¸èšwð[½o‰‹]ñð½ƒ?~è[üS?‚ÇÅ >®îãq«+TÿªÏ¦ê˜9&¾´ Õæ£Åsë6í§qà€øŸ5$¯$®ð˜y¦ß<˜ïÈN>.nÄ×Ü#ÉPés{ï]“@º}8Ê]…m÷{®W/ô֞ѢÛü´O}õ^ÁÑÅÛŒ#W½{ÆÛî_nD÷-ì½qßâÈ•GŸ Ž£µh}\ÙŠNžè]½oqäÊ£OfF8Ñ¢“'{ô¾ÅvpôÁÌÁŽFtgèĉޕ½ÜS8ºv§üu#èN—G¯ß3þº;«×õP0ÂÑöÑ-ØðÛÝõ!ˆãèÊ}‹#×Ïð÷ßÙGÛH·à Ûî®A'NöÞøŒàè×§p´}´ågb'àè$·~û~Å‘«×}$Æa·ûyviËÏþä‰íîú0<Ù{õ3"nÀ‘<ÚFº¿åщ÷±ß»ä¯ƒ¶¿n\’Üлu'/¥ËÕ—Z¯­Þ§p©Ìn§ØøÀîôë[µá jzÃ[Ù\“ GãýžÔ€vNžÌ»àþµ•*ϳØÞ=îì÷}RÔªv²wõw>8úȇ-ÿýª½i¸Ü)´^ùüΕ ôÖݪúw®ò°‡ìM=+­õÃѦz¨qTWoðín G¥ç¹VÞîwn³¥ªì]ùŒÈ£_?߬ÃцuঠõññA§R}Õ![¸M8ZïmXôŽãh•q´ÕNõî$Žîk½ÎgøuT‡#Gm«(4V)õ|Njʣ/ ™bE“ÖÁúªÎ˜ ªZêóx~½µþ…Í›ßiy|w‰[Š^Ø÷;èÙX…j. ØØÆQùÎú7$XÔáoë±öïTé7pqä<©~?æ¥Ê$ôºûG®HPªL\}°ï~ÅQÉ_W‡£BÑÙmÔ÷¡ÚjŠ%ëË<êü ro·c ª/] øÖMì·›Ým_ĦÝãëÅq«£²RÍulþ.uªrÛ»ÝÓ»«×ß=n÷«ÄþâqºOÊÆQéWZc 'yTQk~ŠåÐé›ý¤úI´ JUp$ýu2_P¿ÿYŸCÖwù¿]§\~£öq¦Seý;4è¿N$ÿÀQ Ýj°Cùa×_m}ˆ–zv¡õ5zýæ:Ãu _Ö{C×_Ûd<çVý“w4žaC„ WŠË£_|ÕÎeéB[¦[jã¦úJo¥j?ļ‰;_7ÜOr·B“­ÇÝÑøºÛ„#n½»Ïƽ ü{¶!üÞÉ£ÝIÚzœêNˆ¯ãòèúï|2J½nï½ÔëaïCûœ:¹Ý]‚„<úêgG«'Žp´}Ô;qâ¤щBòó„Í Y9œ¶»ëCÊ´Ý\~WpôQ4ÂÑ6ÒvsÀí¦û"a…ûG8Ú>Ún¸édýa¹¢BYŸ[¤[ªlw£hHÄ9ñÞ#ºË4zöe:Y‹#ìêõÄò°—ÊÏ-Rv+•y7|Þ Ù§Òï=ÂÑ6ÒèÙ—©ŽRnfM¤=°§7‘‰Ï^oïwù/n¼‰PTÞZmÕ½¢ ÕÓé}öõ¸±«lÜÂst²ØzþĉÂð=iù– ³øäóæ@Q†×³ æâãùçÝŠ“'´­·‘ÞE_`~î„ÓŽÕ7Ýß“•þºŸ|¾¦®é÷ ·ßÚwÆ?\ÿ„{ß'O8÷]”?aßïGe:q¢ž…jÍŸ†þäŒ6Øf¦òÖj[Ýpâ8úôÐoõr@<ÿ¼ú•¯ëßúy‹EŸÏýJú€fçu ÏçnY½}²Œùñœ›lôÙ¸<¡xºÀ©¨[ð{ÁÄÏ×µú{Ââéüxá³úWܯ>^yUä˜ïý“'*õŸþ¤…¯R›r„£2ÕÉ£†âÞ“8b9›^NËTÞZí^Ñ §!!ýÖÿkDÛF#•éäɾ üßãÚÓ>þùÐV‘ð®|+8’mì zaÞÈùÌCk×oܸ~ýƒëׯ߸þÁ×?¸q]ü»®¶ù)qVœ¿¡ÎKúà]ñÉψÃâû]YPhIד­\7ôª!Oˆ¶ÕQ¹m‘lN´§¾Í¹wMƒ¼¼(õë×óm}J]W_ëÝ?uÝL˺SæKÝ—¾GQG_âF¹ß×ßÏûW{}yOú¾MýúfÍÅMìû58Ú(r:§ c¬K¥í-gÉf*o‚¬èàþ70èRpD¾ØØK{d¬1A·ŠÞ„¬|+8’ÝpòèèÞµëÙÂ\–ñÿ†°úêfÙB¶ wäylèòÏ9]iAžœËÛ˜[Èæ¬z¸›·¼°€q~¥¼Œn¾›·?×ÕßXuD·¿`ú5W´2—}çß‹ö}tõѹW¬Îëò s ù¶i6ë×ou‡EÁ~ן³ê/˜kvÍÇ+Å®&#;‚}c>Ý îŽ6œ—Ôç\qèÄÉÍ3÷v“À‘ÿU#Ìÿ/>µ~iœi„áœÔŸFâwÁá’kôQÜÍ1•³2κ ™imÁ:%[įXÍIÎÏŠ‚5uûçŽïòžÏaçbüÛ\‚/dÎk‚WZÐU `gÕ~ó-Q]¼N,äô»þB±‰³9«¼»eg£OׇŠE¿eÝYÚª}·Ož¸u¾Þq“ãÈ~%»äˆ‰âÕÝ-d ç=ýæ]pX’Òõ8Ãq®+Ÿ³^ÑöqÝÌ‘†^QÇCϹ¼ùŠUŠweç—YÈ î´ˆq†…9w¼ „ïd¶…¼¿ZÑZ~}«³ ò%‚¥„â-òâ XHº9Ý ùìx©%Ÿ2sý9õaÉ#õ]žÕG¥I’knugö–9'ÿ›©O¥ yõ5{âåæa·»f†°{53ÙÜã;TõB#›•»š2ý ¶¡a¸©`¦EQK…OÉ7íœF[fØR¼»M2'æÊ\®µ9Ì-X ør~äu¡™Y%ô­¹¼=%1ì>ÍÍ{%¬òwÀlÏ5O-r„t2"RôNˆÙ\fJˆ¬òöFheMÞ½ü¢/öŠPRóÇ©nw«öÑ€¹¶çõ-Ò·ºÆÑ€‰³µs^7Eëã58ª^¤î\~üäNÅÑ$ÇÑ%FZu fÛݲ ˜'qñÎEIQi1gNù’vëâœ^±6§ñÀEDÑÁÇsÊRÓfYÞ“Ü’ã\¬ì›ÕƒœÕ¤œÈoD¤9%í÷ÂÞUZè+º%ƒNùºèæ×Ç®ð~%ËÕ¸WL­ñhæôÍbý˜^1Ï@¶Sš‹\Ÿz¤æåÞ+µŒÛ8rÓÿ”qTÃòÃPÏÁDí¬Ù~çvº<ºÉqtCrEÎ’æ¤É$ßò†_°b¸ÂgÐU&öÎna!s4»œWE]¡ít5ÓL¼ Å•Ñ󌉶 ®+*ðâ¶«Û^蚆Ìi¼`C]˜]sù‘Eeüã…²,ê*}mÁ´Š•0Îu@iÚe¥*NrˆDÈBáÁXÀF¿Ì̳QWݲ‹£êwÃtõ¥ ”²¬²¨ÚæÕËnGµ‚l¨½o}ôWZö‘`L.œð%Ûfñ\wN!©‘„5ë{À’6ê$obQ1šo(Ú7¡ÒÍ‹Áhk. xûFƽbzÔÀÚúào~ѾºiÁ…¸2€ºÖÍ,æ[Ø)Ú•2Ë4%¥éœÙÊag«•s„tÊÑ`9»z›…_íÙþº~‰"Ê8ê‹•Íá¨"ñÊ–Êøøæ·tëë}=}´< G;S}ôWûŽ —œàK—4×Ü¢~~iÍ4Ý0l³h[ý Ê>—ûº…:VR %Ëÿ›å/+à[1`3/Ù¹Ø8Õ0]–6“àMa YöWaÌåØ.ûR¤ÆŠ»®š§Ü„Xk´c£æÍáF£Ñµ:×Í ñÖ•ÿøóùQC‰_óX¤Úˆs…ó†¹rÉ>rÒùª˜Ã¨%Î(.+5ÝL(Æh²;QȪÝ[HªÙÝã•fk÷J9]v0Ž> ÷­½¯XS½1±f£ œœäGÑß¼×°ìmoŽƒÏpR׉iɼà 'š²æ'Î嵿ìös6x¡› Õ9ã—祷l13gtwD½…ÂC _ Eq¡pU«û6Œoùø×®\i¨ž6æLÿô—êÛ~ùË/ÏIËlAioƒ¹ÿÆû Ùè0ñ wÁ]_çn]«?íPûhåù¦Ôë¬rÃycË:à\ò7œÞkT–Ú›3Ål‡…{w»®fLï®âEþÆ?Õl`¹ÀªñSßh(ið™ÁÅÊÅ€°#Râ/ÓÎ3áXä½÷…ýg¡iN82ßϯŒó1+ícë6W®\!Gò - ,2â V(úå/ßk,¸Ž ëY5ذÆCáè®Ñ¦B%îíPûh5ÒöQÎðÝÆ»’ø;ß)’5Š8Žþº¡µ1©ìtÕhL¦>9ƒýÅ_44plk\œ+ÄbmÛ—øj4®Ã°±hH¿Ê»B,Šó×aãÔÆbÞ»¹bë’FŸ|EF͹žt~Ô÷¬^åg<ÿòíN»Œã›Gž}í ï¿~Ó8/ ñ|~úK‰£KÛO·!Ü‹¸qC2Ý8ÓèÞS8º'h‡Ê£U3+‡fä+3Ç‘ÖiÌ(?Ó|TÃè½÷Ì)ƒ_Œºh‡‚P·ˆþâ/zkbK.Ÿ°ÒzÔ«\µ¹¨F'¥ÔÕœxãÔû7®CØ0F;Å´b¸ P´x]H,k sAKÌß ÀØV<•÷Í2³Ìó€°b‰¼0F.H ˜a¬û¦AÂ5ºæ•³ÍG®¼¦ ³FV GK×|cÿ£¿ü)Ò{I{åÈ“Š‚*,£…KÙÄ CáôºÏíPyÄ4ŽôÈ)7$ŽÞ{Wó:6 âlÑx¯i`ôÞ{ZàÃ9™BDk=)“Ô«˜ÃsA›*gG…+ –P¶(e‘ àT0éæø2Ÿï^ï i¤Ë\!UãXwÿ£@©³ÂÊ­.N. Ïã92XÆ-ñ£ésñ… ±ÇO§±*!<ùj0 ®‰àŠÝk [£Õ2in±ñÞ—¥<8úeCYùE.©;@Fû³Žª´Cý *.Èøªñ%Üø‰£Gj«x˜Æ{ï=j`ôžòÙe …/Abè/D²ÅžÂSC ‘¹<¢›Y–WWÊ%ðúuHýþõUÈŽâ6þ÷®sÌ_ÇÂ62jgf:…™² ûþÿDºÔp^YŒìZ¡yFùíqØÉØ / ã 8õŠ/¤^ô®F_ƒ\9Ð<Ëat…4²FnAs_¾÷Ϥ<@úQCI "$¤Ûm<ðë™™ý F§E'G8*Ó•GëÏ~míºæ&å]ø“ÿØJÿßÍ9õõ68úkƒ£÷„Þg» 8 QÔ[[W(Ò8*´«­¹q­HYSÅ`§ð 7N½ŸO¸Î- \`˜á"xýFöëÙ_wŒÔyés^Ô2AlcÙ÷ÆŸüIÃ\Vÿ¨&<_YEFž–JÆZôž‹Sœ$Z,i;©¸ÃÆB¸,â8ºÒh\9ÛPá]3Æ üò½ßúóŸþèËÆ—ÿF¤âÞ%¹Î*&VÌìßÏܸþàþýb~Úvóí½F;G½¿:°vÃøÁþDÒüÿ5ŽrÈ=yï(`¤4»l.Wk8£piÔ[3(Ò828XÄÆÛÖhXÁŸÊ¸åÞ„×õl§×ßÿA3çÃE%9øyn8q¥n–Ÿº>ó¨´òu´BY-»Í…jÎýÅðŽ@ïc#Ïž9ܵ‡š½8áâû  öM“¹ÌšÝkB5΢×HÃÇÒëÒxïÑqýèo~úç_þé{¿l˜3ª™ØÌÑâPÚÿàþ‰á¨L;U¯ Å8¬ŽÞý@㨋M<4òm½÷7 iËcc®gs .rqån6ÍOsFèÊ¥¿¢‘И)&¸ÁS§2ÖÎŒ[-f¯4f}fð·’®ÃÙ™*9°ö×uÔä é+Qñq¾Iž _Ë¢lΘ7sGÄJþsè߈½nѲl©!œÞB]9pöÊÔ°æ!É10é®û­½÷ÞOôí/¿÷ËŸ6¤<4qH¼0sfFÛF\{}ÓHUh‡úë>ýοñusJïÈõºw¥p”‡ɱ•Fóol ÙÕ™°z6ŽtÝ5Á‰tµŸÁ è[±g Z :›M1>¤l £Y5œº¾Šf`óÀ©Et’%~%Ø‘2Orð\¡œ ©/¯Ø F±<¹,‡Ïµ:±ØHl—’hkÛˆp=‚ˆ޵ÆÀø½=*¤ôOç~ú£ý¨!} ¸[Ì=lÌÌ̼0c$`ôOá¨L;T¯ûô¿ªü ¹ð'®ß[[@2žZŒY0zïÏÅ(ýœR GÆ/g&4ÌfWENXp¼ýS\ïy_ è@s¦ ø’±0ÔP-·°I39ðƒ³ œ÷{NÛ¶šãPpÄÊ&Ó#G¥¹¸s"D ¤,áhš¹¥˜ÿ÷Íàí%íýЇ}Dzï€3ÎÜøÑ{;?}ÃèÛÜ–|ïÛbí4ÔØš)žPºþàăÿ4—Gg‹½FNo3Žv¦<êýÕ׊ùG]Åãï~ðHJY!˜Êag‘½£#œÝ9Š”ÞóŠ©/ÇiÒ¯&Û~E‹²9#Qp£9{C ˆ€ š]……ôk¹Øâç›Åù EЀq’ä3ã´‡Ü×íOï3ÊRˆH±X£Ê¸Š!´yí5ޤäÒ…Ü›¡žÏ‚B¿õçFY<¼`MŠmìÿ­ý3ñ 1—I_“Ò¨°61»Mzà¨çå*zÏ>\àH½|…<ú@yºbüd!Ë®u$­ ù2c±r$´ap” „Ü múÌÌ@Õ‘isÖľÆ~›J³{äÍFã’tÇácטð7Ö¹Ì0jt• ÐQFœ70Ò0•>÷WŠ˜íLI^†M¿çì)‰ü  ”q±Ä„<ÏŽ—>‘ÆÙ³•8zMJX_nQ¾DPÐ~ë/~ô£‡÷"¤?>=_îýû'|p¿Hû¹8zðÁ‰FcHUwïüX8²´SåQø{ÂÏ`Þ¹‚»”ëØØ0¸åä|ô¨­Óå‰<¤¡³ E‹Á‘´öM‚9Ë–/HO󱯏@Ⲧ)²óüêÀj,'šài†Ë"nD½Jœ_°my‰KF¾˜*fž¡iÒ>2ñbË ^UN:ì Yä›Ã]Ó:]p =+Âì^{\!g· §GÅÀÑ—½û•°8ŦKÆþ‡~˜hÿþ¥—ãÚyã}b¢­ nwò·½7~ÄÉmG9’v¨Ÿ¡÷Œ˜Ç—ÏSPÑ=Eœjn\˜Ø˜\Í™yÒNÆáGÂÈÒ]KÄ ›“þ…kÔ¿1;Ó¼Þ8ŵ·fÞ†~ŸË Y(Î__xír)¢ff¸(Å&ÞGÏ÷Ї¹´9l¥€P™œŠ™Hʈêºîñ’Aˆ«k $ %”(çiï©h†Ÿêç'cW‹úüàÄïÿþÃû÷ÿÖ?÷çÚGƒf²–ò)8zÝà‰G÷:) ™•hv(ŽØ³rþÑ¢=w\¿?µ—Aþ—Þ[Ás H?j˜@¬¦öXªYÃRéæ\OB‘ºËò ÌÉ=ípãç×ejÙö†ÎnøÁ,Wꮟj¨@ÖÊ܇®–û¸ÅÅ…ñcÊ`5yÊΓ‚¥Wg~V½¼ ”ñ{ÂÎeQÃIø¥$vCF3ü¨!½Ÿù\ -κ"¤CiÿÿõO…7gãhm­?Æí¥”7ÂÑŽ‘Æ‘H:«öv¨}ôaÈí#{˜GG]瀚ë.LØ7W¹0:ÐÐjŽ,¦gøå6”…€bú’Nà–‰MÔ‹~±@Ô¢8Ãtà}’ ËùÚÝFóÍPÏÞ)ramÉc¹tÓÊhã®u£Ý¢ˆp˜ã9Ùßóüú•2:­œ+ -‹¡ˆ2jüˆ?Ÿßjh¹ž'FšË³/aÜh<ÐxÀÉÏ0h¶¸uÞPŽ …nG!©×ÉšÍÞδÖ{Ïäy·¬Nö,3kH%Olpa4§“‰X‘°3º9Ë© Ÿ®òö-Ètv9êA£¹E3öd8UM¼3¥Ö§L°Öv’ä2èY,:‡³Â’Qöž#ÃyʈêĽ̪µ gÁ êR¹˜š°äø3£OæN)¿ÕóQ/ãÜ/§ß —.eZíc Hãã«È£µ'’z½“Ö¢Ñ;G½žG9xНÌ-hÌp_W³œàr!¯rÄÜb^¨˜Ê{3“¶M åš ÝÌMÞe¥wX¬Ë¢W¡r+Eë‚:ª" á¶h—µ24X}¹dS‰èÌüðÊØm·È,± í­=q£ŒÄ·Û:}‘¿®ßlñÝ…3A•-¾Jy wÃîá²JÞÔs–^ßé8ÒYátK¦äÄÊbÁªEž++7Iö^PÓ,€Úe•ôXÌú G'ÿ*®²˜Õ+•’WZÄ*öµˆ½[´°R„=䡸îõ…rÕVߩί€­‹fJ†«\] *W…p¥;w3—9Sns]<\<ÃQþ>Ýnxl‘v¨ŸaýÏ~GË#Ã!…œX°lä*N OH1Uø¬‘I5­.,”pd¦4Xq;ýÑTBÆ%Q‚gºä}ÃÅÆ\­‹&‡ÐbgWÍÍlØ9ÄŒkÂNî­ ë—ÐbîZ0Fš­šy‰·y>ìsx×Ò­ãˆÜðX—‘ód\=z.÷g™ÌMùµ ÓýéRsnCR(Ω‰î¸kR'åÅוIøëÈ`¶Ýà`zKµ‡>h]Fàè;¿[ö×ÙÜX¥× /Ì•+h!/a'`Ìa±˜Ù¹q–'N­*¸ëà´ ©}97‹.Ö—wã€×<\•\•ÖI_˜w¯X}²ûgyá¨L'O¾(be`Ñ÷}·Å—üŸ¥©[FŸÉT)¹e7u3QE–qÛ¡•ù¶s\•ׄ©£u§š¿"yý‹ÏYlhĉÖT°U¦ÌnœÎ÷kŒ6a¡&?®©dCxtù²\+úl¼Ø:“Ç…’Vt&?›¥Vcv;ؽ„›&³›I8Ï Üóm¿÷ˆr:yrzH"€øþd@H»DÁ”M,Œ[9†ŽX”†äØ1ê…)ô£Õ¢h?éSYÑ#±Û-¸òHø½ÉÑGõY|«-ñ—YÛâãPQJnâCjFO^ÀœÖŸ¸hóPå|[Õ|§ùâúV]ë[Í&ÊŠ~•.¤(;Tî˜ïÙmeŶ®æ;ÍØ×¯»Ff=ë9å×Ëœçi=‚C#•éä‰aq$) } Ë0jSèiŠ@ù$i"Ì `NAŸ1 $&‹UHGR™ÙÎJ8âz5;ÿÒëìå«ÈÝ(Nßp‹Þ°k'ëO—ɽèR*¥û¶S.¤×Ø»á4|#?^íÁàÞèswȬÿW|„£2mGÓ{HXÅš´Ñ±X 3â…Á0·Z­¸·©)Ø"Œã%È‘ E°^ý»ßÎó{»‡µ×­=*h±8ÖÍjL–â³ëÖ1£˜8³=q]磯c×´jyÉ»yWÛëæC§Žþ­¾–‘U£o™ní¶ãÏ,÷„£2 ¯×)Z ®à(ÛG§h€Œ43àØ±ˆÐ‘ð€ Ó0†M¸ú ZH)0”ˆeÕNjwê;qpô‰ÆQ·C,Vx²†iÜul†óH›©o°pØ s¸”›u<ÌØ¹DGÅÆb-PrÀ:QÝ>°±aÜÍ\PÛ°86ÂQ™†ÆQH¦§Y2¶'Œ*0jcÇq›†a,ðÇåö g1Ê\Â¥"6Ž’YDyI9x¨6…PU"QOêvØñ3ôÀïæqAuLŒs£[2lZ.“:<œZ‡êÀ7ˆpÿ#®+À\Ê­ÖbÒ¼ÿ»Õæ­á¯ò¹ç~¹ÅÒ;ÛetýÅò³ëëvÿ»#ÕЉaq„Æ c±&«â¨ h ¾b‰“w ãb3xÒd‚€PW«ãá8b IŒfwŰŠ$y»zÝyhízÉ|æ[»†ô!w×öA”ë–Ëû»æ·þT8ä¸ÔV^Þ9~(/o;<¼þûÒ ñ¸½[·e5/ö¯x9§wjÖÔ¯îÛÝ{üÊý-Ïã~µ¶äàÉ雜¹¾¥1]'„ièkÙëM m‘¦¿÷ »€ß®£h•„JÜr)sŒjÑ4Ø@É@ò„\è^-.®W^©³ ¿7cÓ‘‡Ó€F°Gî(RŒ„håÇÄŒ”cOèuÌ Ž‰˜%}\ò(ÇQZ‹#I×ßîˆî•p$Ÿ{oÐ4¤ÝGå |E¡~³˜êf®kïÕÌ"¬½Â`ªÃQŸ•,Kçã¨÷þÒÒÍ¥÷ÿþý•••B«ó''šÐ›Ø;&IŽ&C× PÒj…l*ŘªC`ÒƒÂ×À¼#GB-‘`e ¡²^wó;ûÖ>bU½n„£»B¥u-Å'k€0^*YšÛ„£ükwuvzyàšÕ—-ãH¯ŒYENÝ-æ¥NÔàÈÏôúÊÊz¾3¹kllrA8­GM‚@‚‹€á¶kQÉ"ívŽ8!†^,¢ñ’;½›e ¥¤ì¯ƒÕÚG#ÝÊýÞ6»¼æ(á¨d‘ÔÏ2/µï Ö:pä¶Ú[wÚ[«îUî¦ÆïÝ[Yê¹núÍIÆ­#0¶k2ÚÕØ5AA–ëu°“@  )Æ% Âר€‘¢©~²VJÆ 0.æ•„`É>zÞàH%k†¿u—î׈n#õÅÑxÝj⃴.ñµ^3˼Ú>7±Üz5ÓÕ­¾˜¿·{X©V!­Ý«Á‘ígxe‰+r½ª€"l"hNìj4v‰,_ŒÁ XHäžt!Èc!c±ž3É”Áˆ2ÕŸ˜×‚“qm¸CF6­”pôÜ£kÆË°ºªîÉ|è ÷kD·“\ ¹šøøøZUË“;»kf™[íëVzåIê%çC^ÐEÕø0SÕkÞ¸ƒöªUŽ£ÛªñÕ16Mš_|è‹]aÊ!D)mÄfÚíÈ ºcžG–ã©AÄåÖ^B8ó° Ü žS–¸~†ßù¸Ðë¬ç¾Vªp Òm¦;Ïp«¾ô¢•»J›¯Cd¢ AÐ^‰Q|¸­Ìž.‰-1‚‰¸oŠÎj3‰"9J;FS,L›¸EV½#a>xÄ@i<¶4~ôô¾µU6Gú7¹Ëô3Aw2.è¶¼öî>Ž6ï=Íöîi À%Ñ” X%RðÌ’6jŠÀ À"‚BˆÆH(x q`jB mµ…G,ôDî€lI¯ ÷¯•äÑH¯ëGßz%Åוièø: I~œÑvˆ˜'$¦  „!ÛØã†HH«µCˆcl£)è yÂà‘Ÿ 4Ž”H²5åò ÝÈÏph„£2m GNS¸|¡i›¶’ã±!×Þ€ç Mzôˆ”çîÕ…©(#|„D9tB8@=lãhDw—F8*SE¯ë ð6¤`ÏžG|Ÿ Þbá¦k²)ÂqT Ô8B¬µ1 œkÑj‰ H´@=©„£¿Ü?НÛ>á¨L?ÃÒµA)ö›×–—¯yV°*¹¸­ä… Œ¬< !k1ųU !è9<æeL ¯I §wjáÈŽ ’y‰G8Ú6á¨L½î­·ªvä‹8)Í-'aæ|O‘¸Õ¢É1?#H„5„‰ƒ£°ÕrR£@‚i¨Äˆ–ŠÀ†À’G¥x†gÊÇaÙêNM¹ci„£2UäÑÍÞ@M³°+˜ˆë#¾)—2T:²Y*ç EZ¹kAG"Å”88 I*€§JBœës¢¾öÑCey4r&Ü=á¨L›õ×Q?öšÁrV#.v˜Â…-Ž¥D£Ãs;ØCJ1c 3ˆkQž@ÈŽk(ûë„^ÇF8Úá¨L›?¢{÷t9vÔº<ÂÎ ¢ƒ­ˆ;¦½ t`@hÁ„ä8Bˆƒ(Ô@ŠúÉ£¨©åÑÊGwŸ6£!¹×Ç.6ÏÀ©É–#aG•YtfH+]i¥ÇŽT}·À ù­ Æ9ŽõÂ3 ©H‚—¥ô:5÷k¼wµfƒK-ÉÍ¢äÚÚ\™tûi òhˆ'\WÄ ¿§¨ç®W¾yy,!(QS„ý00õˆHÚ ‡’©Œ¶|‘œÁÃ\ÂøpÐP, ­V“å8jQ“¯à>òëìãd–‹#JA?‚L€„ßÊd@ˆ@_ * =½E2(bïÞå a°2Ž㺞š]A%žá3~Äœüu#º;t›ò©:Mîl­`ö†ÉJ@Ûêt:”Ñ%"Ù&RØÏ” :þ:¥®!1»(Ï}û¨—¤&ŽNÇÞ%íµ¢, Á‘xUO2¯È£çµò3l÷CüÌQYhxyäÒí °Ž Æ­é“áÞ¥aÖP¢‡ ¡Ù w6€­:">,õòý@¤}v­˜ÃG§„„´œO5?âie»âgŽFñueG£4òCÒÑĵ±|Ȩ,Ž|3VXH¤˜;LÐVÙb#0„…R(aÈÄ¡˜˜qذ,`s4ÿhûh„£2 §×y‘g£R…©‡F”DLMæ±Þ¨âÖN¨px+ˆÅ±%u ¤°™ (Œ©ÑêX‚!0ßI+@‰\Ð%¬ Žp´}´Ý¸¸çèÄ`ûˆ±i¡ “‚ó’(bfñ™ßÛ/G¢X°`t ÙâHª³À´¥bëâ1vìXš+yûpšq©E´fWò3Œp´$~…íîýDFõº$F AÊ.^¼¸,:SùXX)l*éŠq#fáˆX¾í@¬yéeåJ"i5õ ŒU1+î;ÍCÁ‘֌ßZyòGtwi„#—Nn€£ 8ðhŽ"Bÿì¨' ÄÕ-Ïgn®³ö+öËR98D±…#ËïHÿ ”f-†ˆ‚Õ˜CŽA¼UÇ+ž´Bš¡iU¯3~o6’GÛ@#¹Äa4P¯ Va§£ÜtŸ‘dÙŸ ÷xpÒcžZfBÎäÙðýTzç®[¯+M€…ì!©` ’ð•v”0™,‘•ŠˆU1è‚#q#ûèž"£òD áekKö¯~Ç—-ß0óîàõÊO ÆgàN'Q8B«q<=ý¸Ì%Q2==SœO,—8Òi·Šyrøh 0(Ì#"QĤÄbì;æó#¡m‘Ô‹!À÷ETœeGÄplÚGl„£»M9Ž\~Tµ%qqÝÙ"¶ooØ—µÚ Úa:âö‘ÁÑÏ¡AefÔSª| ŒPPé'Ë>³ùÔJ©TßyŽ !Žb{žëìsÌ *Ñ4á[ÈÅ8sÓe\+›‚€ñ’re¤Ò|XxÈÊs2Н»ËÔGÝ¢pª”„£[½Bý¤Ž0‡-ûèô˜øŒ`'Õ ‘Ö!@!2JPê‘éÉ=ÐÁ7‰Â4’¾lüØ‘ ÷n!€`Bþ/æØAƦÏhû $P¯\žêÌ« ™„w E·+ùëfî½nü^—~ç^/.ކY*ÜÔ®&îTÏ'‘éÚy½ÊœswòÆ0}©P- k×3+N9Ó¤Næòˆ6&ÞC{w‘„B!x¦S¯*Y„<²²Êç‡Àñ2¤x «u–SÖ¢KÒ@D’T\¬ÚÂb.‚R  š»òfµÆç¥y„žq¤‹ù€ÇÂ#4+寋Ëóœl·^wÏâèΑkÕÏ1ª(Vý¦õ6ž«ç^¨t…ÚsúR¥:U§JÕÓǹ^÷Êj|£¹§™Š½0öpJQ´ ÅJÉˉ†„88²BLc„AÀDHw\ŒÐ"ÿÁ± EÒv" .É› á1È-¤´¤×Ýb|]ñT§”o,àk&®Ýºz³ƒÈ’Gö-ÂQyA˵jýA8Ê¿JsmóóÃ÷¥Bë»ÝÞ¸+c®ÕŸ“Gzã»åq#¼}¶ÌBRz2¨ý,°‘JÌ›“ÄÎ k €`‹‚"oª0ˆZkD „"0‚>©¹¼!IKòHãhëë¶äIÆ«©Æ7¨ç&tÐóÔ^hˆ†wmGù³*eoX«ÇQ­ZU’· GŸ®×ÙGíé*jÖ”ÈÓðêÜßÿ»W—ÿoË„Mú Ú7B/bbÄ$ãˆÂ… }ÿ0A€ '´7N¡í`H§PMJ ¬,ÞcEQIQ £ë ×wæ9àUT‡}î±8ZßpxÃÂBå!ïÞ ÞGG=õò'¡Ú3ÂÍ™õ¾Z×ny¢×+Ë#ë¹Y8Ú½îªqù–l Ü—<ƒÊÆ’î£u¨Òÿ|¯ô:8yâÄI4éÑe൱‡iSÈ!J;q@I°Zº\“0.–3&)t´º4uÉ£y¢ @Z °c³.Œ²Èö.Ô"­ïCñ‘#IæàH¯#Vä9‘ú™yj»­½âÞ”Ž\¬Ûº›þ+,˼A§emnW[³« ·ŒïÐìyG»¥gw/gbç^w[øržÇºÙÙí?5f¾:ØÓ_½Ý–×AÎK﫜mô„MC»{v+ýÏwÜüÒ_$ÈÃ-`€ "Œh„‘l’k2$h)©ãe >õã:ãÆŒdb­VBKÂ(…ªGüÉV ùRªäÉVàè#7严¦å{æÖÕŸ !'ßSñšéÙ2G·)œ#†Š×]¡êeK]¨l¼Tf‡Ðgâe÷­·r‡:Wš/ì#°Ã¤Ü4RQ@AÈ<×M¤>•@ºæ»1AíÀÚTŒ#Ç YwžhÂhjŒ(:Ú%"ä;qqtâáj>Õœ“Çs§é`•G®9…Í;Sîï.Dyå*ᨮ±5«±µR—ÖvŒîF\ÐmÒw Ge€Ÿ8Eq!™è^Æ&Pn)ÅóÔsƒ¿'Érì=Ÿ-/3]µq»¢×aŒÑŠÑ!H»(R+µ¤ýa„2€R€LXͺ-ZóøjäQ…–6$ŽŠ•ÂÃàÈnnÅJk;‚Fñu. y$²ÛÇDO$"!0š[óaIÑæ¥¤‰˜ŽrãT+†·—Z0r¢íb½Ü…ý`„Ò¨{T$þöê×?zöÑ"?C!Š—~ò˜Àv‹ÈTjã¨ä+Ó’TÞ†Xéo–8Štè†Sý`¤J$4¬]Öõ3¬¬¹ZÓ¸ §5ç &wô¬š’ÏBm6¶FŸT©mÌh‹kùWqÝwP$݉¨þ#œ,è„þÔüvÒf0çÐ «°]Þá\›‰­úNû9¬ºƒúc·ãö)¯}¢tà„S¤ÔŸnSihË<÷t/õTççç¯yM:}óÚÛo­»C°sÐeXF{³ÂmWš‹¢))ëHΘˆ³FyÒǾ0Ò‰¸èRßõøäzå¥|ª=›Ø:Ùñ ynÖÁ^¸õª÷üvÑ]‰5T9y ;ч{±RÇ6lÌ8ŒÜ¯¼’¬(÷§tiW2V…äI·Ë'ê œxξŽW¬õJ»AÀatñ"·Žn^»YY0¦¤1"vd‚Öëuˆ7:©É;{Šy¨ðâ°¯£Nç¶óriTÍ“ÿ¨™ĆÂÑí±[û¶¼¥Æ‹Z;-жWQ²\­I«W'Œjgÿ/8¹\ÞBœsôDŸòÅ©¥þœpvsÓÁ´ÕìóeTºˆ–ô¼%HO>WTŽøþ÷üÉÂ{Mb“„-ÏCŸN¯\»9]¦ äâGY»-~x´GÐk¯*ÓgÊȹF8ÕJ]2Õ—@‹¨i}qôÝQž“m•V?úhõ#µäßkdݹ,›ãÿ8-ô²5!o÷7®_ú¤ƒæCÍ=þ2ô9ÌEÉßÿ»_äl¦PãÇ ?Q?'©I!ñœQX“¦ÁBÀB ,#@¬æz"R8FX)~ bŽJóø¾ûðG#Ú"#‚u2¤Ž Œ%œ„#²‚£•’R6Ùô bħˆy‡§~nÒ,àÃV†_„¾ëqH`ËŽo¹žXN´—Ó‘,itL{À %útÎ TXG?ƒÑë6ÀQÿhçlÑí"½ü\.²L £±¡äÑ'?àp}ïïKqÚ“cËËËõ•]søŒ’,ÔóÄÔ×ΊÆ£>«‡‘O€aW’g!#¡¹×A¤ÌGÊÙáq(wÚB,ˆÁ48" Å•õ&†Êï=¾…3#ºß©Èì¡å‘MR}R’GÓ+®bG&&—Ù2‘Y¹Y¢ÒwQè¸ÊthŒ&>­ƒQw2¡Œ@ƒ Ž’¥zv>u fS)l,˜êGÁJË;¬ Öj]Š«öÑÓ¿kâT?º8út»êÝA*2äò(Ãò³›ÕÛGÓ7K8 Ñò2I©ˆÿ ähªÿ¿Â†"(Œçƒ4&~ÅÁðÿ8ê-SÄ&å‚åV|V­w#°K:!¾×W©–ÒsÌ^ÒÒG5~ïïìsâ‚ÆˆÅš•¥s¥0=ÖZ)BóêÞˆv( žùȲ†^Ñâ¨[kMß\qvÈ qÒæÚ™ŽI€ït\™!e…î üÈsû a²B¢j@« ŠE:üÜWG[,ô`_‰e0a ·¤ 59òküuOK­˜xïµr(Á¸º¯‹KסvXÑz@µAPЈv o`¶&ýuJe…}´VÆÑ´‹#”bˆÏBæG“‚ù‰ï~ÆNõÈ<y9Ã¥f¦ñ.Íhô<ØDñLG¤>ÄG¤ÇGÈ2|Øò¦Püh¡…^üH‰¥Ìõ3üÙï®}”':ɃGíéø}ã‚úâÈì•Ã~¬m§Í ¦{vTL"¨lÍexw}4ùÀ@ Nà˜̓لáXÀˆÊPG(† ›ô ª¦ÑD0 <ÊÂ6 ”qÔoMrá  r_]ÿ¥b)—R¼iÏÓÑ¡¯Ä‘Zn¹,þìw­y|;ñžÅ×m„£’Ê8yúÖîaˆ E«Ž‹JÛGØö×Uôºé›z(•1æ,Ç("Ì×~k ˜Z,ÆíŒ„pyžÅÕ¼&ÓxÄµÛ ž¨Yr|óVú ƒ£„´ÂþîîJcªHs‡lµ®²>¬;O> @ãÃéu=57ßÁQ9ÚÎ@®Í5¢I.Ž„<šCHx!÷×Uq4½¤¾²]cM²çø¹J‡޳&ì0Àå„‘'¦SS(æ&ÐŦÇj¡èQ|g6)YG}õ5‘˜X—ÅH-òX±â2ôfŽp­<åóø¶;äˆvUí£r<ÃZ­A+Õ©{Ó«ÁX…þýo*YžYqÔI>OÏ>Z$ÞH²2äòHû»WA½¿îwjó©~fpôñGFÔ‡ ÎQò¨›-̽² |vÊ_Wƒ#²N–_c±VÇ`ÇéRõ4Ö / d  —®½½2=½^š¶4 ÄÀQ’›AÊ_€¨Ò-@ôZk뵚&eJ¢!`„h@[‰ŽR%O‰ë¯{zßÚGâY¨u-ûæ$Y[»ƒÊGtÇéμŒ0ZÊã°ø/}v½îZuü(!€ŒÍ®ÀP*c8 :ÍN~纂Ë1!0ÀÂxEÕ{{ÉõyŒQ+N9$Æbá)Ü Æ± FÜB‚‰rÙan£)¹TI´b‡“ê8ìzìû¸?ªöé—kDŸuú¸b-3't|ëg Øò²×A(\† UNN)7ŽXnÝmO‡Õ­¯Ú J¦¹^èÑÙ8©Œ¢É@QÕî­éHUHh$¥8zªÕÚÛjEžc •ì£ç›å|ª’J³!Ö6JÜó™¦Ï¬&X‰g3Ê»¶}ô{–<¢c¿‘,//ÊÙB‰\¥2É#r1Ñ ó)uR7w툆¡H«Pš~—@&Œ# PÅÓ•qd| €µh0`N¹\Ý¥åy0‚X4¬Àû(Ú¿!ŽŠÔ‹#úŒÑà7ħÕñ£3o¢«äÑG¶}DvMŠlÜL¥Òö* “ØS†Ò‡Üä å*íÔyê–h“35 È7'×mE™r”Ç‹õp¨àˆiÄà€ä ú"RõÅ$„bôÖL+i5¿÷sMk}Ø‘^7¢MPŽ#{>¬”IE|ÝÛ>Š#´¼¬—†HšíI·ÜkaÒr‰XJ)&ÇM^ÝàˆÀÚùG¥¼Ä#ÑP$™f½_‡íøºÞÃ<¶ç‹¾·glï¾åùeÎô0>@DáÈŸ¢*ÿ€Ú ‚ÞzRGSÁ£Š€@=€D*oBéêÓE:$(N§XKy”„”ó˜LÄ`$Sj2˺ØU~@¶jœ`³€—‹ó<Ä]gyÝÇ7 ÀÑfÈGE¼· šsæ}”M/£É‰æìüüŰFm<(¿¸%$–äL"„­¼õvI« ¤Hdá 8Ù—üà(”c@àX ‡772±ª9â{ <ÒT¶Gpk„Ôâ&;Á$™lAš„î˜ï¬FyÈÕ’<úËQœêˆ¶JEL±nXaAÅ|Øååéåe–Ðeä{¤sæ[tIû¹¥dZ 7-ʇUØØlÓ¥¥·ËQAqàs»¡”$\+¤(^å‚K@`‰W"àÃîQЀ˹Y*r?lüs@Kª§‰Ê·êu[ BFê0 ñ"Òòdm‹0U'21vb6­ÅËqtûœ ãuù*Ίís^ç4àäÚPç»ïIhuE\Tëºs&í–‘GÈŠ`O„’DGu¦9á§‹Bèi¿ÍaÄd¸*ˆ™˜{Ó d`MÐ&iÇ0Á(Hk‹øeI_:‹_dm¹x‹ŠE&¦N†-`ä3.ëp´8¢Úcçx¿;ˆ¨ÅòÀ<æG¤Ožü°2ï¶ñuyM÷Ë)v×è¸Å÷Çó>E׆9÷Ç‘_§4º9Wù¬Óˆk]L¬ó•¯«BÚÌ[ͽX{Ì2E0¬ËDŒ!¸ ¸~8Mm"&fXTÒ«öŒN'< í°)ý)Ñ1Ûó-HgÊ_± #B­†}pôPîgX¹8ªÙÿ¬âèf÷ª²Ï€±œÛÅöøQÚAW™YÁEâÓbRw(a„Cµ&,@s5©¶¦ ž k/OO¯LNRäA!&¸4•*“I‚†\ É%gÛäè³Â' Cü»8òìQ#ŽruÔ‰pmAã´s󜬗ò›TŽöÀÑZu=>-gv¯;EJK¼ç5œýRì]ÅÑq[•38:®¿ä©ãk¦ÄqS¡q¥sÇó½Áºâ¦Z(#øGŸte êBÙ>úà CúDãÈxXT 3]’óÄiv: “šuZ.<׌ AÈÕ=ÄuÅ8`DP$±^Œ…¡ˆ¼‹B­Àµ@¼:E=ƒ°U0éAµj—ÇÞ…Ö¨—NK껉mµÂP'ž?`ù½Ë˯®­­—päF7ôÆí"¥Lwããµ ])TâîîÖÉ£ãÅq kÇKu*8ÊÏYU6qk÷®lÙ UâëT ªH¹}Ä‘Q™÷M¼ :ó‡È¹yŒ5I§²§kÄ‘”>Ißñüäà4·‹X&©·J²ˆ2.í¨'‡Ÿ”ÈÀ±bKŒŠk‹ &¼ßlR Æb#pt¸^" ã ?ìÈ#±xR¬ÖmÉUâT‹Xº|ñ×ñŽr |ê`£ÊZ[Ç䀬IÕzh€<:~Ü’=Åiy°„ŽsÇ‹ãƒÝ÷¹qAb>삊 êæòè@£2í»Í‚štWÊ\% kM 8!58šL¤ÞçËE\ÆXB§Åjåàè·0LFnÇj–\ÄÈõǵN—O;Wóh‹ÑT…Ø=ç8Æyí$ñ=¤S3 /n•€„i5•礌#7Kª¦R>Õ\w+åy´Šö•GÛ‘ž¸Ö>Ê…J~´8“×9^–GŹãvµÏ’Š7FÍj’G_“8"#×Mùaåjçó:yEH7¤R!íyhzbt–Ç$À@{Ø<9""©…#ötÕ42Š7dxAœÌ§á¨YÉÒ™ ¦]•ïÝ/4©‡…ŒR3`Ê@‚=D@"’K2âDbˆ…4—J\µsGúÍžðê⦩;ob½÷—j}Øù@î'_Òm¥+eî,•çá9í°+⽎\?êh  Ÿ¦f©æÉ‚($Ñj pG ¤0âòÆQò õ}ÕP19Â#²M¶g!Qæq$&áæ‹_’˜„A˜˜oíé^ê·d¹—Å«N„ +z]óÓm–GwœîöÛá³ó6*Ë#œá…..­Ç×n_—˽ÎJ¥®ê©+Ff¿#Š1‘-.\Zª£´9†) ݃‹ÝJcëx‘v¯g”,KZifVÂÈð蟡ø0.Žú§ûæÓH ¾÷ôºÝm/fW%Ì2bÊÕ å‘°T’:ÉÆ‰3ø*ƒà¶ê åêa>óÓë"ÛV 2þ> ]7Þdé`àPZ@°"ÜŽ0Éí@iFš-_ÌJÉô"㢭Œ£Ù~8š-H ­‹ 2ôÙy“Þ:íðgu[ºoù>µó{/fîø‘ô‰Ŕ'G#Dª¡ZÛbRj6¡hzz½’²Žëp±o‰)ª6ø¤"²›‰¼u¦^HA )!.‹<°OO^\‚: ²†¬0n¶EspÔO¯«LKWÓòü£ÉÜ>ZÉ£mЬyåkf}ØE-“lyÄPØÂRŽÆ@A`Ô-OˆÎ#Šr èæÒ’5qÂÐB‹÷N4v1æ­ äe"ï}ÀO"€—Ù$Œ¼éé®Ä eZf±”HÄ ÛÒ~ù «ÖµRâ—æMäãGì3­×}¼Ås÷Çå·J•x†,+†Œ<‚ZԽʡ¡ˆ§¦ˆgFŽ–KY"@aªuºõ÷WDVý<3±¯AxÁ“ÉÙ즇؛þžÉåå&€„7ÁÕÁ%?EpL½öj’D:MC.nH:ŽZ.éu°9²F´E*Ç×uµ,êÚñÞ"?õ™Xb…XŠqoS…í/µ:…H^VädØ•¥›75®šöÒ|x‚K-!ã2É_m1ˆ”0F‘ÿH&—é(˜Ž}£u~ÇÅd\°JCÀpËWö‘åè«õ2¥»MA9äc#h‹ô‘”E+N<ƒ\’oa®›Ë£)™ H®'ŽÊyâH!"¤ZYG8²x.nÊ|ª+N8Db$/¢ 9AøgÇÐA䑱IŸN2Údt‚ìmB}Èq4½­â4á ÊÝ[ êT'ùÈP Šnµ*8‚•¸ GyNF´5ªÄ{ãîœLÏ€3œÛGÜjáÆˆ/æDøýaÔ)Šƒ¸CàÁ°œ¹NŠ&ŸT=Þ#`š ¢ Æ‡!Ãdùœô8¤Ðž`™íÛ–ç¹TZ^^¾(E•á°/‘Ló‚4OáàzìX‚<è£ Š¸’—¡ŽNŽäÑgœne}Øj|]·’ŸA¸¶Y;KE\ƒ #l›þM9Ëæ±i0±×ÅL¯â„ü±‰`oLô–YL›G¿½1„Ø#{è^úÈÉÄ—Ø«ËóóóÓ\Í“(±{R±N ¥`imÄÊhœ@´êˆµX—ÆàÁr~†hH2 Z)Æò<'–<óæÌ„›¢EÜ‘)ó=æI‡šô\T#€tzÚûÇ ®ÅÁf<æ}‹Š¼^t,ø½°99æ± ¾¶ÌAtqàå‹\ ÍÒIÕ´X£¥Ù*D¬5ȸµÒêGa˜¦e­±íþ]F´³ˆ³ ³åQ7®3ù½{_k(‡t®LYì+üб„QÉÙä7šÓd’Xª“GÌ—1áÞ䄈ʆ“ca0M ›ˆé²G‚‰±ézË„Î/‡>ǘ·ÂqÄ@'Ö8 p†5)Vhq«?ù8sÇŒ<2ƒi#ÑÐT+#° Sµå‘ÐìÚ¸<‘áB 7C!PCG”›>¹Ÿám¥ê ì´Yò2ðÂ1–†Ü$J' –— ž@{át2†³MnáLSÞ˜Ÿp ‰…”\ĸôª"JŸâ; ¦­A8ŠkæMŒì£»K÷ðˆÐæ¨nþQwÑ­ }£¡#ÒÊ 'µæ×Qná^„U¼ U£í,¢>›^j6{Çâ F“åÀ šÂ+34ýÎÿ:að ›§!Q³1‰øÓ Iç9I¢ˆÍÀ’ßZ~†•íþ]¶@[áÉíâãû?†VÓºQøÊöÑ”\§²2¸™Ã(ŽV¹8šG ÕeE5¼mÄSÍz±4áJÜÄ?n!›ôöÃ8šqxÀ»4íL²ð¹n‹…ÎÛ` ‰dÕVA"!#⧦e½îc'hwi¤Uî4Zu†LŠõÊ­ùGûSý¨ƒ%™°š0&5³÷”qÔ{Káçæ[Ž©Tä-&xßt3ð&›”€ð°ôRàÃñtÏeÐK–çC5É=AžÈ k‘‚2G èìg8uðÖôºB:GœZl™„,‡þ>âíÝ—±ÜÕ°"a4½Tça˜^ªÈ(oŸ<òfm „¿¼|,=ߎˆ/%‹˜1áM¢¦K"ÃëR6E@XŠgð¨Ï¨Y´Ï~%_P5¿÷¸åÆ®“GkE®Õ!q”³¤–k©ƒë½A8*%ò‘Ew–uñ z¤ûˆA¨ë’9ˆœn.U:'ˆ€Y›–ám9í¨÷vÛ¨DXÒèæRm%º‡Í'+a¯‰e`Å™,!M5\$ ZôÅwÌ"°:Å`"mCZö{ëyåê­ò±«59K´¬9ó|ªvš’ÏBQÝ>W:¸{|@cF[¼»,³ãéάW^ò×-`nÍõ?b!dh½ÉĦ¦ QÄ€XäGªs7ߔӪ œE=!™BØ„¾/‡ Ÿ!Ò’Ù‘)Xi1Øb+!a4äÒHæj+Õ+?~9•2·Êz]M|݆ÞçÛÏÃ}[,­a1¢{‰ªòhΈ]+áHØîzÞ6+óÉ…%Èü<Žà<¥PúÀ&™–ª]ObaEG77I®üq…QïÚºŠ'#Ä §"Ò9¿R!"uŒˆÄbf«‘Ú ˜V2.ÏãMhZÊs’¯#ÆTÒAÙvÄÖ#2T3ÿ¨‹ûÄ3ÊFTH™(!à0 é<§˜ÍÏ/çã>qs¬YxÞ®½%½½·Þªš;++…1äžpö$ªÐž½A²¼LÐæ ‡Œl äAh’06E9SÅ¢˜­¸’ø;ÀeytâáQ¼÷£íEؘjæá®»>¬ÁÒˆjq$¬#À”4âÔ™Ÿ¿V»ŒåôÊÛÆå½R5xVnÞ\’ô~Éç°rmåý÷¯½­ª­ëÔ¬tÌ›Ëó]¦XŒ… ‹ÐYªÇ^BA±Ô‘HfäX­xCæ•×ããGí\Ýï¬zOSýü#.“ºùzå4Žäª\AS)x¬Ýƒ¯Ì]¤°Š¢Þ‡Ÿ\ëkõ,È…ØÊ[K7o®Ë@™¹‹Ÿ¥“»š„aºŒã^B °_¶ûÇ‚F`»3Tç¯ËÜùG?'/FÆêPZÝ;ßùµ…#ߟ͞¯ææÏ¦ßžî £¥~Ó’‰Ä[ºööµÕi-ŒÜD{›^˜êXe^=€ÀTTÅÑQÑe%ŒØT¥´_wòVô{ÿ'6¾…3÷% iÑóî’ÒHOCc6ÂWwFŽ…‰#ÀÀ¨âáo§Ö«CÄX_9e<jøH|Еdo6c8Ö$RY‹@%1R‰T»SS/ò.'"Sõ„Jó&žûšå÷îÿÄF8úŒS¿õÊYE¹ó$ŽLx‘\šluƒ(ôÙ …~«;ý·+58áæÎúÒR÷®Ó{ÿš.C`LNƤîšXƤ-&Š)H:0)¹0…@Iµëãlª/•ãëNºã°v€jý¢yî¹R˜k-Y[[«Í!p‡ÓÇû(÷Ö9ò(ËóÐ =ÃĤ£öÑùù˜z0õ«nriT‚Qïí·8-­¬¬L÷§ªƒ<ðètsblly¹éÇÜ4Ê)ÀÉW’AA%ìÃÃB—£dj •ôºç8ñÞkå†q+t!?<Þ'.a\CTZ1§K­ì|úl«y«)yÄòõæ°‹Í^Éí£C_°æœÊ8D'}ìtØ^8½ ž@°Ìüë\•ñö[o/-­ôzÓ¨WÕ÷ÐÊ4ýÏÛÈØ2¢áRL§p މÌf’ê!a+ÅA˜Mm M¥x†__[5Ëñ­AØÖZ®}ã‚úâÈì•æD”—޽p4 ¶»ÉÛz•‰ 2òèÐçŠTx¾hªœuri±p™5 †«q‰÷×6ýÿ-ãeéíRJ-ª¬Hô•É=cÉR‚ãBHŽÈµèš0’  6UOƒ‹£g-Ë£2V¶Œ£’Ê8Úž¾ "wÞDWÍ©ÙG–}òT)QÖÖAÞ`&¤ûƒÄNFrsåfïÿüÛŸ}ZG&AÃ@¹EнɽQ:]Ë@à @pùy¿&©^NÜhSÌ£5§3×Ïð]{öc'NN3ûzÝxGƒôºm^¨|gÒǵ›ÛI%š1•ßÛØGŸgŽù.¼u@ç|L©Fqäu˜;»rí“O+&Zu¥îàº0™¨P2àüü5ÂÎ'¡=!ê| rA™¸Í"ì,mªeÒ:¿·+ª±¨}ý nø¨k ð3¬U÷Ft'èÎÎ]ײð×½’YãG…LXô)i'jæÚ›„Ó,Ġɹ¹rm£hÕÞÒJ­ïí·®©yH×Dóì"ýB3œo8Íœ¦mür­0 ŸÖ‹2*üz(†É3”ýzj%ȇQGÊ>ºÛù½?[öÑ}KÚ².Æp·â¯{ ÀÑ3JÉl ÅdZ 1o#Œ\{ëý Š,-M߬³Ÿ–VÖWùqú{LîmÒÿÑ[æ;£›ž)ƒöÊf…8BÈY¼O$Ø[«6ÏDjqLŒ*þº|>ìÝ]oíz?P%žaÎd9)äÑ.K¥Òœ¨¤&À¿°|ñLÒ¨ã1ÂÆ6²’ˆ£’Àêå™QÞ×ÁvAÓƒÄÛó@`\ƒì[ÏOé(TŸê ptæñU–Nn„#`Mˆòè/¿^4RºF4­i­Ïü£Ç8š’ˆ‹©G “ >š|G 'ãfH††ÍjÉ¡°RÖûzXú›áÉxoH÷„c“y™£‰˜œ«G°È™/œÝ(I¡‰Züy€zGJzÝ÷«Í§:ÂÑ6ÑŽae]Íü£ƒ;†Mî_‘CQ¬·< ›:Õ–I¢Ì ¼áató­3ÿui¥Ç±²>°8o|b ›ÜHÂ…G2 †`÷Q‹¥f»í­€µ¡˜µ"fvÄ,„ýRŸ¡&Þ{„£mL«…Ãn­Ïü£C»Ž;– ¤@…ˆ¶Û~§ 2ˆ6¢›7WŠù}bÔ¶ÖÝ}ÍXLÄ ãˆ‘]\k$‡ÕæJâѨµ÷2€ÑÔŒÌøm‹äµ#s„wy¥Œ£r¾ Õ|ªkÕœ$æk}´(ĈrjþÇ‘xõ«;¦nµƒ¦ Ÿ)ÀýuOHts}úf%´´R‡#+BHJ:æ×HöЛ¦XætÌ(ÇŠ7U<”¶ÃŒž´aR>_Н{þÕ¼[ku‰ää—“uxDŸufþ‘ÀGô‰4õ†‡¬C³,†oÀkç”Kzÿí·ßv Ô{Kej¸™‡ -mè@KûÍåùe꡸-ƒ <¡˜ÙãEÖ²L1”&Œ À²NµKóòx†ƒ#I¥Ùk£Ä=#ªÒPóŽi)Ó),Õ:®0y¤‚3ÃŽX¡¼žzï¿_[åôq¯÷Ÿ*;˜ìÊG#Ú¹óøD¼wuþQ®×CK­V@!@H qíj†VVzKï×-ª—¨DÕÉõ’êx“\¯£tšN.+¢ãP8"Ø+ÙF!ñc3/J×â©ÃQyv_7¢­’f›bý£šùGä8:“‹?ôS+ZÄž@+7E÷fÜ ×VúN=÷<›Á4G×..{Ó^€™6¬¤×1•ÿ¨êhŒJ~†OξK8êm÷>¢ÛNeû¨[7ÿ¨ÀÑ1D[ÃGDvoä!yL¢G¶qV†œ–®õõ†ã¦Ù¤O.ÎÏ_ä0"ñr@Âbå„C „’€LI¢TdW² Ž6=o“N‡qww½”ºÁñdìvš.­|9>îì›bÜšÔ[.¸!ÝfóânX+Û˜WXÖæY8:[-@)l3"4@õ–r9Ô^ õÞ®s1H¢Aš†¿7ñ…YéÅe š¥ÌË—z.¶ M’ =J~ïS‡>­‹S•4˜õ6‡£Ý¥ÝÞ§•9çù¸ooÝM‰RN4dï[²tdäkÜ ÊŠ¿®:ÿèƒ#ìÑp 2J‹È@ÉR ­Lß‚Þ$œùµPâÏ3 ­2 ‘EÕ•@€ã¨Ht"qôx½îvâ¨&5CŸÜ)ƒ2F–³9‰#*—±atÏ}}|K§·—†˜äâèØ1@lÓIX—¿¤Ÿ¦›~z‘ëo)ÍÔˆ ‰7(le ŽJzÝ÷·¢¤\«4`T—HÕ]²o|ÍÍlbgK)Ÿ[냕MáhpnIwñËÛ„£{š¯ï6 Xÿ¨Œ£„ ýC04ûo¤×=4<ŽŽ6E˜ÂŠ„0õ0hߥüueË~fƒ©ÚʱEúظs®fÑÊüÄ`•W®í#]rKöш†¢!Ö?²Æ´@ y†lbêëÊ@G›ôé 1‘6 =ª½”Þ>åóÊÅó`Ÿº!©U­mŒ£rñµ!ÐaʯmPÒÉì5GªÈxý™Ï ÝIZÏP™dpD™E4Â+e²¨Ï H½fIDATUð‰'|4¸~Sê„#§ÉPDx¯²Ž@¸ºV­<~Tš묳l?³­âÈhwNƒõ{ãÎ9{æË A¯ÇQŸ3#º4Ìü#”óšHôرˆbbÐ ¦‡¥zÅŽ((‚ ™þÏ“M: &§§}DÛêb‚ °6±"¸)Ý0»‰m•Öm90X¯Û8‘j‘yµ¯QÚÆ”*ॄ€Ùˆ"Rx¼@6£’}tÆï§º¶¶æ¸ú&R-| }å‘c¨˜£kŬ´üãŹþ%õY{f÷I›§ÁÊàóŽ‚# 9ŽóBH[ÀC,¨ãþf\s0­Á‘@ayÓÐ#ÀpÂ÷W=<yAz8PóbW}Ÿâ)”@æîm¶QÖ:W¹öÑŒgͲ¿¿ÄÂ`xæ¾å’£¹¼·™6\ÿèc3›DÇÂc^+̨Çj¬2–Ià¸GoÖ„Ëq™ÂÆ&§÷@°g#/ô™ŸÆá4ƒ)#ˆ¥ZG›)ŠX@Ã…Á&ÀÓ_™8Õ;——x4ßbÒpN ;NõÓB-Ì Oƒ?þpÄ\ N"FJbDhgçñÒLˆëÌÊ´#ºd"GM'“_h6›4‡ýF-ŒØ^ož-/ON£Àã !˪éI’CD§½-z¿K~†Aã°#º×è½’ª…®kÌ­nûîUwCa‰¥……<š[¨ØG«^›Ä-+@:F€ÌU ø¡bÔUßàˆa"Ž%’§P X1L‰‡=šL†iGòE<Èí(‘ÕD5›ìõÈòò*ˆJT?²q4zÃÞ!ºOlahÝœvØqå.·çy%÷’ÔîˆHŽ¢ÐšQ—éͳñ‘X!"Áz$ Sh–ÁTgÓò¸QDÉE/åL¹âÕA˜¨X憙/ÚÌܽ¶=˜ã¨œŸáàÇwxþшî[ZuLé¯+roò¨Mâ=8kÅq? …aB[­éA#n­˜d>æ‡EDà-£  RØ‘b„¬$¼4 9ðR5cN„—çç—/1hËABsg]Ó•KnÚËÀá×èuÏ[þº•íþ]n?ݧ‚à!kÝ–µ"¾Î]ÿh—Ô®VAÚªw5h‚³¨® ðe‰”D+‘’è§mAŠRйø™d‘#'¬P¯Ðc^sRâ‰`"nGMùívHâUãÉÛµ— GÛ4Žòêü õèÈ>úLÒíxÔǺ sùô£®’GM‰£(™Š¸,!€tŒBB&=q„¿ñÙ¯÷nÄ-#åÔkµ¸‚‡#æµ!ð Ar=4L¯¨”º¥Þ4`cÀƒÒÁæ§üÓÃfÌÕk’ɦ-ÂÍ[GŽà$ªÈ£çöp4¢-’;Oä÷Î½ÞÆ_×|@0Ÿ€·p¢c)J[€›Q(ŠS$;OxÀ%ˆèQ_ÙOÜæAhžc‰ñF=‡a¾ˆÒ:cÍe‚XDCê{m¶ „70=K–M"`OL}”lGmnQ…U?ÃÉ£ÛB·ôzߩڧ#>é6¤ŸaaÁ?j~^BLt „[8ƒ„…8dRo âÐ •4B”C(Œ d3¦ Sâ,¡”5ùy¡YÄHhIÚnÃ1c -O:æQ´w æ‘Ð:«ã°Ï?jeOÚîßeD;‹*ñuj->;?Cóó³ü!tÊc­w7HÇàF)äêÝ3Fž„Q‘†•A¢Ìãiò¼ˆÓ ï"P«qàrÁs=ŒÃMkuñrâæ""ž·­¿â¯ûË#y4¢-ÒG*¿÷J¢/ÌåöÑõý»çyÎÚI8´ZÕ!å^)Wë¸ÂEž¾!œF!HCALÛ(^޽Øf´ìCvA¨"‰„T¶ô9}’°±½NqoÏܦ´ÕÚH"%É ˜bÇH¦2߈H:¿¼ì‰°9Ì5;ÒÄá„;,ÝH…Ž æ;˜\d°`Á6 °;)r«ûu8‚‹´s¡Ý”ˆRÑÞey´ùx†MOïÝÚU·†Ìˆ†¥;ªb1;Ÿª^°\x`š¤GܨÈc­%H ´…¬Å_ýS€r^¡v 43À¸^'&À ÔD‹Á9ÝïtX«y³œ°È¦pƒj~~žÒå„¢6ZÑ|ôHà¢G¡#¦’0¶°GÔÁ²Ÿaÿ¦×+x¶Z|àz)ã•t2{螢ÕuÅ7ë&\lâlÅ3<ú¦Ñ â(à  } Ĥ-¶Z³JA'D#ŸfzÓƒ€%fµqaÈPŽ#g2Š Oƒ@ÆÈ@‚d>!IÏW1fÔŸÜGU$r,IeãèåGló8–vßZÉM¢ö>¡a©~äÊ#1_BG©f‹Ú_÷Èç¦="õ-aGä4á²D¸áâ@Ñ@MMM!ihýŠpÕ&˜[>áRs'ü ”U«JÿCjn:Ê}”·‚’Šq[¶§9‰¤u:¬ ü<Í ³&=GYJÂPÓ™’’æ&  @Ú@"µZH¦ª"83ÍÙ@1;˜T[@«2ÅC¡"†ƒ~ç¡P å0)Wë‰ÔYD„£PL="€ÜÄñ&š"‰ mSÔIL:áÌUÉdÊ!‘#•Æ.Š|è…tÚãöÕ2ŠÅbÏÀ³?ùZ5o´„ÁŽ@XÀÁ+TE±_Ê»õWûݼ[âñŒç‰T-ªä¥+/'QÅJu¡åêRè¥Õ“K×É£{™Êó„0ê.èY±Ê>zärHä )‘3óh‹À~8¢q‹‹®©Y^-šŸgIæça‡(h nïpƒ¿~äGH22ÎGÐçpœFˢ°@ôÄžUž b­Ø6 1yƒÛ^TIB´¦·Äç…Á~7¹£Eõ8 jO×ãh€<á覚øº9“˜ØÄ{ïB*”æ®dÀT¨é´¯™DâV+àfNØ)M@€:V&м~ÙË |pÄspÔ È¼MJH;u³âV)€‹¥Z¹ŽÑTŠ÷­±ó0ú)_kk¶è)çô^+ЏkQØ­ôSíVÆ×Ö{•ëp´´Áz原AÄ×)GÂ=6Œ¡ÏÜ’)@$`ß¡$ Zp*âòˆyÈcói‡©Ï•u¢0¤·ÎÅ—bÜ’òB â ˆ³$¤²'V}Œ"d¡“0túSy>죥|ª¶5â¦G-ÎåyQ],Zq:¹V-‰µ»z=·íÝCT¯[X(­Ç×ÜEGBX<ɼ6,•i´fû‡5@0­$À„ü˜ñ`.Ñ`íJ+G%"›’‘ð9@¤Cn Úªa‚éá />œuRyß-åS°·ÕV>+t§|·©Ýaš©ÚGöÂ-kj^¹4i•HÎm¦<,³%\o«×î È£°ÒÇ0¡b†bÔîGb­ fàâ(¤ƒ »žð trÁÎFT^gù·§:ÂÑ0tßzÿŒ£w%·Dž|ܵåѳ†ùS & ¥ ¦RíZÑ>>;H#Oˆ£Îü<"óQ„= ªð×É!¦0`PÌ ´Ô:Y<`ŠsË“r•<'VþºO·û‡ÑŽ¢Š<ÒJ]á¯[m~.ãKÂΧ"¯A‡iYB 4’>³dAËC”@㈼œ›ƒþ8ŠéÔ¿ãöƒ8à©Å1áðiÓ•Q{´HT¹åi   ÛFM]¯ŽFù½G´e*ÙGX ȵ>m~~¹ð‘Í 6NóiG©–HÌ«w7D"ÌDóÌøØr È«eS© œcPÁ'\øx1ŒÅ"JÈãÀ°’'È(rÈ\\öF?È…S£òz×VW¶¢×m8.:> äý®É}FÈ÷Î]]· |v¹¿Žå0@ò¯&åIúã)Pn¸Gkq )Ë€4‘¢dµPËÀ»}äÍ ‰ÇÕODéAåŒc ¨yÊG·b#qsÌÀzïTC\ÅÑ&ãT‡:[» ØÐuG´#ÈðÍRÏ€Åé³SùëÖ›ŸGÞ„’q#Slø˜t ´túû%­VL=3­ô4$<‘ °ÙÔslP&o길Ãç:8ëèC,^%«à¨ägpæM” âŽF4ˆ>®ØG ÖH*¾®ù9oš‹"Y0 —Œuãé0¹vÈ H¨F³Ã¬Õ èìw:>9¸Ébñ³D£×ìÕ@&Û›!V 6ÁçÚ`B™¿‚£²ŸAù½WjÆúÄ:áªãîÈk]Ôª»V_Qa„¥O•x±ªå\ײ֛»¦§ ‘^œ¿Â[ÃÃJéÈ\“ÿ„LÒƒáªHS æS‹™¹†HEÞ„þ«€m*ã0³œ{°„™8¨ŽMký }ãr*«¬óZ €¨ À+*Œ`t×èNùÝ?­Ž-˜eÄ´}´~`—7Ù¤~¶Ò< ç¯1`…5H†ÄS¡E^U"­pÍΛ’ªžO,.–ê ¢á—xíC¸_䂈CJj=èeÝAK:§º!ŽÜ v¬ºp«ÑÛ·‹3vêÈνÑïGö|Ø ëM|,äQ˜ÑIš¥ÓÆd²j,QO.¢O¥@{íª@ DØ·ŸˆÅÈI܇׹²‡*ÚÝæû5-¦íŵgÓ¾~VSý´˜¡jᨷÙ%×Fòèþ Õ‚u>ÍóIé•nÏM7¡Zä!p‘A2Ÿ¿ß¥«à]8•r‰9˜ª¾LZ!×BJ5›µüŽJjˆ2<ŒHÿ@º¾ÑAõëÃöÓëÖó€·ôºª/—wÂU‡Ÿ'{ŸÓ½!\¶BEÚ-%ºx¿’-,Ìëñ ûˆMëüÁƒI ÆX›"’‹á„,„­É*! \±C„y„Ý.i1¡ž­©;"े·Ž‚Îæ©¢×­±bv¸8ÕÝëN¸ª.X•GåÀÖµ¼‚8¾>’H÷>mï-h½_‡KñuEf4á qÑbb±Õó¨ZV‚VR AJ1õh1… ­–ù:d%A/l®ŠÖñF8‚lxøôÕëÛ®<ŸÞb¡m;e&Þ[ÍÙþºÏYy€áüüò2REs®ÉSë…%r ù„“+ DG…—Ž")hðHE³+,"’ª©BBF1Ê62•´Æ¸IÂ÷ ŽFtçè.©ŠElÕä¯+‚Šü y Ó4ér‘ÍüZù‚ žòQ,–9’à¡“…Ë2±à o|8H„:ÊåWQïX¡ÇIû‹=‡ÃvÔöpyøUŽÇò°„1üt+8*­#ö—ßʼ‰}¦IhuE\Tëºù²–Z}>_[… Ï›{Ç Leö|¢Ä SS¾ˆÊ*±ß"ÍwÀâï<ƒâ`vfQ-_[ò1 =ØFa»óÀBrKj5Á›:ß%:²2ÓÓ&›6Î:Ä⎽ §pÔj1 2;›7‘¸bGIǧ:îšo²Œ£¼%ê…Ú4Q³ +ÒH¸ší¶—©Z LÁ­À¨’Oµ²ŽØm0ÿïrîÓ-ríqA·áò·§•Í\ï®^n•ã0–óa»Ø²>_,ï† ®wÚ3aâ0âäÖf±O¥·!þîÄkˆEœ]À:Æ©dâ Ë!o³…yô2³`‘90/ —Úq^%p+ÞºYã°’!o÷pÔÏñµãöÎÚÚ­óä-·r|¨CCŸ½‹´j›b}Ø,à Ž}ôé]¹0Cßzå•v§‡R5[ijaô‚£~3LèpauBmµ|&Üj´#=}”ª‰u‹(ùÉ3”„ÄâöØu2øÎ·Ä\£"Báö0¨ÙGz]KÆn£<ºG1$èáèöwón_qKT‰¯Óiò…@²âëÄJyç†G?È9\ #ê± ltª Q;ŒA«U“ ’ËkvLÆÕ)"r€”D ÜÂÉE›ÅSšÎAx´ ­éæ$Úš4ªŒýå~{þ‘ä)çE]s‚·íÈÔú4&:µ”àdm:–ÈU厎kÅLŸrÁ¥×¥;%­VÖ*­(À–JæE¬ÆÖôUŽå§jª›îØ×+U_snìΑ$æÃ.`½l‹ñ×=¢üÞ“¤ÐÄ Ðn†d~Ÿ©Ÿñĺæí„ú-P ùîâYã,G(îÄ™ÌÕ;ck¹3 ¨;x:$²cü¶æó–ò(­àȉg(…c×g[ÿÝ ¹aFqK­ŒWJÞ}ª“GrŽ× ©ãÖÿ¼…¼HÎó¥VŽWJZ8nõ@Î)yÜ=[Ú;^:w¼TýxÝÁ;AÅŠ?FÍjž«Ç<, ±‘Í¡ä¾5n©UVD*aÉò0$u@‚­–È ,¹>˜'au2àˆãg(òäÕ$ЖLšêz¥ñ£ß°æM”sÆåɸKò¨HÞ˜+Ø×M•å´b*låòècÃoÇ nÌ_í%yTð¹)â0çq÷ËnåxIþ?~¼ÀÑñ ‡ÀQ¾UôE¶ùñZ ŽÜZw€ªñÞåx±þ§8ŠAyðÌ3”|ä„L5#µr›Áµ¢ Žâ¨Õ" $„\²±yšTˆ$nÜhƒ‰g(e­s"XY´5ÙSïP?:Y_ç¦ävqTHš²ºW<^Gn+Ûm:õ“G–îf—é+/*z]m+¹f´ÃµAâem(9mÖJ®».ºX.Ù¢ç©ù° 1ˆÕ´ºR̤xŠ5)‹ñeb{ÀÚ)›­™d.׸$¯íQˆ@ȂՋÿø(ë@µE¢ÇŠ,q$•¶Ø¾Þ`©ø¬Ñ 7S*ù*8wp4^‡£ñÁzÞZ¯kåöêu›wxÆÑñ:¬×UqtÜÅQ¹±ãnÓ}qÔn»Íê…îŠ}d­7Q,Æ—¯7ÁqÄ@“Ab ‰r­®9I¥ ¢³R†e€œë#Ljuñ£- <;B’à0„ ;ÃDGÝ…¬Ð¥NgµX&Œñ `ˆäA 3ºâõpTò3œÜïÎ?wõ:;«°}p?ƒ ·Ú¬N²ÝNÊu¶|׿_ûà~†R+Ç k»¡ªƒÕ^¨8Xn¥ ÃãUix'¨<ÿÏ™u-M¼7{ôsL.0N,Q$Ò˜ ¹4Dx8q0õEÚ+[AFÈká€È…Oˆ&㯈œvó\ ¤óÉü *—Bè*aI±¦æ`iÔ´M ZCyrý 7O~}twéΛ-ö…î(•å6¾:œá)Ø£»Àòr¦¨f ¦`0h/nC¶ c¤f!™Mm¥“J–ÈAƒŒ) *wŠ7/ÂQ烎ÉÄApEóˆI}I.xŒ« ÙäˆÂ°b5_Z¶z‡Ãhù"|†tšH…Ç¥OI±Ë‚þæRy}Øýn~†hhªÄ3TÖ›àz]»žÂ4–€J½LR/&ÉÑÛÜÔ¾ïC˜`Ä1œLÅ\X¨¦R`zA乃t%U’Å[Š…™3/ÄË“¤~ß2ö¤>G|ìÁB¯c¸ý,ºxqYø$ Ô‰¼ùù=‹¸L,áèÄH¯ÑV©_×ÅÝÌg¸Áí£:‘€ÑYjÆM9T¥l†ÿ¶Xl r« Åá±cÜ~‘0šT)#…ÊYåˆÎ ×AŠ9’¶…ª&1¡ì¼ `H¸ÄÚxÅ!\‡ƒQ‡°.å9¹¥u[Fô™¦¤,2®^-ºv>UnÕJ#±äªY…ýW¹‰ Ë)¤€­z0 ¶ËŽêì\€ ¨Í"VD˜€ rmñ¨ÀS1Cp€\ÖYÊ& © #o‰ªã°yΗê¯Ñ6Q5ÞÛ†•òh•ëu•µŠP ¼Ó.Ð I*i¡pÈ4 mä·SÚNBXš+¥P@ŠM–ÐLD¾SØë¸@‹Ù#Ú¦P¬RQZÜÕ`ù´Í ùy°!r\*û½¿¹æ8/G4¢¡©_×Sÿºò“ê]ôs¥ Á°I'´9/˜ŒpÜöçã ´c®œy ¿·˜j‚,)ÅÓ)õ9Þ ÓƒejE×bF¤MR&f;ÍÚqwИAd?W]#l 8:±¤×h‹T–G9„ä¿5#7¹)á&Ë`¡GE‡ø0Í4…"+ªŒ*%8ŽÂÔ•$\ÂA Î=ÔSÓ1Š‘Þ1‰ û«Ò)¬UÞtž®(ˆšOÏÝ ŽÊzÝþëMŒè®ÒÎ{úÆ 0þ:ÜË»†ö×5Ë8òa0¦?#¨Ú‘K¿m1\‹2E§ŒcZ£¢ Ôé·¸F&a“Xá¨a)¥8eG€Jû8Ñ ™É~hüN‡záØ•æ,æM¬ŒäQ3ï<ö¾kTD”yd¨¡óýZø½CšåLNC™m+ < & šaš‹eH‘$ÁqÖ¤$-O0מ†V Õ˹¶c¥“Q;ê1õ£ùy¹°Ë”3Vò6Ú‰̲6SÄÖMg“;ÿh ~ãã| `„£mŠjì#ÒаÇVýÔ È þ0‚íØ ôgJ&9gJCÊÃ:$KãÖM9ì;Ô8òŸ¥‡E5 cÈ‹í¤[ŠÂ:â8âí0ä—$NÌ¥D­k ½™¸º>z]5_ЈF4$•ì#.ƒT@–â‡z<úù„_9Bw€ô)̼6€òýNQ' ™Ç… Ý\'à#!<ìaš •-À58(Y2„ˆpM® žtV`„!…1¬¬Ù¤;æÛùLXŵîRLÜÁX’ŠÕj_¥ˆðŒ·‡Ÿ,Ñ_Á¦µ»Ý¿Ëˆv}Tñ×™‰Fýzÿo¨aQ¹Jy Q¦„:ÕDÊ-Ò`yj•ÁŽ7?;”„ ž•yHF á”X8ÊWåë³V îWäp‰H– èb‰ >´<Å3Œè6‘;o7p/ *üuŠíBiÁ(3Æë0cÔ†šÅ aq¡•J  °<Ÿ¯Õ‹Æ¶K-œÉí@HT‹#T“HÆ….õÄHìmGß\ùF´5’Œ³4Ø_÷yÁt ³" ƒ„°8ˆÅ€¨YÐHÍÿ&XŠ’Õ˜ òôòÄOE®Ho* ÐÕb‰$IF‰§} «‰Aâz°ñ:Èf)ÃÃf#ü¦5«±ò þ4ÿш*äÎ?ê–»5å÷îtÞ8ŒŽ‚„i ±4«Ù‘aÚIÙªY © <.#Bâ!#fË«˜ScX !A±Æ¸‘2L$ðjû!³ŒáŒ¦GS¤ìF ùJ•X¤X Ã’Oƒ+Çï½îŒÃ²OkŸÖG#ª'Ë_÷±%pa}ràN|ÔöJ'rþ…žf^ù81a,w´q I‡Íà.uÉØ1¡\) 2®½¢¸ J> Q„KÆH I;L *»µe†!I—·P2ƒÔ>Ë «›>cwrlIúfñ4VÖþôOÿtíO )ô§êãOGHQõ?êv<úèÑÏsFnZ8Rúݾ6¤MÎÍf®l«tÌ#‘\Õœ›I ̲âÉ̪Òc7%üÚ°‰¸ã={æHIú”Á EI¸ÛˆV§MHið„Xм:sÌÃ%'7{ƒÈáà±ägø¾…£UB›éu#@Õø:=!6—GG>cô[ÖÀŽþÄÜLBÅŒó´MŶÇ:M&ùœ€ùy€{©Ë°±HDZ©ÙvÁˆË棣Ï9’ú:rÆ+!W ‚I;˜4º_‡iÿ¶Pëf$"ù*(ó°¼~Èæ-÷d"9QyôÉoÍdÉW8ZáhDCR´³1ª! ;±pS;C¨{›¨3 ¿Bιza*RèÇ:X•Rñ»BOL1B¤$Ê åØáŠÝ‡GhˆAŒ‹½N†µÙ“ Ô:˜úLº¼éŪA îË®BŒÁr øiE¯;8’G#Ú"ÿc&ž¡Ñ5@Ròèïý\ C”z\-R-Œ –aÝHººDÉ(mçZc¥I𡱎B†d¦oEñ¡+pÈ #ŽAG±øˆÙââ.nÂh,bQy°h=ò$t ¼Îáy’vj)žŸìX"€˜ªy¸ZÂÑ÷l½Î²þÔÅÑK#ªREå“a¹~§ã>’çÇš+Bòܤœ¯=ÎøíØÈ¡e¾'ñDשòõ#d^-Ï£0·hÂUĽZ ‰¼(Æ)þ„’#eZŒŽx”Ä$X óù„©$À(Ž!ä’ååBQsÔ6‚{ŸXIùÑüü (éuß;´Æ\¿÷Ÿ®i8Iƒö4l÷/6¢{‘ ã¬Øë•;ù>yô7žˆ‰¥Ž‚PÄÏed‚b„ ´‡Ú„|çFäã6Œ¼6·ü=îADdžÇ{Ð jБA-“[Aâj<âIäG—LI9rbFºÓE.!Ða>\[¤ÒGýØ^ñ9¥E°^qÐO óÉ: °$säüf9ža„™ I+Uû¨4ö“Ghg~œ´ÛQ(&7‚Ûp·¢mÒ¤F"Z›Û8üx‡É9 4›×@èAz¬X€"Ôþ:F€°†;ÂÂ(9ÂñC<Œ…ôˆ'Ü \×Ã\Ö%Yr;jï#€pý¯Ã`(²ß…‘H"™;­Œq{ˆw‹Îšqâ&í¬BHHŠ¡c„³þ~ïŽF´)ª™›¹óa?â8Ò±9SSf(V,n,¥J"S¾p‹‹1 ft:D4ŒÂ„ÚôŽåq߈J%€WŒ=ø ‰¤ìI¸ì9z€KÄApË*V$·æÔT„ñªj>×ä8Â];‰\÷•é9ŒŠ9·õ‰ôYÌ'•¸ ë6ݸ¡ÿòjûÆ kÿFQÖ¥>¸~Ý-ç´¥› U¿hEnY…õùšë\/5*è]uñº²Õ ¼QÓ×7ò>Þ¨”¼!O‹7Þý /^-Ã~>}Ú¿aßé s<¿gÝÿëæ¡Ü°½áôíFéY_¯ëÿ çz×ÍÛÿàFިݟn?óßòƒë7Þ/Ž;íÙ¿cÑ9ó°ÌiÏÀ¨Ï$CBªbèbÚÁ€½6œ’sÉf§±Fbú8€Ôƒ«ÆBÒ3`8¥Ê·½Φ©ÀWXF@º¤ÀbC¨)G-QH\ËË"•ê<αpäÊ£0@¼fˆÛ€5•F"B`L´ËW®Ì?º^(µØQq­ãV"cJÚEíz¸T®–ºª~·t¬v7o/æMÅ¢ôÂ¥Rã¦ò=õ¹ÇL®nŠí*[W/ÚïÛXµel>œ‡Ñ]à-ç§ôtÚÇåV˳xEç²RÿU=UA·Í"®Ö•Ü+t‹Ï¹â.Õ±®’ïâ9§˜'qä§ÒÐæú™'‘©¨lyÜn"!`¬MÒ£vðŽ§’àÏ{Däô‰q> *q„CæO²6”ÊO8¬¾pyë(Bd5‚+\æÝèÄ‹‘·,h~ÞÏ/HS;‰wUD %1YõŽh„}OYSóó%ݳGÝ*tÕÏb=Zìü:òy5*×’øîÖüØ9Èr]l±x£Qünع¼,‹K×îšë5ò£†ÚíÊOµƒåé"nXkĉ‚ Þ*©çаT‡ÅèZ@ÒÜ"ž“Q/}ß8]¬n3ç-Ó„A¶:17ç° E ¢Ævï£x8ùuÖ#ÐÏ%ïR73¤úê cœé{ÐæÜžtØÄÌO.ôé­so­Ø™ÄÑo¤˜øRIòOb9 I/ ËâµW㉠m_îØ«†{H¢hU¥# •A ¤y Ë E”IdSBòM,`uäH¼‰Oˆ (óMÔ¡\ ]œ·Æ`3Pšé ¼q4pƒI!1!/Ýü Ÿœ9,呸ùÅœ‹ôH§ÇÌßù¸òä$_rþTÌ_•2F&ÉrN+ªBé f€"-çbqEþƒ6ä-54/7r¶£’«Ä Éͬk:&ÎÊr’㦷|zÏf^q­b ûn޲…¼HÞI!&q·†é»‚±…Å|æ°#=8ú^ïtSnÑÆ«’ÅùÙç†scÅÏ#{ÛÀ»æUñŠ}á¢ÂâœX×¼`²KâmÉÌ\¾¨Qñû,Qˆ2%À²â ÁqD'?Ï¥#8 ô.f§0ˆÐªµC”uĸª%&(qµ<¤wb•¿Îóý#>‹I Ga±XY§¼#Ps”(W $RÜaÐx»WãÚecS;6H¥øêt|Ñ=×Ïð.|LéuZJ蟥Q|ñg¼PÖä,©"£B‚tù'u£QðJ&Å_£à»®‘9E%ëmõ?Õ»®LÖÍÞ|Éà G9Ì»X×rp¤øQ±Œ®€mnί¥{ 9C*9‹ö¹®ÅA"ªÌá\‹§K¯^³´Ô©B攩‘7ô]ðÛhÔ”Õ¿añ&³1ævc±Ü¡~ŠoQ¾Ý•F­âGû>5ÔJW@›zrĈUÁ¨°Y\ÆJ©©E$ö¸""™]“±P‘œbÌE!«I²B­3g ˆ1¬9³`¼µ¼L¹r˜±Ê²HC/Ì—ü Ì\»‘?%­6i®7¬>W¼b¤•s«á@]0‡–>e}öÖ*UÃRÐÔUù1þéhStü%g«±†Ð e•nþN6ÜÕh<Ó0‚¢À¥†|®ÊÞ6º¹Êhî¥‘ë± …¥‡-–Ô½ÎÜzên³âÞ»ö…ÄuºJ ÖçÅžûÌ,è‹Þx5Œ¤•ò§a®—cª0ˆ4ŽtcE“¶åXeý2ÊpÖVE3¹>ìZg‡ÖzW÷ýÏè©E¡ap«#Û ­H¢`”—¢,lµ ¨Ãá¤È3ä±#”Á,J'€þË7Ç ùË0âÈâ20Æ™Ž`ñ%r‘ÌÀðÓá&ñlÆ—H'KÆ”äÇÑuc\t “Jqìn¡5\u /hiÒÈAÒ-JZuŠM­,©½n~°á¼Yç²ÂP“ïû®`Œ®ádl,…Láh±àø†ý“kn³@¬*ýˆ_ºRµ æT·¡u%% dªÒ5 ¤Éy­•dž© E«ó…•pïêzJºuÍ Fÿ*¹-©ÁbŽSÒ©™ÆÌZyNc¹QY©§_yº6Ë%³þm ýÚŒa$qÁób"Ó‚š€kgl1æ1†9¿€„Á1…,9 ·GކA‚——`óÍ´s¾3»Ä÷–àÔT‡I^G›‘RÒ¡!Ä ‚ •äÑ»Ðã8*Ìc3(éTyñ¨‡¨YÑQ¯ºþòGžoؼˆ’dJ϶À•cUõÅõuäç§„Æób£x_wóÄÆœi›‹jÅϼñ»9+Ú°Ëkåþ¼+ lÄb–›k]®Wr= ¼ÃÆ,kV˜Îß=]ãb)¤˜u»Ø¨”Å)#w]}}G«VH×HU÷éü–ØÈ’üÄ¢eÝâ²Z´YתPn¦( õºßÈHC3œÙ çY†õ” Øc2û¶C‘pÖAm¶Pâ­$ˆÀøé˜«s\;ã@¾:Dªc„xp"Ê}pY¨MâÃ$÷éÁˆÅÞŠYk thäÑÈç0š¬b.HGÚq%4Á"€•tÊ~ï_Ÿö¥¿ÎÖó¥ö¡˜kÁq‘f…š¦ÄFWq¤mëàB¼t '÷¬…±ëêu ýÏ_Ü|ëR×ö3(c&G|ÁhÚ¤³ÙßÒë°âtÕtÃÒËæl%Mñ<Î=ÃÎåÊΜ6îʰ2Ƥ©PèŽ]—½%·òÈê™{±âQ^±®\Ç:TØGX# Ù+øºù£SÖg·Ü®ÁŽM¹swK r†4kª*â8zsòó> )HqÉM(âÜråÒ¨4•›þ4ãï{€BÐÎÑ8c Q!ŒB–Ø’† ±C›©ˆTE¦·œXp¹áÄñ|*Vj"¡Š˜EÈ•:Ž"Xº©Yå¤!ï‘|²qDO}Sø\fÀÖóÂs¶F-u)ügÏ}o— hÇYªª^—«…ºéV®oϱml¥F{p7ïj·”Å–Ýœoó—»RÆubiV™%ºê¸ö])çuáÒͯ޵ ` ѵÚ4êžbk¥;çîE¥Éi w ˆ†aÖµ±©úÑmØC—ì6Œ$¶Ägn@i›Ò<€ hpñ‰ ,*¨è–ꙓ¯º ø—'ôº]óó¾/ÃaLˆ¦Š2—rýNŒqÒ&çð” ¶Tßò›$• ]]ÈjpÐLá)?’²#ÑLÜÂ!¹Ž Åê0(Â!ÇCÈ q¹6PÅc&-8ŒIZ?úØ^òhÚ4^•‚ïÍwÞënÕÝ€ ?CÞÉ‚“Uç±ÝÏÌuh¿ƒs®«o(+umÞw*ã…îb~E˱-õ¸ZÁ³hµlÙÓG !*/qŒ’Ç!ìp‚È‹)Ö™NQ;@RÛ‹d„€p[*à¼MHpÄóHUô58‚ ”Ž0v$õ¡ qH ßbè!¼@ÜJu„BÄeŸ¼A&½²`F ‹#v&8²Þóæ)ÈE=l§ÇrA”+ÑŽÂŒ‹÷Q7ëÚ¿f© ¹ï;J™ÃflEù/p(ÛÚ¥66*¿§Q/©~”Î7ŠþŠžàE‡Ü`ëB]ë <ç°aÃnU›®êi÷7˲†Ã‚.ã–Ëcç`µoݾ;V׫ç9ÞøÙ…lCrT㺠Ýä®®øùdXLh;+¿Æ"c£¤Ùd¡çaªU$HH˜›0ñd“z‚hI…Kb B£„ÿHq]LºÉ…bxˆˆyµø()1,³ŸN_²Â_štõ{\yœÉÿùÆãf#ß•§åÛÍ3å<ÏߦÞ!Ï©q(?÷¸Õ^^þ göu›óVyáL•ô=§=§£²S^¾ç´¨8n_óP~üÝc]÷q«|QʹîãÅIÝëǽü^íöõQ»üA/?átÑ”?hߎýsÈ¿Çe ¾õ-÷võ…y•çó-ûɘ«Ö–÷ìŸëÕÄã•ò‡¼r÷9»¸}´oWì‹eÉ}‘O;“ó÷¸††PS¬ç*f—»2@ŒæPFXÆ”b1ÌD´#(ˆ£#bš,‚¤GG’ZEF:Á˜‰6 @K *Ò€‹ÁU&=¬„c¹FèâÌg5y·ÊK,|RíûñZ¿òUÞlùº>Qe‡^ âãMžùt˜ö?Ùô‰r1§ýOMÿŸT¶û—×WødPùúÎ~2 }ýà8ß°•›xMÄ{»ÿø¡Þûvqaä·=¬£ïåz!G‘h(™š ˜ÒÕÀp ¢\é  ýyŸ%ŽŸá×ðà(Ÿêˆ¶HÎü£Oº¥‰¼@ïÊ>5o‚’6iÇ^ –Í# ÏVc¢¥iÝÅ®B!®í%G0 X±ÿR<"ä¦GúbGàÖžsÌ&t„Ìr£‹+1ÀK#¨¯…Í@?¦óyùó¹òˆò¬l~Ÿ|jãã}Žß¶ße|¼ÿAC_v\ÕÈë™Úî×f;1øêºÞøFõLJ:´#¨Ïü#\Ì?zsßçM|7§oÉØŽ¥£7€œhN‹ÈÄ:à\Ý‹£Õ€!AZ¸ Ü̇ % ra—<X_bÖ³DÿX$@+1]ŽEª/¢A+O¼ϋɴødž•ý 3‡†—GwG4UÁQØ©Sãy‰ñÊÁ@ÚbOóf7sÃ_ñ$+Ÿêš¿Núû¥<úÿ·÷-½qYº¤Ê=hÍØ²@µ†‹»ÐH$‚„¶äš¦0«ÌÎK-T?`vÂíÎÀ¦²ƒ³™•:'®1D1³”® xE+`Ôê0Z=À,4ƒ¸ÙFéAý¢{ND>"_õàC–KyXÌÊŒŒWFÆWç'"þxµÕ¡©™á&.ä/ãöDp²²UÖoùµPúòE³ùŠ&Áe´D%!]ŽXsA]²p¨¨JmRT€ EKFá9ñ,á(·4|ÕúuüêÉcéùñ"ß8“!E‰Læ a u¤O"«Í=CÇØ—^W´ËëBà›4ÑÈ6{÷h˜é5ò£oJûñ˧p•G¤Ëká$ GÞ’–MÚÑ-/Hz0‘"]ÅrÖD[& ’Á'ðWÉc¢õ§¼cjˆQ{"*ëH8«›PÃQ’ùj—sW)E~~•ä8ï˰8ÿè?î'úÒW\êgù>²¤•¤“TÉK¹(¥Ì*˜—K/ô¬BYYyùêgP[Z*US#Ÿ4fM”¥"„Ìò–’š½Îe¶T,aéo²‡­j³w–†¹­³ªö?âWZÀŽp±+—Ruz ·—ŒØÌó$hêÝæpbSŸ®é‘Tä0x"|Š€àUö¹çkkUÊÏñ+’Ô÷ô4sQ0KHª†¢¬öNR¢ò×x‡Ù@tJó'¨¸%ï? £¾è…$/×ý‘ýoƒUã¨Ðw«:_gù(KU?®U Œ®Xýk¼T<Íã(Í ­T¥~TDj)°Gi­óÑFó£×)»ÎZÉ@ÚRU]–^OhëøÑi˜S Òýø¾Éô#~í¤Ç=ªV·ÇÙÚhž„ü6È8È‚:U[-„ß”—tv8wA´c¾¬±pƒX÷ò“$’­$XmoxEñ ,YcÌ÷5ީӉЋã)ÐŽÓ÷sK€»Pñ~4ð öºá޹_&ÚÔIVùfôŸÒÏýÒRmFÕ Ìª“O«ù‘™ÝÑâ(ÿ¥¥¥×á¨ÔJKUŦÙ/e½ãT±¾w¯ ]iíJJq&„íBOõ™^5ŽKî æ»B Ñpçºâ‹?ýa®“ƒàpiÍ@áèš³ÆÊˆÐ܉U§â¨l¹š7ÂŃȢ®%;NQ¬{H€™›_ßN?à;¯ ÿÝ1vo7·ŠfË${³Ÿ•¸ShªåœJ ^aPN»4XB‚¤¬ƒš5{ÃQ ¨ÅQø<ªršRE“ªZiéuݳ׷Ù;H™\‡ã°¨}3—,M¬õ£Ç+-½Â` Â¥O>×#¯t‘ž$ —¶ë £'™!Àgâ' “@ž´>„³öÂ,Ô՜̕šY¢~¨IÛÓéñ ´íCcÅ\%¢÷ó:\92Ç©8°'N)Ïó£Ç¹õ½ ºvžRáÄü‰­³3˜¬`";CNü©OöÏ4ôu$Ù½¥ÊcÇÊ÷–J5ËÇ,¦3+Ÿ¯uE+™ÚY–üu.õOÌÎñ£Ì›Aó£GWŽ€.4ÜÊŒ"Kv‰'ý5'BS^À@ó’Éâ(j±:pæm ú”é§°¶fkI¦SJ7p Æò¢çìÀ-/ŽAêVþî‘Á• ô#ŸôJöoDðgàˆÿ›UÐŽìwðmw„¥¼#,t´LûNRÅ~éjªšýéʼ|ˆ0’–-€+I[éõzA rËeGâ«Â„åú>y€<¬v8…Î-âpëoBË‘¬zX6“ñðð<òyD˜R¥Sz“Ÿ(OB\–ƒ{û)¿ ÇÜšeè°šá$gàöe^®{ô»’Q¿x›ôÖûà10Ÿ4ŽªÖSýã•–ËQ°»i1øDó£ ò)¨ûCÒfÏ9—Âá\©:jyn¥ßX D¨#w¾Ñ Q,“QÔo~³&\×¢ãq$\¹`R`c8*å•'/…X¢Z¥Ž9?»j[8ó)·órÝÿ»ocƒLìí9Ó4¡siC)¡#Ù¨¾³Ï/µúöÃ]Ÿý_ÁœÙñvCÚØì 麠1iùœcOÇN®å2Ûí¹æX7Ußç„=w”L°¸)AÀc®‰#œ´gzÖ!V•k6¸ÄšÚqáb÷D"æ¾bÜëþsA‘ï ‹’Òêô|Xþh¿¡†Ž‹vVN†dÐcÞo·wQjÓÌ5ÕA@\’8/h'ÔØÒ³üÂ¥O:„·……Ü â?û Þ¤ÁHɾYƺ†æ á‹hØéx²×w„‡S “1×ÁÍ<ŽzNØÃŸéæÃî¸î×í}ùeˆ L}ý%ÎåŠçÍm‡½0µcÂ9^†½(ênáIa/·º[ÛÛ]<Ý‚c[êtk{k[…b  Ç­ô[“yÖ¯ulÌ 2€¬!=U1êtÃ2 5a]¿®®§‚ø~Oà“E½ Âggž}ÝÛùæ›Þ×_ãâ*_FßD_AÈW_ÇŸ~}i´ 4Løe/üªêH±!‡/¿Ö2p¡þC=µ÷ËxÁTL‚ ñUÚî… XqõDÝä!›?èº~AÞf盛ŸTE†ƒÊ2Ðö°Õ(ºˆmÌi¿T¹p„ŒC‰ƒ@g§a’Þ jÚ®~ñ›Æ<»Ý$ëÐ Ã$@½½-ò¿Z7`¬ãR9PZ‘̆6¹¡N0"¡–ë¶J½^IdT'"¨Ÿz×!_QÖ=^;ºÓ}ã:ö²~ËIAËIOXÆLÏ_8Õr{ÿå[" ¢¡YϤ‘%ÿNÍ%jQ™áyö—1§bížXó7Ñk< R8-ØåÈC{y"æ1úHâ«Ä'±)t~pb”ÓB«’’ãBe¡uB©ëy8›Ÿo-œX€³y8ž˜‚ }R¤ÖüBv£u®çU*Mk>N{"9™O0Š.\¥8'JþT¼>±`†/`Ìô:¦ù…¸À¸•Õ\ÈJW…guIiZÑ \²ˆ² ï¤óå8%^ eлùOK}[o¹’¬5Ìõ7w½¤³«!šxÒÑ5*4ÄÜ Ó_yìl¤sLF¨€¼BJŸwdÔuä5U?ÞÏST0989UÒ¾ãÓÓwø÷í$1¿"ÿ‘q»ÝO?J„Š kR"l¬¶w=ÚÙÙi·wž=C±$¾x´“‘:ÿ“HDül§"Œ–2!Ý uy„vл£½—ÆÅóÛ£ˆ\¸Aæ¢Ý«NOX_î>HÛ=Ç…ŸLnå^oòƒ^«ôÑ­„¼ÜvÆ6Q.mJÚg-‡ÎÍÍݾý—=U½pûBÛl9Ø}ÂMWÝæá­ŒèP­ŠÝ!ñµ£×YHã¦sZ=©×þ—çÞÝ•vO‘c>½`µEðxMJB,ŒîÑàß’KeŽ:ááz`(, Äì$$ñC}>=ždœÿ'ó´ïÅ(«—ÎÐ-á¨_X6 Æâè§JÝ­Oÿ¶[M‘†Óõ6WøiÇßÏq G&ŠbOò˜ÜÎå¸  ‹£°F·±/ïïý¥F6³Ù®¿»k“݇ÏÛñŽWRFeè ˜ØêŒ £ßç€$Ñ×Zwç_ßçGTî?U…¸Öm{ñÊé–¸¾©±þõ-G¸Ó ®ÿ¦/Õ =*âí]íЕ‰«©Ò½>"éagðô¡ÛïYÚ•ºÏ"ÁûÒ¹ qÄI\{2îhI˘@Ÿ¦U¡Ï‹Vîi| 'Z;¥ 5¨ÑÖ Œ@à$À6±Z´?ŽxÄöz³‹£îÕ:Ål)áCm}¢p”ð£=Åôy$MÀ 8Ê]ý7†<ýK%D›µwÝÖ.5 G® BûÒ–œôi¢…šßæ­Ž.®M/È`÷öé äôé½ýFsÍ'âãï{V–Ì1³cŠ« j°»°Ü-Þ­ÔÕñ$sl8“ )qªÍÛ}+s¬á¶ÇdüLˆQŽ^…¹y ò×5áÞe¡M’q†…1”(Xjx*)X⬠‰™ãÁJ«]÷ú<ìUâˆz^?œa]9]!Ì™]?†Ïމ£íœ8gò£í ;A)³cùïÀ^=ÿþûï+ùÑ…6I•|¤pb†Þì„øå³&×Ììø·ÜNž„‹LŒöøÜÕ‡”Í;q!rñš„¼‡¤ ¼,QxK¸‘ k©I¬!8„¼N N9ð\_Ð?OïÝù—uÿÏýt¹ƒX)r=id…ÜsáwÁí¡ƒB-(i)Åå~ÏùÄø˜–¡ó]âäŠÖâ;Ž%éóïÔl÷þQL‰¦óu­œœ‡&»^0Ã8úÛrŸ 8∣%ÙÅúÑj>¼ž%¹mgüh{ ~44/^¢~$G{•@¢£ÝÁ½ÞCÀ‘ϸ§fÈ ç‘^‡²¤´Žݺåw¸ÍL ùØÛàm±»{í,Õ(ºíµ­=Ê ÃqÑ,6ÿ­ÄM¹®ãj¥CÙ?¨ÎbPØQÓYÛçå<DÔí“?Û_vtùL}¸²1#wS&4ÂåƒIȹ½9/½e܉[cJ¨ +J½î |€Z ¯]¶†‘dõ“ûf™}ö³ü#áG£Ï7y¹Žä:‘ÇQTÎl:¹î¹©½ÑûÀ‘* DùvJ\“]öö”ÖKž£[2ÁYÙÒ B'a”ÃnÏc~%Ñ,ðàr9°¤Ü}(-_#•>B>Ç%ã|#7—  8æ@¡§, ¶:×¥+ÎI×ÖêªàÜ>þxËtµlß7 â.HsTòº‚ »r˜ 謅Zå ¦Ó|êÜðF/• ‹NEÔZãîÈÇkH³Œ£­î/?Ù.aÇïVŽþ{G›ìb­Æ8Š )µ3ÔД8z™g< zö*’Ml7žnÀ¥%Xšˆu¢„¨œì&ÃŽ Kg{ƒ«ß׎êõƒŒ€ÍñEq›¶o»§? Q‰ñÑÿÔ)“J;RŒÊF;D ¡u"Mt´_Ɉç;ïÅ¿æÀ<­€KáãfÔ3—ÎâV¼°–͘¹› çGkhRˆivgÅ\Oj/V†?)bôz'ŠfÙÎðùGãº>JuQŒ£ÑüèÉãn7v©¨ÇQ4±Ý{˜³Ö% éöí²¡!¢a<×pDÕ˜X½Õ½šôF \Ô vZË,jË¹ï‚øÊ– .RίYܺ¶È]vÜ¡›„Ø$g»Ð²ÂQ–xÄë¸"ÅígDOc¾TøU ¥{R¸¾“·ß¶q&DÄ=€˜N3tP"Œ9 Êh”n›F–Ç`kÍ#T5kTµÍeÎ>»ü¨ÛýåßUKtQÚõc±Ni´½NÉuQ]V“ð#žãGy¥ ée G ðƒ zˆ›ÓÛž騺²ËJô_Wj˜#2‡ }%CÂÄî€[»¸· í6!×ÚJ|¡À©{HÏ2q„£Hñ÷¸QGI’GLe ¶¸Àû£ 0¨Ð‘0””Û9I—9G`¯Ä\Ȧ‡4ÇMB®ôôÒà¸D±»F)Õˆ¬ïE>÷¥¾WöövM/¡^8»8úüÃÂV­={Æ 8º¾ÊëqTOár]oUØÈÃbHሠïf¾’ŠcÐ>®þö@â*¾R!*£[m+ïH„ìK¶;z Arw l€.¥¢}{ƒ£ h‰1;EO¤CPÀBQà\¡¬7¹9jáÄ>zé:\Ê;ˆAÑo(9ΫËìc•œ#…—Ãâ‚©ã[Ú6(\-åÁ%ÈÔ=\3YRIÊáh¼?ÃO”u·?ý¤V5ÊpÔÖ´ÚþG“•±ôøqzŒÌVs: ~t{ïM-ޏLGa^_ïdP—ë~NœB´Äúö-WJÓL-]K -m^š%9‰7{ÊÉî.w%ð<à†xe/î0š%6uÁn…<±¢‘thrÚ©Ý]•»>e6(†BHêŠu¡€®±áJ$jYº¸CëúÓjM£AéÇSÎ eºÚå÷J†È¨˜T-1ÒÞ0ÓrÝÏ”'rêœ\DÒj;AŽÄ^)×qñ}–°Êú7¥¡hNØ«ƒQäµI†£û±DGÀ Ô¶Œ{vnÆ|Üù4oh˜t\âJÔ—¨oi§Ê/`öçq@R0vË~zVußÓ RdÅ|‰Üº¥­u‰Uœû¿36¯ Y¿GܧAS…ˆÂˆØ¶OÈZˆ>tkŒŠ5Ϻ“äN‚# 7RÞz,æšúŠ)JÂÍ“Z Í/¤È~ptõgá©Î€ ßIÇaà G9ž±½îù~.ûÕ@’¡=@5˜~+c5c0 ‚†€P <ºë¹Ë \ô¨dzèG¤s¥¥îMÔåD ½£ÃÅê ‹H´ÎQӵͅ@(…ˆv±£IÏ"Ï€ A$³<ÐÚ•çu4•‰µ'šË$‚™GB¨‡ñ ¿;Yì À¤1©è‚êM/åLÛë¶>=3®ë?Ë“ÆQ†Icô#ÄQŒjR†’=ao¿F¡NòÐöEOù1 Ÿ ú=nöhšÓ€íDECÕ‘Ú÷ôeä 'Å]~ôÛߣ!íg4Q¿J =äG{,µî1»ï_Ãs/oÂ+pÙwmPÓós±]mT¢Ç,fSµ±—“ ó€qÓI oÁ¼#I"bžßIÙ©ÉÝkšO(ÙÎ2ìvnêßd“~4³v†ííÏ3…•]ÕÑH¹Žï<£èü¨™J†äKø5ïñþ^]”ìÅq‡lé«ÍuiîJA% v†[) õé-?òÛ.‚ ÏSÓðba‘ 5&•1§ïõoWí<ÇœN‰ˆÇ 8 ŠxÆ¢˜®sáÊNK …éAQÎwµ&uâ¿m¡cP<ë²6Ñ«§6w†Û#1ÁIÔIäRä§úˆÍ²\·õùÇUÞÀÑueõþF™“£’¡¡Z®Ë2œÀß»7 G•;Pf„å“ ò½>®žHá÷^ù© RìÕ2 ÔÈ‘%3®Ä°d܇2›&¢ÝH™ï ã+͘ À4Œa”H2Ò/ã(?yÙœ@çYcjž 9ñpûbŸsêRRÐ|¬=óÊ_”’r¼Q£ÑØåWüŽŽ2•-@½‰‚–×vY_ºeÿ ™µ×ñîö§ Ž*¹‘–ëRœ$8Z½^m÷~2™_@;CÙ‚‡ÄK4°Õé…²ÝñÐíT•·ÜØõ@Is$Ô™ ÔqSÂo‚w*M¹2Ǭt‹ÙFf¤TèéøÖžÇM"‹Jbq’LÊ[»–tO™,:Œ\ T+2Ÿ…öï£÷GOÒBO mq î†ñN¸ŽŒ %£hÍ’8Ëü¨ûË? 'ÁQ¦ñ(ꀾ5:Ž^–Ç[+†`oz‘2š ¤F;I-õjNH†P²#4¤ðû)Aà#–e°SAD‰ š5PTÁiGw‰Eãü|¨-8!‰-ûh»€œ<­Ž¶×åiÔ8,"tìøçL/·ª–? ³ó^z^¼ŽÔʵQ|/b@@|?èE:WŸÈÈ3Ž©oÕ-µhlDYü°—•&áÉ*¹=}7PyF:~T¬sX‰^’gfõ’•jçé¥O’T@×§dG3M/Yì6É*Ž_η:~VjX? Êù¤í’ùúW´sØsg×ÎÐýôïFº×u¯ëqXžâ(ìÖù{ó¨ וøÒêu:ŠñI“°—9nv$YŽ +ÂMœzâÀðP©÷8‡«ù¸Ç™-}ÛÝúì㤿‡êSìû5ú‘!>‚EÅÌËeg8…‡Ïâ]*gvg¶pÄ·¶??[g¨ÂQb¯»^9|4‰Ÿê8ý¨¡÷‚f GÝ­öG£M«7&±3$8zÜਡIhÖpôůGöüÀ´3ðöo¾S·>Cƒ£†Š4k8ú÷ç놎´€Û4RÆò#‘cmA ŽŽO?jè'B³†£ŒÕHvøeŠÒ¸ù°«« ?jiÖpT¶3XR­¿wÕÒX¿ ¶Êó¸p$÷“ûWÃ}>'÷‰}ŒÝÀ(Ç=¶rÞâãøoûqf GÝ*E¹®8âcùÑN=? ÓŽFñ£ë‰\·ºSÁL¥›·|PÚÊ2;&¹®¡ŸÍŽ®~\Á7PÀ‹{µ~TÄQ2~4™ŸjãÏðÞÓŒáh«›®_WCãÖ ÊÛëªpš™58jiÆpÔݺq>íìÕëWÍ›¸¾:Ž Õ«‘ëÒ4k8êÞíï=Ú¿®ÚΰUDJPÚà¨!M³…£o»ÿÚþä8ºQã§zøu z?hæpôyåzAáhýªZ?:Šýz/h¶pÄ»0pT¥…«×'Y¿.^è{,ŽV•#_cgxïi¶pô¨KGÍ›À•O®×¯§ZvU…#cÿ£Gï=ÍŽx—¶GÁºþ¯ÆE޾ÏeÐ̇m¨†f G˜Î^Wµ>Ͼ7ã° MDï ŽBG¸Uù*~Õ.Õ쥇2Ž;Ã{O³†#Ú.Ìã«àGmƒŽ‚Õë;•TÅ¢2Ž~ôÞÓLâ(¬ïùÙT#}¬ÛGŒùÑ(¹®áGï=ÍŽ&Ò2šhÈ >³ñû5ô^Ðû…#µ¯åN†¢Ä^w½f¿‰qãG7~Ô¢YÃQ¢àG€£(Ùnb§ÖŸ¡Þ/ÈÛ75„ôþà(JX*E*)ŽêäºïËü('ä5úQCšf GøìŒ ›¬×'¶ëxŒ#\ýñ ë×8¿ÿQCïÍŽ>=SÃ;bºÞVVºH‹u¼ìÏ`jJZ®«_(¿±{7¤iæpÔ>ÓIm# £ÈàG|z~´Ú޹®¡ýÙÃÑýñ8âH&þaÓ¤þf¾ãÚç°õ;æöçÕ糆#ZÂQMEi!~žl?Fð<ј¯ѿ…«å1'^ÑücàPí#[÷ÑÈd5åðBL_[¿‰ê¿“Õ\ûêù&ÈÊúç@ZŠÇ™5±Õ¿/ó¡©ÄŠè‹c• ÞsšU‹Ãìáèü¡Û„E‡ÎbFéÝGÁUÃYÃÑFû£¼&XhØr;DM±sfP3¨)',|¨#„S„Žªm1ÅöQXë—Z/4Ñ©:ƒb‹NÑH“¶œoÖptoÜþGSS0êÆö!ÌEÁèpýUì#áˆä“¼þ4ÎvMº)zu>êĈ۞øÆÖxVNkLeÂ)Ãg GwnœKŸí =<ë¶«²™ Ó£6ÄVä7¢·W2à`ªzM¥`:Ž5-ï™~¨ +“Wq* šwf G¥yåá˜f0ß®îi¬›¿®Þ5#–º°"#ì›áöîÔБ1†RÑT¥”ó$,c*Oy»˜rÖpô¯ísc?éxõ0¨JVm»«2ßíüÅ´ZG!~U}¶‹w¶GDîR+9”ÖtÀqᣤ£·F̎;|£hÚ¾=*J|#í!ÛÕzt £kVŒÔæSÊmt/z[Ý:£­êàíÊÓÃÛ.&¥¤-g Gžë¾‡¯†¯^¾z5ÄÿøgCøª#†b¤„àü<¼Šã¼y5|“ÜH£àMˆõ2ŸN¡„Wo^¾ÐqÞ ½@R'pçÍK¼~õæE|ýJß‚À7˜ä ¤~õâ%ÄÐqâ¤póå+…$oö1ú>„Àß UiUL8êU Âç†üðÖ ,˜/FƒRÞè²!KÈoŽðÿæÇžW&U¥ðyuVOô Û›W¿ÆÜøA½x‰/àMþ»óÃ~ÿ0ÄP 'éãT üá ãª^0Ô½E½Ó!´'Ö m_Õþñ;}õæõþ›W³†£;íÏ?o·=ÏÛ€O™~·Y QÇõõõõÍõõ»w‘667ïÞ…ÏÝÍM<»{×ÝXwïÜqכּw]¼ÞtáOÅp!‚\¼¡nÆ'Œ¤pßÝPG¼³înnº›ëp"ÃaÊPåÃÉÆÆ&„cµîlxê{ã.„ßÕÁw¡Òw66àó»ßAMà! fþ’ l…ßoèö€¡ô÷÷è½{¿ß¸‡ažw¡<Õ ëñ·A¶Ò¦·aÞÀ|Uú{ð‡YßËNs¯øÖU+«¯ø±ðûîú;ðŠàŽ»qNÖ70lBLºW&Îóf¢Ûg3n(Hi×ï`~ßÏ&^c®ê«èŠ+¶Ž%mªòÖ7!¢ ¯SçùlÞÁW½õÖÝ ÈÊUoàÎú&„ÁÙŒáè_®,ž…? økñü9 8œ‡ÿÅÅs‹ç!(!8[İE¸unQEHîÂÕù8@â“ônÍë¿ùVk~>ó'æÔA]¶æ j-¨¸p£¤Rå#ÌëÐøS9Ì«8 ñy÷„Ê Î¬•܋˜/Pšý‚®Q\Ï$ïŒteâ]SUÕuaa!­_’uöððwB%Œïg÷ôƒ¶Ì¥—ùg/Wþ04§>pHŽsɹyw~ntj3àxIU0®rõ½\Mf G•ôía;oµôŸ6=š2Ö£ âéãΈ|¾5bìðú7ö­‘ªú-OVÿ2åK4k@>:@@>NB5WJ;z`ZZ¾·I–´ÎÉ›Â.¨ÎHE¢ûŸÑ Ý¥9Þ¢…eÏöö;»ï¼sû.­Ç÷îœÿ÷#MAëö­íí\ËÛ;Û˜Ðýö.:¢ŠÞÝ!ŽÈåò~ ½Äþ”¶Hà­Í-tÀW(‰[,“¶6»;»è°»C.Eè¸ÃòÁ—Ø å¾‰3ÙÝ&eÂѶiávHIØ¿^Œ[( NŽ}¥´¹µ¹‰‹Eøgscck}Ãccs9¢¶b{c UÏ&r¹¹¼$mn"ÇMv}QkB.7‰ëÍ-ê…ÂlnoâÀ7··È=N eµ<ðoçB"áüqャmav‹&iæë„nàÿ7Ö×ß|ãÆ tq£Ù$Žk7¨÷ B¯QÊ7ILܺmgÄy¡§ÞÄØÂ¯ÔÜÎÎÖ«mJo¡›]üÆwoáwƒßÃza¸ñ¡È —&;;äÝà‹[»Ûˆ§SmÌ †ÍäÝBäæz“TïÍuTÕ͵õæ7×ßXo¾Ñ¼±öƤòoð Gî€6HeSöÁ¯v“"a‡ðú-T±¨6Qnctíp¨l öd¸ÚÂ,´Å¢!†¢X£,|‹rº€|u€Ó0?1ÖE$|tƒ”se ð‚n2D°0ä™p©6·p©1š¶±ôÜܾ)Š/!ˆÙ–°Eï[ ®„i¶óíÈçÙ¡œ(Z’m‘#úCÍ>Æ –ðM[7)I˜-Œ¤mT8‚iP"Q=Û›[¼¥’-´ÂñÛ é`ØÒÆ‚¾ \ÔLà§V[-œæÆ&ª¢M <Êä‚Wï©ûä¼ñÆÆÅÿ6òÙj®¿¹^_Ùþùááz½ÎZ¯›„7_ùóì‰hš:qýŸ˜Bÿ'ñ¢“kaNžè¦Nd§?yò$º>‰O8;t@γ¤y¾Žü¹çãâ@é¸êñ'Û)ÿQGN èø‰c¼ÇðÕ±ãÇ=qìÓG>}ôè‰O=vìØÑ£GŽ!WôCùC¡Ž’rC!°ç‘£GQœ#¨Øàò;NˆGókYÕòhocjjf®I¹æMÄý·ö[­õ5ÒÐ4×oýâ µ¾Y§àÝÀ~ë›k˜ÅÇF"·ñi彟þË?ýãÿù¿Õ«¸9Æú‚ÉÙãÓ/–®–Jå þÿťJ¹\Y,£¿ÅÅ………Òb©¼¸ð* R"´¸XFŽ ¥2ö+•°?>–Èí"½ÀÄ×Jsø7?_š/᜽‚“[\ıËèåM%M¼Ë¥’u-á (í2ù¡,p±ÊÈsq•Re±Ra@òå2.~t\ (W”xÜ ?V–kK•ZµR[®,!ª-U——+µJ¥ZY®˜T®" ù¯á–*ËËË(Ærm¹†~+5üC´²ŒØµ²ŒÒF©£Tñ%/SC×變NUZ” ¿„C¿ŃVÑk8®”2=à#©v\UôU£J.Ï{¾†57D?Økíï¬ýpm­ŠáÒ¼×úÅÎÚÚ°ØD€Y»‡ý~°V¯b‰rùwG"»Hh¬üäGÿüý}ÿïÿâœû2j°¼~ó™Ï•Õ*^¯ƒ{/äP]bàµbFZ^B¯žræÄèí2VAl€ï‘#â'¾„Ó]¦œ‚yji ýj5–#a§ âNä†nPê„YpBèrê"!òº ëWÐKF˜w* „‹av"¬ŽË„Í«¸te£RÆ·4PÊŒ¥0fþRIãÁÐLp^©ˆkÒŠÐFc‘+´  N%ò£¾Ä8=úè€ä9Ëôy1ÔK <"ΘýÊ„ái#/oh5€*ó©åeá_ž_½µ}s{»¾ÛÚ|…Rasgmwsþì7Ï¢¹ûYký•W^}õ¥—^-®olÏ>Dþ iTk?ý§þìÞOþõ/ÿè«_^ÄB霯ž8Ç«PÔ0Á¤  ³pì,UqP\½*/‘Rµ àA€#1ÇegI1$\qÃŒ™D)ÌK|I¦LYŸ”ñ5a+„-ÿEÚzbv" Å"~Ã3–Æì*8œ–¨\fÅÄ’c©"Úw„dr¹„a¿„ý–H€ED­†Ú‰Z7Xvàf5;è®VQeÄy†Å,öHƒN¤AK…ÈC‡d¨.U«2%^³Uòˆ[ÆÅ K0Ç%qRêwy‰:ÖÖ± ¾ÞÚ\®R*.n®·Ž>Jéõ+t·õñGoTO?úèz±º±Qø‘‡È{·wwßý§þé/~ñÞÿòÿàs¶AŒç›žÇLÃZ«E&n¨RBÕ§ÒBPjµ‚2Ñ}Ð è›ÃlÝŒü µ¥L%:á\Ì´˜ƒV %0¶+s€#S¬Ð$(80ËQä!nÃòÉ%Ä{KDKÁ‚§Z!ì†XI1ÄrËTN-SÁ¶„Åá×%ÂËÕ C¤ŽY«©V%,/IËÄE®Ri†bcñReŒ¿D8j‰;WX1–Y=P@Ò( aÅÅBZKÄÚô2 F'rk‘'%ZVs´Ž ʨ‰ø)㪮 ¤!1Z1ACT¥ƒi’L”ãç¬pÑNà¾ÚĹwï5DÕ*:¼rvóÞ½G9D^yfãνêÇ}ôÚo=ú{ë¯žÝØ>ÿ;¿2l&ï"ï ˆüü;ÿò“ýŸ¿÷¯_ýÇ?õèÍwv÷nßÞÍ]äš2U”–Ù=Ћ µ¼´p‹I”žÖò²-åW… !ìMÞ„xÿA ýÊ"Ækwˆ&®Ì[i"«ˆrU­ÐVºR[¢ \‚…—Ù ••ÕÕÚ*"t^Y¹¶RÇ×õÕzíÚ5l&¬^CÎ×Ð56е®))ÐS§OtGÁ (ìÔZÊÄ}‘Ê¥m¦•Ak_¼FÐWCC€‰ÍŽ ¶´D2«P¬žÅ·ø +DùÄY¥ÏN‹D ]Åe¼V%§eYøöhèáP§ÕkøÁWk.ZYÙØEôà‡ß»z…ÑSë‡?ø­ßxý‹W¯œºqøƒ+gþ­G~dã_¯„“Y$½ $ÊQ½¨&µÈzD7‚ Ú»@:˜©@¥&ö á©RFìÜT/RÃû—Dˆ>ÄÄÆbYªg¼¯,1°,Õ«F­4ls!Þ^â(_&6þŠz wíkøq8°:2bøkß+5ÐÀÑÖw°¢!w$°pÕµ—‘’qs³µðÝ+W¿GR"`+ ÿøX! Ób ]–Z%|] °ú´,àX”ÕHÜQÏJ´cŠ\·0NPìËzSh.eœ á)Ê[˜çˆJŽÙ‘¹åÃB¹Ì:ÏXG¢yöæÑÅüåÒå9Ñs&xÞ€ ñ2Žõr©t'ºÜX–¯‚[Œ¬Ï`Xˆþ$ªÍP8`Œ”‰ÒjØU¡l‘ÞÂyÊ2Õo±šÄûKäv:/ò3i%X.X«"î"E)5שS˸¤¯q©NtOjÆQ#«[ˆˆÐ’"¨†‡z·\ô§n<¸òððå—®~ã©æá•+_|ø$EÖ®œ}bm r™æ?ý_üÇòßÿâ[ßùÖÇ~õ÷êÛ»{{·÷ž%­Q@Zyú·Ê®‘"Òº««­ü­\ Zרjè´Š¯ƒVk…ø #i¦È» ŠoÑ Ç×èÅaqÚ~‘3rÇ9Ò.¦“6–è’˜ZQ­²^± é(£Z~ɵeb #çËê’Þõ@Llg`ã¥Fìd¨0s»’N¹%¢5Ê~×*0˜uP=Ƽ×HézXdýed"fÇœMì<"YU#}AC2q(Ó~3„‰E R™¸b0¥VJei‘—¦Ì»*:9¨‡«‘ɵ µH¨M‚ê`©Nf7ì¾ù±‡0U¿ù™/4Vøêç}æ¡+ŸùÓúÏ S=ôðµ‡úµêãùµõËGþð™¼[ˆìomo¯^ù£?úÖwþñ;ßzø£¿úù:ž:±}³r×æÝ‡A…^Õˆ>Ü"ŠÒ›˜/–"̲`GÄÜ8¹¢ï„^#ë…0Ý" ‡ãá_…h[è‚("ØÉ’}éX:°!:0²À™Rô¢šjjû/_ÆÒ£„…êõ2‘0@¨àš¹9tB!ç._Årçe|=Ïd Êt‘ŒÄ”‰ªVáÃD \¬&w•uk-W—pÏÑ’$ҧͧ*Án…ÙÇ5 ?Ôlcëb™B«l@¥ÂÕ-ÜúÓþfÌஃ*íG¤Š´çµ)KUž+bô*M“÷·ã®û±oh7.A ëx´¿u‹Ð4Êoîá‰7^ûúC#ûµå'>ùk7zè×?öëÈåŸ, »Ï=ôßÿÆß}ì7¯ »¹#ÿqØLÞ-Dvoíîl¿ö™ßþƒ?ùãßúÏýèï]Ý`Ó.ávó.S¦0³)²€Ô#Ü{…ÝW¨eñ µKÊ ”ý‰µAœ+La{¥ºD  - €_WHìQJ䇇ñ°ìæ*eÜc\Qzz*ÑŠÓžÚE:BÁ;vÉ0I…·»Ñç$àŲ5Ò†ùrII½\áqh/2vá~åR¥TæÝÉ%*©ºIì¶"ÆIMÄ#<Ï—"h‘kšô·À4P(WD÷Á¦ì…§h^2ºõ•Î…å¥úÞžá¶QÿÂw¿÷Ê÷®Î}jq}ýõx‰Ðgyâյ׿på{_øÂ¿ùÜÔ¯¬mÏùwÃfòn!rÏ ¼öÒñG>öÑÿôÑþþ+Íí]†‘%ÆÔUÄÔË-bšcÉ€\jä¸Ô¢æ7òiQ(`Öoa»„Þ\~´h\‚qÍ\ª48YÄwx”¥µDCò0¬r¾µ{571­^[ýO†íI4ë%¦_× r]s$àŽa2€Qá}J¬_^⺠mÃÅ(—2¬g•!–rêB¥ÌGõJ\+ ¼U)»âÞ,±~K~r؇uT„JÅk*ÚH SÉøÓ/‰êHÊÒ2ŒY¢˜Yb8)+E¢‹üê{ûÛxæÖÆêò_ýéŸ~þ3Ÿ|ôñ«¯¯¯×_û«/~ñsŸýä#O\¹V¯¯,¢»Ïö÷™š[Y[ƒiŒïï"ók½>ÿ…'~õ¿<òD©¾qss‹û6PC†ô¬…22ÀZet]Â7-ÔÄË#’$¨6q¯-v!ŽÌ—\e&ZDw"×È—*q4øÔ"R_ânäzkè›,-d‘,W9›¸ÓwÔÖj«+¸¿–j¸Sg…¾àpb]œÈf¸`Þ*|–i®é&´s:€PYªñq2õÌ{¸Ãw‡¿†ýð˜ ÕaDZ+à1HW4)- {Œk0Øý¯0 ‰äÇì-â°,KÉz£øµLaI<—VËJaÔƒt¥­ÖÞÜy°¿Kéæë+óçûäÔ׫7vvw6__¹úÒï~òñ¿^üj[ׯ-Ï¡»©¯/Ô‘Ê~yôçhÝÙÝ­”K—/žægŸ977D3ÑÒ_.moß~Ðêž°˜€·=HÒc:lÓ}¤ho»Ì¦n½:wþì7Ξ=7Gì²ÒÜùçž{é¥ %b•ç gŸ;ûÍó%Ôîžý™¾ïï–óù™|~:ŸCŒ¦ÉŸ°ÿ §/}‰¢n338%ƒ_äó¨ngH§É¡Eœ¦‰O‹ §I)N —<)ÍéiXž|þ Äuzšú¢ 1w:—£)Lct—;=Ó©Ü©SOžÊf³O¢?tÄ wòIôË=‰ˆÅÍM£"|Èšfÿ8ëÓÔQN#épš…ÂåÂÿÓÈ×H>G«&wýc‡}V|âç8ÍR9E C D.Ÿ×§xA‰+ÐSYz5•šÊNÑ$ìÄ®(Ñpzõ tsÙS¬ð%qÁ%šF¤Ð9Â'yúÒr¹Ïã'<ˆ¼}ùÉa7N)1-Œ¾¢õ^)?ìZLil©Øzëã#‘ƒE‘0¥îé°Ga||†Ãv#P*[o¾9,ϤI©?„ ²;ú¹WÊ¥I©?„ ²ýñ‘Ÿ ÿ~ ‘”úE"[£o‹´Ê_J!GÉlÓa—Ò?*yˆü[i:}¹q”¬÷fØ¥ô cÑ£õ~ ‘xJRCÅâ°Kéa[dô·wøàâ“)Dâ(…Hg„ rsô¥ÈÞ|j®ÇR ‘ÎAäÖ'F"wˆd‘ vk{rŠ…³‡ 3ÖèŽÀfê}Dq\e3HØ$ZCFXå¶Pl+ɨÇ.´QõX#õiI!¦¦’„Ò Ù";£‘Êy"ê…»¾à%gà˜Zx…q/„»$œÌ1aiD´Bé‘™餄fÊà©ÖT$Dô " &‚HÂzCRä­Ñ:Ü¿8eƒHl}E^Újµ¦Õ5a ý„HDä~@¤íš ÝIšB!2£ëï_ÌZ ¢èQ††BѪËÈ£Ve L& íQ•w#NQQµ2gD~¡;0o¯•”!S@ˆÀÀ¤P´B³”Ö LþÓŸÌ-jh)”ú´w`Ë< #_fL(¢ukô!r_™£•QYJÊpÝ4P˜(RÑÒÙ &©qd r{LTk®¯:‘² KàHµè²™ÈÀZÑ áˆF$ÂÒ8ž›¬‰ë¾ḭ̈ÔÝä#ño ¿"ÁÞ^ A„ÙMw•9Õ,EÆàã .duˆ@=Ô ÿø§ïZ=!Žq¯CóùÒ…reoÞŒŽ`ΦYë&f¬Ñff´dê"±dGÂàED"Š–|È€ Db„”öÌu½>óc!El¹ƒè½÷l\N‚èÝïÚ+¯ICßþ¶£r ¢®‘)ÕË‚QiÕK+¼{s{ón„äë‰HTì ÏÌÔÊ*tä¸È¸‘!E:}$ˆ†H„Ämjý8§ÇÂyðü'ÂûêÃg r[ð1 Ù,CÈ»ïf-ÚŽBðñío‡­z`S‘©¯–JNG™¿_¿gjYM™€ýªÍÜÌŒ%ñ™çËåÕUâ3“áÇ"¼a ¨ÎX«Ò›ÀGRd v@ùðù#ªA5uû=› Þây—ªZMXaXv0|´B IšjúvìP « ô{1o{Ap~¯¾WÇaïDù˜©—f¬ì¯¾K $ó¥æW/”kµr¾‘ŸY…Âd\!¢wúî ŒÐKGSß×(!2£ë:D¾F¥ˆ"#!U‹Àá#¤1•­fY:vilt\%×¥¼ÉçApy•!äå¬ãíͬ®6VKs3y ¾`NvåëÏ—kÕ™ç+‹µÚÄAƒâ6ƒÆž„H³-T(8“Ñõs'(DÜNÿÚÿ °árA$û]`±ó D¸ÀøhQ€8앹é I`¦L\Vño ƒº6@Ì!€ìÍ¬½9{—¯¯ægòs—­zZ~æKL‹bÔBÍ\*×ê&#c ‘ÂݽT¯œÌŽ!ÂÀ’ vBÙ},¸9â s[ç§Áø¡¿E‘Q¸ûÝ“!#Ê]@dˆ Ñk+,½‘Ÿ¹€ ÕzýÐïÔ¹gç÷8Bê{¥© ÓSçp´™9…ùYN3 ‚Œ™<ÕÇ`)òåBçj~ µq‡HQ@°g¡ˆ4Y#æ˜;?¶îŽyá„P´$D)rB„1#éÐy÷Çj"Y )"b“"ͺ»?q(Íá¤^*•u»»¼¼w®Ž;|÷öææ_슉6óòÌõºa¢×‰ä 4c1ëDjõÚjþBCUŠ‘1†]g¨¸­@ÄfNÆŒ#5EµcEkô' >ó˜„U´þ)Zw¨¹®[ËÙCˆè¡šV$DÌ\·JØT¯c€\¸`#SÈVŸÇïr~.;…Ĉ% öv®[­™™<ƒ‰Ã Ïc%¯‘¯ÔV±<icèp„¨xH‰FUëiƒ)ÒñÌ…‚Èчȃ¿þ$ƒ—_ >4)ÂZUˆ¼ûîßýÂA4DȸxÓ‰l®c R> !¤<ÓÐÖùHÍš»·7??55õr[#@L¨9À¤_áÅå‡é—/c;A¤^Cw50rJ s•(CUd¶¯ Œ ‘¤Š–ör÷‰m‘_6“w ‘Ö¹)£Ó÷Ž«ÓÛ뀂ÀÁ=½ eòTÀ2Ñ#Ò®ØK%"AJ:‚Hé‚nskäå¹ìË÷÷²sÙÈ (Î~߯Œ€ˆ¹®´‰¼ÊHÈ4êXáª3]¯‘d£ ‰ 2´©)n[$*WPëÍ’¾œä+ǃNßs'´Ñõf@Õ,ÛDèàÇZÃïÍ’Þ¶µ°ÞåõL„ªZÊ`‡M#˜{ùr–¼¾ù©ù)×dC"ÄÌzFŽ¿7õä‘jP™"aR¿†±Â|c&Ã;à9D.aH€`#€¾†¢åœ©e‡V´Æ"Ï5F×)@¬ 8•,›’Ê!Ò™„žy¡Tª7.Ôèøº9™1ÈÎ!92…_ÞËÈ( Ú_œ¯GNQi°îà2DfÄ{^RÕîÂ\ýóuɾ؈Ü$sHjØ !8 ¨=3 ŽN}s¾„é±]?8w¼iŒ&BÌÚ!]¾ª©ÍÇŠ/#PS^o cÝÆÉÁüËÙ=d’ìÍeeùm›µeËÇOâ"bD¡' [Ÿ€Ïv²0·³o˜÷"¦¢…Ñq›B„ª[º±Éw§‰yìO@ýNß EËÂr ±#ë":¸õÄóù elŽàY$öÔ§ææöîÏï•\#ôQ„Ë5;…N!ÂK ½½C» sµOxú‘= "ÓàcßæX(Z6ˆ8ù§N­‘gƒ-Ôe!DÕ¬XrÐÈ_(½P/å-}³,öìý¹öæÚ+d”W-î6@³IP› s£¸ΪCÖ£Åì<"1Š–«vÕnűP´ZÏ|ÊKH„\¿!áæ)–Oú,ö·,sçÙÀ­æävŒ.̵ªdðEŠw;]O:ck<æh )r?ásm't’ÚìÏæAŰ*ª‘–v°0·“o˜÷"Ðà Ôþ딕9C‡¼Ó·ýåäÍø ²prÒ%WûÙ7äÝÆ¶×.Ì D’oêHÓ ¢j+Zý¡C0Eh’‘ëÊ{CöÜ­{üD”©âZõC5þæ "m×PT+dTzþp,l‘gs™ë¸*‰&}ã¡ëŠW»©Æ‡ï5ˆÓÌ,I…b7¯×öŠuG$EîŽDžy¬×»1ê•~]Ôœ¶É‚“©m9·S–Îâ'D’I‘†å*)[dä­ƒ¿V!’@j8Ü]q¯7„·{¿ñ†Ã¥s´$Ø[¾‘ÐqÜ!ÒLôµäŒ;=> s§Å* y©Î=¦ñ: «? i#¥ëºƒ„¤š¯ã W§¹ßi™¾Y¸é&¢ôzùpšÊSLsÿiæ~Zœ)+Dx•Áúõ¨^ËÚu‡ÉOO³Š#5ŽÃWªD<"õ#U÷;LÅI‰TŽ)D.´Uuw¸ßU+î.‚Èôh}åwÛ°EúhûLc ‘B÷5A±:L‘v ë~SÂlÝD4¦i÷û"m²E>81òi={Ä€H’N «yݰûYœ¡“#Vâ¥<æ<ÉD вŠ?¦ s‹îZ1*ÁîÎߟ£kI‘GG"çD˜Å5 ¬6nIwa@ƒ€§Å-½ÊIûí4´ž‰ût„ç~Âå4ÌÇV~™ËÃLgr"IÍ„›ü`ÁáñtÞL;F,Ìí߈_ß‘¹n¼ãÝ›ï[T¦COÔ\ƒ/æ¶Î“•vØç—Ò ¿Tö…¹I¸¸ >ï;Dñ ùÖc E¾üXø@Pÿël$ɾ0wÔ!fdvJö!ëuõWÖ£o®·žùD ‘8²/Ì5¾| NÆD_^ ¢¬Q#(³‡ûD½€ˆÂ:BÈ7TÇÁyæ±pß‘YL=xj*ìºÍj~ä(T§@@!9Jh(–eSÚbã ë0›çËÛSéõ@ÑR!¢Nœo)²?úRäàÙ#òA÷1i¬Û=FD*³ò^MxÖr•8iGšQ¡ÛÍF]˜+YËúÍBeù‡‘0t@DYÂkEX¯©RŸG¤Èþ§F"­‹Yú ûô9ûË}? ’´ AD_˜k,©U–T…ÊÞD‰C|ô$}’" EŠ|p| ò$´ETÝŠBd–iJÌKÅͬêG¦*h³"¨r?+£Ï ] 8ºr'(oZqe*á¬/©"i_˜§h±®¹m!¥Ô½9´J‘:”"cð!·Ö…“йn“"³D˜5+üfÁ`N«†ÒÐ3”2#=¿ÐH“ãÄHeV}†P+F ½`,Ì…J‘j‹‹@¡C ¢E×ïFÌ\·Ù"ï¹þ•#‡1RDðŸhò)"øLBÄL^èR²3oþg­‘fe!fIsL™©€èÊÅ’ìÃê[yC=Q´ö™ŠÎ¤HS—"wÆÀyæS‰¤ˆhÖ€ˆZ1D„iý¨!gÃhˆ˜©èÒG44NÓN$ DŠì9w¬ ˆR$¢‘Ùv-`ð(J_ì@áå3€Äâ)…ˆƒâm‘1„$®‡HµðN¡Pg@%5ã¤u˜Ñu;æ`Äðq˜ë\™OGã ‘Œ‹<ƒ­s'ÒÑõ8Oˆ DŠŒÁdøó'ÂSˆDS«UdTP. Ðe8ÍÇßOø,þ[ÒFZø\0\à©ëЉ—"{£o®œ#£ëûtôpø“j½¤ÖXÒ@¤È8Lc|þ(xбT(º§a3³×tÐë‡ "ϰ-’d9œ:ë › ûBÅaÀU®aƒÂ€HDVèàÐLbÇäÑuÿ ?ù@øÍ » ½¦b±'ÏÔsÕ¼èDø4Æ6 Ò%¥ñz‘>”kØ 0 ‚m±`Ä\ Ÿál ¾â§}°/Ž€¹©LÝ«Ž0™—'šÖ8B¤B$)Dž9 ¢5à*ƒf`Ón4õòc2ÒŸÇ·îèÔ[@3Ìè@&õ "í6=µÍ|•"…âÍa£B‡ÈeèPY}a„Îø&Dä÷›@Hç&"å4dê"‘LÝ6ÇÛ"´“ ñ"Åâú°Q¡CäÜqÕЈ‚ˆM}Ò#êòF¸;h Ò“ÔÚƒˆœÌï/D† "PŠX-hSÄ*ZÀ¾E‘–2a’{…Dlû:Dnï`Dç'ùDs—%FèÈ(±ÑzrÝDhüƒÈ…)UÑÒŒp»Âôcd ÑĈ`ÓÞ0kß–ùPÉ-EâÖ Æ+Zí¬: µ:ZÞNeH‹}FÞOˆx(E^l{cëà ¦BÅaL(BŠèËÕ£·wÐ÷ £×õZ#X³MF"üY¤éRö˜<„Èó}˜éëϸxoÈc†¸íl Ø—é:Øß²D[)å“ êžy ÃÞ’‡yVŒ®ï?xpÐý#Ž#EB$ùö¶ÜÛ¢„&wZÄŽžƒÖ‡¢æ íUŠ´# ûKBDÛÞ!% Å)Z6 E†q$j~¯]½ CMkßr·Û‹6¥IP<…€H×°·T,ø7.Ò%D¤ÚlÚÉf,fâ#˜Îgθòëˆú9ºÞc=&RŠ@ŠV×°·äá¸È¥l—Rtäf¬~ ¢ÇE°8GÁàLÂpI©¯P†d¸Y­Ž„aïË5lPh9à£ëûÝC$L!2Bäí­Â°A¡AD_»Î'ž(M‰¡îc†"Ž1Zh¦ ƒ(wÚœH½±%¬æ VªÎ„gTÝ ú©^`œ®f‘,cÐ×¾ärׂ¸·¸ë«mÝñµ¶#C˲_×J_¾ r€éÓ³§ñMŠ´Zs9Ë4F 7‰;Àõæ|ÎÍ¡Úâƒ!÷PISñ1 ¦Â6&äP ¶‡UrœÑ¤(_;ŠBˆ Ecá¸á.غ$>EKA„-%£ƒT(Ó+¡Ä¡ $©!O¦UH!ÒDPxÏŸÆ»ˆ@EË€ˆ˜ p%=u2¤:T/GìÕª„á÷ÐÈ7DÚR­ýd¦nÉϧò"óÙ"Šõ­1¾T›BD\gdšDdŒLEƒˆ’8ˆpGÕQºÄä'3uK~>•‡yaÊ&EdKo“"!—Â!""S*ij—*EQÆx> D¸ €&#?™©[òó©<„È¥œÍ\§”H G}Vb(ic]`ŒK1[lA”)ŽRÃRÌuj~ŸÆ¸éÇprFƃom™ëÃfœ~ŸOåaÖ¥Ü1.Å=™¸ís`{äìÅ=sFë¾2ã%(¼üd¦nÉϧòOŠÌK)²ÏçhE2ÑHÏQì¬ðSáûWξׅŸñp½H)—ÎÑŠ£ Ò-‹÷"ꨟñpÊ\·P&€:`&_!Å|*Ô¥€È~Dœ•çCµö›Ñû”ùé1S|CǬ\97 {®Ô²ýOåûôÏI*E2øŒ E*Zm/BŠ[ƒ &*ôv0S´ø)DBäÂS"¤qR·Q»ø´U·ÊZ bÂÞw bˆÈMP, s=x—BDÙ$H¿¨ €÷@d›XVôX =x!ɨ÷R$„!4 ¢J‘Þ>ž°¥=•)ƆJÚ"/‡“áÕ¹†¡¸ËèÌmˆƒt3î­¥2"” "ÚêA÷ú0 }˪h%^/å|øñ6‘0×#¥ÈùÏ*£ë¬º  ꜀â„¿Sk\yÙJš¾“"`}·²@OŠ^;i«nÍSFyj†Æ©­ç(Zž*…HD´õ"´ºByê"†F®C?^H2JÒé;ˆ§éVŠXŸÊ3EËCˆœwAD™A˜@ÑÊè‰R´4ûÆsò"ýyªÔ\ˆMŠ˜Sæº2óP_6å6×CóÎcòsz<ŸÊCsK‘8Dö9Ðq°EFü|*¥ÈÉðƒC‡½&?¤zBò“™Æó©<ü¾È‹'ÁnŒÃ®OÉOfϧòp£:.’’üd¦ñ|*­—ŽÛæh4ò“™Æó©<4ן;yh›Æ˜BŸÌ4žOå¡9{$L!C~2Óx>•‡y@äC불]Ìxj‹™:¬¤Œe̼¿õB$!DÎ~ÊÜ$(T¦•ØË'‰‘p…¹Ã…‘¯|*üP…};¡2Å=ì÷¾&^Ó@˜ÉR·}€ˆ{a®'/×Ãq‘¯B—"´ÂÂP›ŽèE‡"fú†¶Å5¡cª®]]Â+¢LëéùªÃˆ…¹~@ÄÃqmIU˜*Z&¹ â^éÁü£xÜO[¦Õëµë!ù´´õ©ü€ˆ‡¾"ûÔJgÂÔ\gä†H¨/°UÏúŠ\}}n,Dz[ã‘ sÕ%†öÎ=´E¾ŽÍõŒNß”Å@Du0v DŠ\„„úz‘ÈeÆ$!âI P,D¬KjÃ0’Å:P´º_˜+¢¯:ÔÖ­‹ÆCˆžð•.!Ò]?p&6­ËY‹"<@N ‹R8 e' "~‘‡Rä+Ÿ6D„P?gƒHBrà¨ÎRŸ¬LË‚:?™©[òó©<„ˆœÆ¸ßùnŒ\X‡ð$C†NÑÍ“°E!œ”“²"›ÍæÂƒ>S¿,•‡ŠÖ3GàWªÔ-LBq—`“ °JFÚ9HŒZ…ª2•Qƒ€é/våø€q:fo”1;eüCˆ ¬[íKÅTÉhp:ž }ùÙø„ôý+ÒÆÇÓ3ÿœtÁ¬À‚ŠÊOý"µícÖòÃÒð»ëðëëàƒÖžBÄ?)r)î«QM·6·šƒÎ‚»•¯I+Ss@Dùè¡CŠH(d¥I†¶3:HæçNY-ˆzlQ¦º¨~ż 7ýÀäü‚øz¡yVÇ’Ž ûé ˜`Ù úQýl< œB$!D.Lõt7FK<õkÒ*H’@Ä"§t’!‡û­³’ýå9'oEðwÊêAtÔÈ$ŸRsåÙEZC^’§ñOѺp²G»1Z!’`‹FyrAD@ÃÉÍÙ¬¢hq‰!QddC€ËrZptxR ž AX&¥_öÕâÉSˆø'EžýDvc”Ì 5#ÉÕ溞m†:$Ybö ²©ÇìMÌuݰÈf‰  §,” ÐÌŸrÄ3§F'ö}îuðS. Ñ’-A’B$!DÎOçhÙH™h`hR£;¥I‘gSˆ$ l6;¨P(…HBˆ< LcØž¾) Ÿü„ˆ‡Kª^<™J‘ɤö!ÒŸùZê¦>BäD‡i³¾2QÑ5S^;ÑîÔ GH±ÔA™’$ Šâ!DÎE,©J0Á0yõ·öI&ÍϼS3Κˤ.*v“å< ‡’ÿ+Ž™dz¯©›Nøh‹ ˆì;v†ïD,Ñ®9*æ2 “q¤Én¤°I!¢‘õCnQ'ôßkUý¼‡Qæ- x”Èù‹aȧ™Èð!]ÑýB Ú‚ˆM…Šƒ1J™'ëç@õ“X ‚ö¼-¼+KÞýÛGë┹I:XÎ(jXÝ>=D6ó|n–ƒñ3a DTHFAD™uœBÄ (ˆ„Rß’Aú¹+ ¶E¼ÛGë¢:GKˆ†Œ"a@\dÜ~) ҡĹ”í×nŒ™ˆ)D†OžBÄ?E+…Ȥ’§ñOŠ(C‡}Ùј¸¨OûJi(”B$)D²ýÚѺ}–Œ"dÈ”B$!D.=Ù¯Ý3Ú!†ÒÓ†O)DBëð¾b$Ô'^ê"0d˜JÈOˆø·ê°uiª_»1ªŠ # ûmL8ù ¥ˆ²aéA/wc„k32´ïS"¥I‘óŸM7 šLò"Þí£%¿»¾ŸBd¢@l¯?lÑîá÷EΧ[ÍM(ù ‘aƒÂ€H1›Bd2ÉOˆxh‹O€M‚H- ¹’F‰vcì.™•Û/y*1£Ü¹²•gúÊ~㋹æ!rñ©þmXê!µ»Õœ3™D޳‰üÜ9Dm 7kÜ)û:ØN*%ÿbî ÉCˆ@[äCZg­’S ’87óÊí⊟"–ûRÄü8n "ª-ÒÓÝ=¤öwcT¶pÛ#†ú~ˆöMÅÝ¬šØ¬ Ÿ¢J‰,»Cè;4ÂB„DôT”PbVú…zEÑÊ´ä(¹:UÄ5Èž§ls7FgD²í‡hsTwG„˜U¶É2Ф*Z³Z¼Ðˆµk¤Z2‰Á„ŠÖ€ÉÃœ[Íu»£‡ÔþnŒbGžYݲ“UÄÞUâ ·÷ÑíkcÖ„÷‰ÚïK-™„p”¹®Mž y¸½ƒ2º®2¾¼ël7F©ÍÝÁÆT¡ÎñmCdV)€KŠô"š F×S[„Œ®ºo»1úHmîÆÈu}%1D'˜hÎÕýà,{*š1m™¶¤¥d–ZŠx8txñ‰¾íÆè;%ÚQ±ÓÁuÇEÝÚ³ZbªM‚(°hú‹°œ*´à#ÙNZ*þÎÑ6(œÙã")dŒ^§=ŒGI!’"O¥Pâ©ïãðCx”" !¢n{ÒäP ‘d9˜CRd?…ÈR ‘diŸê푲Ú'•<…ˆ[ÍÍQs}¿—IW¦y ÿ¤ÈåS½—")Éž¬P|XVJ BýDÈ\‹$ždbße¥ì…Sp V ¢,ÏûeÍLäd…M…”>w itàQr²¸#B !ñÁé~¬äõ"LÑÚ‡ûheÀ¶'âÎ ®Þp&Ï™B#îL)¢s¼üϲ Aeø# rS2Ê‘B±»ƒ‹yèD\¨$—Íj¾àùF º¹®m¨™ë¡v' õŒÕz#s]Q·Åâº'½ÓIáÖ,m‰9±vY˜ÔÙ¬ !w(ÝæHÔN+D„1dL ’#R #p¤X!r“)eu_!Er:°F€ÒÑõ„¹4uhBDÙ<+ "Œ}R¤Ò–+&BK‚ €zÍg¡Éå²jŠøÐŠ6X•’ãŽhEQz›ú Vˆ¨Ï>Bä)D|ÛÓWHUÑ áîïvˆ4ä²Lë‘2@Þ…š_È„ÅAÈLZ¡¢h)~‡,nž&,@{¤Òfb˜ÞŠ4 PÔTy¹iBTªÀ¬xtG·š¿ä)Dü“"Š¢¿Œ†ðÎlêÖ£†¶´†¤ÜÀí?棜0²Üúæf7ÙYtbtÓ00#Þ=£wÙhˆdõ)«%¦˜ë´,(ÅëW¹3…PêR@üˆŽìxØ›Á™Á‘Ÿñp\ä’e7Æþì™;mè1 ýúDÎܲE£M~BÄ{)BiX›îf#8/;\éµRJ@ø‹¹é(JÃf>+‡]ð4Æ\ºv}2 3À°Ë S±è[™tˆ¸C:u¯ôS£J)D’^»žìã ™|RòšRˆ$! ‘)D&“D¼Q¼„ȹ“Êm¹€˜v£~4³pÄ .6‰MŸÉ£‰ƒy—Ò0ȈŠqí!DZç”M‚”ù‹a(î2:sgÀµñÉO3î­¥’ÒɈ1±ëBÑñß.©óï£ð}´öÉ”ýü žÊìMKûFC„ß©Å2¾†˜Bd¨Ä!fú†ÆlÞP±X )ö"mlV¡†ÈI]Šè0è"›cdÂ!7])qˆèr »\ðÑ6QxÐÂôIŠtºYEHm‘cvˆ +¡¢e|8:JÑÒì›”†@&DÂPÊ”J!ѤI Û\»MØBÊ$A--ëB‘g™RD³Ó£Ìu°}F†ÃE*ZNs=4ïR0Y!¢bzT(J«H@$¡lsí=¡†tlV¡ò§c_ "E†1%µE†O>AĸN"Û´½'ôxVþw>bDöšø ֔줛ëÔ•«ƒkÁŠ ›·h‡ˆ•«Í a<ÿ‡ñ(Ò r *Zé­ "¯Gׇ«*‡¤ÈóCQ´Ânºª;KÜók›¼†HÙfS´„Ý¡…4ƒèhp›ë_¤Í7”‰¹·e mÊ”ÑýÄÞgƃeŒ<ç§LX~F³×n~í“)ø7ºŽ¤È °v]óŽ~}†ˆk ÕvBúeœIuÀ²zWµe¤³ùeœ~ ókŸÈò 2lW`£wâÎrTÃè%pAœ ÖÒAÏÉà (­Ö9Œ=…{I‹G»ù)\ÛÿüÚƒˆ;m@ˆÂùˆvv¡Cd  C£æä#DN†â <Láß‹MQv€P÷m³ ?ýéðé§ŸÖOj C˜(~Ží"mlÂüÀ£…Ìϲåe›ùµM¾1£Ÿ¥PöÍ­æBƒ¥]óaµ­Ïp·ŒæG/Ÿ)çÀ“š'ÈÁ`>_R÷̨™´•Ÿ<ÛÏüŒ4Û̯òý,‚È 'ÔM‚°³˜ÆÃ ¬"z Ø¿`¼gÊ0OÓÃÓÒ…†ÐrPEš­\ꥥ4ñùŽ%vÿó³ôÁ´“_Ûä3úY*l®U{´ 4z®ni ÊV6­¬t‘!xZ½\Ú¥ÙòÆç»¿ù鸽üÚ'ߘÑÏRa[ä¨sO_µéŽS´2ˆ „nˆp]=,pjp‰ ׌Õ3Œ`ÙˆübÙ´?ù©iv_ûä3úY*¬h4wcCŠì·Ï_dwQRÄbsª,$OOÃìÄì3˜ð³NÏL²îüÔµ2ƒÍ¯›çkŸ:`ÆNŸ6ây‘¾ÏÑ2Œî.ëíé䩵‘¯{´{,ók›Ú`F9.ÝYN™ô£T!dž¥½¥ø‹}a¡ Î/u‘Né09gõgançDv@Oé/À¦ÔÁÙP¡2ÿ/ÔT<àªw@åÿZ/´h°îR…þ@$ݰtRɺxɾ2IQ´«–"¢GÄs•Jä6l‚_Ì݇ñ¢t)õ•D`×€:™\·A@¤Íx®R‰i¼ª4Ó†gT²‡ŒWòãÈýÅÜ"cO@ŠÐ³Íœíì'£‡:t:ˆØ5FüÅä•„Ø4FË’ª"cOEKG Îê€\ëPÑÒ2‘ÂIï×PéÐ;'c½ˆmŽ¢½w>¥Q'‡¹Õ²ŒÊ¨Æ,W51xgQåbJeÅš:ÅÂ*ðŒ=S´ö•ÑõÐ:7ÇxSu²vú&ç¨Þ4Ò®Rõ"½Q´æ§õ (4«PbE¶©#ê"}Ò*z»0·7æz¬±C„a³÷Õ‘Ò0É·ql?K¥®§ŠÖ‘oÌèg©•û*5×Ç“|cF?K•Ž®O0ùÆŒ~– Ž®§™0òý,•6t¸?ìò¤4@òý,•>º>ìò¤4@òý,UÐ:xÁØ1µÉ'ƒ|cF?K…¤Èy²^$…ÈdøÒ!˜ª1ìnK?!²/fÃÇ"“ArÌ5Tææª-ånØõ¢†ˆ¶Ü9Qæk[+€aE%H:t2B i¸èñ’*ûióì1és–CŠŒm¬·IàGŠ4ˆd Ñ(õ³ékµ Húsî¾;¬v‡!ò„eŠ>y,£A$ õä?é8JV² p’ÇÞL˜,.ÿ¬ô°¾˜º!rñ)'Dä],DBË6Z)ùMº¢e…ˆ2ß¶_åha€ôR%^˜«,_1ÖBÂG)Û¦Weô»Ž®?åP´ølbDÌý%DRœŒ%‚ˆ¢_å(pöja. `¦½"¸I3×án¼ÀÊŽé§A'Õ³F‡â ¢rL?Ë!ÒÁÂ\ci£’¸UЍ«®`ÒæR,¬heÃÔNß”&ƒTˆ¨ÃU+ÛõºEK©’¯:4Êh].¬9E­yI‡TŠ<•N@™LòmB)U{ sc-'D*ZŸµí£•Òø“×ioa®Ë\·j_öæú‹é4Æ %¿!â ᙾÇD>H!2yä3úY*¬h=‘J‘É$ߘÑÏRáq‘"J¾1£Ÿ¥¢¾¶ KS{òý,•>º>ìò¤4@òy©ü"}IÕ°ë'¥R ‘")E’¿v ­ðrªhM(i sµ9ñÃ+•o9(>ÙJ!2‘¹0wˆ¥ò "­óOî³ (û)D&‰3}‡^* ݆]˜ÐìôvyR Ù!¢ÏQ|©üƒH:t8ÖôK§OÔÂÜþOw—Ê;ˆ¤ã"“JQKª†‘Þ,Ìížz°í5Ü?#c÷‹ˆ§=Й3îQ~)u@^C¤W s»&¬hu»3¼X°ž1—­gbâ‹Ý£`p&a¸”’Q4D†l‹ôjanׄ!2Õå-Àæ)DF‰¢æÏ °B¤ó…¹]þè)ó+UênŒüN”@숢ôêžì_Z‡J F„õÏœÁJÕ™ðŒª[A?Õ‹)ÝÅ«-Š!ˆô_Ѻ|ÊÜG+ô&qÇ †ê~@ÊâÆPÀè_2†­P“4gBj{X%ÇMŠ€ò¥IN^C¤7 s{@Aë ü¥¯\—a'VzÇËZ ¢íM*åã)M½u,B„ßC?"?ÜIÒù5Š-KåW¹¹Š¿u¸ï–"ãKµ)!DäÒ1ÅA„;ª¶ˆ¡»¥”€übEY*¿ÊåR´@®MŠ„\>‡8ˆÌi šyFžâ Â¥ˆ`UÙRŠ#¿XQ–ʯr!Ekþó6s’ò„Pq»1–†®ìÂ"Ô.j~ŸÆ¸éÇpÂõ.YÎÔ\o‹übEY*¼;c±ˆ71§<Ð_± 8¶ž;% ¯KV̸¾Ú>´×Î^Ü3g´î+3^ŸŠ4îä-DŠV¶·\¦\ßÛðrt}?)D|Ü·×Ã"ù ‘a—@% ‘=L÷Åÿ=pÍþïÉë{÷÷ ÿ=‹›5ßæfo÷¿wOæ3¿w—ypwJ¸ì2RPp†Lÿ»æaîò ý{–¸÷E1Ôk%ûûÀ=Ë]­lJùYfz¾Îô÷Ø+Ž÷ïpÏ{4/ߘ‘’o¥B¹0îÕëõFÝgê¬tÍD>Íø„ÚM¾¿á›ÖÉÚëê½oÌHÉ·Rѵë{q•ë|A(çº;`¤K#:,Ì/BäŠßÑËzàHL„‡è¡aäù8† çÛ *pÐ¥¶åÀžÚÒ弇HLQœÞ.Ž-híÍ=Þ—ï(ìµÜ!`[MC›á^à$ÿ…#lÈišÂ¯i´— T, ŃÂO¬é ë5-ŒІÈ"AW æäEh4¥r‰ñ&â5dĦš£Rt^xŽY=$(³¡¶5·™9à3r~©6¶¤8d‰¹=?¤ˆ¢Õ µ>0M Æê"’»ÃKÿÖè EÕ†°ya¤é$Ša™7@ Ǧ‹)É©æJSH(±ššÖ(Ù½%X½©†œ„Lƒ¥JŸR×§ÈÉÒ›“ý«‚ñ_«é7F|ƒÈÒéHs]kŸ¬GÊúËà~0ˆÅš1 ÒTóW<v5@a5ÞíAÔV¢AOöÖÙ€ˆ‚)»…¡^Z!½PØ;.…N/•ËBqôÛñà:D¬_«Q?8@)¿0W÷³|JG•‰‘«|Ýy!ߣlEUo‚áM­!)‹iªŠÄL¸xÓÒ_$–ˆˆÒÎ †Žoo¨ˆÒãišaSMS‡H¦Ë®›V‹>æ5õÌ•êS1™ÑX{¨ÜhóÍ‘ sÛû [Ø¡L Z»—‰¹Ugý×!« ™ yR­†¢§Á¤£-]«‡»@\(IÊuð0Ñ5aIŒVdm#í¥ŽèÑ’§À°l”. Ì«˜-N¦Dèm&LJºL4º·ÿ4"Ws@ŠèƇ!›¤Åo6t ¾g`™ ùa7×ibª¦LCÅÔ¯ÉË©$°®3…maª i˸³¾ë,Y+ƒ¼&$2Ô[%°ÅÞhh•Ö”AÅÉ–\Ûãœ5§—*EÇXÍu¾\®ÿÝ]Ý|Ô¯kˆì—g@o´Öˆ€°¼Âf=ª¿©'§¤©ÅkÔ›ö´ÚP@”‹Ä°Ÿ¦>u<°×´^Új Ö=r°$R’¨Ìè õ"1R$±¢u +Zùü4úÃ4“ÏÓ«ivÎçÅ:& wÏŸæáy”Ó<ê4‹6âçÔää™§9ÍŸFWu‘î4(ÒééÀ£×y>ÓÐyZæ/ ŸÎ7dzÌó4.øt^ Ï£ˆºQ2Ÿ'¥¶”G- Ÿ³¦ŸWž3ª<´4–òÀðy¥Î¦óZ@ùPˆ4)â %ÿb®i}ÖíP:4×o•r–M‚ì„Ò› ÝÑ=‹ƒ0¹+&çxî¡Ýû0*ü¡+™äá[ÎÀvïÈñèCç½oãØ~–*h½?—K?ä6™ä3úY*‘Òt(–®§™$òý,ƒHº§ï$’oÌèg©‚Ön ‘I%ߘÑÏR­íR>…Èd’oÌèg©RˆL0ùÆŒ~– A¤òå"“I¾1£Ÿ¥ Z.ˆì»<) Ô9Z m8ÑCˆ)²ŸJ‘É¢Hˆ mNŠÙ.uû ž”F”¼‡H§Kª˜oF²ÍÐLøAkca&…Èdø(˜é›Qxkh¥JP„Ho>¿KòÛDÖË)D&”¢/D,·Aäîb_ÄMiÜȵ07ãDÚ_˜«”Y`Â"EÔ%¼1´v××[)M(©wC‡H§ s|LlÈ'kg½Èçž;wî\½¾¶ººZ¯“ßê¿À§úëøŒ/è?¹Y]Y¥T¿†+×VVV—kË5L++Ë+ôª¶¼‚þkè¾¶B<ˆñ©¢Ó2¦Z•ž)U—q*ËìHÀÇk$Uœ¾[Æ7(ËRˆ^”•Uî°²º"\i ñY8 ò øqVëkkôÑÖðº#²D¹¬­‘¹ÁUAëf×ÀŽð:ú£é¬òOÇ\»./¿ë|s°UY X’VèÃ(÷< ’Òꪌϊ¤¥°²j£ÕÝÊŒB„³|4D´e/ÚR|"–Äœôÿ§Õp±G x*tEXtSignature943e3397014828ab644961c1d2488773@nmIEND®B`‚gri/doc/screenshots/gri-screenshot-1.png0000644000175000017500000010133613147557614016731 0ustar psgpsg‰PNG  IHDRdñôŒPã|PLTE    $!!!%$"(&#((&++*''(/0.0.,10.<6.443786863886==<H?@>)HF,LJ0ON@>>@@>NB5WJþøæmvÅnŽŒ~tãöíÛàóæŠe»~Ã$,*Zï6Ö5ú‡BAŰ2ìwý&•ñæû:ÔçÆ *ôõ÷¯]§&8ÐÒ×éæ=ÖÐW¯az¬‹a÷¾;ĺý±ß»ví#P¬+š/°¨p†©¨ß§¦ºqóX¨÷Gþ€ÁÞ§ò½O¨<Ħêƒ÷Û7Ûïó A.ôÙ _#Â2²3¹s 1| ñs ÎÃè{õ*€éêµkÃp=r Ãýðð{ð¾‚Ç«ïÑ UÜÞÃàÜZ€²ƒ˜×®_“4q®cR×0%Ì’Ç?H³¡L®öߦ+H<a1ÁÒ¦Œ®]Ã2 3f¹CÛciX³_­?tyhèò»ô_‚qvùêå+—/ÑÿåËWÄ @<Òõ»ôñ®P’»|R¦”®¼K®’…41èÕ«œpL_~—y_¾JIÿÕ«”øåJSnCœ~7ô»ß …CCoÃ9 ÷6Üý.|{hèΗñE}‡Ò‚ß»¬ìx ¹_¥|¨/8Q³þ¹Æ Áx¢ÃõkbŒ¸G˜Ã Ï° G0 ƒËuÖÔ¯C][=¯eÅ‚¾óöÐÛï„!”8ü+)]ÁËÎè]¬VñwT[jgVÿ!l³+ˆ7ì]VbÈ–Ž#¢¨„-D!†Cd\¾Œ]0|e˜|8Vx¯¸°Î ^#èO·Ãˆ#ÄùUá]‹-ˆPyçwÔࢨCÌ -:€[ †°ÅáÂzƒjI®Ri‡¯\½ö."±ÉáLÈFfpñYs62¡ø4D®P½Þ]x +Ž,F+6 xõI óI“+—¯ÀÚö]åU,ƒè0^Ã%µûeîb¨ÑÅ:†®P\ec•5={ly6¢þˆw–"æ…G¸a•|€ˆL•ð/™hÇ!> èo¿s¹ã[²«€±ßå2ÜšÊå®òæ¦Â¥ÔT¥êꪪHUÕ;ªðogs€C»tÄÚsí¸ÝQMÇ”R /1›,Ý< Ýí·UÎ,Y ·¯³|*lñ¤msºîܹsG•;öŽªí;ôØÛž©Ú†‰Àaû¶ª­ÛŸÚ¶uëÖ¿ØŠ´ ÿ·‘KÕ6ø¯1HÛŽôÌ3Û·7áfÛ3[«¶R€mèW˜àV Kn[·mç%Þ¾sû_ls”~›y€Vnì ;½þÇ0¨ÝÿîÿýÃØtaèr¸.Ž…º ¯€0¾Ü± @vQxþãßÿêþüç¿Lwz¡âp¹r°ª®½»»§§·7îK3êëëëí=ÛÓÛw¶ïlOOO_o_ßÙ³=ð÷:Üõô‚G¤×ÑNHà_'·žžnü‡CÏéîW{ ø?-ÝΞåIôBŠ7äÙ×{¶“:KÙÁ \œ…Ìá¦çõ³i¼9{öõ³ì ™aAz{°¸iH¡ÕOÖñôz©làô&¸õ@Å 7Œ„’Îõ÷§ûÎ¥3é4Òü€¤…ÔéûÓù\ú\æ\F§~öæ?€éfÒ™sçàYa<Ì8Ý‘3ésý¬ýýX¼é?'“gYõj¥èå‡^^‹úµ£µîÅþìÅ>íct–Z‹¥»íH†$×;C—>)üñ÷—.å~¾€cw¹_çàîÊe¼»öv.—K#»¾E ~7óûÿøå¿ÿúßÿñ÷JÓçï¬:Òi<¹[üp¬æÎÑÑ3 BË^#¡ëØ^½W±  ª0 ÄÌñÙ§°AmM#ÒñgÓÈÛ "G$TPoS¤;d¬Ø­½ ÈEzd€Õ•N¬ApX0ÊÐPíÏÐHœŒ³~{ÄPå:ˆA6\ÖúxÜŒøg„#¥ßOùa^ÐÞ»cˆbf†P¯*\=‡ôÖ[oJ_*lÝ´ñ‰'ŸØôDŽî®<ñÄ¥s/>ñÄÐké+WN ÈnÃ\áæ/õ¿þ8öñ¯ÿî/ÿ셦˨)hH³&Å*B ¡áû¼´·×Sð°+Î’´„A1ž4V½Bo¯B@oîϦy_÷¦ùU¯Ç†N/'³}LÈ01ÑÂ/¼žØ0$®'F–FÖšA^ ÿçH|œãÒŒI!ð:ODSšýPÇfˆ"`±ñ¹)òjä°ÈtÓý¬÷‰ƒcdÌ ËåIQâ§ýÈ{yÜ àÜ€1°ÞˆÏ´){M´@ŠˆŽ·ŒáBòK Æx”Î{å(b¢$‰ÿõ²¶ge€"¤¹¸='Ôd€Õ ŠÄО˜O“®ÐŸ qÖðÉ'o zýå¡ÑO7nÚôàlï_?8ôñ'çžxbÓù OlzýЕáQ\Èþ¿þÕÆþøñ¯~ð—úôïÞ¸12:2²«S©ìoÀ+À  ÌUPš -ê PÀ=úª†F™ ¡ ò¶‹0S^qWƒUôRTÖ ¤œô¿Åtêî~ÂÊfă?Ð UŸóô48ÿƒƒðwOYøƒó… ™Ìæ Ž,ôª©¤´®V¥E@„‚ä ³n&eXUHü#ŸégX¦nÇ[6’H#Dµõ ¨a?žà/M|Æ^õgÎQÝ©-ÎÏäeµ8?008 ×âÂü]`M” ¼¦€²½tº x™^ûÅkœj†¦½á?®\Êåú6œ{­zh*÷Ú¡ÊÊ?ݰaè­×v…ï#Nvùw>ÿÇÿùë?üþßÿûß¼ôÍ •Ùü¡ª›Ô…#r CÌJÂüÀy€Â¤YÈBZ^ãî!`ÿ[ýp 'dd^/YL!ïe"™[°½B$ÐÈ4G°ŽDé&½\ A‰Gb•æÆÆ6pÛ4j9Œ_*>Ú'挧ª© ŸÊÃèÅùÆÙ׉ï"ÇÈÇûPÿéé#i eG­èlº‡f#°êçáïÑ•' —~6pÒ4±`Ã…„j†‰OhlXÝŽcqÑã#{Î e rá 2Jjp€F1`.d\”&MšOLˆÓ@ÁÍhF¼<ÝwæÌ™×^;sæ_^ëÚ9XxkÃå¸ý¸òÜkÏ^í_~R¹aüöÚ©mƒ×:žDN2ö?_zég¿üÙßýíK?ûó¯oȽsy( «Hõú qÕ‡ƒ!§±ç¡»!z{)ÌÙÞÁ¯Àb¡\-x6³$߈þoökuçëgùÔ“M =\â*µƒõH¡é,‰ Ô‹û(²ÒŸúØlö,ŸÀvõ°Ù*NZq–Œ'œÁâ&±JOïîéí‰R7$ñ*›¿ “_øƒ+¡ž÷ÊÈLÃüáŸÏe{•ÆÀtA.ðú,'é­¾^>j êÙÞtÍÆ f†(Åšbœ&H­?­Þ^¥‚àè@Ч{zÒlºA©JY€ò/ÝÏÄ9›dqõØ$b+Mˆ&鯃ïÚµ‘÷®M½&é'Ï¿3õÚ†Kx¹¯òÜOª/ßîJ  ¹×àî:q²QÐã~ûã¿þë¿ùÁ^úùÿøú×6…×FFFGGô£ñ Yøy¼b¿ ^¡§’GƒÄ±2žbÔóÎÎg‚”«^á<Ê »†¨†Ýq)4±&9œÓ„´Ð•„ÂÌ”g>²© Òiš°¢ª›¡Æb‰ö÷‹QI H‡٠HÇ8'æµÔÞç˜n—&J`vIúŸÓb˳.ê·5-Mw곚^qßk‡Œ˜æˆŒ]Ó\ãì›ܳ4aH–xçã„›øØÁÎiI©åJÄä9²Ú#2íuL!¨Uú…}€ÚŽi_¨¯¢/S@Ï1ÑžIgGв;rò'ë‰þõ';ë/ýáäúsß­ýîwŸ]ÿÚÎÝ—FNî\_Yùï__¿~๦K—»¶¬ö cW.þËsõÒÏ~þ³—*¿üЋþåa\I%XÀ;‚\,@g šEœs Í@æ¥nÀÏH\’håD-Ž4-4¿“ÚJ¯ÖøÌ^#õ˜^®º’âò 'YÄGΞ媜»z§pêB¾Å¹™ÙEÀ–È8'|ºˆoõtuwî†k`a§Éâv)Ù™&þÀMLìÊ.Õ„:”š´ 0‹K•kÄ6+C6á}€Ô-1ÃD®Â 9çpò’áºÓšØÄ$Ã'¢|f:À€pŽåM˜4å—aŠø˜å‰M`ˆC1&8é÷4²2ôŸæ "óÃNg—).½õãõëÖ¯]ÿõ Ï=u<7ôÖ××}}ݺõë×þäé“᥷¾»výùÿøë•¯}ûDxùôÖ/x…÷G€ýýêÙoþùßþÍ7üâ—ŸúÅe¾8ÑI<˜ó¤³ÎAÌõ‚¬cÏ>Ÿì¯à x¸N†š˜×Ël¯‡–§Ã”]ñü[CC¹WÿôÙ Õo†C¹Ý¯½¾ûÅr¸ú¹žàj÷Vàd£#€ÌÁWž­üÚ—¿|ÿWžz=d‹Éׇ™L@ŽPËÐÑ<ƒ¬ãS]äSÌ7Í|{Ï#H¥ \ñg“€&\ù|ÁÓ ÏÌDΓù|‹[Íh´ ÀÒPiòäñwaVïW‡~;DZ Ìc ~,ˆ¸n˜Ïõ ë–Ö?†`ê•"‹!š0Þ—–¬ÐbŒ1M†Ûâ]‹ ÂÄu2šaô±)•‰|’îý©•²_ÎnÓÂ<$ƒ®™Ñ ZÊ¥÷íþoß}öÛOTŸ|kßîÝß}öÏžØÙuáÒ¥óä÷ÜŸm¨î:œl ÙÉ®\ʽößžûÚÚÊçßÌ Ñ\ºz'L{08‡ géX€VP,g›p¦c»ô²k<7+¤iR‰¡¨]À =ÀôNÒ˜Y©Ÿ)EL+è'ýLØ"Ò.!ÐБÍàÿày8âô)ÃçVƒxÌfbé‚{fÕ/0§aL̳ÐVÀt¼LZ`.ÝÏ sç¸\ʤي—eBBf¸ ŠäxþüüΟäsBffq•L…ŠÀÛh 2ç4rI;ÇPÆe¡ˆ%hÞðÚÄ0Fnþárn°ëä·ŸÞùrߨðWrçϼòí§vî3¼ríêÐÀÀk¯lzªú'}—® ŸÞ ûhd$ÝÛÓÝyäÐÁƒ‡ÚºÎ_>êÊððÈD™Ñ|Ð|¥“ÐâÑôÄíkB¹èé:~ sü ±c¸;ÜÖv¤½‡¤Oϫ퇀NtƒÏÍ.?émlllhhxþ ªkhh„ÄÁƒÀ¯±ˆŸtbNbí¦#¥Ù@—t€txš"í†Zv·üXOÿ†“ u­‚[-ºÔÒ‘ý½X_ÛP[[nH»jwíªÙ•Ú•JíbÇT*õ\Ê"î!kv!Õ쪘»06&D·pFŠ´§#…-UN(›€“]G;Ù³ ÈÌ‹øõKå*Ò¥ª$\Ê\žc™¥q*²™—0š²Vë2 UdvE@–/ de¶èdÃÈÉ>í¬v¬dŽE/]åšÉðvG-3……YéÈó ²·Ô, µ ;Å×.ÇÚSÒ0"'´P,ó u)— $‚©$5GwT£vòT,ªUæ ™_>>°àFÊ‘îS¥Ðë[¬mô´¢D{ЮY|B®¨ù’…²úÀ•y>_´3K„² 8Ùq²ž['3[ÔÙÜf7—v‡éIZAb20ñR"ª3ƒ¸ŠèUQºPªlå] 4Õ¢Ñ–Š‰“/’P^/ML­µ¢WDZÃL¡DK•ʦS' 7P'›4f—NÌQ3³½æ ²2£jƒµÂL®LÅæI–€«¹c “íTHU㨙;!»¥ìZ»C™½kW×VG EC9@vuS¹ sõÌ|‚Ì¥WăÌ—³ËÜ +ØU¶XøÄ½T’E€)ª3¡’ stXdŲ¢¡lk—yË„²ò8Y,ø5o§ˆ¯’dEZ}vâÒQš…*ŠÎú”Ž3G•†ˆ»­5.Ó"¡lÅÿ6¾ÎóÓ®š(ÈLù‘æ¨s…ÚhÔVE©Ðýb3Pg{¤›ŒÑÍ E®DEÌbèwîúhÞ¥ 1-åŒã¬n)1S¨¼ª§Ö}ùHÙ"";?³P6¡â:Ù§§x«OÉ’$´ô¨¼N+ 8Ù Úêóê¯]& [†4_ ;Y¸¹•È“M‹ -¸$ƧøHÜb&¡{““¡¸¼ÓY“€,¡…!Tü·ÈN–БX»üôhU²„†Nrºq™Ð€ì=Tü Éö너NñÙåä‘í…Bû©“§Ø?äÅÉÈ ÒÅ,.z|ŒˆÓ©XÓI8œšIn%Êçrr„Ÿcþ³ /Ü;æR¿rÛ§H ‘ ìN1}ùì²á±ºuðåõë8)]OY—Ú…~«%vÒ HTÎvŠÕÑ¡z²ÃH_ïuÍÃw°< _yÙ®•§]yÕ’-Úq2¦r–»™J‡•ö)=+¯M‡»åµ3ðÄâòŒx ëéyhét˜uÒÒïõ×ÛGEr¸ó”Û­ôUw‰@'YsÈnç÷'…â?ÙðØÿ•PB DlÓâgG¶çGoŽÊßèèø¨ Û££Æõmr0Ž£*Êmí†]’˸ž–kœýßVqÇE˜q-Ìèø¸L‡¹ƒƒ+/-}½<·µJàµQ§ÛÔˆ¯¹:ÓÕó׎²ìfœj0N©Œõ¾mæ#Ê©j1j•ŸJ7ÎÚA†‘Çãê;îè—¸þrºkmí_…7F;‹_¾p›t²=OæG³H9:AÍŠádý!Ý…pã‹0>‹ „¾ˆ-S€HÏîC¸ Båž•§ °Ã—¬t háUPž~.Äë@¤²«P/¿÷CVíÀç• rz @+U6ËÒUùcÚ9«–üò¢Y›€ÇÏò³Zzªu±ü¡ÚÑçA0MJ—ŠJ-,24ê«êÄÝ©/x]±ÑEûu7Ú ôô³‘xs²‚0Ü„¢ÐÙ†|á2‰Ë&2V^_kÐè˜,¶µÏ}™•È·â8’ÑzÚ¸½¨’ô³eÀ¬Lß—å eïFRªõ°÷¢¹øÎËm•Í©°¬y/Æ¥Ëj웫=%$ÜrZ2îÅ‹¬¶†»QX?8 oV7®O´tT¸˜9á§÷@¨Õ@ö.>A^8¼M™ÖÅË¢ŠìçÜîÑİTA©Î bÜñœ…ËKÇ7.ÌŽ"—H’¢©‰ËÄ—•§pÃ+d~ ÷EÌfz»Ë¢j‰]T1œÍˆ É'ŽjN²ÎvÍÙ)ˆÒÄu„‹xés¡L”]ÈFÉNväd1­7*¼ê‚ âçªE|vUDÁÚè¦ôÐÓ3ð-PšgÌ¥{hßá®Æ{YÜ×]Ú%[Œ§¯üEGª§;pÅr1uIè(x.ëd_¡êPM¾Î^|™“ A¶Ýó& ¨ø[=h7\ÈZ>çlG=U;@è;*ßä/ºnrŽfK%æ›gß[sЄî1øŸ“W9+¬?³ÁP”êYS8ŠåSþ¬…<æÂNYã¤ù›'ßóeózENJ×*ˆ`åf_È>%Nv@æcÂxˆÀÈ·nTÚa´¡„ŽÇ/|M>…¼}4 ŒTLðšA5½1äç\¤|‹§Æõ*Â"ŠcGùÌü}®^Åò?MÎEIJï¯Z~Ò[/õÅà¢Î‘ÓÆnÃKÏI*Õ!Ás1þÑ2eEŽ1•PÝ £waÜ9º@–ãͤ×ÉÑ+²!=£E´ªûE¸K s¦;¨l.2ÎE³*Õo¢«b4=Ïhk«Ä™¡Qr«p’#F7ä=-ò3 á¡0 `Àö‘ ‹râ\iÝÐà‚,/ê€ÕIÔ‰rf_ã°¿ÉáyBÈÇù‹ö‰ówf\Taóåô9ÙvYUa´xÕFÌnxÞ/¼R*HhÞvÿFt‡‹üó¥ø’Mk²¬h¡×ån¦<‰°«kXÓ:JÓЉnÀGOοèE>ðKƒi¿ç½á±²\“]3{H¡˜¸ô³F©Ž©jVÑ *Æ_–ª¨¿h?Ô0à3Dô©ð\'õKSñ·QÊu_d ð‹ßÞò#\´É,ûBiÕ좞–`ZXd[ˆÔëJy%Òtºjå6¤–h-sºÌíU’OyÞåá«+&Ïžù %@øÆ­7p¡Ð¡d|è²`3R=ot”¥­Uð¢òe0÷­žBx`D $Òã_*>/=7:Ó²¸zš#º‘Å¢³ZYˆm•ÇÂ7@.ö[ [žžX”mðÈ1ì$ð£†8e—„ÈÝßñgSœG$êN!B ðåuU{L3°ø17CÏÉ9§mßà,[cƒiö’:"*Rž7<|eø2òqj¡ÀT‚ÊöƇ@·þøæÍ?ö¼¨ºÍ! û…2¡_ùaÞOj¢PU•àÇÓÍ ¹{´‹…Ðija#ÿðÆ»F{g\FYS/4\`å ÓШ®µfiȤµ¹TN–1‡jËðå”—J{>Š9$âß~Hô†wÑÌXdzŸ|òÉø'xècHsdôƒÑ‘‘ß@x¿ù¡'š@è§ÞGŒ¢Íë1ŒH”DAæö÷JÄGPùššã“7ÈÆŸÆ·úØâëññMø×8ëK?ðª«ße»u«´"Û€­îÂ~úÓ|!Ëx¡èo`aNrI‹ß öë=}Z«žškD”de¤~˜&mÈZÍÜ¡¹+ŒiÍÕp¤·7s¡Õ@PóC)]½z%uµ?U}y˜©Óž›æ Þ¶m·Þ~›¡ì[Yk†Ì f72ˆ~ò )¶úÌ™p±F~3ò’0&@v‘ý¼»ýoÐzÿöÑ¿‘ 4#ë ñ˜äÓAVÜ?Œõ(PdFs›Õýû™¯Vø2ÚOäuÙÍÕô–± Ê·ªÆnÝò"ä_„°B>_ÜÌ\J_JâȈçÝ>̓Qßâ Ï¥>BlÔcQLZ÷ñ?•%Ô"ÛÔ ËJ¡Ôú ÙÎÞL¦·1ÛØ˜émàè’©{W‡¯|']]ßœõ„‚+-/ðлµá ޱ?ô‚‹ÜÖ§¯/x^Ï'œªr覵ô+@ì‡#Œ~ð2 Œ0fË ï:zœ•éš1d„£„áE©<¡2—¶ˆ¿m8ôÍ¥Xƒ”Ý4U¿Ž+þ…#[§>Éiæý½ÒX™ÍÉ m0Ó¶<À€‡qˆ1‰)²Ë´½È„+Kê|—Ü_Ð,—2PÔ=:î‡ã¤ó{žïÐø<ÿð÷}RY0BŸø”á+úªqðH:ã2†Ö¢)²¬@ZV'=|yøÊU/•ÐUïÃ7'»u þoÁ Sïœ\îâEˆôI_Ï6†±^–S8iHpùàe…1Ë|ÜFmà¢üŒ»\¹ˆ8F bn#%ücãk†NvÖ—¹ÙôÐÒP‘“ÝfÆØê©O|1Êþþ<”•dºí&DýB€ì–Qô<„XA@LéeË¥’Gs´]´§eœíïé"‘¤ó!„ úa Phêb„,Øûû¿gCPxBP¬"~çÝœ5~&fH íéLvÐoðÛd½ :Ãw…Ô~üB²ç]M{–/SY?¼µáå·ßØàyÞ&V¦×ï"¨ „®žªª`gª¶‰>ôy·yø]ÜŽüd”a̽ÂÆ>úèÿĨ,}Î/ “Ôbþ~ ­}ƒPU ¹^ÉѦ÷Î. dÇ«å²ô Ò?ü?ˆ0¥“©ŽötŒÝº¥ñb ²ÂT^@Ì™VYÏiáF–ê&€1˜‘boÌO½j@Y7`¬d¥ð×LŒYbâ÷÷‘, \á ÁåãŸG2ÁÇ¦Ü ,ýÁlÃ`[ï…ì`ƒ>TY cW†ñ#êlŽ©u>²¢[;ÞøíÞøíÛ/ÊÄ(dUÈå ’”骪ªÊª­R‚ÒÿÃ3?ùàÄö0ﳋÚDfø}ôOSh Ñà¢ô!L- ÿxó”äb†'¯4Fœl²­JêdÈ>º©f—ŠcÐäRbìÖo#껜LBL™‰1eZóy¯òÍyÈÈÎôX#ú¸°¢¨ïêé²8­ØÝÅæ¯”åd~ÿ p£ÔÊ´Ù€ÂÄ%2²ÁloãEY;Ô5`Öqeø lø;é+ÃiO;9’ço¼ jÙ‡¾ýÆËnÝzÛÓÍd¾×“î‘ Ù'ã¬*† øÿð‡Ø·ˆ1˜arÖ!µ;Lè"ÃXpÑÔ×<7H<®ó…´”HÕ§µ®øÙ"Ä0ÃÒhÈ« ;ø‚ ¦¯‹K¦øËÝu¢ J#ÓQ¦Õä¥2fˆW6ÏgŸ‚—±1æ+ÍÎKuqqÙÕ•ª6l­l‰÷;ÀÇ@YvWW¿Zí©yLoQ­,äâÒ's5•€ÒÌfk™, ¦Ñ û/ó®¦úArz9®¬Š*xÛ¿¿¼ýÆox·Pù7§§¯§GÀl|cåÆÇ6R j!0ç}=ÿÁÃØèo^æf2ˆÿtûŸ<{B 8õ Á‰B1b8U 6€¡¿ÒÅÝÈâ-¢o+ ½,ÇzÈçžÀÉnÒ+ÖnF…ØC <•ç›7ÕìRö„ÉÈnÝÚǘ‰. jp2>}Ò¶uPç3”1›‚ÞϨ•¡¤<ªN½šêÒkÈD!(d]±®ÔwR]©nON¤­5yß™­, óùdÜ»ø½Ù씚²·˜!ñ]±,:¨þ¨“yÀÈ@?K{¾¹ÏÆ{ãCÙ-ÀØË ¿~ø²VƒÐ÷ªzúúh}ŸŒR‰ôØ*Ö9ª‘ÉJöC/ÿæÌ/Îü‚Ç7M}ÞRú˜6@<¡LyœMyš8 bA&P™Kœò¦Ô…c Ö³&ØEÃTadó*ÔÉv’¸”KodÂ@Væâ”ž±[\  ˜Ðz KBÌL€q¾\bzÉ™gŠA¨ktYWµ±¸„‹¦¨µ¡ÿøhª`æÅXù’OheÎ¥¾F)[-ÊyHÉœ{’Üìm¸˜3§êÀÊ._î÷2¨ý#Êì~øá­?}1¶m¶¾vz †õô¾ŽÜ¬ª²r#€l£ficÅ Å ´’®3ðÿÙJQ;Hˆa¢bvx:,ø±:›ªšæjøûbwµ6§´É½ L*þmæ¦EŸ,þÝÔ'¶àIËÒÈ¢[t=2£¡4yFIî‘ðzBã(0_E y¾±0åçy÷a½ß«îîúd´k¼›ºÐ°4Êé/N –±ß&œyJ êåZ`ã" ¶á«ir„±7<TVîä”ÍΫˆ“ybo‰UÔÊ>øMdÑì"  ðoÿ$ŒKú¦µÀPüÈÔFSmæ¨Ö)rŠ‚L<¥W8P~< ݰˆÒ©NÌ.WY ä9ç.wYTÐÊ~[-f=b6¤š¢ˆúÃi%BL–™?Å" p§bêÕêñT©ñ^_@{ ̼J >¾ÌH64nÒÉêb@Ÿ¼r¹àz*v3¶TüÛªŒ‡{dZ,ƒ˜½Ã®²biOiJÛ¦o*ÿ¾$zâ2g‘{6À7” â’>Ь§d0ÎõB•º‘ª¹PåËÅåxÒŒ/«™(xµ.ªAME© GÚ2h ^Ò—Fƒ‹^ „¬ÔŸá_.©ûF”~»×äuÔq² 4Ç[}0çjkÌ—E>C4ױĎð@X—+.Dz¢ÉµÐË!5¯ÐnLº¸g=|½\jœ1¡Ü·C©åŒÐžÈ»ÖöTÚ±Ê{m£³K$ÅÎÔ¶ly ;Q7ϳBË­î“l9Ë $ÛWÍù®FœlšYü™dÓʼnÖ4>ߎ⪭/¶R1[­Í¦Ã'1#ÏÂ9Ÿx+Ùþ§è›"YÅé±Ù…±WÅ Ç%êǹȄ冹hÈ 2»$ÈSÉÝ}Ò[×ÝF¨“=M Û"Ä%‹þ臡Ú(‰Æçí±ûúgZuŠIµsó %¡@äb²ÕØ’¶riò_,Ïý»ü}‘GÑ× ˜›ÐbæÚ%ê×heAÎ/aƒs§™÷YNÛ‰Ìö“Ñ;cÈd¸È•Ýb$–®¦êѸgeø‰T-¾Ëdù˜ãJÎW õÒåüò»P×ÚôENÆÑWØPišrÜ`°Ëí4ÂDÛI{fº\XD”TߥŒúq‘cY‰ÔÃ}|¿R­Ø´¸Ä¥Ô4ý¬öTJ gè¾¥kòùcQZkÃhyýèJÁp7«HÏ4êûGŒ†1ߨàûêg½º‚ذrâ@tk½a¹Wn>ÛÕëi»ª,[Cjfe4“ˆ,¬–—–¾Xp”ÏÙçBµõeúz9­6—|ʪ‡¯%'¤YŒ ¤Ì2‘6VuÇ3r²§qü0(þ ulŸU¸R÷H¹:u­‘tÉÚÖE–¶pEÓç¬y_g§’sf¯J›Õ#Ö©³*Ÿ™p4¾;ÂÇ“hƒh%1~áWgû[ hÝf¹c´íå³’ÁcÖö©3#8êWWÄ?Òt­k(²NOž?wY8 ã›Q‹Q)ÿ™Ð|¦5—RDË¡5ƒðÆuTqéªCÉʘ±ÆÞã.§ñ˜üŠf;®§W,Hɔʭ]ñªsMîÝÌt2íµv6ä{àqÊ*ìO¾uÖÍÌe2X©hŠ}bì‹õ —DÈüA:û]PR4 #«®,ÒSKa`H*1AViëlþÒÖ`©éifÀœ­éFß»Á* £´¶ýLoÉRÖ*‡\é×{H[”3Z*Èi»ÔrvK‰}ø–QÜlvòUÏDû>n.K;dÈÆ¶ q©¥l”G‰õ˜€ï†»~ãš²Ñ6ãÀW£@¨‡•S Å%gƒLkTZÑ´^½ƒkAd™0¢éÄϽhœFçWŠ—\¾Zñ´+odzYû¹÷éc»Ëµ/}"à[eõ#ñ´RhÝáv· n ò0º¤d¿éD0d>‘ kÛ†ŠC½Sé¯75¼ú†¨ú¹µ\Lß:åTk' ô‚¥—jEy±Þp®W‰ÖG]+ã:®U×k5ª‹†¬m(êO™Zå5CÉÖ²&8Fþ¥ËïP¢ãòg-Fõ *Ñ:™2^ÕFúEoVgÖk}iÚ:#'õVFùÂǤø·m§/”Lñ/•LwM¹\>/"âðy>ž¦ò3§)ÇõT|²óšš©_9™–Yþ2ãO• 55#gÓÏôy9 ÅÁ¦0öŒçMZ6ç'Æ&8•Ù8 %DtgbBƒŽ—å>ûSá³*nñ7B&”P¹45a@'ëé>~®0ñ ٵʃ‹Zc|Z‹ø%to@fLçdšöˆ“=MïñÆàd­ª*EàÒê¾.Í„î%Šp2ÝHEœlŒ8YGÍü‚¬5â—Ð=K–N¦,‘a¶àçQ'c Ké kEI´"Äh·|«‰8Ʋ˜Ÿòjø™ñxPÃOiuÜ%´„)ÂɤÁ,d'#qÙ^ÏÉ8Èäu ÷j5¯Å©ÕO8jñdË1ŸO8â'¥’MLJŒÓÉÆÉ„qpkNÆÌ1Òé’[i ÓÏžŒ:ž48‰%|lÉ“ÉÉ|M'Ëe'c{ü<]„“å5”89™ –¹‚ÌJDÁ¬˜7¡Å£ˆN&—ñ®“må_‰+dÄÉ:™°WðëVÛÏ ²Ö" ³ZÂád¡ö@ˆ6»l«Š5ÆjâÒó”*?GšÆèZõé€Cñ·ðÔIe±[1¡¢ádêɉÓÉ&«J€Ì¤¤Ã²)ÂÉô ìšÅÿØ :–€,¡“ÂØXžq2¹õ*dœlt+¸÷3‰²Å.tBË‹"v2ùLZÈg—Lñ?²un ä…Å®hB‹G–Nflfœì3Ù´±v9ù=3‘ï}/>ƒT!¢|Mª¦NypªYìŠ't÷ÈY ÙÏ.ol*þ6¨ŠLâ©F8èŽ ­R>»[ÜÏìd4»l7Ö.mTY ¡*Ÿ§Ã1¡•@ŽÙ¥0Ææâdw˜NV•³Af}(šQÊ8%´‚ÈÚ´h¾·Žédâd‡-;™ÀƒÓ÷JçÄäcª&µØUNè®Sì. Úë“ç³ËéBûkvÉPÆÑUdJK%Í•FÜF¦q2þT¥/f—cRñ+d1â2å¸Jh…P„“ѳ™|ŽÉ,þ1ËJß›‰¸äÂRZI¤Œï'So‡ÐöøO·WGA&õ2·ª¯SŠŸ€i¹â(2»ôµW"hÿ£å.¥`EèÞÝ ]ò‚„‚“±]Gw&Œ„*Ÿrp\ÚÉr¤ú'c&Œ#:'›\ìR'´¬(ÆNFj³øªðM‹³— $#ï]érÏQ¬Å_êd…íìi%i·›(Çø*(…Jª¦¦&…3Ì›f&ËJ÷•1Ø£œÌßN ¹¼|$®+Ul¼ž„)6Åç™ ÈVEìd¹@¾[ޝ]>ãxî²|”¥$²8ÖRÂ1¡•B'óÅÇ€i'›Ø2~ø^^7“9-þ5h!“;0–ͧî·BõHdr?½QU·øwÕÆ/‹_<Õ>–XüW(Et²P¾•Ú×íd]5ñ äåÉÎÂÙ å*‹A1³Köq_6»Üáâd± û^ì"S Û€‘Zì*/ %˜§ÿ4öVh{%'›f;cwÄ/—æd)~H!?KhÎt=ŸY˜¯ótí'c ëÚ5™¹q±(¥R5lj™Zøæ™ÿFZª´\ê(ì«ú~2þx/ãdyYgMòÎØ„fI;Y„ò{€ÚÚeD'»÷h¹ð…åGÈ&¹L~^UÛã?Ý}ïƒ,¡…"ó‘8ídì;\¾àdÓ´@Þ5/â²Oö”­@ríÂFrÛÉÆìµËvXía8þ y²¬´Âȶ“±—“…Q,~¼<Égá˜ñ¹-.- Ý+Z¢‹“ñe¥œþÜegüäÅAÆðT¨°ªQŽ‹E÷Jß-›ºI†i'ÃÖñ÷“\O+Íp\íÄH8Ø ¤('S_å»0pÓâtÛ6Ó+-ýßckK¥Ø™°ú/¬5vIŽã„rp¿xîRßËf—'«£k—’“åËY>áe÷Íp0;t2ùвÈ;cÇ¢ ûž 2÷~2œUêJYB+‰"ÿ€/*á§À5ì„ó òï}¯v)83ÆÙ¢ïŒÍë äåNRÆ)¡•C&È/ˆp²Éí8»Ü»Å½ ã{ß›ÁäúénSÂ_,N–+p­?gÍ.Ûž‰] /ç…+xH©WGÍÍ8 æî") ßãÕɪñ‹$mÛ´×ËNaLí;¥W—Ä$ÉùJ¤Èì2´u2®ø?]VšÉùòS÷^Çiî Y»,dÅ;ð'ÛIŠÿ3Éù]¢{Ý 9ìäñ²•,ÌÂ<¾Î“}%î™d|ÙÒbÃ6†“‘NÆö“}ÎÈçå‹$ ­HŠZü=ùÇt²)ÙÍ Èš%E8™þ§Yü%4[ŠÛK‹ä:';¸ÅzZ)¡„LŠ×ü"œL.+åøÓJ dG¶&œ,†î†Z½ØªûÜÈÁÉBó¹ËÂ6²ä+q÷2-$Œ' !h<­” 'Û–¼Î3¡9Q„“©·øì+q²éÎäA’9ÒÂK¼%+S#:™/¥%ÿÄ6þŠõ1±Ó'YB3¢¨N Õß/yõQÕDñ—´d9ÆR¥èìR|])›S»0 …ÉÅ?¡ÙR”“ñ÷“ùA ïÂ0Ö.ïéÏC'|jÞ •,Ç›³!¾l]ãdÑ®$4GZ9hž0X™'M±öIøk Æ%4c2Å%ÿJœ0chœìD¬h&yÎ(pBóNw…:×.ÙÊøWâȬM‹­RZå!o^E©µdˆ¹RLÚ+G4-Erq2ÒÇä—{£ŠÿÈòq·¿EYBóH3±wlNj7'»CRv§¸`n܇³·Ö¼.J¥?b¶•—§bÆ3"XÑÍx<š3dB‹D&' =ñBdgöVŸöT,'“=š§ƒÆ­°“óQQ*–·üd¢v<ýŽç ßÑßçŽÜóÎŒºÛ³ŸÌÏ9ßø"Éd­ÞÐÊÜ" “×ÊU°ÕbWy΋ìx3zê®5š»r±›ye“²Kß gߊӿH²ÝxáJ«Í”CœÌŒ ¥ÐêŽg±>›[µºs¤° ”L-b)º3–},‚æ—ºNf}ƒÜ1»ŒŠ¨V['3Å—S\:ãñ;î§©µÕg¾Z$Š®]úb㢘]î UY/\ѨÕT¯å]”[åMíÍ@g-ðÎX‹“Ùïñ/¤æðöëd÷͇ñœL¼ÇŸ^SОJÈš%ádÆÚåѪÉd •$'·‹µ“©ÙåŽ9팭¨¨˜Y1SyùîOÍ1ÅNÌÉxUª¼dy@–öÝy§èݳj,qû‰˜0jœ,ßUå³K´øÙ²b(ª(áõfïdÇCæÆoRx`_à‘77:ßä˜ÊçÕ+øj’WŠÞ]’À“{üscŒ“¥v2ƒJ¬YAjÄ'X Œiø’_žà·.îÄÝè|È’onÞU*C'KEŸ»¬`B* ‰X!y튇̋xù¸èH”­ãÝÿòŠAG| €kø—§I’¢þRÏ¥ò·óðµÍ%.•–,9t²Ðš]’NÖ¥ƒŒIàÉĈá Шy0°IôÅ2»”ºTÐBÇTJjh)2•ÏÛ/¥îwaŒªt©|Bw"»0bìdG¥1öq2Œ[Q!”AcªPGò2wtFÆÇ—Rކ˜©±e+ÒQ\¦VΗP–Ótp2š]úANèd5N–gHè˜)Ȧ+/‹YÊ„ˆ!í¸‡ñYs-pAÈÙYÃf¨5÷þ·*–Y äjM1µµË®ZµiÑ%. -ÌVÑ,<È**ÜДv [Et”@I©à)y¯Í RÆ–ZF*ÿRbFs#‹“ùòU¡ù ò®xÅß´…Sü5EŒ‹K1°‹U“ha°`ÚWª–±¤H-RFòÂð–©©áê›änKd÷†J’bOlv™S:™¯ïÒÙÔ],`j±[(¡9“fŒ:™[°ýx;Ù»YÀD‡ZÊT;vèd óúÓJÌNV›¬]&4K²t²P{€œ¿ŸL€,Ù…‘Ð,Éæd()¹56Èi»0ºf ²/Ëe%]3ÈS³Y W6ÔRÿWÙ³K0_=w‰œlúÕšøwa,Èye(K‰‹¼Ü¥¡Û]9dDIÖ.ï2™ Ä{ P+3t²®š»·@Îí5šS^·@àllR„+2EHÕÔÔðÏ–üÐï=ÛF‘ýd¡>»ìÚ•—«J ½@Î(e^J«¬ö `mû½@.>}È‘ÅÏ"²Äsw‹sgÂùÜehïÂ({ÜÙÈõ-‹ò¯jä¹8ë¾jQ@[ 5+d'ÙÃs¾¬±Î­>×¹@îäd+J/h2·ë4^–жÈñ.•Ê't×iÂø„|î2gs2û‘¸Ør±"iø9AV|¼`ãF§–­8¤ä$³Æ½ÃQ_ OY;8–5-=^UœrØ÷.…¤´Ÿ ïÜY\\[ÈÊãd%È l¥„»(í—Ò_êró°iqåÒÜ`mŠK¹36ôMN6Ý^­¯]Y 'šóy*/Å\Н– å*œoeÄ%ñçÔÜ F“ú®Ú¥Òü+ƒbt2ýýd)ã5¥>aéds¦94Š!$AÏ’%›“i»0 ;Ù‰²ß~]1cB÷8Åî'Sv²çg²„–--ó¶9™zèRêdô•Îä5 Í–”¢Å8YN}ÀKŸ]N3;ÙØ]Ù|+x - EvaÖØ<‚¬î~äd»lí²TìdË‚ŠÈÚ¸Ùe“œ¬n5êdÕ“ ÈšÙœL>s‰b“q²ZÙ©Ù=An®]ªr#†±\^ì©”„–%M)•,öä dÏÍê rÓâÏYÞÔ–Ë+ ûEÞX>Hhy’ÃâïçÌÙe-êd'«Ë\ /öp¯ÄZ…É®´år‹& »ÈñÎXŸ›1Äÿ†ûI'›ëä&'ÓƒTèÌÒÖJ.¡åH6' e ”N6ýÊŽââò™bT\ÊeJ®p9Å¥ÜÌh0¹9‚l­‹É*Óì)nv©íñêdŽ'ȧE‚¶®®0£XXtª áP§Dñ_B4ûaÑÉÔº’X»¬ýBdv¥é¢O•묯8­8D•Óusà¢K‚G8³ø9_®]Ö®’œlL® ÌŠí5.¯æ»Êx(f?~Yɰ“uíJÖ.š%ÙOfXüO% »7én0Û8N¦ÙÉêè{—Õ‹²DñŸ!-Mùlí¹ޟÓ-þ«Jp²dí2¡¢ds2Ÿoñ4‹ÿª:Ù‚¬Œ·$´äiB=7IûÉäó㾡“u<·8 äåÍI—-My¶ÀdïÂÄ>{?™ÔÉÆfòùœÈ˳®%´¤©œÙåŸD¶_Ïò òY,ÏóÚå¼1’Ïgé·"ÉædÚîkÓNöÜ\Ÿ ŸÕy$ù„–!©íd'CŒí¨ý[ñŸáäsX 7C–I 'Ybc'cïÁ“ûɦ­ÙeùO' äË`ˆFu2_`,v²/ÍÄëÄE²@¾¢IgŒs²0pêd§Ë^Vr>A¾ äw‰Ù;w*cvÙ,'4'ŠßOæÿ¾æd ¹¨ Vo¾ö“ù\bæÔÚåt¡·qá@&ß»™ZìKhAÈ1»Ì~T'ë®ÝÚe9”€ìnÒÝW2­OzRRÚ:YwýìÞã_% ³é›mÄÛÉŠq²òÈÍ%qc-<¡ÙÓ‚£p^3ˆÙOF’‹ç.iv™šÕäÖK<Í7'´BȽŸ,Ë>Jœlª0MOwß»,û r‰C¹‘'º@žÐ½NeØÉè‘8ýcwòe?Aáyåþç“L´ÜcšÓ‘½ C~‡Péd ¸vIËJcñâÒXÔŽ¬p‹­‰¸\‘ádAy?cË\ nS«ßÚZx‚±D¦âï|?m¿îY@clB÷89t2çûɺj- ­ÍnB±²|ÌûɈ“u7$ »§i!±nq2´“EÞO¶ªÄ²Ò½Ö&Ë–ZÛXËJd'‹¼ŸìO`vÙÓ¿¬4WªŸL-vs$´ g'³ßO6Û‡{Ë!ù·äÓàˇfÂ.ã÷“É÷“E—•¬4’ò„ŠR„“9ÞOF&Œ†Ù,’ò„fù~²òŸ OÈ—-Íãô¡ŒµËèÿBÙO?ÀïVàùR›ã-"Åq2{?™|M·¨•ùùRX ¿hy#6f?Yäýd†Å¿ü'È“ò%C‹ˆS÷~2ÇûÉR³z‚|~È—÷8NÈñ~² K¿äågo˜¸,ã{— ›Z™TŒØûÉ´çÇ_û¶RWÙ_î] J}B3"çì’ùF¼ÕçKÞtáLíd™ KènѲÑ"lN†¶Xþàe`ØÉ–ØyBˈ&&bÞO¦=ANÿ»²•aC[Ö4sc'3t2z1qõB¬]VÌÈyв‘`w•¢:™|(N¬]~Av¬jáÈmšmz˧‡—OIç…$pоŸlºÐ^5«'ÈÝïO¯¨PöYëžùåÌÇr“kv)žŠãœl×jûM‹3zźöþô¼z1±ñÂâ˜÷&´Ðt—8jûÉRøpo{Jß;“W¬kïOסe^9^›Ð=CŽ÷“ •LÌ.ȸ¸«œå¿b½"Êó$³J@¶"(vvø|v9^…âòÈ3³}źöþtýÓòÊý4ðŠ¥{pNà~?SÉøìr´ —•?3«róýé'Ñ£ÁYìì¸eEEìd|v9¾AÖVU¦1¶ V´â¹ÕJ#÷~²@íŒþ#ÙÉÚçs<1êÏŠ–-Cvî' ùCäìýd;I'Û®¿Ÿl±Kв"ÅÈh?™c?Ù3ÉyB³${FT'›¨^­™0–Àù²•¥hž+¶tÚÉš]†rƒ ¿Ü›ZUBñOÈ*J6'ídð iKq²é~,ba@æ¦c³ …æ[sIßâdæ7U™N–º?ò•¸d<¡ ²@ÿZ_»œþ.+­Ö$)ÿëÉyBEŸ ϱ=þÓ¤ø·í(óäæÛ¯“ò{™Ê¡Ê‚¡Ï.C}g,)þd'Sp,óë÷òyyM¼tæx‹GE8™Ø›BNvt{ñòdŠ.q™,¯hŠ®]†–Œ¬ÈÎX:O‹#ûÉ–ÀyB‹K 9cy¶Ÿ,à†2ù.Œn¿î,±v9=ƒ¥¦ÅãVËKv}>×%MÎ]¸—Lq²çQ'ëÔ_¸29ÇLnµ´i¾q\D'œì;²£;’µË„fI¥÷“M1V¶ð [rlnÉh™QÌÎØÿÆÉ&ªï¿«_$YÔ­ˆÙäW¨Vy0.Ê ÖVý´ ÔS2ÛQ©Õå;rp2Ÿ[üý×Éè‹$»L;™N1F®bh©˜•—“¾¹(¨8=0SÝ­UkìÖYLn- x²edÙš/djÈÌ3ÊœŒ)ý¾š]~¡ÄVŸùµ¤Îdó@Sv¤ÕXÍžï:ÈæH³Ù¼æŸ×$' ¤56/ȧÛw”»@.îÔÒSÔS™Éï]Ä›åô£Ù''}ˆ_·†'¿ÿ}vk1hJäoÊDÓÚڪê•0ÇÜDwê!ä ¨üt‰èz<°5—f¾U$ÙÚªedÈàVQÎÖÏ#(²"X lÞPád|¼7»0è˽µšúVj\]Ęó ÚŠTtÛÒð÷9A !Æ]\dˆËïG\L§ïÛA¢äÜRñ¿é½¦÷Ck«‚K«K؈»Ö|« ,u­‚8û8>MåÔªÐd„”(vøµ¶æó‘"i] 'óCaò÷ÙìrŠÈ»êôÏC[ ‚Ló÷hAì½°tý£¼<þHœÜ™æ÷}3ÎÐÜäÞud¨d&'cæØª˜ŽÁ’xÐV2o‚¬UqB-#ýÂêp&C‹&ã Yø|~~8™ÃÈÕÉBþ*ŒœØ…‘²AV|¼Èd'jG;ˆâdyÁÂ~¤\¢T dùÏ…,UÇ¢:\Ü󣱊¿æÐeF"”à#­Q¤G(dtíó6Ì4FØjxF·€:™5» ¬'È™Åßxglñ'ÈózâV¿5wiÈ„N–7A¦1&SJ—ßw9¨+úŒ²j|'È„ÎU\\ªnŽ—y#í˜ùž1âReɘVÞ²Ö»2ãýd¾ Ã|gÑ'ÈõÕo·âÏWÆÝŠ¿ 2uú‘ "ÕyíäÔ꿯ûÙŠ¿y’å«pA«”Œuž.´0­RùQݬéê­F¼1o±ÒRºˆâ/UµÌÂç-™=¯v²1m?™nñ—ß OE8ÙÂ>w©uób‚Dyå_Tï*7Gæ—îúZ÷,ì_óQÆ ƒ•y„lŠLºÅÿÎ]k”ݵœV).w7nŠKùÜ%{„\ÙÉ GïÒs—ËŸîZï-Ÿ=?‹¿/ ²úÓJmÛ%4Krp²@½q%/u²Î Èš%ݱ9Y(ö_‹'È™1¶=YB³%““…_ço&§Â$™0Nܳ:ÙòQm–-9t2µgQ³øŸØ1u‚,¡§‰ ×s—›§'ÈéužÛ´w/v¡ZVÝ‹ïZd_ñ2f—e¿i1¡„,Š®] ÌÄÜêÓ¹+YB³¤;ñ:YNp²Õ Èš E9™RÉ|nñLJ{UÇïñO(¡¢TdvÉß…1¶ƒvÆ>—p²„fIE8·øí@qy*YB³¥¢v2ÆÉªJ}Tu¦T‘|ž÷îÒbÛ›'”¡,¯½ CÛãϾ­ôÊ<.' [a$3&÷ø[œlœž ?!A6Vê…+%ñ“€l…Q:ÙöR:YôA’èó#ÆM²•E,´8Ùv4aœÚ55E(ÙJ¦È. µC|%Ž>Exj—f·-ö¹ù6Eþþôèã$ È–-ô¼`ÒÁɘÖä‚B˜Çe%2aœÞUü‘8I죪'­E`äbO—Âa²D'“/[Qï'¯þ€ìXõÌž O@–$eÁ`³Ëœ®”±ÙeõŸx…ÉS»fò¹dêAòd+‹4c¬üÞ%{-qèkÿÉ.ã%xÅž ·ÿ¼|­Š ‘€le‘K' „ƒq²dY)¡¹‘¥“…†-–8Ùí*Ú´8 ä ÈVÙœL{XÉàd¥>‘PB±dÏ.£ß»d ;•ìŒMh¶d‚,Ð,þ9ÎÉnWߟ€,¡¹Pü~²@r²/ØÿÅ.tBË‹îLÄ=w)žVú,ÑÉšÅs2¡“Mî¸÷øïºk/ÁKhaéîï“U…ûÉ|5»¼³C‰Ë±„“%4sRì‰ï2´9l²¯9— Í’Lq‰ïñ…²<édÄÉ^ÈËEÎd%i±ÝXZwèd¹Ðàdc;ЄÑýBÂÉš%E8×ÇB²aä‘“U£¸ì®M@–Ð,)ÊÉøÆXüVÓÉØgo;YB³¥'+°¿ àØûÉ&«VE>‘PB3 ›“¶cìH{ü'«¸l´4Ë«Ûe„fô‰3þÇÍ Ýþx.±KÓGºÀéÏ4Æ'3 ŸþøL’)“Æ‹»ç ·éA’öªühHÂÔ'+‡ŸóIqcµPÛ»Á®ö%áÏ®ý ÇÞ°§Â±Ï‡b³d l(ŽøÝ—ñÙNqæ/ÓÌjŸí¡{•¢y%ÒÜõk*Å…sN\óÔCV:È4çk¥£Ü°Œ9Ÿ•‡µ/g có.AègUmY›bðå•3Ú-ä5q×%ÒŽ,¼h±Lhä‡Y‰’ð£¶)Z¥#Û9Pmëk-ÎÎz~Ü=çgÍ>ÒÃìÈÝä²Ru~T÷õ8€•5c¨e˜õ<¶’u@Ib@_8yÚ":ç$îxš9õ=묖Ÿ§•ÎÇùŒGÒ1ˌΞˆ5²ñx˜œ'\!í´ÓË’ËÚñ a*cÀ <¬ON{ßs.Ë^6È’>ž‘{SI³¼(š(’'^´EÙŒ.±ó rÐ܉ºœÝlF–Nè[åÏÆTÙ3&”9æ.‹ÓC ÷:àdÛdéÆühŽ0;=ù€>/©$k8zæãÃvQµ>󵘜_°ÔÍ4©°¡YUÙ¢AdP/à`! y¢Ð9¥æÎ^ 7>ùF=”§r‘¥CçIV<­B3Avk…Qcíä‰0F“êc_E²\ÉÛH`·…š3:§3Žâ"Ý/›+`½A¼Ó§7Äj3?Nöþ3_ð ¡N&ËçµõÅXò¬¼"¨÷XßzYK˜™EµÑ+ªç©ÎφªtFM¸DûÒº…':Îg½¡•ØY–}"ÙXðåÌQëÙÕå¥ÃP¼\úf=ÏH Knf+Šoä&@æò*¾§ òÍ’ûE"úXQè«x¡Š¥xH\2zÏRbëÒY¤²ÙM˜]Žj-Î9ßó¢9b/”=#9! ¸œ|.RH’l\t˜iJ7ÝÇC⿟ÕÄ KG@c}+KÒÖ\Æ/'àd[d7º¦FsÖ8á¼ÄÑÛ@€&(ƲNy~z-ñPKSaÁ5d|é'{Eõ¬.”$+”½/ßüM¬Ç@?°’ùºP-ÂɂгJ Å,µÁ9=U$“p‰zF”™ ³ÈúlÑÌÐ\8o­ ‰â&#äd²±^äd9«¦~Œf #¹NÎ7`aã0+HŒp¿0’¦ÖÞ®Jf¥îf –I'eŽu¡êQÑ>Ћ¿’:’ˆ§ëN¦ØÓ«˜õ•j!, œV_ DzF 0`º4b;pëd¥È/áÌB䯦WNZ!€ì=ÔÉntƒNÆc¨™P6Nš›(Ña$³6AÆ21œÂk’Ó6È|CmP2æw(ÐÈfs2Y^©A)?dÒ‘2¹¾äYMäÌrØŒ г¬!fM¥÷ìi’—Õy¯§qæ(ñ ëÌ0À‡kÀç÷ÊìV<¿²)ðëPñ'q ³K©·)’ÂÕšÜÓ$#÷² €šÔ$d…òNøÚ†5vË•Is¼ë“Ñ'¾f ‹€LK5känBÀz¼¥Xh-ÁUu_F‰iEó6týA+’ÞÕ¦ŠaHáÅó§r9•Ðo™9ÙgvÀØTìû009šé¯¿ Ãoà:ÙXo#š0|e‰ò‰‹ñI©ähšu‹[¸üØŒ"n¾~­_HNf6¼¯Åâ–DßlQ/kÍÏd~¾• M×}­Ó|-?««k±}e•G´”6à}3?rgÙ×Ë(¿ôÒ¾(c¶kÍF´Êo×4ª‹)Óƒ[±2sô¨£&¡¸|@vÅeCCCÿÉc¸®ow4ÖŒàæµ ]§¹i)×ÛnH¯ðYOmòH\B³$ù¬AÇÂ팽Žâò³ž:²;‹]è„–™â2D” ò'#솲D\&4#ŠìŒÕ&ߌ“]Ý~¿7}µ§!YB³$d¾—+ˆ})‚“]Þr¿WN@–Ь)ÊÉÄž3?­ty˼Â{é–d Í’”Þ/g—lËvÎ÷ØÓJ—·'»“€,¡Y“‹“‘° @rÒÓJø¬4‘i™TÖŽÅ.tBË‹¢Ï]†ÊËu2Ùpò¼„fMQNæåʘNöÎS²¡ÞÆä…+ Í’\O†ÅÿŠËw{“ÙeB³¥('ÓŸ!'¶Õg8YB -.oÆ­>CïJh¡(|ê~¯ð»6 Ã٠Ȣ-À#]Ó/›½gæF¿Þ ž<¿A¢Ì`æBi€~òZwÈœ óþøa BÌ™… èT¥‘aÈþ|&%8d¿ 9žg4();hºÐ6½KƒðJg/…~ö´Da^¢—^Êòàÿü— x£¹\ʲ&¤(}ÕväEmŒ!–R¤l¬.çô[Y‰¬È}pPåË<µ 1•4ß ›(‘ …=O=JŒÿ" (Qf»au53¨7ÁA´øùó¬»(Ü¡ÊÕÞ–ÍOn‚¿'ŸÜüäæÍ›ŸÞüÔ–§·lÞ¼eÓfIOoyÝ•^nÙlÄÝô$ºnÚ„imÚ´Yý å-˜ö&ÊáI~Ä€›0FeÎOb›žüÖ“ÝÑc ‹G¡àš•ãIʆ"ð¢ó£( ÿ×¼¢ô$««ÊÌn‹ª ÈÛ„6q—M,ôÓP˜MO©ðÐBOa"òšñi:>õô–-[ðÉ?Å‚oÙ N˜0KkË–Ï–-É{È2Q:Ÿ‰#! ÙÍ@f¡èüÜ“¸hà¼Ý ’œ×%Ò!Ïkÿ™ŒÞ—™òû²x¶ϳkdí@'O´k?†‡ööcxèloïèè8ÖAèÜÖv‚ÇÉŽò" v7ôîÄ\v‚C'…ìèêèìêì„8tžé8Ý…tº»«ûL7üŸî>}æÕnt9M W»$'úgÔqºãô)¸?ÅC£S×)ò†|ººNê¡O£—$t‡¬º)ý®®NrꄸP4ˆvšåLžùÔ™NÝÎté9sF8efÅ‘À«"0/:AŽHx-ë@1Oó#ÝvtRsŸ:ÕAêê8ÕÁ‹Œ×TV¯ÓݧO‹Zc;P¥;14.í$'Eê1êè5ÖǰwQoavbå1éSPÇ.l—N‘1&vê´h½Ó²]©éy3‰6M| ž¡Þå-Ý}ºf•—9M}OýÏp€¥Õï$ í<(aë»F,q_ 2 ÚÎþz, æËã@uÚñÐÅò‚Òò‹¹SÝSL­œÔF„’ìî ,T‡Jƒj€¨4Xؘ?Þ~üd[û‰£ípuàpìdûQ¼=qüøñ¶míÇ?~ôèñö¶'Úá²½ ¼A cíG±ë î±ã”ÜÑ£GÁ_»H²ƒàíèrŒò8 )³;êmìôcm×ñ'Nà8?ÃOmí'ÛŽÁÕ1ÈnÁp#épÛøé÷mGÛ <'¸†#Ý;ŽÕhkoÃBSâ$Ô¬©ecË©Ž­õ;:ôà`×AÓÆï`l´â0íâýÇ‘Ò%úîDÝ#žwþX›IGyñá kpŒû@A±°XWh ª75q3‰.†?Î ñ×Ùy{æ(Ö´“¡²£¦S!ºÃjPjï¨c~Ø‘'¨ñŽŸp˜þñ‡Ø8~âè1^±£¢*P£ÐæÇO`£0Ú¶tŽcýN?qŒñhY`^Âvž-Ãgwï”Ý£®;y•tê0ÆN' lÄ´KìSÂ'Ñ…Ð …$,ž?¤vlñ"ôñvQ@ÊuA;ß8þ:¸S‡l”'E:IÒjk§ÎÀKbíGµÚ«R³HP$(X: :´ÓXD@@ë‡aÈÚûDÝ:ÏË´”º¯þçÔÔЯC™!¿6ªjgKÕ“7>þøãßøØÆ•¿Q¹~ߨ¬¬|lÆÇ6nØhúêô_!sgp¦kº¯„ƒÿoT>†N:œ¥/Óä¿ OnØø_…#ݸe¿aƒY†ÊÊÇ7l€oØÀò©¬„¦r#¦»¡òÿ`åÁÿÇ6b@Ì Ë¥©ôÇПâ|ãTî¼]}cÃãWjÄëDߨŒølÀÿ•‚ÊŒiVn`eÇvƒÿÇ£²?þØãðÿXAo°³å^iÜ=ªßW>ö`QœÇ­´ÇÀ Z7‡>…34LmjGK;—=™¾ö¶C‡7£X8Üéë<|ïYGº3=G9¼ð×I ëv|ø÷¿þÕ¿ÿÇ¿þãþ®­‰¤#rÀªÇv´håÆcMÜb×TøcáYeôFc]³g¿¸ÏýFÐÌÍ2dÓ‡?¸íeç=tÜ{Àê–1˽QÀ -@Ã@F+.¡YG°8Í’Z˜Í¬Cx©Ð©…‡ÁžEÀÐõ2‡0äØD9Ò R‰ßA¿5µ´ð¼šÌbbŒf6jðùØmØÍ2ºÊz4ÉòòáÂʘy7º7!BLâxãÍ%‰†^3Ç'ov)ñØÜRw„TéC]™ãû`°75íÛÕÞy¸«½açÎçvîܹ»¶½óÈ™Ìñ¦¦¦ÝÕÏ5íY¾ëaÙë0¼ô¿þç¯ÿðñþõ¥¿¶Ãµ÷}ßHAôn:bväå5áY¹·P r[‚šv#_àC©…®±75fÀ<ÙÐk”c‘†ánÎËv·4´àQóã£VA¥D£w‚¾¢-›ùàWN ŠßñÎBnÛ¨€Â84ë`¬I‚·±¥Qn‰Í»÷X­°Ïn<â0jÙ½Gø´Fµ%ÕØÌÐMüº™@†XjnVƒëÙ"+ÔÂë¯@–¢$‡Ô~vÞGÃ]c-’Ù´¡rv{Zš‹1—8œ#0ÇŃîQ{‰°'÷6á[ák™pU;0‚¶:p[ «|Ûa/¶6h{‚o k޽‡Ž^ºÒ‡_xñ»/¾øÂ‹ðÛ|¼ÿКÃÇ_9x¤iMËw7·;ôÂί!½ÒòâæÃ²nPå>ÿG—ø÷—þö¥on¨<‚Sø¶c•u0H<ؽp$±£×®TÍ-^ j\ßäCG£Æ®ò4643Ͳ…) œzû¤¡ASž…Ñ,¤C#%Œ'6iZlŒIŠÑK2¦ñH®û0*æ/œ™²MƼÝꥺ#g BõˆøEcé?¨1o© ±2´0Q­”l¦ÏµÄȲ½Ã(C/ã"æ zÀ¸9ÈÆ A~Ác/ý÷ÁÝñ´ŸFØ>BP·—Ò<À2A!þ OLü÷ á„XÜK? ë¦chlÉ4×׿Xôâ‹•‡2M_;þbýîžýÚþ]•?É4¿°Qvè…k7êªAÅ¿"ýçK/ýì—?ûÁß¾ôϾ~ÃfãØHíδ.RÀÈðOêaäÞÈ\2šä}y׋¦ê47Ø¡™¸liP*ªè(b ¨•43}ˆ%Îg„©,ƒÎë|ù:ï®WÚ5بJ¡Eoµ©“7za E[ÎM5íŸ[h¢KÿMtÆÑD•jÆ)£¡"*£‘¡w7Í¡1‡m#t3Jx·¦-6óQQ4Ì„ÉD1MÕ€lx¶xøABuË2˜¥k…½¸ó‰ãéÖ¼‚×ÛÖ´ìÜtäÜ /<ýµ¯=øµµ‡^¨Út¸½öÑU “öÛ¿ûë¿þÛüà¿ÿóÿøúšo·už~µ»§+Õ‚„t¯#¤ƒ$e®f¸NÆ|÷‚Ëî²wÿþ=0ö0Isù, ž–=$¾`à Ú ¿= ïîe#Ç)ŽCpÚƒ,*¸¿åÀ~¸gƒh/çý–~¼—†ú^[?â„£~–štШD®Â0Ÿ9YÔ,Û^e¢±en`"Ù’>Sk`ã‚ñJR”˜OóJLƒiEͺ¯Ùƒ›äø4G­þ†'D=ŒŽzaBjæ WPÓõã–ú–†1yls•ˆI„ËÙ&­ÒÐjš^v¨«³óÕŽ®šç¾ò ÐWZž­ÜòJçó6=õÔ·¿]ùà‹•Oêzî‰üÚËà»ÃÓ²Çd}Àýº~ñÜ_½ô³Ÿÿì¿W~ù¡ÚƒÌÎÛ˜jhdZŠÁäg¤êKáÈÜÙ±‰(oûæF9Y”L¶Išsø=¯–è”´²a¨6²ÉêFó”„ Å6ðYº4Ð556Q?6rûYÌt¾øÝzÑSÖ{ÒìWq öôçYõõ»ëˆuÕo=kÌÙ´^lj¾Ý{L̲©&ë2MsjŽ0‘˜!à œ{íq%ìhüµvW*›CyÛce¶‡G8ÀF¨¨­»³«½ópã³_F=¸Óúç·íÄ}Q÷ìúšW·|ûÁ[ž}ö+Ö¯ßu¤½A†«Oo=ûí?ÿ›¿úæC_üò¦ýÇØ"P{-6—iäGœ?6Ò¼’›iî‰+ĨŸõìA6ßÂ*&í¤…AñÆù›¤î…ú 7?(KA3Bç"ÃbónÅi:M³²Ö‰ Ò‚PX·T2 /”ˆåOåmVÖÍ&„·04iw|æB…&±YãJÍ$ÜZX6J²¡ƒôbCƒb]¼~R·lˆh÷êøË ã©I•1þn%0H idVAä{›"ðnR­æ¦f½-±iö45ì馥¼COï®oªßýâók759zä¹çŸî¹çvþéÚMÍGŽzê…¦§þâ©çvnÜÔx¤½ö4aà cÛ+Yùõ/ßÿå/³¡/ÃílinQ³K]Áoa˜Ç}[¤ÆÖÂõxÒkÅüZ‚€õ]£Ò¶ÔzO‹0±)ÇÒnÁ`«KÜÝšÔ–v^ö]7råA«›¦Јi±4‰==½l‘õHË_üÙSOmX¿ö‰o?wO?µqýÚ/HÙKËILGld÷$fö¨bB©É¼Æp8‘à ì9úçp=yáÄŠ°‹Ic ¶wï÷QõY&-àˆÁ´paö¡^‹ÿ¬Z ¾hÐÛK ò^6ûI+ÞC 0)ðè1_ÆÔÉ‚¡ù2«.&Ür#@;´ì§ÖjëL§Ñ€Ô~äà ϯtÃΖ6`RGìox~ÝúÏ6)ضÏsÏ­[¿a[Óa`V8»<ºëÕ]µ©TÕÖ-›Ÿ~ú™ªR AÃKgÒ¥6±]ˆ¹ÎÄFÙõvNùŠ´Îã¦þÌ=B€Êéh¶Î§8Å7Oò=v¸%]Ëx@»¤gÔ=•ãü9–¹Ü¢708˜þ.ˆTÉ#_°öšua/œ—;ϳçd ÎÔ0Z’?ÔÀeQ¹ o2£M/ÈF9‡yœgåÇŒûÏ«L˜KFºˆG'¨Œ¼}„'kõLowgªfWí®ÚÚšç«¶myê©§¶V×ÔÖ|¶n}ꩪçᦶ¦¦ºêi m©]µ5Ì„óÈuëY‡ëk×=¢×=ò]?¥Gň_RH•ǧ3y)zľ6|Í<" Á®^Çtñõ‡×®[EXD%pYn¯{øá5kàß ‡´‹‡ÖØ¡¿ÆÎãÿÚ5”ÄÃâi®Y³nÍÃøZÈ”Îæµf-åyS¸µ¯Áþ q×@"(#$ñµ¯¯]ûu¼~øë¼äTAkyU¦*®Y‹™P]°`âÈËüðYO½º=ô¬êWZó•5_yð!t$篮ùêWÁç«=(Â>ôÕ¯|õ«_þòW¿ Ž2‡Òš†h-¿…ûµ_ƒ¼¡lXú‡¡ÄØQ¬« –Ô ·5Ð.ŒÔ|>®Ô{<§¬Sâ¨;OGcWSÅÓ´žØ[ ''ïJ”§E)“ì“(>wúäßÙMœ¬föp£Å¨@BËŠ¼ý:Go¿žNã첿æd5YBåQä]ú½ £9Y¦öÑ)‹“!ÈÜ̽¡‘³ÈùEðBpÝ„“—MŽwaäøÛ0Ø»0&dg«ÖØœLÇ‚ÖÞeÁ.ž*ÄažQ溮(+øLU¸î0y«ãd“}²ÞÔ#S.qY¤fÖÆæa¾¨"溌à3 TQf¸F¥ß~ ;6F'ãWœµáÙ†ž Qaa¶B9æ£q4ÏYẓ§¼A/ t«ˆKZ)–ƒ‘¦´Œá¬ÞŠ£(' Bßx)þ;.2uÉûV‘ ÀþDè)_aöžv–!£¼3D$Æþ´riØÖ㸓ÖQ“ƒ]é¼]óh +–äGo' Å7ë8'›L#'ëß±¦,åóö¸a+\°â,†aÄ”Wv—ñ*Œf~¢€#5JMÚHÌ(˜*®–f´ÈyW +•:™ùE’ 2aô<ó¥rAæd6N±~sŠÊ¼áîDB…+tIN–Ÿ=Èìâ:&> È\4e‚LÃ~ídc(.Ï÷o¹¿ÔìRë®(Ê" «¨(¼•FlÈŠŠ˜ fÖ€¨0¯‹€,Ô%Å¥£à+m&È|BÿÎ*{ÿDšf—Û¿ä°“U(}Wª½ŽæT­¯Ôä8Å?"Ó¤«C|U˜wºâŸ—}Ÿ· ($zÑR»¦$öÔBOÓLÚÌ6ïò[Qdq2_r²×ÉFÐNv>óô—–¡Å‰•p‰çî‘|m:,Pò2à:ÙhæQ´øoù/ùée·v¹ôK¸2HÙ$×É|úð˜]ŽÈú·|)ù¨êФùø¶¶C' B}v9–y @–– K>‘ÐL)vv)8Ùãd[uN–/"-‹‰¨È þ4b}bXvËO Ìp³)Ûœ«·¼É5»4ìdãiÒɶ?h~‘ÄÑnöt "&„që˜÷;¨t/é¶„H”²:¹¢”S‘éÎÔt¾9Ë2¯È›qmï*ÅÌ.}ÅÉÈ›Ùú僬xS¨Û2e©ƒ,? --u^`s²O˜âÿTdÎUå %5WQ}sÜhç"¸•t>¯™X­¤ó± ›Ÿõn«~¦çó¹<Ÿ¯° rv ¶yNkÝ¥7ï·8Y®Àµþœœ]2q¹ùþ('s¯*» 겟*æÓXái,ó˜©h0Z¸".ºî6£õn£~E‹YÔ*L?³¨eTÚ‘ƒÝ.‘ zw,5ˆ1i:™os2¦øgžü‚dfgÚ]©ñ³¸¾0:Ïeêw%­aT_Vr–Æ]2ÕQ3Yï¶¾`ËóV®v)6B–(ÈÌÙehÎ.?í#ÌX»œ*dÌŠ‚Ìì/“T ““é!\|Õ]2á\aG°¸`19¼Jq23Í’ ³Ó´J^ d%&#w“ûÉ,NÆÅeyœŒWü¼3ˆÖ6ªƒ§LÈÎ0ô!îW¡-{WL;º,d3Zïž.ÄÀ¶¢4.4N6«åùi‹a%ó³V\]9L/–¦3–×wÆúY˜à7ÈGÑ›yúþ¨Ìf ¢â…iËǨ´ ÓÈØÆˆ·†®âb¤>àRü égEŸÁz÷. ž9k)–˜^Ι.Ï0s0K¯­]x]2ãåKfådl£ð3ö ò1²ª¯æIu»3qw,þqnù¥Òt³©Â]MzÉ4Ti‹?—[¿²>]dj°iÑA¶d(†“i:Y¶A¶m)€,¡eI®±bÏ"ßK ä™­ÿE{`±KÐò"'Ëq­Œq²Ï‰“U=˜p²„fI.Ì|Ziéd&ûÉš%98™ùÜåDv#íÂøRÂÉš%•´øO‡Ì„±&YB³¤’³Ë‰Ád Íœœ, àÈ-þ\\V%&Œ„fKjUIp2ÔÈ|_Zü'CYuÂÉš-©WapNä„´Ì‘l"ü†-.ǻР-/Šêd¾ÔÉØäÌNöL".š-MÜ‘¼lÚ¹vy'$mýß%4K29™ãi¥‰ßmä äw%4+ŠÛ…Ê]Lñßöå©„“%4;*ÉÉ>½TÝ´˜PB3 ;&'ÓŸ#ñÙ¶ÕÇ|?YéÇ®Ì-×3¡%³Ÿ3¡ù"““™Ï]ÒìòÓì†Èì2º¿Ù ø':Ê¢ ×u‚¼eL–N†Ï]úYÚíƒ×à4~i#äN¹ 3}çd³¥œK€”Á?úÜ%Ûã ëÏìøªƒ“EŸÅ þ…ãÉlNv<þ„Ï Ÿ·v¥iû-½§©W 9vÆZ»0n³µK—N}vKbƸ“~Z ’O)VXqäIV~y-ëÄ„™¢ë¹ËñðIãA’1ÁÉô§ÃØ­þüª ¹xÞ:òÐœŠ°LÞ¹RèN„“Ѳ’NöY¨öøâÒ’3ÈŒ<Ý «pE(2f&ëKðµ¤(n?Y(ŸVbœÌñbây—3}Þ:šf… ²D\.гøg-‹¿0aÜÑ@æVüÅãÌ®'³Ýñò³{Þ:’¦¦Ä%ŠÿR¢8N¦Ö.‡ž¼+÷.Œ-Šåd!·øsmÿÊÔØrYBK€äŒQ{î’í(ãÏ]ޱ]Û¿š¬]&4K’À‹)nv)u²Âµ-6'»S´¹æa­x9´ÿœ+½*9Od¾ÎÓ± cš)þ5ëæ¸@]+v~k[<b>‡.¿´·˜4? äê¡x=B>o<°u‘BŽøÞeV|ïÒàd)ÙX‹¤-y"kÅÖÉÕIÿ\³r\ì–š§Jk×%ÖEîŠÙOFß»dv²Ë2ó=þs[+®0>ª­ë„Åoü9VÚ¨f>d÷"9÷“9ìdöìr.kÅXÙR#óWéü ™K'»L&Œª‡¢¯ŽšãZqì©ÂÙ ‹MóZéhý–ÓçbgJNææ÷.'Þ!=c¬]ÎqÜù$¸õÉmã³ÚKby^*óÍsÇwÆï!rp2ó{—þ“«ì¯ÄÝíO.»YBñ¤lšÖ.A%Ëáækù.ŒLå}ìC÷‹¸¬´$8YB³%{F€ïŽòoo$N–|‘$¡Ù’´’ÅYü§}p²…}FB÷.•ÜO6‰:Y¿¹vY<Éd­8!“bÖ.Cù¦Å±wHñßö_æñ ò™ù&´Ü)ÎNæ‹·_On\]b«O²VœPQŠì'Ó¿Aÿ¶_W=<ï ä1kÅÉDòž#©öËÙ¥zî2$;Yn#[VÒŒ± ¸V¼DÖ)šOŠêd¾µv²e¥‡5<.àZq°{#3ßã/ß…1‘{rµã± µVœ€ì¤' ½¬ø£µË;Á“‘­> ¸Vœ€ì¤Èì’þ8Òˆ“eŸXeïñ_еâÅn‘„ælNÆ>GBzY@ïŒÈlŒŽb[)E_Eò»TÍÈý$f|3‚«ÍQ<ÏS…ɾÊ×8„Ž„âMd‚¥(Ϧ7‘;›‚ÀÉšÙögIúªÜ­d–%Ç’SŒÄÏéŒË!à ¹ž³½qâRÍÊò…ó(.ûAñ—îRúåàJ$’Çc–$@|Oô´Çú>tÜ1+½4GŸ¤^Ö¢‹Íóø> gOb‰‹=ÊÜ„•v§$ª&©X!ý<ŠªµtŒå$[5bH÷8ö”—Ñ"i!Öui+­áMÆ*èëhìÜ–ô¡dŒÃ*…²<‰Uù²Y‚œËsq9ø­Uì‹$£²»³¼³ñ.ÀðÙëÿõngJŽ`œ'0G_²Ò¢Ä&._Fà'?ÑE44(æÅÍ …UÓ¡ªƒ,gƒŒÑî_Ï3†¼¸ VrýZH¯ÀŠÂ­Üî0¨èIî'ÔJMÌzžQ²¬ÐV=#MéŸSdM.'Qiú‰ƒd„z00"ÌÏÉ÷ãœ,“z„Ï.M<Yûs,k,k€LBGH2é£BjB5@Öc‹Šéj–'R‰Ó'³FÿúZJVÆ{‡}T-c@ÐU7Ö‹b©N+‚/+-ÊìqÎã{¡Á lsìJ´w%¦ãF9|®P„ôd£AøÝoÉLÙ7N|ü˜)¨®¶ä¿·Uü¬M¡Å'av™FÝ £)GÄUàó#36ÈTø0p §{¦À’9ª2>|Z) £wºzJž>¶®Oä=‡¡å¨'¤©/FÎV0“éâJ€KÇëxOp9m¶Êªéi³%æòp9½ÿ³ËPŸúR:dФ>fbGCH¨§ªB`A‹ÏVM{ êd}Ýçezd€½œ*å N†+Å?‚.Å4< '“Aâ•êhÓj¿Ù–¿!©èdL缬 E{&ëNL‚LJb Ï2^À®}+3[\²4W Ì+1Oä³6»*±“Ä8 ,–c™6Í;?W,)YïcÈÉP'“Auy3SPí¤Æènt©Î[XÒ夔†¶£úé<Œë“¾š8È>ÑÕy d¾*†YNíÃ,Y!.5©iËl»Â¾Ué¬P÷´‚Z•6=Í4 ‰³šÝ·#(©¥YU‰˜¿#RÎÊÄg`*Äq¤Ìz*b¶X—/ô< ëJ­Ó-þFûúÌ.šcúY¹CÁ³äM™$ô/_/m4O¯tJ9cFfGð#×\|Í|£~|X/k„,B¡™`6n€QØËLÑ g=t»•Òí|];ƒ8§œ‘ƒQ"ƒbx©¥e1Y¶œ¬û±Õ^¦£Äe]ƒ"¼®Wu¶k¶Aë$Ï+ÂM<á\C]Ôq¶‰ÍØÏ”õÅãy¢ÑÊ.[½ÃÍAõʻΰ®DÖzvõZ ÖÙèj»ë]g~gà¨V/*‚ 8YgjÍb/å—OSwû]Ÿ/v£M°Ø@ú¼l÷Âi—'Žów­LLLN²¯dNOLÂ-¾dR|9óÎùBF~Ö¿©9¡<åí¨#ˇRŸœœž˜žžœÆ3f3=9¿iºŸœ$Ÿ tÃ(tïé©©),%†_*)¸NÓo²EŸÆÈHSÓtÉÈ|X,v==É®‰ÈŽt/`ÌÂtÿ•TþPž<ÜB1§ Âð›‚f„–˜Ð¿89f756þ$;OÊž¸s‡îŒÝ›ûl ÎDŸa p!ÇîDúu8ä}@ÝAmÇZ~jršZŽz"夯¦¶ì|Äe[ªºººª½«³QG{gø?Ò±ök?vâĉcGÛl?AÔvüxÛ‰¶6ºÄsôÝÑ—Ñ~> ÿ‡ÛÁ«#ì&J,Ͷö¶ã˜ ^ÇìNœho;q ©­ý$èêD;/–®Cµ³K¸†°@x-¨ÿ;袳³³o;:  àx¬n;XØcÔ'ŒöèísBÜt°;:9‰´õañ¨œÔ ÔxÇŽ„u·càzòX¤#Ž‰â³”xZ¼òÇÚxìë-Çû<Úc#´‰ÆÀkr¢­'ÁC·kkc?êB Gri Frequently Asked Questions

Introduction

This is the FAQ ("frequently asked questions") document for the Gri scientific graphing language, (c) 1991-2003 Dan Kelley, to whom you are asked to
email reports of Gri errors, or suggestions for Gri improvements or new features.

The Questions

Q1 Features

Q2 Documentation

Q3 Can Gri do ... ?

Q4 Gri and other programs

Q5 Evolution of Gri

Q6 Gri on various computers

Q7 Gri bugs

The Answers


A1 Features

A1.1 What is Gri?

Gri is a program for drawing scientific graphs. It makes xy plots (linegraphs and scattergraphs), contour plots, and image plots. Unlike many scientific plotting packages, Gri provides precise control over fonts, line widths, grayscales, colors, etc. Since Gri was written by a scientist, it does the kinds of plots scientists want. It has few frills; e.g., it does not do 3D mesh plots, because the author dislikes them. Gri is command-driven, not mouse driven.

A1.2 What does `Gri' stand for? How is it pronounced?

Gri stands for `gr-interactive', and `gr' is the name of a subroutine library that preceded Gri. The `interactive' adjective indicates that Gri can be used interactively -- that is, Gri is an interpreted language whereas Gr is a compiled language. `Gri' rhymes with `tree'.

A1.3 What does Gri cost?

Gri is free. A commercial version, called Gre will be made available soon. It contains most of Gri as a subset, but also contains quite a lot of the Perl language as well, making it a fully functional and efficient programming language.

A1.4 How long will it take to learn Gri?

Most users can get Gri working after spending half an hour with manual (see Q2.1). Familiarity with your operating system (for example for viewing PostScript files) will speed this somewhat. After that, it's best to learn new features only as you come to need them. To begin with, you should skim the manual and the cookbook (see Q2.3), looking just at the illustrations. This will take no more than an hour.

The Gri manual is like most computer manuals: it would be a waste of time to read it cover to cover before starting to use Gri. But you'll find the manual helpful as you branch out, modifying the existing examples and inventing code of your own.

Learning how to use a new command usually takes only a minute but realizing that the command exists can take longer. That's why many users with sophisticated needs find it useful to spend an afternoon leafing through the entire manual at some point.

Most things in Gri can be done elegantly or crudely. The elegant approach may require a little investment in time at the beginning, but this will pay off constantly as your needs grow. For example, folks who like computer programming often start using Gri "newcommands" (a form of subroutines) within a few days. Other folks might avoid newcommands, instead putting their entire program in one long "main routine". What's right for you depends on how you think and the sort of work you do.


A2 Documentation

A2.1 Is there a quick-reference card for Gri?

Yes, two quick-reference cards are stored on the Gri development site http://gri.sourceforge.net, and these are also installed when gri is installed.

A2.2 Where can I get documentation for Gri?

Full documentation is available in several forms on the Gri development site Gri development site http://gri.sourceforge.net, Check out the FAQ file (which you are reading now), reference cards (see previous answer), etc.

The Gri manual is available on the WWW (world wide web) at the URL http://gri.sourceforge.net/gridoc/html/index.html .

A2.3 Is there a cookbook of Gri programs to use for guidance?

Yes, at the website http://gri.sourceforge.net/gri-cookbook/index.html

A2.4 Is there a newsgroup for Gri?

Gri has several discussion forums at the development site http://gri.sourceforge.net, and users are highly encouraged to participate!

A2.5 Where can I get some sample Gri input files?

Sample files are scattered throughout the Gri manual and cookbook; the manual also contains a test-suite that you may find helpful in learning the language syntax, especially for programming.

A3 Can Gri do ... ?

A3.1 Can Gri do barcharts?

Gri has no specific command for barcharts, but the operating system can easily rearrange your data into a form that lets Gri draw barcharts. In the following example, the synonym \width is set to the desired width of the bars and \missing is set to an arbitrary missing value. The rest of the code will make sense to any Perl programmer. If you don't know Perl, you should learn it.

    \width = "1"                    // width of bars, in x units
    \missing = "-99"                // missing value
    set missing value \missing
    set x axis 0 6 1
    set y axis 0 20 10 
    draw axes none                  // will get whited out by the chart anyway

    // Create dataset
    system cat > barchart.dat << "EOF"
    1 12
    2 14
    3 15
    4 13
    5 10
    EOF

    // Create barchart style dataset and plot it
    system perl <<"EOF"
    open (IN, "barchart.dat") || die "Cannot open barchart.dat";
    while(<IN>) {
	($x[$i], $y[$i]) = split(' ');
	$i++;
    }
    $n = $i;
    open (TMP, ">tmp") || die "Cannot open tmp";
    for ($i = 0; $i < $n; $i++) {
	print TMP $x[$i] - \width / 2, " ",      0, "\n";
	print TMP $x[$i] - \width / 2, " ", $y[$i], "\n";
	print TMP $x[$i] + \width / 2, " ", $y[$i], "\n";
	print TMP $x[$i] + \width / 2, " ",      0, "\n";
	print TMP \missing, " ", \missing, "\n";
    }
    EOF
    open tmp
    read columns x y
    set graylevel 0.95
    draw curve filled to 0 y
    set graylevel 0
    draw curve
    draw axes
    draw title "Demonstrate Gri barchart"

A3.2 Can Gri do histograms?

Gri has no specific command for histograms, but the operating system can easily rearrange your data into a histogram format.

Here is Gri code to do it:

    open "histogram -l 0 -h 10 -i 0.5 < inputfile |"
    read columns x y // y is number of obs
    draw curve filled to 0 y

where histogram is a perlscript which creates a histogram file named inputfile. An example of histogram is:

    #!/opt/bin/perl
    # Calculate histogram of 1-column data
    $usage ="\
    NAME\
	 histogram -- create histogram file, given data file (1 column)\
    \
    SYNOPSIS\
	 histogram -l low -h high -i increment < input_file > output_file\
    \
    DESCRIPTION\
	 Scans the input values and finds the percentage of data in bins\
	 starting at value `low', ending at value `high', and incrementing by\
	 value `inc'.\
    \
    FILES\
	 Standard input:  column of numbers\
	 Standard output: columns: (bin_centre, per, cum_per, num, cum_num)\
	     where 'per'=percentage and 'num'=number.\
    ";
    require "getopts.pl";
    $opt_l = 0;
    $opt_h = 0;
    $opt_i = 0;
    &Getopts('l:h:i:');
    die "You must supply commandline arguments!\n$usage" if ($opt_l == $opt_h || $opt_i == 0);
    $n = ($opt_h - $opt_l) / $opt_i;
    print STDERR "Will have $n bins, running from $opt_l to $opt_h in steps of $opt_i\n";
    for ($i = 0; $i <= $n; $i++) {
	$bin[$i] = 0;
    }
    while(<>) {
	chop;
	($x) = split;
	$i = int(0.5 + ($x - $opt_l) / $opt_i);
	$i =  0 if ($i < 0);
	$i = $n if ($i > $n);
	$bin[$i]++;
    }
    for ($i = 0; $i <= $n; $i++) {
	$x = $opt_l + $opt_i * ($i - 0.5);
	print "$x $bin[$i]\n";
	$x = $opt_l + $opt_i * ($i + 0.5);
	print "$x $bin[$i]\n";
    }

A3.3 Can Gri do error bars?

Gri has no specific command for error bars. It has no internal representation of error bar data -- that is, you can't get them by a read columns command. However, you can get error bars quite easily, simply by reading the data line by line, plotting each one as individually. Here's an example of error bars in y, where the third column stores the error:

    open a.dat
    while 1
	read .x. .y. .ey.
	if ..eof..
	    break
	end if
	draw symbol bullet at .x. .y.
	draw line from .x. {rpn .y. .ey. -} to .x. {rpn .y. .ey. +}
    end while

A3.4 Can Gri draw labels for Tukey box plots?

Yes. Here is sample code, in which a label "My Label" is drawn to the right of the median of a Tukey plot extending in the y direction:

    read columns x y
    1 11
    2 22
    1.2 3
    3 5
    2 20
    3 10

    draw y box plot at 2
    draw label "My Label" at {rpn 2 xusertocm 0.4 +} \
	{rpn y median yusertocm "M" ascent 2 / -} \
	cm

A3.5 Can Gri read compressed data files?

Yes, as of version 2.6 Gri can read compressed files, e.g.

    open myfile.gz
    read columns x y
will work. You may also, of course, do
    open "zcat myfile.gz |"
    read columns x y
if you like.

A3.6 Can Gri use scientific notation on axes?

You have to trick it. Here's an example:

    // NOTE: this requires manual setting of axes.
    read columns x y
    1 1.1e3
    2 1.0e3
    3 1.4e3
    4 2.3e3
    4 1.0e4

    y /= 1e3
    set y axis 1 5 1
    set y format "%g$\times10^3$"
    draw curve

A3.7 Can Gri label x-axis with day of week?

A future version of Gri will have much more powerful and general ways of handling axes labelling. In the meantime, you have to trick Gri to get such special effects. Here's an example:

    set x axis 1 8 1
    set y axis 0 1 .1
    set font size 0
    draw x axis at top
    draw y axis at right
    draw x axis at bottom
    set font size 12
    draw y axis at left
    draw label "Mon" centered at 1.5 {rpn ..ymargin.. 0.7 - ycmtouser}
    draw label "Tue" centered at 2.5 {rpn ..ymargin.. 0.7 - ycmtouser}
    draw label "Wed" centered at 3.5 {rpn ..ymargin.. 0.7 - ycmtouser}
    draw label "Thu" centered at 4.5 {rpn ..ymargin.. 0.7 - ycmtouser}
    draw label "Fri" centered at 5.5 {rpn ..ymargin.. 0.7 - ycmtouser}
    draw label "Sat" centered at 6.5 {rpn ..ymargin.. 0.7 - ycmtouser}
    draw label "Sun" centered at 7.5 {rpn ..ymargin.. 0.7 - ycmtouser}
Note that the offset of 0.7 centimeters looks OK to me, with a 12 point font, but you may wish to experiment if you don't like the placement.

A3.8 Can Gri draw maps?

Gri can draw maps, but it lacks builtin support for map projections. (A previous version had projections, but they were not working correctly and were removed.) Gri does not have builtin coastline files, either. Many good coastline files are on the web; see, for example, Rich Signell's site http://crusty.er.usgs.gov/coast/getcoast.html or the USGS mapping site http://www.usgs.gov or the Global Self-consistent Hierarchical High-resolution Shoreline site http://www.ngdc.noaa.gov/mgg/shorelines/gshhs.html

A3.9 Can Gri draw residuals on regressions?

There is no builtin command for that, but it's easy enough to code, as follows:

read columns x y
0.05 12.5  
0.25 19    
0.5  15    
0.75 15    
0.95 13

draw regression line
# Draw the residuals individually
.i. = 0
while {rpn .i. ..num_col_data.. >}
    .x. = {rpn x .i. @}
    .y. = {rpn y .i. @}
    .ypred. = {rpn .x. ..coeff1.. * ..coeff0.. +}
    draw line from .x. .y. to .x. .ypred.
    .i. += 1
end while

A4 Gri and other programs

A4.1 Is Gri better than Fortran/C/... plotting subroutines?

Gri started out as a set of subroutines. The set is called `gr'; the name `gri' means gr-interactive. Although I wrote both `gr' and `gri', I haven't used gr in years. I am unaware of anybody else who ever used `gr'. Thus, in at least this case, the interpreted Gri language is superior to subroutines.

In some applications the graphics are hard-wired into the computation so using Gri might not make sense. An example is the SPEM numerical model, which has builtin NCAR plotting calls. But this approach is inefficient in user-time and computer-time, because changing the format of the output may require re-running a model. The best approach is to decouple preparation of data from presentation of data.

In highly interactive applications, such as many uses of matlab and statistical programs such as S and S-plus, it may make sense to use the builtin graphics routines because they are so tightly bound to the processing.

A4.2 How can I include Gri plots in LaTeX/Word/... files?

Latex

There are several schemes for including PostScript figures, such as those created by Gri, into LaTeX files. That's unfortunate, in the sense that it can confuse folks who are not experts. The example below works great at the moment, but 5 years ago a typical user might have another command instead of includegraphics, and 5 years from now there may be something new. Still, I've found that decade-old LaTeX files still work for me, so you shouldn't worry about the chagnes.

The example below includes the file fig.ps as a figure. To test this, you may run a Gri script named fig.gri consisting of the single command draw axes, and then save the following into a file named test.tex, and then run LaTeX on it, which in unix would mean typing latex test at the prompt.

    \documentclass{article}
    \usepackage[dvips]{graphicx}

    \begin{document}

    \begin{figure}
    \includegraphics{fig.ps}
    \caption{Isn't this a nice graph?}
    \end{figure}

    Nice graph, eh?

    \end{document}

It is worth noting that LaTeX has handled graphics in various ways over the years. The above indicates the preferred scheme as of 2001 or so, but other older schemes still work.

MS Word

All you need to do is to convert the file to GIF or PNG (see the next question), or to another file format that MS word handles. It is a bad idea to use a JPEG format, since that doesn't work well on linegraphs.

A4.3 How may I convert Gri output to GIF format?

Conversion of the Gri PostScript output to GIF is normally done for inclusion in web-pages. For a discussion of the merits of various image formats, see Information Architecture. I have been told that GIF images suffer from both technical limitations (no gamma value is stored in the file) and license restrictions. The PNG format was designed to overcome these limitations, and is expected to replace GIF over time.

It should also be noted that there is no generally acceptable way to convert PostScript to gif, especially when the PostScript is vector based. One problem is that of resolution: if the output GIF is low-resolution, then the text may be drawn roughly because of rasterization. In many convertors one may specify the size of the output image, which permits control over this resolution problem, giving the user the task of weighing file size against output quality. Note also that the colour table frequently gets reordered in the conversion, possibly leading to inaccurate results. Simply stated, PostScript is superior to GIF and other raster-based formats. That's why Gri chose PostScript for the output model.

There are several ways to convert Gri PostScript into GIF or PNG images.

  • METHOD 1. Use the convert program, which is a part of the ImageMagick set of software. The convert software is quite powerful, being able to convert from almost any format into almost any other, e.g.
    $ convert gri-1.ps gri-1.png
    
    If the output is to be used for the web, the above is fine. If it's to be imported into a word processor such as MS-Word, then the pixel resolution is insufficient because the default is 72 dpi. Try this instead:
    $ convert -density 300x300 gri-1.ps gri-1.png
    
    The ImageMagick software is free, and available on the world-wide-web at URL http://www.wizards.dupont.com/cristy/ImageMagick.html

  • METHOD 2: The GNU program gs can also do this conversion. In newer versions, this conversion to GIF is builtin. Here is a shellscript
        #!/usr/bin/sh
        gri -y -p -b $1.gri
        gs -q -dNOPAUSE -sDEVICE=ppm -sOutputFile=$1.ppm $1.ps -c quit
        ppmtogif -interlace -transparent rgb:ff/ff/ff $1.ppm > $1.gif
        rm -f $1.ppm
    

  • METHOD 3: In older versions of gs, you must run a little program in the gs interpreter, by typing
        $ gs foo.ps
        GS> (pstoppm.ps)run
        GS> (foo) ppm1run
        GS> quit
    
    This creates a file called foo.ppm, in the so-called PPM format. Various programs exist for converting image types, e.g. convert.

Availability of software: ImageMagick uses Aladdin Ghostscript, another free program, to rasterize the PostScript file created by gri. Ghostscript is available from http://www.cs.wisc.edu/~ghost/index.html and many other sites (including any CTAN archive). Older version of ghostscript are available under the GNU GPL. Speaking of GNU, gs and other GNU software are freely available at many locations on the web, e.g. ftp://prep.ai.mit.edu/pub/gnu .

Author's note: this answer was compiled with advice from Peter Galbraith, Toru Suzuki, and George White, to each of whom I am very grateful for the help. In fact, the answer is mostly a patchwork of their suggestions, and all the helpful pointers to information on the web are theirs, not mine.

A4.4 Is there an Emacs mode for Gri?

Yes. Peter Galbraith has written a very powerful mode for Gri commandfiles which is supplied with Gri and which is fully documented in the manual. The capabilities of the mode include the following.

  • Indents loops, if statements, newcommands, etc.
  • Uses built-in knowledge of Gri commands to 'complete' your commands. For example, typing 'drM-TAB' (where M-TAB is the completion keystroke) causes the mode to write 'draw' in place of the 'dr'. Pressing M-TAB again gives a list of all Gri commands starting with 'draw'.
  • Provides complete access to Gri help on commands, including the full Gri 'info' manual if your machine has that installed. There is even an 'apropos' feature to let you search for commands you're not sure even exist.
  • Lets you run Gri from within the buffer. If syntax or runtime Gri errors are encountered, the cursor (usually) moves to the offending line in the Gri editing buffer.
  • Lets you run Ghostview without leaving Emacs.

A4.5 Is there a Gri module for perl/python/R/octave/...?

No. The task of creating such modules is so time-consuming that the Gri author cannot undertake it without help. (Note: Gri contains about 40,000 lines of C++ code.)


A5 Evolution of Gri

A5.1 Where can I get the latest version of Gri?

Gri is available at the Gri development site http://gri.sourceforge.net,

A5.2 How can I find out the most recent features of Gri?

Just visit the gri website and look around; it's pretty simple.

A5.3 Should I keep my copy of Gri up-to-date?

The advantages of being up-do-date are:

  • You get new features.
  • There is a better chance of getting your bugs repaired, since all bug fixes are applied only to the current version.) The disadvantages of being up-to-date are:
  • You can get clobbered by new bugs. (You should avoid this by keeping your old versions of Gri. That means archiving both gri, the executable, and gri.cmd, the startup file.)
  • You can get clobbered by changes in the syntax. This is the penalty you pay for using a program under active development. To protect yourself, use the expecting version command, which will warn you of any incompatibilites between the version you expect and the version that is presently installed.

Most people should not be more than 5-10 versions out of date. To keep in touch, subscribe to the gri maillist (...see Q2.3). Also, keep track of the file ChangeLog in the FTP location. As with most software, the supplier may be more enthusiastic about new versions than the users are. Other Gri users may therefore provide the best advice on whether it is worth upgrading.

A5.4 How can I protect myself against changes to Gri?

The most important thing is to save old versions of Gri. At hard-disk street prices of about a cent per megabyte, an archive will cost under a nickle.

Archiving the source is just a matter of copying the files you've downloaded to a location of your choosing. Since the directory name is of the form gri-VERSION, keeping track of old sources is trivial.

If you're using a prepackaged version of Gri (e.g. in RedHat or in Debian linux), then you'll probably know how to update Gri already. At any rate, you can skip some of the steps below, since rpm -ql gri will list all the relevant files, saving you the part of the steps below that involves locating files.

Archiving the Gri binary and library file is quite easy, but archiving the documentation is complicated since there are a lot of documentation files, and they are scattered across your filesystem. For example, 'info' files go in the /usr/info directory, while 'manpage' files go in the /usr/man/man* directory, and the 'html' files go someplace else). This isn't specific to Gri; the filesystem is just defined that way, for historical reasons. Your first step is to determine whether you wish to archive the documentation. In most case you won't want to. The point is just that you have an old set of scripts that you need to work; you won't be writing new scripts, and if you wrote these ones, then you understand Gri well enough anyway. Besides, Gri doesn't change that much from version to version, and the changes mostly involve additions.

If you do wish to archive the documentation and emacs files, locate the files and copy them. (If you do not, skip the remainder of this paragraph.) In Redhat linux, do rpm -ql gri to locate the files. In debian linux, do something similar. If 'locate' is working on your computer, do locate gri and examine the list that you get. If none of the above is true, look in the second-last paragraph above for directories where Gri documentation files are often found, and move them to wherever seems appropriate. You'll probably have to alter other things as well, to tell the info and man programs where to find the documentation. If you use the Emacs editing mode, move that appropriately and edit whatever dot-files and system configuration files that Emacs uses to locate mode files. (Note that all emacs modes understand about using different versions; see the C-c C-r or by calling the command M-x gri-version. If, as is likely, you're only archiving Gri for old scripts that you don't need to edit, you may not need to worry about changes to gri-mode and you may as well go ahead and install the new gri-mode and forget about the old one.)

If you only wish to archive Gri itself, things are much easier! You need to copy only two files, the executable (often /usr/bin/gri) and a library file (often /usr/share/gri/gri.cmd) to a directory of your choosing, and then create a shell alias (or a shellscript), which uses these two files you've copied. Let me take it step by step.

First, type

    gri -version
and make note of the present version number. For concreteness, let's say it is version 2.6.0.

Next, decide where you wish to keep this gri version. For concreteness, let's say that you'd like to keep it in a directory named /usr/local/gri/2.6.0. Create that directory if it doesn't exist already:

    mkdir -p /usr/local/gri/2.6.0

Next, type

    gri -directory_default
to find out where the gri.cmd file is located. Let's say it's in the common location usr/share/gri, for concreteness; then you need to move this to your chosen directory:
    mv /usr/share/gri/gri.cmd /usr/local/gri/2.6.0

Now, we need to copy the executable. If you don't know where it is, type

    which gri
to find out. Then move it also, e.g. if Gri is located in the /usr/bin directory, you'd type
    mv /usr/bin/gri /usr/local/gri/2.6.0

Now we just have to make an alias to run this particular copy of Gri, with this particular library file. In the Bash shell, just put the following line in your ~/.aliases file:

    alias gri2.6.0='/usr/local/gri/2.6.0/gri -directory /usr/local/gri/2.6.0'
and then you have a new command, gri2.6.0 that runs this particular copy of Gri. Alternatively, you could create a shellscript to run this Gri, e.g. a script named gri2.6.0 that contains the lines:
    #!/usr/bin/sh
    # Run numbered version of gri
    /usr/local/gri/2.6.0/gri -directory /usr/local/gri/2.6.0 "$@"

A6 Gri on various computers

A6.1 What computers does Gri work on?

Gri has been ported to several Unix machines (e.g. Sun solaris and sunOS; IBM RISC; HP RISC; SGI; DEC alpha; and x86 linux) and to x86 MS-DOS. An old version is available for DEC vax VMS.

A6.2 What kind of compiler is required to compile gri?

Gri requires a C++ compiler capable of handling the language feature called "templates," and it also needs the so-called "standard template library" (STL). Templates have been a feature of C++ since about 1994, and STL became part of the draft C++ library standard in early 1996. If your compiler vendor does not support templates or STL, you should obtain a newer compiler.

The free C++ compiler called g++, available from the Free Software Foundation, is known to compile Gri on at least a half-dozen problems. The compiler version must be 2.7.2 or higher for success.

A6.3 Why can't I link my compiled gri? (on HP computer)

Unfortunately, I made a bad programming decision several versions ago -- I decided to start using the STL (the standard template library). The STL is part of the draft ANSI C++ standard, so I figured I'd be safe. And my tests on solaris and linux platforms indicated that STL worked as advertised, in g++ 2.7.x. However, I should have checked further. It turns out that g++ on some platforms (e.g. HP's unix and IBMRS's AIX unix) does not handle templates properly. The linker cannot locate templates defined in one file and used in another. This issue is discussed at some length in the g++ documentation, where three methods are presented for solving the problem. (In the info-format documentation, you can find the relevant parts by searching for the string "where's the template?") In Gri I've used what method 3 as defined in the g++ manual. Apparently this fails on some platforms. Although I'd welcome tests by users on the other two g++ methods, and I'd be happy to switch if one of them appeared to work more universally, I have to say that I'm not optimistic: from what I read on the newsgroups, nobody is having much success on this. The GNU folks say that g++ version 2.8 will handle templates much better, so I'm waiting for that. Unfortunately it's been, so far, a two-year wait.

Almost certainly, commercial compilers handle templates better, but I lack resources to purchase these for the various platforms. I'd be happy, though, to act as a broker for anyone who is able to compile Gri on the problematic platforms, and who is willing to share their results.

A6.4 Is there a Macintosh version of Gri?

There once was a clicky-pointy Macintosh version of gri, but I got frustrated with modifying the code each time Apple upgraded the OS and stopped maintaining the code. After several years of living (happily) without the Macintosh, I flushed the Mac code down the drain.

However, with the advent of OS-X, Gri compiles without modification. It has also been packaged for this system; check out the FINK site to learn more about this project.

A6.5 Is there a DOS/Windows version of Gri?

Versions of Gri have been available for MSDOS/Windows platforms for years, kindly provided by Gri users with MSDOS/Windows machines. In summer 2001, the porting procedure was systematized within the GnuWin32 project. This project provides win32 ports of GNU tools. It has been keeping very up-to-date with Gri development, trailing the Unix versions by only a week or so. Please visit http://gnuwin32.sourceforge.net for more on the GnuWin32 project, and to download Gri (and other GNU software) for your windows platform.

If, for some reason, you'd like to compile your own MSDOS/Windows version, check the Gri manual under the heading Compilation on x86 (PC-style) Computers.

As for viewing Gri output, I recommend obtaining a copy of the Ghostview program (which is a general PostScript display program), in the version called GSview.

A6.6 Is there a linux version of Gri?

For non-RedHat versions of linux, one compiles and installs Gri in the usual way; see the manual for more details.

Users of RedHat linux have it much easier though! A RPM (RedHat Program Manager) version of Gri exists, so that installing it takes just one line of typing, or one mouse-click in a GUI interface to RPM.

The RPM (RedHat Package Manager) version exists at the Gri development site http://gri.sourceforge.net, Once you've downloaded this, install Gri by typing

    rpm -i gri-2.1.17-1.i386.rpm
Later on, Gri may be uninstalled ('extracted') by typing
    rpm -e gri

Knowledgeable RedHat users will know that RPM can also give information about Gri; for non-experts, here are a few examples:

    rpm -qa       --  list all installed packages
    rpm -qi gri   --  summarize gri capabilities (if it's installed)
    rpm -ql gri   --  list all files related to gri

A7 Gri bugs

A7.1 What are known bugs in Gri?

Gri is used daily by many users, including the author, so that it suffers few serious bugs. Generally, more recent versions of Gri suffer fewer bugs than earlier versions. This improvement owes much to the trial of daily usage by folks with differing working styles; and all users can thank those who send in bug reports (see Q7.2).

One of the main problems with recent versions of Gri is that line numbers of syntax errors are reported inaccurately, if the error occured inside a new-command.

A list of Gri bugs is maintained in the manual.

A7.2 How can I report Gri bugs?

The first step is to make sure it is actually a bug. You might try, for example, posting a question to the Gri newsgroup (see Q2.3), and getting advice from other users. Please be clear, so you don't waste others users' time. If you think you've found a bug, let the author know. Here's the advice from the manual (see especially item 4, for directions on emailing bug reports):

Your bug reports help make Gri reliable and useful. Reporting bugs often results in quick changes to gri which will solve your problem. This is especially true if your version is reasonably up-to-date, for then you can simply get the corrected version and replace the version you were using. Here is how to report bugs.

The details of how to report bugs is in the online documents , but the quick answer is to go to the Sourceforge Gri/bug site and use the slick GUI interface there. gri/doc/texinfo2HTML0000755000175000017500000003061013147557614012736 0ustar psgpsg#!/usr/bin/perl -w #$example_indent = " "; $example_indent = ""; #$ex_color = "#179C4A"; # dark green -- too light #$ex_color = "#14843F"; # dark green -- still too light #$ex_color = "#056819"; # dark green -- " $ex_color = "#82140F"; # dark red $usage = " texinfo2HTML [-h] [filename] Convert texinfo doc to HTML format, through processing of texinfo comments as follows: 1. Pass single line to HTML but not to other forms of manual ------------------------------------------------------------ \@c HTML some-stuff 2. Commented-out portions ------------------------- \@c HTML 3. Break file here ------------------ \@c HTML If it occurs on a line all by itself, causes this perlscript to chop files here. The filename will be as specified. The other_words will be used as the title. If neither the filename nor the other_words are present, then this script makes up filenames using numbers, e.g., gri1.html, gri2.html. If the filename is \".\", then this same naming scheme is used, but the titles are used. 4. Insert latex command ----------------------- \@c HTML Plants a comment to be stripped out as a latex-only command. BUGS: Does not search for closing braces properly, so that lines like blah \@code{blah blah the end is here} and more blah will not get the \@code{} item converted correctly. "; #require "ctime.pl"; use POSIX qw(ctime); use Getopt::Std; &getopts('h'); if ($opt_h) { print "$usage"; exit 0; } $debug = 0; #$date = &ctime(time); $date = &ctime(time); chop($date); $CH = 0; # chapter $SEC1 = 1; # section $SEC2 = 1; # subsection $SEC3 = 1; # subsubsection $allow_P = 0; $in_example = 0; $last_was_node = 0; print "\n"; print "\n"; sub get_a_line() { if ($_=<>) { s/\@noindent//; if (/^\@c\s*HTML\s*\s*$/) { $_ = <>; return $_; } } } return $_; } else { return ""; } } while(get_a_line()) { $line++ if $debug; print STDERR "$0 at line: $line\n" if ($debug && ($line == 2000 * int($line / 2000))); next if /\@cindex/; # Prevent unclosed braces if (!$in_example) { while (/{[^}]*$/o) { $a = $_; $a =~ s/\n/ /o; $_ = get_a_line(); $_ = $a . $_; } } else { $_ = "$example_indent$_"; } # Handle HTML inserts if (/^\@c HTML (.*)/o) { $_ = "$1 \n"; &sub_refs; s,\@value\{(.*)\},$value{$1},g; # set/value pair print; next; } # Process image commands (NOT...it's there already) if (/\@image\{(.*)\}/) { #print "\n"; next; } next if /^\@top\s/; next if /^\@include\s*/; # Ignore all other comments next if /^\@c\s/; next if /^\@comment\s*/; # Ignore unnumbered, since special case (see Makefile) next if /\@unnumbered/; # Ignore special-cases text next if /^Copyright/; # Ignore texinfo command to input files next if /\\input/; # Ignore some tex-type commands next if /\@summarycontents/; next if /\@contents/; next if /\@bye/; next if /\@message/; next if /\@global/; next if /\@setfilename/; next if /\@setchapternewpage/; next if /\@settitle/; next if /\@page/; next if /\@space/; next if /\@sp/; next if /\@defindex/; next if /\@vskip/; s/\@noindent//; # Pass contents of ifhtml blocks next if /\@ifhtml/; next if /\@end ifhtml/; # Pass contents of ifinfo blocks next if /\@ifinfo/; next if /\@end ifinfo/; # Pass contents of ifnotinfo blocks next if /\@ifnotinfo/; next if /\@end ifnotinfo/; # Ignore contents of @dircategory and @direntry block next if /\@dircategory/; if (/^\@direntry/o) { while(get_a_line()) { if (/^\@end direntry/o) { $_ = ""; last; } } } # Ignore contents of tex and iftex blocks if (/^\@tex/o) { while(get_a_line()) { if (/^\@end tex/o) { $_ = ""; last; } } } if (/^\@iftex/o) { while(get_a_line()) { if (/^\@end iftex/o) { $_ = ""; last; } } } # Ignore indices (for now) next if /\@defindex/; if (/\@[cfv]index\s*(.*)/o) { print "\n"; next; } next if /\@EGindex/; next if /\@printindex/; # # Save set/value pair. if (/\@set\s*(\S*)\s*(\S*)/o) { $value{$1} = $2; next; } s,\@value\{([^}]*)\},$value{$1},g; # Substitute set/value pair # # Fix some texinfo escapes s,&,&,og; s,>,>,og; s,<,<,og; # Special tweak to make 'Gri' look cooler. # s, Gri , GRI ,og; s,\@code\{\@\@\},\@code{TEXINFO2HTML-AT-AT},og; s,\@},TEXINFO2HTML-CLOSE-BRACE,og; # retain inside e.g. @code{} s,\@\@,TEXINFO2HTML-AT-AT,og; s,\@\{,{,og; s,\@TeX\{\},TeX,og; s,\@dots\{\},...,og; # Put in place-holders for some accents. I should check for all # of them, but for now, I'm just kludging in a couple, # to solve an immediate problem and to serve as a place-holder # for better coding. A good reference on accents is # http://www.w3.org/MarkUp/html-spec/html-spec_13.html # which I found on 2002-feb-24. s,\@'a,TEXINFO2HTML-ACCENT-ACUTE-a,og; s,\@'e,TEXINFO2HTML-ACCENT-ACUTE-e,og; s,\@'o,TEXINFO2HTML-ACCENT-ACUTE-o,og; if (/^\@titlepage/o) { while(get_a_line()) { s,\@value\{(.*)\},$value{$1},g; # set/value pair if (/\@author\s*(.*)/o) { $author = $1; $author =~ s/\@\@/\@/; } else { if (/^\@end titlepage/o) { last; } } } next; } while (/\@url\{([^}]*)\}/) { $the_url = $1; s:\@url\{[^}]*\}:\@code{$the_url}:; } while (/\@uref\{([^}]*)\}/) { @items = split(/,/, $1); if ($#items == 0) { s:\@uref\{[^}]*\}:$items[0]:; } elsif ($#items == 1) { s:\@uref\{[^}]*\}:$items[1]:; } elsif ($#items == 2) { s:\@uref\{[^}]*\}:\@code{$items[2]}:; } else { die "Cannot have more than 3 items in a 'uref' at \"$_\""; } } # # Convert cross-references if (/^\@node\s*([^,]*), ([^,]*), ([^,]*), ([^\n]*)/o) { $next_node = $2; $previous_node = $3; $parent_node = $4; # Start anchor, and set flag so end put after next heading. # Need this flag because xmosaic 1.0 does not accept # ; it requires

heading

# or it will not properly search the reference. I think this # is a bug, and reported it to the author in an email: # From kelley Wed Jun 30 16:31:13 1993 # To: marca\@ncsa.uiuc.edu chop; print "\n"; print "\n"; $last_was_node = 1; next; } &sub_refs; # # Convert headings; put the end anchor if needed if (/\@chapter/o || /\@section/o || /\@subsection/o || /\@subsubsection/o || /\@subsubsubsection/o || /\@appendixsubsec/o || /\@unnumbered/o || /\@appendixsubsec/o || /\@appendixsec/o || /\@appendix/o) { &sub_headings; &sub_emphasis; print; # # Last was a node, so put the end anchor in if ($last_was_node) { print "\nNavigation:\nnext,\nprevious,\nparent.\n"; $last_was_node = 0; } # # Done with this line next; } &sub_emphasis; # # Convert quotations s,\@quotation,
,; s,\@end quotation,
,; &process_examples(); # Convert Menus to UL (was DL before) if (/\@menu/o) { print "
    \n"; while(get_a_line()) { if (/^\@end menu/o) { $_ = ""; last; } &sub_headings; &sub_emphasis; if (/\*\s([^:]*)::\s*(.*)/o) { print "
  • $1: $2\n"; } } print "
\n"; } if (/\@table\s*(.*)/o) { if ($1 eq "\@code") { $start_item = ""; $end_item = "" } if ($1 eq "\@emph") { $start_item = ""; $end_item = "" } print "
\n"; while(get_a_line()) { next if /\@sp/; next if /\@cindex/; s|\@anchor\{([^}]*)\}||g; &process_examples(); # Handle HTML inserts if (/^\@c HTML (.*)/o) { $_ = "$1 \n"; &sub_refs; s,\@value\{(.*)\},$value{$1},g; # set/value pair print; next; } if (/^\s*\@end\s*table/o) { $_ = ""; last; } if (/\s*\@item\s*(.*)/o) { $the_item = $1; $the_item =~ s:\@\{:{:og; $the_item =~ s:\@\}:}:og; $the_item =~ s:\@\@:\@:og; $the_item =~ s:\@code\{([^}]*)\}:`$1':og; print "
$start_item$the_item$end_item\n
"; } else { print "

" if (/^$/o); &sub_refs; &sub_headings; &sub_emphasis; print; } } print "

\n"; } # # Convert lists s,\@itemize.*,
    ,; s,\@end\s*itemize,
,; s,\@enumerate,
    ,; s,\@end\s*enumerate,
,; s,\@itemx,
  • ,; s,\@item,
  • ,; s,\@bullet,,; # HTML does not use # # Multiple blanks lines are paragraph separators in texinfo if (/^$/o) { if ($allow_P) { print "

    "; } $allow_P = 0; } elsif (/ $title / $author \n"; print "\n"; print "\n"; sub process_examples() { if (/\@example/o) { s,\s*\@example,\n\n\n\n
    \n
    \n,;
    	$in_example = 1;
        } elsif (/^\s*\@end example/o) {
    	s,\s*\@end example,
    \n
    ,; $in_example = 0; } else { s,\@value\{([^}]*)\},$value{$1},g; # Substitute set/value pair s,\@},},og; s,\@\{,{,og; } } sub sub_refs { die "line $. of file: cannot have multiple refs on one line" if (/\@[px]*ref\{(.*)\}(.*)\@[px]*ref\{(.*)\}/); # anchors s|\@anchor\{([^}]*)\}||g; # Change e.g. # @xref{Viewing} # into # see Viewing #if (/\@ref/){print "AAA[$_]AAA\n"; s|\@ref\{([^}]*)\}|see $1|g; #print "BBB[$_]BBB\n";} s|\@xref\{([^}]*)\}|see $1|g; s|\@pxref\{([^}]*)\}|see $1.|g; while (/\@url\{([^}]*)\}/) { $the_url = $1; s:\@url\{[^}]*\}:\@code{$the_url}:; } while (/\@uref\{([^}]*)\}/) { @items = split(/,/, $1); if ($#items == 0) { s:\@uref\{[^}]*\}:$items[0]:; } elsif ($#items == 1) { s:\@uref\{[^}]*\}:$items[1]:; } elsif ($#items == 2) { s:\@uref\{[^}]*\}:\@code{$items[2]}:; } else { die "Cannot have more than 3 items in a 'uref' at \"$_\""; } } } sub sub_headings { if (/\@chapter/) { $CH++; $SEC1 = 0; s,\@chapter\s*(.*),

    $CH: $1

    ,; } elsif (/\@unnumbered/) { $CH++; $SEC1 = 0; s,\@unnumbered\s*(.*),

    $CH: $1

    ,; } elsif (/\@section/) { $SEC1++; $SEC2 = 0; s,\@section\s*(.*),

    $CH.$SEC1: $1

    ,; } elsif (/\@subsection/) { $SEC2++; $SEC3 = 0; s,\@subsection\s*(.*),

    $CH.$SEC1.$SEC2: $1

    ,; } elsif (/\@subsubsection/) { $SEC3++; s,\@subsubsection\s*(.*),

    $CH.$SEC1.$SEC2.$SEC3: $1

    ,; } } sub sub_emphasis { s,<<,<<,g; s,>>,>>,g; s,\@emph\{([^}]*)\},$1,g; s,\@strong\{([^}]*)\},$1,g; s,\@footnote\{([^}]*)\}, [$1],g; s,\@b\{([^}]*)\},$1,g; s,\@code\{([^}]*)\},`$1',g; s,\@\@,\@,g; s,\@samp\{([^}]*)\},`$1',g; s,\@key\{([^}]*)\},`$1',g; s,\@kbd\{([^}]*)\},`$1',g; s,\@file\{([^}]*)\},`$1',g; s,TEXINFO2HTML-CLOSE-BRACE,},g; s,TEXINFO2HTML-AT-AT,\@,g; s,TEXINFO2HTML-ACCENT-ACUTE-a,á,g; s,TEXINFO2HTML-ACCENT-ACUTE-e,é,g; s,TEXINFO2HTML-ACCENT-ACUTE-o,ó,g; } gri/doc/gri-manpage-redhat.10000644000175000017500000000352113147557614014304 0ustar psgpsg.TH GRI 1 .SH NAME gri \- scientific graphics language .SH SYNOPSIS .B gri [ .B OPTIONS ] [ .I CommandFile [ .I optional_arguments ]] .SH DESCRIPTION Gri is a programming language for scientific graphics. It can make x-y graphs, contour-graphs, and image graphs. In addition, Gri has a full suite of low-level graphical elements and sufficient programming capabilities (loops, subroutines, etc) to permit complex customization. Gri is not a point-click application. In some ways it is analogous to TeX; in both cases extensive power rewards tolerance of a modest learning curve. This manpage is for Gri version VERSION. .SH FULL DOCUMENTATION This manpage is intended merely as a pointer to the main documentation, which you may find at: .SS The INFO manual is accessed by typing .B info gri or by accessing the 'info' node in Emacs or in other standard ways. .SS The HTML manual is located at .B /usr/share/doc/gri-VERSION/html/index.html This manual is very extensive, and one thing you might like to check is the .I html FAQ associated with the manual, which is located at .B /usr/share/doc/gri-VERSION/html/FAQ.html .SS PostScript reference cards are at .B /usr/share/doc/gri-VERSION/refcard.ps (overall reference and quick introduction) and .B /usr/share/doc/gri-VERSION/cmdrefcard.ps (reference to commands). (Note: users of RedHat versions earlier than 7.0 may find the above-mentioned files in .B /usr/doc/gri-VERSION instead of .B /usr/share/doc/gri-VERSION as noted above.) .SH EMACS SUPPORT An .I emacs mode is provided with Gri. It is at .B /usr/share/emacs/site-lisp/gri-mode.el and is fully described in a chapter in the manual. .SH SEE ALSO Related programs .B gri_unpage and .B gri_merge for working with PostScript output from Gri. .SH AUTHORS Gri (c) 1999-2002 Dan Kelley and Peter S Galbraith . gri/doc/README0000644000175000017500000000052313147557614011445 0ustar psgpsgTo update the SourceForge site: make gri.pdf make html-tar scp gri.pdf gridoc.tar.gz dankelley@gri.sourceforge.net:/home/groups/g/gr/gri/htdocs ssh dankelley@gri.sourceforge.net cd /home/groups/g/gr/gri/htdocs \rm gridoc tar zxvf gridoc.tar.gz # may have timestamp problems rm gridoc.tar.gz exit cd sourceforge sh ./INSTALL gri/doc/mdate-sh0000755000175000017500000001013013147557614012210 0ustar psgpsg#!/bin/sh # Get modification time of a file or directory and pretty-print it. # Copyright (C) 1995, 1996, 1997, 2003 Free Software Foundation, Inc. # written by Ulrich Drepper , June 1995 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Prevent date giving response in another language. LANG=C export LANG LC_ALL=C export LC_ALL LC_TIME=C export LC_TIME save_arg1="$1" # Find out how to get the extended ls output of a file or directory. if ls -L /dev/null 1>/dev/null 2>&1; then ls_command='ls -L -l -d' else ls_command='ls -l -d' fi # A `ls -l' line looks as follows on OS/2. # drwxrwx--- 0 Aug 11 2001 foo # This differs from Unix, which adds ownership information. # drwxrwx--- 2 root root 4096 Aug 11 2001 foo # # To find the date, we split the line on spaces and iterate on words # until we find a month. This cannot work with files whose owner is a # user named `Jan', or `Feb', etc. However, it's unlikely that `/' # will be owned by a user whose name is a month. So we first look at # the extended ls output of the root directory to decide how many # words should be skipped to get the date. # On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below. set - x`$ls_command /` # Find which argument is the month. month= command= until test $month do shift # Add another shift to the command. command="$command shift;" case $1 in Jan) month=January; nummonth=1;; Feb) month=February; nummonth=2;; Mar) month=March; nummonth=3;; Apr) month=April; nummonth=4;; May) month=May; nummonth=5;; Jun) month=June; nummonth=6;; Jul) month=July; nummonth=7;; Aug) month=August; nummonth=8;; Sep) month=September; nummonth=9;; Oct) month=October; nummonth=10;; Nov) month=November; nummonth=11;; Dec) month=December; nummonth=12;; esac done # Get the extended ls output of the file or directory. set - x`eval "$ls_command \"\$save_arg1\""` # Remove all preceding arguments eval $command # Get the month. Next argument is day, followed by the year or time. case $1 in Jan) month=January; nummonth=1;; Feb) month=February; nummonth=2;; Mar) month=March; nummonth=3;; Apr) month=April; nummonth=4;; May) month=May; nummonth=5;; Jun) month=June; nummonth=6;; Jul) month=July; nummonth=7;; Aug) month=August; nummonth=8;; Sep) month=September; nummonth=9;; Oct) month=October; nummonth=10;; Nov) month=November; nummonth=11;; Dec) month=December; nummonth=12;; esac day=$2 # Here we have to deal with the problem that the ls output gives either # the time of day or the year. case $3 in *:*) set `date`; eval year=\$$# case $2 in Jan) nummonthtod=1;; Feb) nummonthtod=2;; Mar) nummonthtod=3;; Apr) nummonthtod=4;; May) nummonthtod=5;; Jun) nummonthtod=6;; Jul) nummonthtod=7;; Aug) nummonthtod=8;; Sep) nummonthtod=9;; Oct) nummonthtod=10;; Nov) nummonthtod=11;; Dec) nummonthtod=12;; esac # For the first six month of the year the time notation can also # be used for files modified in the last year. if (expr $nummonth \> $nummonthtod) > /dev/null; then year=`expr $year - 1` fi;; *) year=$3;; esac # The result. echo $day $month $year gri/doc/Makefile.in0000644000175000017500000011531513147560320012624 0ustar psgpsg# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/version.texi \ $(srcdir)/stamp-vti $(am__DIST_COMMON) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = AM_V_DVIPS = $(am__v_DVIPS_@AM_V@) am__v_DVIPS_ = $(am__v_DVIPS_@AM_DEFAULT_V@) am__v_DVIPS_0 = @echo " DVIPS " $@; am__v_DVIPS_1 = AM_V_MAKEINFO = $(am__v_MAKEINFO_@AM_V@) am__v_MAKEINFO_ = $(am__v_MAKEINFO_@AM_DEFAULT_V@) am__v_MAKEINFO_0 = @echo " MAKEINFO" $@; am__v_MAKEINFO_1 = AM_V_INFOHTML = $(am__v_INFOHTML_@AM_V@) am__v_INFOHTML_ = $(am__v_INFOHTML_@AM_DEFAULT_V@) am__v_INFOHTML_0 = @echo " INFOHTML" $@; am__v_INFOHTML_1 = AM_V_TEXI2DVI = $(am__v_TEXI2DVI_@AM_V@) am__v_TEXI2DVI_ = $(am__v_TEXI2DVI_@AM_DEFAULT_V@) am__v_TEXI2DVI_0 = @echo " TEXI2DVI" $@; am__v_TEXI2DVI_1 = AM_V_TEXI2PDF = $(am__v_TEXI2PDF_@AM_V@) am__v_TEXI2PDF_ = $(am__v_TEXI2PDF_@AM_DEFAULT_V@) am__v_TEXI2PDF_0 = @echo " TEXI2PDF" $@; am__v_TEXI2PDF_1 = AM_V_texinfo = $(am__v_texinfo_@AM_V@) am__v_texinfo_ = $(am__v_texinfo_@AM_DEFAULT_V@) am__v_texinfo_0 = -q am__v_texinfo_1 = AM_V_texidevnull = $(am__v_texidevnull_@AM_V@) am__v_texidevnull_ = $(am__v_texidevnull_@AM_DEFAULT_V@) am__v_texidevnull_0 = > /dev/null am__v_texidevnull_1 = INFO_DEPS = $(srcdir)/gri.info am__TEXINFO_TEX_DIR = $(srcdir) DVIS = gri.dvi PDFS = gri.pdf PSS = gri.ps HTMLS = gri.html TEXINFOS = gri.texi TEXI2DVI = texi2dvi TEXI2PDF = $(TEXI2DVI) --pdf --batch MAKEINFOHTML = $(MAKEINFO) --html AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS) DVIPS = dvips RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__installdirs = "$(DESTDIR)$(infodir)" am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs \ README install-sh mdate-sh texinfo.tex DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" VPATH = @srcdir@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS_TEMPLATE = @EXTRA_CFLAGS_TEMPLATE@ GREP = @GREP@ HAVE_CONVERT = @HAVE_CONVERT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PROGS = @PROGS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ # gri: doc/Makefile.am srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ info_TEXINFOS = gri.texi @OS_IS_FINK_FALSE@@OS_IS_FREEBSD_FALSE@@OS_IS_LINUX_DEBIAN_FALSE@@OS_IS_LINUX_REDHAT_FALSE@MAN_DIR = $(DESTDIR)$(prefix)/share/man/man1 @OS_IS_FINK_FALSE@@OS_IS_FREEBSD_TRUE@@OS_IS_LINUX_DEBIAN_FALSE@@OS_IS_LINUX_REDHAT_FALSE@MAN_DIR = $(DESTDIR)$(prefix)/man/man1 @OS_IS_FINK_TRUE@@OS_IS_LINUX_DEBIAN_FALSE@@OS_IS_LINUX_REDHAT_FALSE@MAN_DIR = $(DESTDIR)$(prefix)/share/man/man1 @OS_IS_LINUX_DEBIAN_TRUE@@OS_IS_LINUX_REDHAT_FALSE@MAN_DIR = $(DESTDIR)$(prefix)/share/man/man1 @OS_IS_LINUX_REDHAT_TRUE@MAN_DIR = $(DESTDIR)$(prefix)/share/man/man1 @OS_IS_FINK_FALSE@@OS_IS_FREEBSD_FALSE@@OS_IS_LINUX_DEBIAN_FALSE@@OS_IS_LINUX_REDHAT_FALSE@INFO_DIR = $(DESTDIR)$(prefix)/share/info @OS_IS_FINK_FALSE@@OS_IS_FREEBSD_TRUE@@OS_IS_LINUX_DEBIAN_FALSE@@OS_IS_LINUX_REDHAT_FALSE@INFO_DIR = $(DESTDIR)$(prefix)/info @OS_IS_FINK_TRUE@@OS_IS_LINUX_DEBIAN_FALSE@@OS_IS_LINUX_REDHAT_FALSE@INFO_DIR = $(DESTDIR)$(prefix)/share/info @OS_IS_LINUX_DEBIAN_TRUE@@OS_IS_LINUX_REDHAT_FALSE@INFO_DIR = $(DESTDIR)$(prefix)/share/info @OS_IS_LINUX_REDHAT_TRUE@INFO_DIR = $(DESTDIR)$(prefix)/share/info @OS_IS_FINK_FALSE@@OS_IS_FREEBSD_FALSE@@OS_IS_LINUX_DEBIAN_FALSE@@OS_IS_LINUX_REDHAT_FALSE@DOC_DIR = $(DESTDIR)$(prefix)/share/gri/doc @OS_IS_FINK_FALSE@@OS_IS_FREEBSD_TRUE@@OS_IS_LINUX_DEBIAN_FALSE@@OS_IS_LINUX_REDHAT_FALSE@DOC_DIR = $(DESTDIR)$(prefix)/share/doc/gri @OS_IS_FINK_TRUE@@OS_IS_LINUX_DEBIAN_FALSE@@OS_IS_LINUX_REDHAT_FALSE@DOC_DIR = $(DESTDIR)$(prefix)/share/doc/gri-${PACKAGE_VERSION} @OS_IS_LINUX_DEBIAN_TRUE@@OS_IS_LINUX_REDHAT_FALSE@DOC_DIR = $(DESTDIR)$(prefix)/share/doc/gri @OS_IS_LINUX_REDHAT_TRUE@DOC_DIR = $(DESTDIR)$(prefix)/share/doc/gri-${PACKAGE_VERSION} @OS_IS_FINK_FALSE@@OS_IS_FREEBSD_FALSE@@OS_IS_LINUX_DEBIAN_FALSE@@OS_IS_LINUX_REDHAT_FALSE@HTML_DIR = $(DOC_DIR)/html @OS_IS_FINK_FALSE@@OS_IS_FREEBSD_TRUE@@OS_IS_LINUX_DEBIAN_FALSE@@OS_IS_LINUX_REDHAT_FALSE@HTML_DIR = $(DOC_DIR)/html @OS_IS_FINK_TRUE@@OS_IS_LINUX_DEBIAN_FALSE@@OS_IS_LINUX_REDHAT_FALSE@HTML_DIR = $(DOC_DIR)/html @OS_IS_LINUX_DEBIAN_TRUE@@OS_IS_LINUX_REDHAT_FALSE@HTML_DIR = $(DOC_DIR)/html @OS_IS_LINUX_REDHAT_TRUE@HTML_DIR = $(DOC_DIR)/html @OS_IS_FINK_FALSE@@OS_IS_FREEBSD_FALSE@@OS_IS_LINUX_DEBIAN_FALSE@@OS_IS_LINUX_REDHAT_FALSE@EXAMPLES_DIR = $(DOC_DIR)/examples @OS_IS_FINK_FALSE@@OS_IS_FREEBSD_TRUE@@OS_IS_LINUX_DEBIAN_FALSE@@OS_IS_LINUX_REDHAT_FALSE@EXAMPLES_DIR = $(DESTDIR)$(prefix)/share/examples/gri @OS_IS_FINK_TRUE@@OS_IS_LINUX_DEBIAN_FALSE@@OS_IS_LINUX_REDHAT_FALSE@EXAMPLES_DIR = $(DOC_DIR)/examples @OS_IS_LINUX_DEBIAN_TRUE@@OS_IS_LINUX_REDHAT_FALSE@EXAMPLES_DIR = $(DOC_DIR)/examples @OS_IS_LINUX_REDHAT_TRUE@EXAMPLES_DIR = $(DOC_DIR)/examples RM = rm -f # REFCARD = refcard # CMD_REFCARD = cmdrefcard HTML_LONG_NAME = gri-long # INFO_DIR_SOLARIS = $(DESTDIR)$(prefix)/info TEX = ${SHELL} ../missing --run tex TEXINDEX = ${SHELL} ../missing --run texindex SUBDIRS = examples resources screenshots tst_suite EXTRA_DIST = \ refcard.tex cmdrefcard.tex\ install-sh archive-to-html.pl cmdrefcard.tex refcard.tex\ FAQ.html\ gri-manpage.1 gri-manpage-redhat.1 gri-manpage-SunOS5.1\ gri_merge.1-skel gri_unpage.1-skel\ gri2texi texinfo2HTML gri2html HTML_subdivide\ make_html_index make_html_commandindex make_html_builtinindex\ mdate-sh @OS_IS_LINUX_REDHAT_FALSE@gri_manpage_name = gri-manpage.1 @OS_IS_LINUX_REDHAT_TRUE@gri_manpage_name = gri-manpage-redhat.1 all: all-recursive .SUFFIXES: .SUFFIXES: .dvi .html .info .pdf .ps .texi $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): .texi.info: $(AM_V_MAKEINFO)restore=: && backupdir="$(am__leading_dot)am$$$$" && \ am__cwd=`pwd` && $(am__cd) $(srcdir) && \ rm -rf $$backupdir && mkdir $$backupdir && \ if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \ if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \ done; \ else :; fi && \ cd "$$am__cwd"; \ if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ -o $@ $<; \ then \ rc=0; \ $(am__cd) $(srcdir); \ else \ rc=$$?; \ $(am__cd) $(srcdir) && \ $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \ fi; \ rm -rf $$backupdir; exit $$rc .texi.dvi: $(AM_V_TEXI2DVI)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ $(TEXI2DVI) $(AM_V_texinfo) --build-dir=$(@:.dvi=.t2d) -o $@ $(AM_V_texidevnull) \ $< .texi.pdf: $(AM_V_TEXI2PDF)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ $(TEXI2PDF) $(AM_V_texinfo) --build-dir=$(@:.pdf=.t2p) -o $@ $(AM_V_texidevnull) \ $< .texi.html: $(AM_V_MAKEINFO)rm -rf $(@:.html=.htp) $(AM_V_at)if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ -o $(@:.html=.htp) $<; \ then \ rm -rf $@ && mv $(@:.html=.htp) $@; \ else \ rm -rf $(@:.html=.htp); exit 1; \ fi $(srcdir)/gri.info: gri.texi $(srcdir)/version.texi gri.dvi: gri.texi $(srcdir)/version.texi gri.html: gri.texi $(srcdir)/version.texi $(srcdir)/version.texi: $(srcdir)/stamp-vti $(srcdir)/stamp-vti: gri.texi $(top_srcdir)/configure @(dir=.; test -f ./gri.texi || dir=$(srcdir); \ set `$(SHELL) $(srcdir)/mdate-sh $$dir/gri.texi`; \ echo "@set UPDATED $$1 $$2 $$3"; \ echo "@set UPDATED-MONTH $$2 $$3"; \ echo "@set EDITION $(VERSION)"; \ echo "@set VERSION $(VERSION)") > vti.tmp$$$$ && \ (cmp -s vti.tmp$$$$ $(srcdir)/version.texi \ || (echo "Updating $(srcdir)/version.texi" && \ cp vti.tmp$$$$ $(srcdir)/version.texi.tmp$$$$ && \ mv $(srcdir)/version.texi.tmp$$$$ $(srcdir)/version.texi)) && \ rm -f vti.tmp$$$$ $(srcdir)/version.texi.$$$$ @cp $(srcdir)/version.texi $@ mostlyclean-vti: -rm -f vti.tmp* $(srcdir)/version.texi.tmp* maintainer-clean-vti: -rm -f $(srcdir)/stamp-vti $(srcdir)/version.texi .dvi.ps: $(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ $(DVIPS) $(AM_V_texinfo) -o $@ $< uninstall-dvi-am: @$(NORMAL_UNINSTALL) @list='$(DVIS)'; test -n "$(dvidir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \ rm -f "$(DESTDIR)$(dvidir)/$$f"; \ done uninstall-html-am: @$(NORMAL_UNINSTALL) @list='$(HTMLS)'; test -n "$(htmldir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " rm -rf '$(DESTDIR)$(htmldir)/$$f'"; \ rm -rf "$(DESTDIR)$(htmldir)/$$f"; \ done uninstall-info-am: @$(PRE_UNINSTALL) @if test -d '$(DESTDIR)$(infodir)' && $(am__can_run_installinfo); then \ list='$(INFO_DEPS)'; \ for file in $$list; do \ relfile=`echo "$$file" | sed 's|^.*/||'`; \ echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \ if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \ then :; else test ! -f "$(DESTDIR)$(infodir)/$$relfile" || exit 1; fi; \ done; \ else :; fi @$(NORMAL_UNINSTALL) @list='$(INFO_DEPS)'; \ for file in $$list; do \ relfile=`echo "$$file" | sed 's|^.*/||'`; \ relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \ (if test -d "$(DESTDIR)$(infodir)" && cd "$(DESTDIR)$(infodir)"; then \ echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \ rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \ else :; fi); \ done uninstall-pdf-am: @$(NORMAL_UNINSTALL) @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \ rm -f "$(DESTDIR)$(pdfdir)/$$f"; \ done uninstall-ps-am: @$(NORMAL_UNINSTALL) @list='$(PSS)'; test -n "$(psdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(psdir)/$$f'"; \ rm -f "$(DESTDIR)$(psdir)/$$f"; \ done dist-info: $(INFO_DEPS) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ list='$(INFO_DEPS)'; \ for base in $$list; do \ case $$base in \ $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \ esac; \ if test -f $$base; then d=.; else d=$(srcdir); fi; \ base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \ for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \ if test -f $$file; then \ relfile=`expr "$$file" : "$$d/\(.*\)"`; \ test -f "$(distdir)/$$relfile" || \ cp -p $$file "$(distdir)/$$relfile"; \ else :; fi; \ done; \ done mostlyclean-aminfo: -rm -rf gri.t2d gri.t2p clean-aminfo: -test -z "gri.dvi gri.pdf gri.ps gri.html" \ || rm -rf gri.dvi gri.pdf gri.ps gri.html maintainer-clean-aminfo: @list='$(INFO_DEPS)'; for i in $$list; do \ i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \ echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \ rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \ done # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-info check-am: all-am check: check-recursive all-am: Makefile $(INFO_DEPS) all-local installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(infodir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-aminfo clean-generic mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: $(DVIS) html-am: $(HTMLS) info: info-recursive info-am: $(INFO_DEPS) install-data-am: install-data-local install-info-am install-dvi: install-dvi-recursive install-dvi-am: $(DVIS) @$(NORMAL_INSTALL) @list='$(DVIS)'; test -n "$(dvidir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(dvidir)'"; \ $(MKDIR_P) "$(DESTDIR)$(dvidir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \ done install-exec-am: install-html: install-html-recursive install-html-am: $(HTMLS) @$(NORMAL_INSTALL) @list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \ $(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \ $(am__strip_dir) \ d2=$$d$$p; \ if test -d "$$d2"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \ $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \ echo " $(INSTALL_DATA) '$$d2'/* '$(DESTDIR)$(htmldir)/$$f'"; \ $(INSTALL_DATA) "$$d2"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \ else \ list2="$$list2 $$d2"; \ fi; \ done; \ test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \ done; } install-info: install-info-recursive install-info-am: $(INFO_DEPS) @$(NORMAL_INSTALL) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(infodir)'"; \ $(MKDIR_P) "$(DESTDIR)$(infodir)" || exit 1; \ fi; \ for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ esac; \ if test -f $$file; then d=.; else d=$(srcdir); fi; \ file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \ for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \ $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \ if test -f $$ifile; then \ echo "$$ifile"; \ else : ; fi; \ done; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done @$(POST_INSTALL) @if $(am__can_run_installinfo); then \ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ for file in $$list; do \ relfile=`echo "$$file" | sed 's|^.*/||'`; \ echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\ install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\ done; \ else : ; fi install-man: install-pdf: install-pdf-recursive install-pdf-am: $(PDFS) @$(NORMAL_INSTALL) @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pdfdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pdfdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pdfdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)" || exit $$?; done install-ps: install-ps-recursive install-ps-am: $(PSS) @$(NORMAL_INSTALL) @list='$(PSS)'; test -n "$(psdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(psdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(psdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(psdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-aminfo \ maintainer-clean-generic maintainer-clean-vti mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-aminfo mostlyclean-generic mostlyclean-vti pdf: pdf-recursive pdf-am: $(PDFS) ps: ps-recursive ps-am: $(PSS) uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \ uninstall-local uninstall-pdf-am uninstall-ps-am .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ check check-am clean clean-aminfo clean-generic cscopelist-am \ ctags ctags-am dist-info distclean distclean-generic \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-data-local install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-aminfo maintainer-clean-generic \ maintainer-clean-vti mostlyclean mostlyclean-aminfo \ mostlyclean-generic mostlyclean-vti pdf pdf-am ps ps-am tags \ tags-am uninstall uninstall-am uninstall-dvi-am \ uninstall-html-am uninstall-info-am uninstall-local \ uninstall-pdf-am uninstall-ps-am .PRECIOUS: Makefile html: $(srcdir)/gri.texi cd examples ; ${MAKE} cd tst_suite ; ${MAKE} # Make the info page (even if rewritten later) to get indices ... $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I$(srcdir) gri.texi # ... but this is clumsy and should be done with a dependency. cat $(srcdir)/gri.texi > TMP perl $(srcdir)/make_html_index >> TMP perl $(srcdir)/make_html_commandindex >> TMP perl $(srcdir)/make_html_builtinindex >> TMP cat TMP | perl $(srcdir)/texinfo2HTML > $(HTML_LONG_NAME) $(RM) TMP $(RM) gri[1-9]*.html perl $(srcdir)/HTML_subdivide $(HTML_LONG_NAME) "The Gri graphing language" $(RM) $(HTML_LONG_NAME) $(RM) *.pass2 if test ! -f index.html ; then ln -s gri1.html index.html ; fi touch html install-refcards: $(INSTALL_DATA) refcard.ps $(CARD_DIR) $(INSTALL_DATA) cmdrefcard.ps $(CARD_DIR) html-tar: ${MAKE} html-install DOC_DIR=./gridoc tar -c -f gridoc.tar ./gridoc gzip -f --best gridoc.tar html-install: # NB. Be careful in editing this target. Things that are # created during the building process do not have $(srcdir) # in their names; only things in the tarball have that prefix. ${INSTALL} -d $(HTML_DIR) ${INSTALL} -d $(HTML_DIR)/resources $(INSTALL_DATA) $(srcdir)/resources/*.gif $(HTML_DIR)/resources ${INSTALL} -d $(HTML_DIR)/tst_suite $(INSTALL_DATA) tst_suite/*html $(HTML_DIR)/tst_suite $(INSTALL_DATA) $(srcdir)/examples/*.gri $(HTML_DIR)/ $(INSTALL_DATA) examples/*.html $(HTML_DIR)/ $(INSTALL_DATA) examples/*.png $(HTML_DIR)/ ${INSTALL} -d $(HTML_DIR)/screenshots $(INSTALL_DATA) $(srcdir)/screenshots/*.png $(HTML_DIR)/screenshots $(INSTALL_DATA) *.html $(HTML_DIR) ${INSTALL} -d $(EXAMPLES_DIR) $(INSTALL_DATA) $(srcdir)/examples/model* $(EXAMPLES_DIR) $(INSTALL_DATA) $(srcdir)/examples/*.dat $(EXAMPLES_DIR) $(INSTALL_DATA) $(srcdir)/examples/*.gri $(EXAMPLES_DIR) $(INSTALL_DATA) $(srcdir)/examples/e*.ps $(EXAMPLES_DIR) $(INSTALL_SCRIPT) $(srcdir)/examples/FEM.pl $(EXAMPLES_DIR) (cd $(HTML_DIR); rm -rf examples ; ln -sf ../examples) # Sun Jun 8 11:40:52 UTC 2003 [Dan Kelley] # This is commented-out because it's not used. Later it will be deleted. #card-clean: # -$(RM) refcard.dvi refcard.log refcard.ps # -$(RM) cmdrefcard.dvi cmdrefcard.log cmdrefcard.ps # -$(RM) card # Sun Jun 8 11:40:52 UTC 2003 [Dan Kelley] # This is commented-out because it's not used. Later it will be deleted. #html-clean: # rm -rf HIDE_FILE # mkdir HIDE_FILE # mv FAQ.html HIDE_FILE # -$(RM) *.html *.png html # mv HIDE_FILE/FAQ.html . # rm -rf HIDE_FILE #info-install-solaris: # $(INSTALL) -d $(INFO_DIR_SOLARIS) # chmod 755 $(INFO_DIR_SOLARIS) # cp gri.info* $(INFO_DIR_SOLARIS) # chmod 644 $(INFO_DIR_SOLARIS)/gri.info* refcard.ps: refcard.tex $(TEX) $(srcdir)/refcard.tex dvips -o refcard.ps -t landscape -t letter refcard.dvi cmdrefcard.ps: cmdrefcard.tex $(TEX) $(srcdir)/cmdrefcard.tex dvips -o cmdrefcard.ps -t landscape -t letter cmdrefcard.dvi gri.ps: gri.texi cd examples ; ${MAKE} eps cd screenshots ; ${MAKE} eps cd tst_suite ; ${MAKE} texi $(TEX) gri.texi $(TEXINDEX) gri.cp $(TEX) gri.texi dvips -o gri.ps -t letter gri.dvi #ps-install: gri.ps # $(INSTALL) -d $(DOC_DIR) # chmod 755 $(DOC_DIR) # $(INSTALL) -m 644 gri.ps $(DOC_DIR) gri.pdf: gri.texi cd examples ; ${MAKE} pdf cd screenshots ; ${MAKE} pdf cd tst_suite ; ${MAKE} texi pdftex gri.texi $(TEXINDEX) gri.cp pdftex gri.texi pdftex gri.texi pdftex gri.texi # Add to some of the automake-created targets. all-local: refcard.ps cmdrefcard.ps ${MAKE} html install-data-local: ${MAKE} html-install $(MKDIR_P) $(DOC_DIR) $(INSTALL) -m 644 $(srcdir)/../license.txt $(DOC_DIR) # This is handled by gri.spec [2003-may-31 Dan Kelley] @OS_IS_LINUX_REDHAT_FALSE@ $(INSTALL_DATA) refcard.ps $(DOC_DIR) @OS_IS_LINUX_REDHAT_FALSE@ $(INSTALL_DATA) cmdrefcard.ps $(DOC_DIR) mkdir -m 755 -p $(MAN_DIR) cat $(srcdir)/../doc/$(gri_manpage_name) | sed -e s,VERSION,${PACKAGE_VERSION}, > tmp $(INSTALL_DATA) tmp $(MAN_DIR)/gri.1 $(RM) tmp # Install manpages manually; man_MANS puts them in /usr/man/man1, which is not where # they are supposed to go, at least on linux/redhat systems [2003-jun-8 Dan Kelley] $(INSTALL_DATA) $(srcdir)/../doc/gri_merge.1-skel $(MAN_DIR)/gri_merge.1 $(INSTALL_DATA) $(srcdir)/../doc/gri_unpage.1-skel $(MAN_DIR)/gri_unpage.1 mkdir -m 755 -p $(INFO_DIR) echo "INSTALLING INTO INFO_DIR WHICH IS [$(INFO_DIR)]" @OS_IS_FINK_FALSE@ $(INSTALL_DATA) $(srcdir)/../doc/gri.info* $(INFO_DIR) @OS_IS_FINK_TRUE@ @echo "DEBUG: The OS is fink" # This is handled by gri.spec [2003-may-31 Dan Kelley] @OS_IS_LINUX_REDHAT_FALSE@ gzip -f --best $(MAN_DIR)/gri_merge.1 @OS_IS_LINUX_REDHAT_FALSE@ gzip -f --best $(MAN_DIR)/gri_unpage.1 @OS_IS_FINK_FALSE@@OS_IS_LINUX_REDHAT_FALSE@ cd $(INFO_DIR) ; gzip -f --best gri.info* uninstall-local: $(RM) `ls ../*ps ../license.txt *.html gri.info* $(HTML_DIR)/examples/* $(HTML_DIR)/resources/* $(HTML_DIR)/tst_suite/* $(HTML_DIR)/screenshots/* $(HTML_DIR)/*` $(RM) html $(RM) $(DOC_DIR)/license.txt $(DOC_DIR)/refcard.ps $(DOC_DIR)/cmdrefcard.ps $(RM) refcard* cmdrefcard* $(RM) $(MAN_DIR)/gri.* $(MAN_DIR)/gri_unpage.* $(MAN_DIR)/gri_merge.* $(RM) $(INFO_DIR)/gri.info* # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gri/doc/resources/0000755000175000017500000000000013147560320012563 5ustar psgpsggri/doc/resources/top_banner.gif0000644000175000017500000000137213147557614015420 0ustar psgpsgGIF89aZñc!!ÿÿÿÿÿÿ!ù!þ+ Imported from GIF image: top_banner-a.gif,ZÁc!!ÿÿÿÿÿÿþœ©Ëí£œ´Ú‹³Þ¼û†âH–¦Jj°Hê&1l½ªNú}ëé„C× ˆ“ýrÄÖé+.}Ê$õ„Íj·Ün7ŸÂä0¤L®\Fâ“ù\¯s¨Ò‰w³íW\ôø×Wd‡ÄFÅ#„å—äåø)Y‚V)6fö6ÉÙéù *:JZšˆøfÑ·£úâ÷ÑøÚQgj{‹›«;ð˜éð›qtÐö0L¬X¬Šœxçœ -=˜œÓ´œM]Ml¼½.>îkIiÙ«‰N~*ëÕî>Ï^oŸ¯¿Ïßïÿ…6ÊV½AaB c¹ 1¢ÄÁ° 9SFØÁþo3ml3…ÙG)³ª9c4¥I®¾×BÙInܺM¼‰3K%è2ªë™‚ _X»SÐæÀ”qhuÊ4¥Ðƒ0M=jU&£9»zô‰?7}÷P kÕÄ9 7®Ü¹tëÚ½‹7¯Þ½|ûúý 8°à¹b½À±¦ÁWivl¸˜NZ [¾|¡¢E³†9G.‰˜CѱTÆŒ:5Ÿ˜.–õŒb#¡ªKYÒ®-f”ržr‰ôh"AЦ‡ªTµrSdGŸ-Vôpg=ªdßǵ_ïa»÷ªÈk]$o¹úOÑ)>Ý|êtŹƒ{ úþuòã’§9nYž2q'`rëÊ{Ι_aÒÙ÷” 1Rp[½”ÔËHØ_‡L¥wŸ†nX”Õˆ ‚*rÖa ¦k~¶Š…"4Ucv+îX—ƒ ø8ãd£]ÅxÉc’J.Éd“NŽƒJ”RNIe•V^‰e–ZnÉe—^~ f˜bŽIf™fž‰fšjšùd›n¾éI;gri/doc/resources/bottom_banner.gri0000644000175000017500000000057213147557614016137 0ustar psgpsgset font to TimesRoman set font size 12 draw label "The Gri Graphing Language" at 2 2 cm set line width rapidograph 00 draw line from 2 2.4 to 18 2.4 cm set symbol size 0.4 set color rgb {rpn 99 255 /} {rpn 33 255 /} {rpn 33 255 /} #draw symbol filledtriangleup at 16.2 2.10 cm #draw symbol filledtriangleleft at 17.2 2.15 cm draw symbol filledtriangleright at 17.7 2.15 cm gri/doc/resources/Makefile.in0000644000175000017500000002713313147560320014636 0ustar psgpsg# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/resources ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) VPATH = @srcdir@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS_TEMPLATE = @EXTRA_CFLAGS_TEMPLATE@ GREP = @GREP@ HAVE_CONVERT = @HAVE_CONVERT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PROGS = @PROGS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ # gri: doc/resources/Makefile.am srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = top_banner.gif bottom_banner.gif math_symbols.gif\ pixel.gif sm_bg.gif symbols.gif top_banner.gri bottom_banner.gri all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/resources/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/resources/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am .PRECIOUS: Makefile developer_all: gri bottom_banner.gri convert bottom_banner.ps bottom_banner.gif chmod a+r bottom_banner.gif rm -f bottom_banner.ps gri top_banner.gri convert top_banner.ps top_banner.gif chmod a+r top_banner.gif rm -f top_banner.ps # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gri/doc/resources/symbols.gif0000644000175000017500000000461113147557614014760 0ustar psgpsgGIF89aó ðÿÿÿ!þ0 Image generated by Ghostscript (device=ppmraw) ,ó þ‚aÉí¼žœÕ‰³Þ¼ûjG¨4ƨ áE¦(ÛÆòL×P«ºc-§¯šx§ÇÏò*"‹0¥í %¬ËîàC&zØßqéô‚X­«o¿Ò¶{–Ó]Ã)­Ð|ï­ñ/3¹Þ´W‡6HøvˆÈÇ5È•dQȨé7§#صFDIè—*Ú¹µ÷¨ÃÇ ¸SZé'ø‡Ú˜ÙZ8z‹»xÕÈŠFtšWËôÈH•Ô{Ùkx‡Û|¨k·ë« +7Û©6ö:aYÜ· êc-ÒòÖʵ‡.o¾3úô™×³ìþ}ÜàÂåÛg7þ¾(ïúþçïïTwΙâ€íÔÇ)‹`W]üE|4hÌu†EÈÝs ¸ dòôÖ/m}¨4v%á‰Wu¨âV,¶¨U0¢øÙŒ6Þhà8Ê6—ޏ£oÞâ£|I†.Þø$Kx¯iÝ î6IO7ôaœk" e_ Õ•Øq`b©ájÅ8D˜†`Rbטx•™šEnB˜nUY`«ôT#iMÌäPkUa„R•Å¡°ªh£Žú¨D}7ʤ‘Ê(b‘ÑåZÉ€T’"ú2|všª¢¥Éàbœ*sd–SÖ'VªJÇj­Ë„yœš¯&ê‹®ˆ‰f®*}ÉþkžÈÂYÓL1nHQ‘G0¥F`–iS[@YJ›°óÁñm:óÝÚ¤‹xnŠnºê®Ë.j™Š`#·ÛUJn…š²6ç»­ëíyB:öi’œ†©ïùеEVÚ$R oo.»,]S¬P½fA»ª®Yº«JzZ<åJ÷CÍ3ƒ»¯¯lâÕÑ µžlÉ ÍáÆ_ñYê’Ë’mˆ|íÁIY¨žÊˆrãŸÎT®(n»¥,uAòVuÖéÛ(Ôî÷¡Óä­%‘aªcµVn#jqcËÛ´Ä\os®Þ+q¯/“’s )qw¾™{Ÿ«÷ÄÏÞ”´„»\³²6Gþ|%vÁœ¼â ÈóÐrh"´“@Û‰Îutï…4gŒ#%+|bŸå¬Ö¹+ûìµo½úíºïnïÀùøÕÂû^m½3d¼-ÿf¼gqƒZ…ˆÛDí«i\_âë'Å—weÛ,«2d;¥ýâ‚/¾Háÿsµßä°Ý˜ð"ä ,ó÷ÇæNäÛÄ• jÅMnà œ!=ÑmI Uð“yè :šk~¾{Çé*8 jpƒ(ÓÝåÂG5Oi!tÔG§žmmdÐ)´@\âpÑÔDÄ×0³Ié-ÞZè.Å\h‡Ù¡ÜûBf²8½…ÿ›–o ¨ðPfÔþë±Ä+2$‹Z E›ºˆE0ŠqŒdDIôôÅ¿C}Ì‹eÌPu¢ÂþÌwk$"tJw£òÕ1BÄ3‹§¹¯½ñkÔF¼‚µœ; îŒ>‹¡}ü×Fg@2’f³ %ÉœK®C‚š¤_'õ“Æ- €òåN˜®úq¤ªdŽE.uD3 ì}u “¤H5ÆR{Ñ€"‡JKº.e_1{I8͉X'´U&MÒ¯ã¡Ï—ûZ愚9,b:Ï–uâ&öî´¤¢YCh¡Ï'û§Ísö(êl¢Û‰v“K^›§=AcÊÿ ȔʫÚ¡™<ô 4])ÒLÞØCo²‹d;|Lþþ¹÷èq—ÅtèòF4C‰ÖSš/{˜E™53¾Ó  •MÛ˜ÎReo¤÷ì&K[­Â`2)I¹hSV†2§<õòDy@àm†Ÿ¦©e.vê’{ÔKÑÜ_3š†Ò3jõ3à-C…À¬FQtV+á¿X6Íd¦.V ­¨¼×Ñ?Þ§?rãRï˜Ìw’Õ~/k ­ŒÉG⊢ó k5ÿÚº:~±ri}eæôªSQ¹ó–jk[N…ÒLBv¶„êMkÚSú½4³2D,gkYJrò³¤Í!~`T#=ˆkÁ«¤B›A¦ñ«­œea 7¹”ŠNU).ö©ŸÍŠÕK daþ£T˜$—šÕÈ‹T¦¸$Æ,Y†Ý$ðâø0dVS®ÚýkZçú¹¿MÎåk_Cê]ñQ°03¤ ;ëŠ-hú´ªçR^¸ê±? V¯·¶ÜzVE·ÁmÏ l®³ÕC˜-­ƒ á1B©f°o»™Öfص|jrIÒTŽ2•Ãd£W«›T£M5¾Uõfo‚+Gm-ÌzýÅ(=×Á®éµ…sè0ðN‡E46Ï;[µÔ¯jâ.Ó{¿2Ù˜ÈÒu/Š)²¹Ú"ùÉ4´2z³ƒ¥˜´îɤºaÎæ«­Åbï· $nèØ,„7ãWÆÅ!PÕlBŽc³3ZðF[þT@ÃÔÏ®p„ª¡öOi[íˆqd8Õ+]åÆB\â!öóYíÝ-Ug_'íŒÃÍËŒgÌBi[®X›Û])g­FTPßþ™éªxù­†õ¥“{ýÞïB”o¦Öm« íÉ]+w½¯V/“ ×é ‰Œ°í-³å©YÅzZÔ¡Œ£ˆê8«šÛY=ÕþOBK”uæ ÕÑnDLÞΣ·ˆíï')ºEùltIˆÚZ%“4Ã/ù ²÷šë{»Ó‘æµyŸ»5Û†-J­å_|&ÁÐ9°3ö-8ÎJ‰+âáÃ5—¡›8i§ïbæ¥N’¯Ëìíšúä+7\­óKì=YcºÃçÛy²Ÿ=^“Û½ažöÊÆ;gri/doc/resources/sm_bg.gif0000644000175000017500000000072113147557614014355 0ustar psgpsgGIF89aÄ ‘ÿÿÿÿúúúíííÞÞÞ,Ä ÿœ©Ëí£œ”‰²Þ¼û†âH–扦êʶî ÇòL×öçúÎ÷þ ‡Ä¢ñˆL*—̦ó J§ÔªõŠÍj·ŸŠ÷ ‹Çˆ ÷ŒN«×ì¶û ËçôºýŽÏë÷ü¾ÿ8DFXhx(a&¸ÈØèø)9IYiy‰™©¹ÉÙé9‰*:*¦øyŠšªºÊÚêú +;K[k{ËFª»Ë«`Š ,;]nV=®¾ÎÞîþ/?O_¯yŽŸ‘nßïÿ0 À Œ8±âuG¼8²äÉ”+[¾ ɱæ1{þ :´èѤ{l> séÕ¬[»~ ûp;gri/doc/resources/top_banner.gri0000644000175000017500000000057213147557614015435 0ustar psgpsgset font to TimesRoman set font size 12 draw label "The Gri Graphing Language" at 2 2 cm set line width rapidograph 00 draw line from 2 1.85 to 18 1.85 cm set symbol size 0.4 set color rgb {rpn 99 255 /} {rpn 33 255 /} {rpn 33 255 /} draw symbol filledtriangleup at 16.2 2.10 cm draw symbol filledtriangleleft at 17.2 2.15 cm draw symbol filledtriangleright at 17.7 2.15 cm gri/doc/resources/math_symbols.gif0000644000175000017500000004110613147557614015771 0ustar psgpsgGIF87aÄ ðÿÿÿ,Ä þŒ©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçúÎ÷þ ‡Ä¢ñˆL*—̦ó Í €iôce«×cVKýv+b•ë%mËc¬ú€n+ÙKt\Π#ôÒ5·¥À×öG6b7Su'¨ågh¡§( iD9t—ÙÕ¸ÀÑzùFõ²ɸºš0 ‘š“8i&öªêpÛ JšÖ$JÇ:*¬Ã«+XæÖÚ fšŒe;h¼¬¹9-í:I|2Œ¼ýÙìQþ`ÌÂg]9žœÞî 'oLÞ-‘sžWài™0vó."g.Û®}˜x‰ëpCTÊì<ÜÍDþ ýþ›!‡Œ ¢cUãÇ23Ž¥I€õ¬q{™r$5zĉ$$@w}žLNèÌcy\"â´TÚºšÁœ 5ʰ•‹4Æ òk‹33©òI“k¯ƒ§Fz=›vŽCW=ÑÂ5qˬÝ=jé…UgR/Q¾*ï^zÕwì[»oncØQgÜ£E û½Lï—›“jÚL)°j‘AÛ 5͋̾ \Ýšìã•B-·<øuÖ]þR »·fÙ~Ù½ÎÜwJm•—­˜ó»Ï“Ó’ý6[yéÛvãÍx¸ïØç6JáKMÞº»q"×ι_ôøð¥[‡‡òøùÓ¸þ%g]ÒuÒÑ·Ævd,å][ ²G_aâÄQ.¶‘÷Þ|ú݇UHvˆa…éÄ—]6ˆ¡‰õ}”Wb*7^†`âœ%’ÍØß_V1GãdØ\4¢BÁµÆa+A×c’û 5¡Ž¨f iÁIÙžñ„¢žc–QIÕ,ü)y`.ãéZgS&òVVb&©íˆÙ;8Ú¤åhð¡w§eˆ‘%È–nV¹'ŸmâiŽœp†¹èhjc•Â=ö€?êß—n¾ùd™Iº¨fÎÖ%€nŠ*ªhž*¦ Ü©öÜ¥£:©W¬:‚cœ¯öGg¡©9)z•nz)°•°zþë ŨbGtz´Ü®¹bŠ%:á)™aykB6Õ^ÙF›)“ VûfúÍWˆ¨Úá™ì´†v·Þ¢«&í­¸Ï¼q‚Ší…êú«>ÔÔèÞ»Ë^x°·žjx’½."Õ-k„Nô¬DÆnˆO£NnYhDäùj'° ç¶0¸¦‰›ãÆ$K,%³êKd»j¬ò»ÆÂܧhbqÊ1´´¦[ë¾ _Ìs½á@™#‰s3+µ±ìﱿy1ø=×£Ô <¬ÍäÊ[`¿ì[¬ÈU[²Ã§!¹5Sp^´ËëÊ [ÙWº=u‡63v)ÝóeeãL6Ⱦ²)츔͜ɇòk÷È–¦þÍ¢ŸO50™,' ÉÕ^/¨¨;Þ•%zØ`Ü£Œb7 ÷؇c91Q£gn5¡æÊ¦nÝü¶º˜ãÝTà/뢦o³Ã"ûuBhïN´µ‰—Îè‡.¿ôíVJ>}ñÚÆƒ"õDÐþ±x³P¬-ꎻ®4™Ã Ͼë”y¾ˆ!Ì-þyºÛ[óÉ¿o=û±/?w2RžÚ·>Já-t àÇ*/ÁDyhaàN¤g¿f‘ÆLôÓY7x<ºïdåJÑÄÊ:v•hƒòÉ_ ÷73xqÇ‚5œ}¦£ÁOÙ …Y±Ürl'Cß•‡rê`¾|H9è|ªH€bËÿª+ý!чCäßþ GC§%qE'B†yδ,¶Ï„– áv ¦‘[þ«™ûRxùq…c¼á{Ѝ:žqÍŠ² _ÖÀ=@1x9ÑGjŒ:à%òS†´éoàÊd Q¦©Å•°$¡!+ ?†b“ô9yJx¹*“©,åÕàÈp2’%ˆ,giI¼Ä²;ðCe+uéÊPž‘—ÔT‚æKšõr‘Ǧd–È&:³9µü[“x÷G@Vä‘K&4?ÙMLSœ¤%8¯éË£±®OB|åS‚iJtzòð …&çLsڳɬ',ýIÌM’¶Ì@Q©Û>þ)‰ÉÕr—z|èøò)HƒZ¡€9(#û)Pˆ€´†ÕiDi™S*5éVêÒ˜Êt¦4­©MoŠÓŒF/§,M6ÛÀ¢ß}ǧߔm„* ¢Â”§‹ÄØN9 =¦B0Eg½Ü‚Ô¤bõ©š¨ËOÿ›’«ªRçÔÈú„¹”]ê ŽÔÔ=^ð­eœkÎtÚ;ÚUnu z×½®õEÔd%T·Y•¨…† é© $œ¾nµYåg›ôÊÇ®ÕYBŠŸÔ&«8ÆÈ¡­ çÛ<#P4¤E,´ sÈŽ |EelÓÙ¢”Áñ™Kü\àèÛ¾MÏ´†iÌnþÑ¢(ylÃ,âhåÚ þι1l•d‘[›íö¶k²îG\Ë.´ø g3qY;!üP¶r}(Û1ÊVV¡V¹mk‘ÄÞöâ5MUeÛÌÎëO Z_×5êxÌJÏ ¸[°x¿ª§µ³èUätßË[[ÅUc æê‰ve/ä„çlAb:³OýtkJ·Æ%9T!Œgwy¶zV¤qyFG‡væ8äãcv‡=$‚[¸iBH?UÄ?¥v¥#JvX?x8jDkÄhr$kÂR<%F}è‡çÒƒkôWžWn^U_tçˆ'‡FRhdþ‰šÈB›Ø„Ø…hXâf‚æCFésBž8†QG|Hzo„Z‰Y\]mX5oèBð&ÛA‚ǧ"‚Ø|&£}…‹@g`{©X2b‡n¶D´ÈM#tІˆÀŠ­˜¤H5j8™@aÑ‹bµtbIXŠ¥÷ (U‡r§¨°aê­b0Õt”8‰ZÁNYØŽmC§'R%õg 6xPÐHuŽýawÇ€R\(Qø¨'‘)‘éH‘¹å¨‘‰‘4Foåµpy†’šÆ‘ê÷RéÆw‚Zè ,f­$~ È\9_á“f0‚㨈|ü§uÖQþé3¨Q'i“Ï¥’+Ù~=5’é‘J9AæØb5Ž>éT&™•KÉŽBŽSY[µp•1æmù˜V5‘éMév#jy•Äty¿0Qq‰w/òEñÈ\*¨—fZk¹rLG–v¹,_YXRYoRáh"ùNaé4Š©k}éSƒE AåM“ÙU˜I—šÙPLI™‚ ””yTTÙ ´d|x0š¤ÙO a‹`šDIR“yši©T)Õ™¿1›€€H“•›¹$™bS£˜nÓ›¡yV°›`Yœ¾é ˉtõƒˆÉS•|ŽY\4åj?9•)¡Z°¹Ãy…”%ÖIž`¹åë…~6 þ¹†œÈåœerx^Ù)‰eRqFëÙ-t˜½R˜'0áÓš—\¶åœBù[3EŸ3©›ÐMĎ̸Ÿ¼E ¤™‚wxÑ'-w¡¥ÒŸŠ1ˆ/9^¢V™&~ ºu Ê Ÿ× 0JþiÚâUÀ—™zM5„,57¨'Tz·XfY ÂQ­å]єɢ†ž Ù(–ž¸…b9€8 OÙÅ'¹s H8~󉥦f£,ÑŽ`j(C —Š’±ˆsijžb–”Z¹žg:£Ð™£EQ¹¤$Š`rŠ”Ø).T¦óIm ÷ ºG*Q†F3âA+’uÕ`[¦þ€ŽšhètÈö¦+Šè˜‘—ºoêooçD£Gº}“÷ofl±*vÎâvê&rúiB8Ùž"Êq)–a7©’˜xYì9Okw˜ðé…hkg"F*¥ǬªèL¸v\>ª£i©‹™†M/#J2(E÷5%Ô:®´¶ŒËøƒÚ: ÆJbJ™m'GØ}Qj’FŠª&W€Õyƒ­ÙAßz“J2Þ£'`W¡gqn:l’DyDlç_x˜âºJæhz;W~Œêrñ¥:KmïӴ;«o°j:ËʦÎBú¯8¸PÐ “F©’ýÚ¦Êõ:>X²kC°ÜþÊ^)vßf´f“^Nµ±î&±èdçÝ–±·ª³ëEö±V±…㪳³'7ËS!j×tØ÷Xý“³KˤOK¦µ¨¯o™I1»a Hˆ¢®å†¬ðפõG³jpPs·@›¶4É·ÿšvWW‚ªÉ;¦ŠµJºVZ‡fÏC®ª€nwìú‚x€Q»P;Š~…™~Å:¦GÛ¶† ¶0(³`ÄF#Mv²÷D²Â7:‰´‡.jKxQ+€Í—zîùÚ©±;=Å Y{¨EªsIÛfÊ{¢Ç;¸âu¼Ð ½X½œ‹ñ6ºq‹¼a:½êö½j¯½ê™›v½[¼yg•þ×[½ç{¾W#K³¸Ç¾=‹²5½ù»‘º Œœ‡½Ðµþ¼Xڞﻳ黕_Ú½Œ«Éƒq›«_á»–徇SÁd‹m¾ ;§“º¿k½Y¿Ræ¼¥»‘|”(iÀg‚ÁÎ'Áï›Â2º3/œ“¯¶°mäÂ÷û”ù+ÁææD‰+O (m9Ì¢7,Ľû«+Lx4ìpqª¾xŠI- ¤íÂ3û¿ˆËeü'g\á»Ã/ Å_;¥Z¬ÃôwÄO<Å̼ôv62Ì•)\¿%)Pc kú»«›Z·hÉD‚²Ãz©D]¬ÃOh‹Wd7ÿ¡Çl¼},Æ~üÇžÕ®ŒºÇN þÀqjÆRœDV É“ FÜØ…›Ü®…(Çtì®l¬Å!è©È\ÜȆÉŒA¤œÂ:fpLƒ \ÇœÊÉs[ȉËÔÈ´]f¡ƒ¨Ë¯o˜¼‚ˆ¬Ì}¬¹dÌxHÌwʽtÈ…ê½{Üʸ{Ïüе°µhʽÀöÅr<Ë›ÌÉo\Æ Êèl¯è¼È¬œòÖl±£lÎaÍ%ª¿æ¼ËʉÈx·Ê’βŒÇ¥8ÍöàQÊÌ`•ÇNÌ— MÍÅܪžó(V Ñœ9‡ÀJÀÆY¾ÁêÉŽžÏ™ÑŒˆ ¥Š·–(=Pƒ™Ñ#}«ü…gË I­4}£-æÒ%þü—éyÓUºÑBÈ2=ή¹Ó~ÚÓ&=µ{º·ƒJ‚ʓªgÏ3]C¦¹=£mUëH\á Ó ÍÕËü¸I ·'¼ÕŽ[—Cía`Ít5aÕå§íÔF½¥§öÕ­^à¤x­eùœ™a=œjí—B ”Œ\\ÀMí׋«×Ýìgf˜„Í™´§ì,¿uíÑ»Òw™ØŠ­Ó5Í+B« ­Ð’-Åk˜µÀâùZÉQÖÒiÊ¥­ÈyŠÚ­ÝÙ!}“—½Ú9‘škõÛŸÉšUÙÜ5uܾð™ËÍÜÍíÜÏ ÝÑO¦-ÑÏEÝSU›¶×}›ûÁݘ ›šMPá½™Ö-ÞþZÕºrÔôݨé~篸 ßg}í]Ýljš¶À›ó¬ÒeßÒíÂ-ÉimåR5ëÚ/UXü­Ûí¥àS]£DúÄJ›|%ݬ]´£dWÜÍÎ~,“œÍR£ Ú0oÁY"Þß}ê@¡ öÏ•ûÖ_‚âS:'ÿ’Xi*4ŽÜ'øØZµ:9çÆ-n]¾ãʪä@þÓÏ˪}ÄW ž«¨fä,ÚþâQºálºtõ¡7îä7vŽöãɺUñ¶ªkÑD-§w*¾z +IN×íÆ˜#©êJæe ²€zº#’aŽÅ­ Ž].™7µ&~uBª^½ç+žœnÄçC¥þvŽ—ÝÓ§V:Ö‰®¸ò‰ÓñkçÔãxén§ª 6T>äûôئíÅ1AÄß,Хؖ½ý—âBã•NÝ?.vÜgmäü‹©OŽ‚ß+ÃÔ;å°<ÁP[ÐÌÍLz–cNÒŒlë)úìê·êANncìΫÞê°ØÜϧNèõÔìÙìÎú\ßË^Ø\øÌt¬î GÊç^f‡þå¯M9œZ ºÉÍù Ï÷>ï9ËïnÌò>küͧ»®ƒLåBSî±þÙjoÐÚ.î›ýU ¯Í¢îÿ.Îl‹înî/é$-²)îc–ÀºŽ¾?~±*æÖÅ–â«öîPíòì_$þ|Á ¹±ô\ŸÐæê•xvÅ»ŒLÅ3O½]Úò‹aôAkuß¾Ö~¿¹Âò™Ž¾}§lD<Àê|»Í›Ç$ÅÀ»“ yö»ë·äáG¼öWõ cöñª¾J-~Ækî2R_êC »ŽzDŸ¡=^÷îK}ð<ôÙj8¬ÖÀÖ¿ ÑÞ»¼ŠRò*ó {;_yZ¶b_÷cÇó˹wñ “öz‹gl桬¡ÍõDÖ![ÀÎÖöv¯ï<ÏúÃtÆ–ŸÛj~||ð&ì¶²N‘rO¸oƒOøq§Ñ+<ó…8ÀlçÁšßðkm~˜lê« çÁ¾Î·(µXohâûùm;ùþOµùQ=äÄZ‹^æµn¸ïþ¦ö,½ý‰kð56)S¾Þ}”ºïªVõæEÈ £|Š®dåmy:ß?.«¨Ïg* ý <5DõòÂIo"/aUqCÑbo_m{q‰üŠŠ×KN9SCˆÛ !…Œ{"kŸ-‡§&w™e£cçf~y½·ƒËY…7]ÕÓsŽþ¸I¡›¤Ñ©ŒÁ5ìáÛÏÉðäoµ)„¬©ƒgÞ2ñX;”°_¦Š -®ë"®†>ZcX´'_5S}ê€D(Ò šŒ ™ƒÉàã›/YÒ‹ˆR"Á†kÌù’¤P›!—%‰òáQ-5*Ü"è›Ç .‰f,¸µàÓz™(be£uëMª“5òYQÌØ¬ºž\i®©Úd'¾\3"áÅgÇc~\‹þ8äÉNo>¼dšÚ—zßœrðã“.ý¼y“ÏõÁqÞžþùù›ÖOäpªúëîõÓï>ìþ ®q00)öLAêÐòï¿ìê£æ;æŠyŽÂÑjN A¬0EB¼ð@QœnÀýIÑ»ù ‰/8Ç[‘A_ÌÁ±=¦pŒqFiìL ur9 ÜȘ r=s,2É#m4PÊ´œÌ’EÔ’?9>,±I-GôpÂ3¥ÔÎ*…P1ñÄÄ‚¬r²!Ë£”Ô SÌ)É”³DZ|ÐOìí’ÌC÷¤ÒÊ,×4´@ßDT“A3ì/R;M"Å0==9å°±NÙþyÒ%…2PáTUDy€±ÑT%%JZÕ$ÎV\=Õ•Wü|ýõÈa…µØb_åY`Ó[ÖÙg¡VÚi©­ÖÚk±ÍVÛm¹íSÅ4»UöÛ1Ã¥óØ³ŠÝÕr –Ov3ÝŽ\x]•÷]dwí0QKç¥wR ×õ—ÙOÁÅW×€nK+[gIXÌOí—^RÞ6ߌðF‡Å%8cŽo]ucj)d§L6ócŽìT„“/õkäk/VrÉS ¶¯5ʼ,¹Õ]‹ÓϳE—К¶”vˆ^i…ë2:Ç6·,f©ÙÁ:E©µîõælº¦2Vž{V9J ÃF[c«¥ »éþÓvqìµÏ¦ A¨ :ÃǺÁ~ºí*ßþ5èœs}ÒQSå–‘Ö´ aÔo'EBθayÓˆ«FqnË÷œhë¹8¿ÄmÉa6¼Îzyœr}Q=|u;g=rÓKwSoɽÌÌÙv\îË%3FŽ˜ŽøÓï…ׯñ-txï‚´Ÿw^kj·’_…ïõ°TØ¥¨(kÂz—ǽËϦp”½e¾{¾Æ¯>o²1–¸Ççßù©ƒ^œ¼1Âï—…ÚD ,ȧ^ð58†7yk^÷/äiÈvbQ[¨¸ÐXfpbPàåŽ?Á€O4Ê_5t3ÁxUð"ŒÚän³¹ÝmÊ âþË Jò²u}pfõÂŒjrˆ”¯xŠ©ßÊ\ØBêf7êÇÏZ‡»°à-oêS!¦®¸¤}h)ø@ÒÑFñš®ÍdŒDÇ|c‡t )‚¼ãWt„¥Š•iŽöÞ%AÄÓn¹«¢ÖîXª.ÆdêÐãìXH3Ja÷`SYqˆVDn$´ë…¹ŽßtðvìÓô §¿IV%Œ?S£¦ìÇžM”ŒlS×Hƒá­(ª¤„Ó–wËÞiql¯ äHdÈ¿ìH‘ýKÅXPø¤¸Ér•L œË IH3&nDݽj‰§ØÌ±}iã ¡è>•p³#d\ä)« HÖ„nB˜éþF:=™ÝYr—½l ONˆ3>â¬èãŒþöbNšk{õ¬:©G¶C"tí‹”6C#OHNs¢äNCßèˆÒæN¥‹ô>™E(bÐï)—„e4œî{a!ó1ó1މeé1?SšŠ"òOê^_ýu:p‡-­§ù„Ðï1o—M±)˜ ÅÌ¥Fs¢²\É0Ù†µŸºrƒä¼(T'Ò£* &Nu±R°Òs¬IÓ¥#­FÍÏñ45ÿ ˜Io'Sk&Ÿ Ì$ÿÚ1^ ©ÌPê[³Z²…®u6dé†UKIM¼Òµ©m5Š[KÉ›Þí$üì§(ַͳò•ðäÛþÏB•`LèhuvZù”õ},(^]ÛÔÕNæfkUÊ4w¤v¶`ŒMOÕú/¾5ª-îZ©KiBÖ¶¼fm÷1¹¢R•“ÕÞ¿¹B³æç¡S¼ç¨Ì›Þ’¸ ¬xmG˜ÿ¹ó¶ÌL0Ë•ù³„—!®ïÛÃøâÄ„:\ÏSÂ#Òƒ æ™ïyK£×9¨U-y•Tr´hô/-raøDÂ"ôì©*»gȤX‰èT±½\1c DbÞ|8|Ñý(nÂsbÅì ì]k˜먡¤ÑÃìßz{̈úÂP ­¯ü¢¼d'Ëo³?É®YþK\S1s0´6FжúC¶Ø$¿fKqûvZAcøË³Ãé¿­‰‰—š3±èÐý¾Ó**žuÛ­ ÏêºiBÅ›­·LúDït£ïŒieù&Ç >Þ`g6D XÓbõÜ>ý\AQÖ3žÞ´f+5'ßFT”GÙ¨v’Ýjí€溳VŠ 5u8AoÁÚ³rLí®ñFÕb–OSOµ¡áßôQA049âƒ%{µW5Ï-1<õñÚanU­¯Hs°ÿœçCIUÿ†ŽY1ŽRfðXeÔV»uYµu ¿iÿIW«#XiËXòŒQ9sÁ$þŠÈQGPÕ¿6òS“Dç ^KU]˜²Ëxõ¿b5]ÞN·ÜUØäÕ¨dM8C“ʤ3å\‘nö¬u³*Œ+. "0c5ÿþO9y.`þñ[{m$×Ì1~÷8µ`•FaWÕíO›¥:Ÿµ[3†Â]¯'7–ZÏRíæ¬cÏ2fÉ'dwŽYGÞøï>|Ö‰TYçUòä¨ðµh+Îý¤6Ä|õg;O_ÓåVoi½Vê.SyĶvÖòê–êä.ëà6nåvné¶níönÑeñVVÍ¥÷Vר.ZÁV‚üVAµNpù–N —û×j}Goÿ–Ó`q#÷Zç•rÓΗWy s ¬1÷Þ—|¿N&mÒ`Ý{A5'íöy ±+i•üþÓl³ 8A?Ö:Î| 0Z‡ˆ–ž•_Y„þxb0Eöcæ $¸kû$/PKE’}'/ ·“ü¬W€Ö›6aÑF\­Ò]±f18Jk…!·Ú†ŒÀTÎX-µLÁ(ÁÖP˜<¬0ôâQ…y;ÔƒkHg¹(‚ßSQuì€ä“HmiI)Sÿh¸ ?N`áè‹æ9Çò<™©Nà sÌž¢”hb}‰ñ€çÑ„¢þ'y8o?p ÐPÝt™x•´³•^AHÉŒØûxË&‘O9Ñ¢FQL9 4¤²D’ó>]ÇQ!N‡t[ÈL±iQRH;é&+DìÙ´’KTwM£Ð-̆ÆYµ§8E-=gªö³8‹ ²o´8_mèyòQ`ªM“‘ð”.E8—g88 ¬‚I²ÑÒö@YbÒ’Ò“®Ø›Å(;1u7én'bµc¥ê£a Äl…ß5˜K"%DÁ Ã.±kVãù’Î)*wp%µK­j¯A¥5¦òYŸ„k¢ÙÇÖYd%hI¶ŒÌ8õÒÒ" ´s©Ò˜&šTµoÔþº -”¢À·Ôº¾\t†EÚ(Y9’ÿè¡QÚIUOWë·,08œ_¦{ k…Ù¿,Kxé(ø»bó—7G²ˆÕá2-Á$:Z¦Æ÷·€Y£ZÆØ’Nz0…4€Ê ÇP«ÿ$cù©Ïto<²ü˜3¿±§MÚønñPZ#+LuÓšU8ºš±ò'/ƒëí¸xÞ–®Ì haí{¥J‘ :åÙÜòbk9ù‰ëÊ^ÛÚ~º,95)§åzà[£Ýj«Ã:ö¨ïBS;NÃè›í³±ûrª¯²9íª+z¼vw}%¹¤¯Y:©¦þ²§˜ŸK´·‡÷(¹ëøÌŒÙ@u£—[œƒª«M¼²V••ªæ³‚ß”d³R·QìA£; ˜Zt4HçØó±»?åSXŸY1)_ÝÓÇû ÑÍ´ÒÏÁä+Rù˜¦SY•å!>?שù0  çu~çy¾ç}Þ8ºÝàUôÌNÝs¸c‚þâ×èc=’žÑÓnnÏv‡%„ÿ·7ïéÏð˜~æøs´áa´ë•>]i¦P…>«…ìÉ~ÐLWìQžôÚ¾uŸn¹©+ÉžË^mJÝŠN >©êVï÷^t_€µ~‹]Ñ´Ù¸+P!«zwKšž“ï»·zóø| xyCñ¡]mßñ™ Ó?òQµùÂþ÷äžÙÕü´Éе ÔŠ,ŸúV׳Uwók}Ä»ïóAõ ½\½™žóÓ¾þås¿ø‹\^‘3¾Ь‰c¹/^OLp‰¿Òùy~»ûMþ”o° ¿ùç>À9Ùo!ÖS&/cÞ‹O×[úíKiã¿á!oû©ëA¸È ´ØfÕ‘˜ †-Z¾:°ö–œzfØï·qa4:ކy–a(Õ®ð(ÚfõÑ7¸ínGâ%^ªq• ©v/JÒö[F{ÈY„’¹DÏjqÈ ƒ¡TlI+ËšLã{e“¦<ûÏí;†ÇUXF\Ñ`œQÌšTÛ¡áÞ_"Ídàؔߢ”—%àeœš`(a_¢R$V¦èª¨¬ªægìé`a¯®Ï’iíþq_jÞò£§. )2ôñåi'c‹_Z°ð³%â)m–¢#­¦!*ðöµWGÞïÕÙ 0ÉûÖ(Ôýí\»üœœMø\mkÕè†@~ ÏÝÓà?V*[£áC+c¨«— /A¯Š¨¦ J'äV-+9’Ñ0u@P¦l(s¢Dv)ztÒ 1^NL˜ö°·Ð§9ŠóÝBª'TŒ0š´'ÑŒ¥vN êØx‡ä?*ÁN$²¨C ¾Ê>}—ô„Ôsþâ1µjNçÖ¨Q¿iÊôfÅHDåÎ…øílÓ}On=Ü+oOÄiv¹læñ‚Ú¤lw^á øëÕÅk-®ú±×aÚrñþà5n7ÃCE†­ëµ/›?G³n[N\Û{ó«û±(o€¤e‹žøW¯ðÐÍ£»¦«ØïPÆ’¡sžî½plßÒÈ"¿ˆy·fðŸ?Wþòã´VŽ¢¦wÕƒãV¿Û³Aò æßL •']~™‰ Rý˜G uG]G_Fn–\f ˜ØwrÔŸ…ë]·—€ B¥7‰¶48š; ¦÷"NìeGØ"+n†âd§å˜Š‰whÄ a!ru£sèHhŒêmèžAæ5_„.Éa Svø™•€i¸ÎÓ$z ŽH$–2W&q3AØåMžFæ`1*8#›­ sÕFc~þ³¥Ï™÷‰U\|þ(wq|HSŸò¸5æ‰Û…õ$;™šðèRðl^m ©¡Hg[¦¢ŽzШ¤"éSK¦*䘬¶š >%®Ä©¦düÉ% ŽÖ4â• =X°šýÒP®ä€C×̉­Ö8›e}™<;Þ4ØLRØjçµyL%n¸X‰µÌJò-‚Ì]ºlµÜ¦ÛWY‰rÚæ~ò8l‘l…˾öÙBn1¹bØî‘ðRûŒ¾Ö:,ÄÃ7…ð´Ë…W®P œÜ¢+koÁ¸>î¿Íz¡1!…ƒñX)Çgϯ%CײX!•Ôȶ‡LïTß "ͳÉòo{{†º£¶*móþ»Æ92Á³€b°Ó”ʶ,Èår‹JÐf -¬·V#еpÛFÍ.´Þþš6ž¶ ð[ݽ©çÛMÿQ7ç›`Ý}Ë­,{Ë( Kmç]õßZÒí5j‚?8÷ãÉú 7„ÚÔxâþ¡ù+}_^åâ|îàÂŽã©°áémRH¼“?ÙúÇú±n±â“Ÿ>ãê°ËΨÅw®»¸’—nøçÃÿ-:Þz³}âì´s~ªßÏSçiëµ±WÒCO§ò)2*­öPnÉ;鼯m½ío…ü÷Y׎~è|Ÿ>ü»¿6òÄu¨ýí£º>äÔ—¼;©ˆXú+öò×98-P€ýë]žNWŸ»þ}ÆsŹҧÁȉ£x×ÃJ2”!ÁBPl^-ˆ¯ÄÈl€jSW8¸B†°ƒ-lÆÛr‡Â3œ0nâËÞ{r»Ø‘N¬H‹ØA%¾ÉYõÛ UçÁî™'gQ”"¤'+îwSÄݸh»#jQsB¬ñjx¼}tN$£ K¸(ÊŽÞó¡óØ@Õ鱄cýØÅ5 ’¸+$" HDÒQ‘Œtá##)ÉIR²’–¼$&3©ÉMr²“žü$(óhªP.1‹Áxbá8JR²‡‡^+9:bÒ‘´Œ%p†ˆJ\ê±h¼Ü^üʳË^b–¿<&}yLh˜þ…Læ}–™>hSšt‚5)x¼—”ëÃf6ÃÇÍ™Nœ3ÜÞ" À¬˜’bJg;GÁT&±”DÜ”ÔEÅMʆ›sfúÏIò3¢Rœ(=íYM$Â¥bÈdAÉÓ¯nRÑ  MàN©SV¦ô¦¾³éO·YR‹z´ÅŒž*ÑF>ôÔT¡Ce£™êº€ô–Wý`åjêF±¢´« ]æF‘…Ì®:ÓªG¼aS3 ÌzM'm.­×OŽù´”›«©u®•þ¢ºöº µ ?ÃÚÏfQO¬.4OC«!̤öôEMv…˜4b1Ó£VöEIC,¶g)©.Õ°ÓC‡È ›Z¯‰ˆ‹?º!Ç 4n †tPMK³zÁøñ¢aÅ8*_?xmj.3ÛemÆÜiÀ¬­:efÉu.éF·Þìp»©]J7ˆ]!sy•3‚9÷¢áe Pë˜^¼®·¾|hœÖ"öG%©¦&Ú‰&e¸ÙŸVG¯1× œÔäñf¥P }è©!ÂUV”©r@ØKgKìB´8£ø#UmgË6Âí±Q‰q%á —¶§¸ép’Æf²W¡–D²õþY-{³°Q¸8NŠáMʦÁv&ÃiEPcøÛª±³ÈıØÔt£‰V¨®]æsd€Ô;QF4DD(nr¼]j®–Ea“ÐWÉçÜð’¿Ü§/‘y-JGšÎÚZ¥Þ¶Í[¶SDðTÏ.Ϧå휬.cÇ‚/& ®«ã‚„»¿ù! ňPň8¿ƒö™k)gêÿ”ª_2¾g¸ÖO>'].½£9 ÜßÐzÕŠ®YÒúúÔ2:8Ç&ãcù)ܹ1ØÏ›vµ›— f•xÄeÒƒ£1ïîQØ4jIréÜ£„™cRNµùJ¡;v¶Å Ò˜œ%[xrÐ^¦­þ•-Z–ݺqHö\Ö:U“LPÃö6°šý;f ¸äš‹˜=ÇøÓ×ÖÕdeŠðFî· ¥¡³§ªoiß3RsþdMrwœO…Òñòò j0Žõj2wùŒAÖcñtTwü3¶³ÁÇ$ó©õd#O¤ë ª¢C<Ôdã ²(þ(•¾'éìU%xŒN[-iR"~uÄ (s’| HøºX•Á² æ"»¹®ümš‡Žë0ž:ΟòóxŒÕ³/"ž»ê±,²3¬Ø¿æ˜k×ðM–•´þî"´A—º+ã7Æô›yVú­þê•ó*ßÝlakÛ”Ñ9êQ·õñ‚CݸÇþxJ9Ö¢†õ£§ÎríÕgðÏÅÙí%>/ãr{æsž¼)ŠëoÚçõévkðÖl-°)öóM?~¦[Ï®ò&6ú”owóÓV|h;òk¯§§ÿzµ5\ëïjþº”ФCŸÓ…ç­ý¥¶osñË^<°Qcî_­ÅiÉQ鯽™R©1á™S‹<ñ_6™€Ñì‘_êtà8Q U•)5Š4eÄn9Nù=`;åß½]–ªÚ2Ñјïi †RéP Ò¢=‘"ýÎÖàêàC¨ÊZýò©à!%±àVŽÉääH“œØÛÑi  MÛ þö`^_RSÊžÜ+õ•’R[!|]à­yàÊjSX9á~Þ`9ýáºÊHõàfQý¼Ýª¡ R!Vàþ!¶àê¡ìE¢:Ý—yý D‰v]%šY#1¢j`Te.â'š–™"XÕÃibnM" ÞØ/ÁÓ(Ò2 „âHMO#¶Öõâþ¢0¦b+1£+Å¢26£3>#4F£4N#5V£5bZâu 6ò`6æâ3c n’Š\ê8J’8vã9rÒ[­’:zÚº;zÓSÕ£0¾£9º¡ .>*K1ýcÏÍ#oä5uÒ7uEþ-E8% ^ãCâDºŽ=b-Z䎔•C¦#=5$Cqä%doI«á”§ˆÝ$9”ÅM$ã¬Fp‘$¥<ŒJš†üÕMÖ‰LKB‰ä vTÆUO† õlœÞ¹dQRRžTºX"iRÖPVaRí#' Ò¥‘DU¥#$ºe•WbDù•1²AuVŽ¥'ÖX?%Tõ$ÄaT^åjš½É"Ðíe’¡7¥#ç<™å`²•[.šï4šñídXÆÔYVÝ]RÖ,˜^Vaf[aî ýLfj¦7˜( &iþßéAVÊ8äcfl‘ÞcéÅv-×øÝþXiÆÚ}½¶ «Ù¦í¥EC6‹zõ+Μ»u à¡AÌíO–ᮡªÝ_Ÿ]åÉ5¦¬ß×x˜já%²åâg&YÃéñD)æ{9XlaØÕß¼e¥ò@F Í—Â_çµg}`PÂ'zib•—Zª¦92&áùÚú1asâ¡àüšï™v’”¦nÙžo‘{Žß¿£,1¢ÝÊ„ØD©•™ñ½ØH‚¡XPÌ!3"܉µ•(‹¨ çr"¦yReß TfõH:})þæVŽÖ§Øeƒð¨‹gÔ‘&oÖ(‘šID" ”¸mæ2†¨i:VÞ˜õ8ÅqÊ[µþ… ×a(U½b”¤Üß \LšoF›mZi‡NÙÈY¥‰qá·Ú>>!™Z&¸…šYk5[•M9Ø…­P†ú¤à4Õ&• ½µŠá¤\Ñm ÏèÕM!¬­Ý®=^¼aj}=§—ž¡Š*¡5Xê˜"¥Ã¥á¤ W¨r¦Ðùe?úŒúá)ãT– ´yÝ8H•{=f$2*º[œ‚\–†”°¾[^}ªÖ*ÃÑi©ç²Î©ða^s,ßTŠåžjë¡¶$¤2!ËÕ(¢‰rç¦~‡ÂZ¦ö—-éº)¯ê¨§œJ©¹jhÙ\‹b)A‰ë›îÞ™²éΡ*´Š\þ¬Âܾ~ë´, é”^æ»êëÞ \€ŠŸRᆈ[¹Âe´Ȩҟ¤Tœ?þfÄzª™¬Ùrú¬A™`M‚`h,©ù®ý²Ý•ò‹z1ëޕ祈¢ÕäìúuëŸN¬Õ¡$YÖ‹¢öÑš‡*Ù…~+Ù…,Þ¬ü8Ÿû9ݧöZ‹²(Çug°äàÄ:-ÚÍÙØ)-Ú e’Zà#*Y“ìS"lâyÃwmžtêŒΦ]äUèi6èÛ.×ðáíŒ耔 ïùêö-è“:åׯžØê߀֞öéäŠ×mZžÞ^^åþ ­‚Þ~ îµäè÷U^N"c‚,¡j^È(þ ¬%ݪáFþÕn÷ynñÁ$îªo‰êàŸÃážÄõn*®ûÌkòÍÆìOØ9ÞÚ©\áê­ÌòzÈi1îð&›ä²lhyŸÊäîz‚šÌ&E΢èQ®aÛš*F¥YþgÂ׺£û&b\¬E ‡ìáún£þFdä}’ç©oæZRæ²%FúTe&°çxaœ üV¤ü¾øî¯G¤¬¢åºb†6ð>ušù¶"8š!AV°&­Sþêab†0Wn!÷×Iâ«F¯šTÞ+X’êó ©_Š’ç-^®½¥`øÜÒf+Çv[‚ì0f®Ó¦fpHî蹢ŠþÆI'æé”Šª‚¦âÅ‚T7îh!ð;¢¯yes²Vl1gº“ßb|½qÍÖØ"²j"Åïë)BR¦ï׫"ûjje‚"a¡qëñ r¢"² é nk O“gH! ÿ1º£"Kr!ç1_þ1%ðC%cSŠcSæ÷"*Ÿâ*+c+SãX¾¬K°˜²r,:¦Ù².ó"ér2qq-¥21óe/÷ï$Sm1G¦ÕJcB óE& A*¤4¿ð+/36çd*3ðNY³kœ7?8O#K~ò(¤“ˆS8g3Re@­ª‹$ñöò_]q/}U=»3HT±¹ve#Ór™žbþ˜²3A«ÙDV€£Æ³VïB*t{g²Þr½öð¤zë>ÛгREMkAwôt¬óBSŠå3…±+&HK4×% CæJss;oEϱû±>{´,“¬3âRó1sðG§tZgKßó1õ.S*QÃÞ\ò4N×r—gÛ]¥§Åf'½š4Ÿ*§åšºXI}z•Øi)¥™ ³Ài)”åhWÆ_F7!M”ši`T¶Ëbï6«në4Q ¶è¬(Æí¬Ò˜z²™Voè^Í­Ntó Œž¯éÞl[£o3kÍdÙƒº‹W iySkÆhç‘©7c·øvµµzÇÐ_³s£ëÄù©ÀYdéçþ"Åó.ç*vgÝnjû õxG¡ j’ptö´gÿe£þ÷¥–¶iET΢S}«ðd€‚²^«G•ÆSðhc+›Þm BlÉi¿oÒ}Zx¥+„GxNÛ½G3ÿê§h4:?f’r &¿õ_?ög¿öo?÷w¿÷?ø‡¿ø?ù—¿ùŸ?ú§?1;gri/doc/resources/Makefile.am0000644000175000017500000000077313147557614014642 0ustar psgpsg## Process this file with automake to produce Makefile.in # gri: doc/resources/Makefile.am srcdir = @srcdir@ VPATH = @srcdir@ EXTRA_DIST = top_banner.gif bottom_banner.gif math_symbols.gif\ pixel.gif sm_bg.gif symbols.gif top_banner.gri bottom_banner.gri developer_all: gri bottom_banner.gri convert bottom_banner.ps bottom_banner.gif chmod a+r bottom_banner.gif rm -f bottom_banner.ps gri top_banner.gri convert top_banner.ps top_banner.gif chmod a+r top_banner.gif rm -f top_banner.ps gri/doc/resources/pixel.gif0000644000175000017500000000005213147557614014404 0ustar psgpsgGIF89a€ÿÀÀÀ!ù,2;gri/doc/resources/bottom_banner.gif0000644000175000017500000000127613147557614016125 0ustar psgpsgGIF89aZñc!!ÿÿÿÿÿÿ!ù!þ. Imported from GIF image: bottom_banner-a.gif,ZÁc!!ÿÿÿÿÿÿþœ©Ëí£œ´Ú‹³Þ¼û†âH–æJš±+æ&ê—õ‰çúÎ÷þ̆Äáå6ˆ)YHCjöDÜšNWô0}.UKì,ùíV¯«o¬õªÇVæ–¬ »ƒôºýŽÏ—ŠJü(8HXhxˆ˜¨¸ÈØèø)9IYiy‰™©¹Y¨çù *:JZjŠÑ×$(c¶æºÐ$V&·V› Æ@åu{ë,,ՆŖvºÌÜì\ÇúŒã«w‚m¡MÝíý .>N^n~Ž®s,l QC6ûjl,]_¼Ñž¾ÏßïïÀÇ^4ÀVÝ›·NÖƒ9ìäp9¦¬˜›uT*îR£Œ"°þ†ÁXü2¤H€ÒˆP0ˆë#1XYzÉ«ÕqcB],á)(Q&Ä"ê 4¨È’BOª„qsÄ«Ÿ2’} ¤‘¨T«Z½Š5«Ö­\»zý 6¬Ø±=¡áÑA»´l²ǔ¬Ü¹äLa¹ÒÏË£.q¶å›0ÝÁ„©Ek±7oÄyjç¸Åïá/‡gcþ£xñ[W[2ÿÁ<™ó›Â¤K/(9 ÅÞ‹øZŠ7vÆw¬s‚ÖÅZIßx=5"³mYâʸ¦‹sE]DÊà hmŒ ¹÷@šÀ«ûæÝ—úõÖ’9F7ž.r½~Û˜I|ӵߚ µó”>láKïÖËäÅYJøýcS¥7›C*iæÓc¡Ñ³TnÝ„Y&“E+=HPzá.ÄñÇáSɉµ¡rK™0Å6#vˆbŠOiö—!Ę‹*ÎHc6ÞˆcŽ:îÈã2;gri/doc/gri2texi0000755000175000017500000000245313147557614012254 0ustar psgpsg#!/usr/bin/perl # Convert Gri file to texi file. die "Usage: gri2texi file.gri file.texi" if ($#ARGV !=1); open(IN, "$ARGV[0]") || die "Can't open `$ARGV[0]' for input\n"; open(OUT, ">$ARGV[1]") || die "Can't open `$ARGV[1]' for output\n"; $now = localtime; print OUT "\@c Created $now by $0 from $ARGV[0].gri\n" ; print OUT "\@example\n"; while() { s:\@:\@\@:g; s:\{:\@{:g; s:\}:\@}:g; s:([^\$])\#(.*):$1\@emph{\# $2}:g; # s:"(.*)":\@emph{"$1"}:g; s:^if(\b):$1\@strong{if}$2:g; s:(\b)if(\b):$1\@strong{if}$2:g; s:^else(\b):$1\@strong{else}$2:g; s:(\b)else(\b):$1\@strong{else}$2:g; s:^for(\b):$1\@strong{for}$2:g; s:(\b)for(\b):$1\@strong{for}$2:g; s:^foreach(\b):$1\@strong{foreach}$2:g; s:(\b)foreach(\b):$1\@strong{foreach}$2:g; s:^while(\b):$1\@strong{while}$2:g; s:(\b)while(\b):$1\@strong{while}$2:g; s:^do(\b):$1\@strong{do}$2:g; s:(\b)do(\b):$1\@strong{do}$2:g; s:^return(\b):$1\@strong{return}$2:g; s:(\b)return(\b):$1\@strong{return}$2:g; s:^sub(\b):$1\@strong{sub}$2:g; s:(\b)sub(\b):$1\@strong{sub}$2:g; # s:(\b)eq(\b):$1\@strong{eq}$2:g; # s:(\b)ne(\b):$1\@strong{ne}$2:g; s:^break(\b):$1\@strong{break}$2:g; s:(\b)break(\b):$1\@strong{break}$2:g; print OUT "$_"; } print OUT "\@end example\n"; gri/doc/texinfo.tex0000644000175000017500000116703613147560122012765 0ustar psgpsg% texinfo.tex -- TeX macros to handle Texinfo files. % % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % \def\texinfoversion{2013-02-01.11} % % Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, % 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. % % This texinfo.tex file is free software: you can redistribute it and/or % modify it under the terms of the GNU General Public License as % published by the Free Software Foundation, either version 3 of the % License, or (at your option) any later version. % % This texinfo.tex file is distributed in the hope that it will be % useful, but WITHOUT ANY WARRANTY; without even the implied warranty % of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU % General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % % As a special exception, when this file is read by TeX when processing % a Texinfo source document, you may use the result without % restriction. This Exception is an additional permission under section 7 % of the GNU General Public License, version 3 ("GPLv3"). % % Please try the latest version of texinfo.tex before submitting bug % reports; you can get the latest version from: % http://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or % http://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or % http://www.gnu.org/software/texinfo/ (the Texinfo home page) % The texinfo.tex in any given distribution could well be out % of date, so if that's what you're using, please check. % % Send bug reports to bug-texinfo@gnu.org. Please include including a % complete document in each bug report with which we can reproduce the % problem. Patches are, of course, greatly appreciated. % % To process a Texinfo manual with TeX, it's most reliable to use the % texi2dvi shell script that comes with the distribution. For a simple % manual foo.texi, however, you can get away with this: % tex foo.texi % texindex foo.?? % tex foo.texi % tex foo.texi % dvips foo.dvi -o # or whatever; this makes foo.ps. % The extra TeX runs get the cross-reference information correct. % Sometimes one run after texindex suffices, and sometimes you need more % than two; texi2dvi does it as many times as necessary. % % It is possible to adapt texinfo.tex for other languages, to some % extent. You can get the existing language-specific files from the % full Texinfo distribution. % % The GNU Texinfo home page is http://www.gnu.org/software/texinfo. \message{Loading texinfo [version \texinfoversion]:} % If in a .fmt file, print the version number % and turn on active characters that we couldn't do earlier because % they might have appeared in the input file name. \everyjob{\message{[Texinfo version \texinfoversion]}% \catcode`+=\active \catcode`\_=\active} \chardef\other=12 % We never want plain's \outer definition of \+ in Texinfo. % For @tex, we can use \tabalign. \let\+ = \relax % Save some plain tex macros whose names we will redefine. \let\ptexb=\b \let\ptexbullet=\bullet \let\ptexc=\c \let\ptexcomma=\, \let\ptexdot=\. \let\ptexdots=\dots \let\ptexend=\end \let\ptexequiv=\equiv \let\ptexexclam=\! \let\ptexfootnote=\footnote \let\ptexgtr=> \let\ptexhat=^ \let\ptexi=\i \let\ptexindent=\indent \let\ptexinsert=\insert \let\ptexlbrace=\{ \let\ptexless=< \let\ptexnewwrite\newwrite \let\ptexnoindent=\noindent \let\ptexplus=+ \let\ptexraggedright=\raggedright \let\ptexrbrace=\} \let\ptexslash=\/ \let\ptexstar=\* \let\ptext=\t \let\ptextop=\top {\catcode`\'=\active \global\let\ptexquoteright'}% active in plain's math mode % If this character appears in an error message or help string, it % starts a new line in the output. \newlinechar = `^^J % Use TeX 3.0's \inputlineno to get the line number, for better error % messages, but if we're using an old version of TeX, don't do anything. % \ifx\inputlineno\thisisundefined \let\linenumber = \empty % Pre-3.0. \else \def\linenumber{l.\the\inputlineno:\space} \fi % Set up fixed words for English if not already set. \ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi \ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi \ifx\putworderror\undefined \gdef\putworderror{error}\fi \ifx\putwordfile\undefined \gdef\putwordfile{file}\fi \ifx\putwordin\undefined \gdef\putwordin{in}\fi \ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi \ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi \ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi \ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi \ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi \ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi \ifx\putwordof\undefined \gdef\putwordof{of}\fi \ifx\putwordon\undefined \gdef\putwordon{on}\fi \ifx\putwordpage\undefined \gdef\putwordpage{page}\fi \ifx\putwordsection\undefined \gdef\putwordsection{section}\fi \ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi \ifx\putwordsee\undefined \gdef\putwordsee{see}\fi \ifx\putwordSee\undefined \gdef\putwordSee{See}\fi \ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi \ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi % \ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi \ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi \ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi \ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi \ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi \ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi \ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi \ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi \ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi \ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi \ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi \ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi % \ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi \ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi \ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi \ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi \ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi % Since the category of space is not known, we have to be careful. \chardef\spacecat = 10 \def\spaceisspace{\catcode`\ =\spacecat} % sometimes characters are active, so we need control sequences. \chardef\ampChar = `\& \chardef\colonChar = `\: \chardef\commaChar = `\, \chardef\dashChar = `\- \chardef\dotChar = `\. \chardef\exclamChar= `\! \chardef\hashChar = `\# \chardef\lquoteChar= `\` \chardef\questChar = `\? \chardef\rquoteChar= `\' \chardef\semiChar = `\; \chardef\slashChar = `\/ \chardef\underChar = `\_ % Ignore a token. % \def\gobble#1{} % The following is used inside several \edef's. \def\makecsname#1{\expandafter\noexpand\csname#1\endcsname} % Hyphenation fixes. \hyphenation{ Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script ap-pen-dix bit-map bit-maps data-base data-bases eshell fall-ing half-way long-est man-u-script man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces spell-ing spell-ings stand-alone strong-est time-stamp time-stamps which-ever white-space wide-spread wrap-around } % Margin to add to right of even pages, to left of odd pages. \newdimen\bindingoffset \newdimen\normaloffset \newdimen\pagewidth \newdimen\pageheight % For a final copy, take out the rectangles % that mark overfull boxes (in case you have decided % that the text looks ok even though it passes the margin). % \def\finalout{\overfullrule=0pt } % Sometimes it is convenient to have everything in the transcript file % and nothing on the terminal. We don't just call \tracingall here, % since that produces some useless output on the terminal. We also make % some effort to order the tracing commands to reduce output in the log % file; cf. trace.sty in LaTeX. % \def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% \def\loggingall{% \tracingstats2 \tracingpages1 \tracinglostchars2 % 2 gives us more in etex \tracingparagraphs1 \tracingoutput1 \tracingmacros2 \tracingrestores1 \showboxbreadth\maxdimen \showboxdepth\maxdimen \ifx\eTeXversion\thisisundefined\else % etex gives us more logging \tracingscantokens1 \tracingifs1 \tracinggroups1 \tracingnesting2 \tracingassigns1 \fi \tracingcommands3 % 3 gives us more in etex \errorcontextlines16 }% % @errormsg{MSG}. Do the index-like expansions on MSG, but if things % aren't perfect, it's not the end of the world, being an error message, % after all. % \def\errormsg{\begingroup \indexnofonts \doerrormsg} \def\doerrormsg#1{\errmessage{#1}} % add check for \lastpenalty to plain's definitions. If the last thing % we did was a \nobreak, we don't want to insert more space. % \def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount \removelastskip\penalty-50\smallskip\fi\fi} \def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount \removelastskip\penalty-100\medskip\fi\fi} \def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount \removelastskip\penalty-200\bigskip\fi\fi} % Do @cropmarks to get crop marks. % \newif\ifcropmarks \let\cropmarks = \cropmarkstrue % % Dimensions to add cropmarks at corners. % Added by P. A. MacKay, 12 Nov. 1986 % \newdimen\outerhsize \newdimen\outervsize % set by the paper size routines \newdimen\cornerlong \cornerlong=1pc \newdimen\cornerthick \cornerthick=.3pt \newdimen\topandbottommargin \topandbottommargin=.75in % Output a mark which sets \thischapter, \thissection and \thiscolor. % We dump everything together because we only have one kind of mark. % This works because we only use \botmark / \topmark, not \firstmark. % % A mark contains a subexpression of the \ifcase ... \fi construct. % \get*marks macros below extract the needed part using \ifcase. % % Another complication is to let the user choose whether \thischapter % (\thissection) refers to the chapter (section) in effect at the top % of a page, or that at the bottom of a page. The solution is % described on page 260 of The TeXbook. It involves outputting two % marks for the sectioning macros, one before the section break, and % one after. I won't pretend I can describe this better than DEK... \def\domark{% \toks0=\expandafter{\lastchapterdefs}% \toks2=\expandafter{\lastsectiondefs}% \toks4=\expandafter{\prevchapterdefs}% \toks6=\expandafter{\prevsectiondefs}% \toks8=\expandafter{\lastcolordefs}% \mark{% \the\toks0 \the\toks2 \noexpand\or \the\toks4 \the\toks6 \noexpand\else \the\toks8 }% } % \topmark doesn't work for the very first chapter (after the title % page or the contents), so we use \firstmark there -- this gets us % the mark with the chapter defs, unless the user sneaks in, e.g., % @setcolor (or @url, or @link, etc.) between @contents and the very % first @chapter. \def\gettopheadingmarks{% \ifcase0\topmark\fi \ifx\thischapter\empty \ifcase0\firstmark\fi \fi } \def\getbottomheadingmarks{\ifcase1\botmark\fi} \def\getcolormarks{\ifcase2\topmark\fi} % Avoid "undefined control sequence" errors. \def\lastchapterdefs{} \def\lastsectiondefs{} \def\prevchapterdefs{} \def\prevsectiondefs{} \def\lastcolordefs{} % Main output routine. \chardef\PAGE = 255 \output = {\onepageout{\pagecontents\PAGE}} \newbox\headlinebox \newbox\footlinebox % \onepageout takes a vbox as an argument. Note that \pagecontents % does insertions, but you have to call it yourself. \def\onepageout#1{% \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi % \ifodd\pageno \advance\hoffset by \bindingoffset \else \advance\hoffset by -\bindingoffset\fi % % Do this outside of the \shipout so @code etc. will be expanded in % the headline as they should be, not taken literally (outputting ''code). \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% % {% % Have to do this stuff outside the \shipout because we want it to % take effect in \write's, yet the group defined by the \vbox ends % before the \shipout runs. % \indexdummies % don't expand commands in the output. \normalturnoffactive % \ in index entries must not stay \, e.g., if % the page break happens to be in the middle of an example. % We don't want .vr (or whatever) entries like this: % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}} % "\acronym" won't work when it's read back in; % it needs to be % {\code {{\tt \backslashcurfont }acronym} \shipout\vbox{% % Do this early so pdf references go to the beginning of the page. \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi % \ifcropmarks \vbox to \outervsize\bgroup \hsize = \outerhsize \vskip-\topandbottommargin \vtop to0pt{% \line{\ewtop\hfil\ewtop}% \nointerlineskip \line{% \vbox{\moveleft\cornerthick\nstop}% \hfill \vbox{\moveright\cornerthick\nstop}% }% \vss}% \vskip\topandbottommargin \line\bgroup \hfil % center the page within the outer (page) hsize. \ifodd\pageno\hskip\bindingoffset\fi \vbox\bgroup \fi % \unvbox\headlinebox \pagebody{#1}% \ifdim\ht\footlinebox > 0pt % Only leave this space if the footline is nonempty. % (We lessened \vsize for it in \oddfootingyyy.) % The \baselineskip=24pt in plain's \makefootline has no effect. \vskip 24pt \unvbox\footlinebox \fi % \ifcropmarks \egroup % end of \vbox\bgroup \hfil\egroup % end of (centering) \line\bgroup \vskip\topandbottommargin plus1fill minus1fill \boxmaxdepth = \cornerthick \vbox to0pt{\vss \line{% \vbox{\moveleft\cornerthick\nsbot}% \hfill \vbox{\moveright\cornerthick\nsbot}% }% \nointerlineskip \line{\ewbot\hfil\ewbot}% }% \egroup % \vbox from first cropmarks clause \fi }% end of \shipout\vbox }% end of group with \indexdummies \advancepageno \ifnum\outputpenalty>-20000 \else\dosupereject\fi } \newinsert\margin \dimen\margin=\maxdimen \def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} {\catcode`\@ =11 \gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi % marginal hacks, juha@viisa.uucp (Juha Takala) \ifvoid\margin\else % marginal info is present \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi \dimen@=\dp#1\relax \unvbox#1\relax \ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi \ifr@ggedbottom \kern-\dimen@ \vfil \fi} } % Here are the rules for the cropmarks. Note that they are % offset so that the space between them is truly \outerhsize or \outervsize % (P. A. MacKay, 12 November, 1986) % \def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} \def\nstop{\vbox {\hrule height\cornerthick depth\cornerlong width\cornerthick}} \def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} \def\nsbot{\vbox {\hrule height\cornerlong depth\cornerthick width\cornerthick}} % Parse an argument, then pass it to #1. The argument is the rest of % the input line (except we remove a trailing comment). #1 should be a % macro which expects an ordinary undelimited TeX argument. % \def\parsearg{\parseargusing{}} \def\parseargusing#1#2{% \def\argtorun{#2}% \begingroup \obeylines \spaceisspace #1% \parseargline\empty% Insert the \empty token, see \finishparsearg below. } {\obeylines % \gdef\parseargline#1^^M{% \endgroup % End of the group started in \parsearg. \argremovecomment #1\comment\ArgTerm% }% } % First remove any @comment, then any @c comment. \def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm} \def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm} % Each occurrence of `\^^M' or `\^^M' is replaced by a single space. % % \argremovec might leave us with trailing space, e.g., % @end itemize @c foo % This space token undergoes the same procedure and is eventually removed % by \finishparsearg. % \def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M} \def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M} \def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{% \def\temp{#3}% \ifx\temp\empty % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp: \let\temp\finishparsearg \else \let\temp\argcheckspaces \fi % Put the space token in: \temp#1 #3\ArgTerm } % If a _delimited_ argument is enclosed in braces, they get stripped; so % to get _exactly_ the rest of the line, we had to prevent such situation. % We prepended an \empty token at the very beginning and we expand it now, % just before passing the control to \argtorun. % (Similarly, we have to think about #3 of \argcheckspacesY above: it is % either the null string, or it ends with \^^M---thus there is no danger % that a pair of braces would be stripped. % % But first, we have to remove the trailing space token. % \def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}} % \parseargdef\foo{...} % is roughly equivalent to % \def\foo{\parsearg\Xfoo} % \def\Xfoo#1{...} % % Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my % favourite TeX trick. --kasal, 16nov03 \def\parseargdef#1{% \expandafter \doparseargdef \csname\string#1\endcsname #1% } \def\doparseargdef#1#2{% \def#2{\parsearg#1}% \def#1##1% } % Several utility definitions with active space: { \obeyspaces \gdef\obeyedspace{ } % Make each space character in the input produce a normal interword % space in the output. Don't allow a line break at this space, as this % is used only in environments like @example, where each line of input % should produce a line of output anyway. % \gdef\sepspaces{\obeyspaces\let =\tie} % If an index command is used in an @example environment, any spaces % therein should become regular spaces in the raw index file, not the % expansion of \tie (\leavevmode \penalty \@M \ ). \gdef\unsepspaces{\let =\space} } \def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} % Define the framework for environments in texinfo.tex. It's used like this: % % \envdef\foo{...} % \def\Efoo{...} % % It's the responsibility of \envdef to insert \begingroup before the % actual body; @end closes the group after calling \Efoo. \envdef also % defines \thisenv, so the current environment is known; @end checks % whether the environment name matches. The \checkenv macro can also be % used to check whether the current environment is the one expected. % % Non-false conditionals (@iftex, @ifset) don't fit into this, so they % are not treated as environments; they don't open a group. (The % implementation of @end takes care not to call \endgroup in this % special case.) % At run-time, environments start with this: \def\startenvironment#1{\begingroup\def\thisenv{#1}} % initialize \let\thisenv\empty % ... but they get defined via ``\envdef\foo{...}'': \long\def\envdef#1#2{\def#1{\startenvironment#1#2}} \def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}} % Check whether we're in the right environment: \def\checkenv#1{% \def\temp{#1}% \ifx\thisenv\temp \else \badenverr \fi } % Environment mismatch, #1 expected: \def\badenverr{% \errhelp = \EMsimple \errmessage{This command can appear only \inenvironment\temp, not \inenvironment\thisenv}% } \def\inenvironment#1{% \ifx#1\empty outside of any environment% \else in environment \expandafter\string#1% \fi } % @end foo executes the definition of \Efoo. % But first, it executes a specialized version of \checkenv % \parseargdef\end{% \if 1\csname iscond.#1\endcsname \else % The general wording of \badenverr may not be ideal. \expandafter\checkenv\csname#1\endcsname \csname E#1\endcsname \endgroup \fi } \newhelp\EMsimple{Press RETURN to continue.} % Be sure we're in horizontal mode when doing a tie, since we make space % equivalent to this in @example-like environments. Otherwise, a space % at the beginning of a line will start with \penalty -- and % since \penalty is valid in vertical mode, we'd end up putting the % penalty on the vertical list instead of in the new paragraph. {\catcode`@ = 11 % Avoid using \@M directly, because that causes trouble % if the definition is written into an index file. \global\let\tiepenalty = \@M \gdef\tie{\leavevmode\penalty\tiepenalty\ } } % @: forces normal size whitespace following. \def\:{\spacefactor=1000 } % @* forces a line break. \def\*{\unskip\hfil\break\hbox{}\ignorespaces} % @/ allows a line break. \let\/=\allowbreak % @. is an end-of-sentence period. \def\.{.\spacefactor=\endofsentencespacefactor\space} % @! is an end-of-sentence bang. \def\!{!\spacefactor=\endofsentencespacefactor\space} % @? is an end-of-sentence query. \def\?{?\spacefactor=\endofsentencespacefactor\space} % @frenchspacing on|off says whether to put extra space after punctuation. % \def\onword{on} \def\offword{off} % \parseargdef\frenchspacing{% \def\temp{#1}% \ifx\temp\onword \plainfrenchspacing \else\ifx\temp\offword \plainnonfrenchspacing \else \errhelp = \EMsimple \errmessage{Unknown @frenchspacing option `\temp', must be on|off}% \fi\fi } % @w prevents a word break. Without the \leavevmode, @w at the % beginning of a paragraph, when TeX is still in vertical mode, would % produce a whole line of output instead of starting the paragraph. \def\w#1{\leavevmode\hbox{#1}} % @group ... @end group forces ... to be all on one page, by enclosing % it in a TeX vbox. We use \vtop instead of \vbox to construct the box % to keep its height that of a normal line. According to the rules for % \topskip (p.114 of the TeXbook), the glue inserted is % max (\topskip - \ht (first item), 0). If that height is large, % therefore, no glue is inserted, and the space between the headline and % the text is small, which looks bad. % % Another complication is that the group might be very large. This can % cause the glue on the previous page to be unduly stretched, because it % does not have much material. In this case, it's better to add an % explicit \vfill so that the extra space is at the bottom. The % threshold for doing this is if the group is more than \vfilllimit % percent of a page (\vfilllimit can be changed inside of @tex). % \newbox\groupbox \def\vfilllimit{0.7} % \envdef\group{% \ifnum\catcode`\^^M=\active \else \errhelp = \groupinvalidhelp \errmessage{@group invalid in context where filling is enabled}% \fi \startsavinginserts % \setbox\groupbox = \vtop\bgroup % Do @comment since we are called inside an environment such as % @example, where each end-of-line in the input causes an % end-of-line in the output. We don't want the end-of-line after % the `@group' to put extra space in the output. Since @group % should appear on a line by itself (according to the Texinfo % manual), we don't worry about eating any user text. \comment } % % The \vtop produces a box with normal height and large depth; thus, TeX puts % \baselineskip glue before it, and (when the next line of text is done) % \lineskip glue after it. Thus, space below is not quite equal to space % above. But it's pretty close. \def\Egroup{% % To get correct interline space between the last line of the group % and the first line afterwards, we have to propagate \prevdepth. \endgraf % Not \par, as it may have been set to \lisppar. \global\dimen1 = \prevdepth \egroup % End the \vtop. % \dimen0 is the vertical size of the group's box. \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox % \dimen2 is how much space is left on the page (more or less). \dimen2 = \pageheight \advance\dimen2 by -\pagetotal % if the group doesn't fit on the current page, and it's a big big % group, force a page break. \ifdim \dimen0 > \dimen2 \ifdim \pagetotal < \vfilllimit\pageheight \page \fi \fi \box\groupbox \prevdepth = \dimen1 \checkinserts } % % TeX puts in an \escapechar (i.e., `@') at the beginning of the help % message, so this ends up printing `@group can only ...'. % \newhelp\groupinvalidhelp{% group can only be used in environments such as @example,^^J% where each line of input produces a line of output.} % @need space-in-mils % forces a page break if there is not space-in-mils remaining. \newdimen\mil \mil=0.001in \parseargdef\need{% % Ensure vertical mode, so we don't make a big box in the middle of a % paragraph. \par % % If the @need value is less than one line space, it's useless. \dimen0 = #1\mil \dimen2 = \ht\strutbox \advance\dimen2 by \dp\strutbox \ifdim\dimen0 > \dimen2 % % Do a \strut just to make the height of this box be normal, so the % normal leading is inserted relative to the preceding line. % And a page break here is fine. \vtop to #1\mil{\strut\vfil}% % % TeX does not even consider page breaks if a penalty added to the % main vertical list is 10000 or more. But in order to see if the % empty box we just added fits on the page, we must make it consider % page breaks. On the other hand, we don't want to actually break the % page after the empty box. So we use a penalty of 9999. % % There is an extremely small chance that TeX will actually break the % page at this \penalty, if there are no other feasible breakpoints in % sight. (If the user is using lots of big @group commands, which % almost-but-not-quite fill up a page, TeX will have a hard time doing % good page breaking, for example.) However, I could not construct an % example where a page broke at this \penalty; if it happens in a real % document, then we can reconsider our strategy. \penalty9999 % % Back up by the size of the box, whether we did a page break or not. \kern -#1\mil % % Do not allow a page break right after this kern. \nobreak \fi } % @br forces paragraph break (and is undocumented). \let\br = \par % @page forces the start of a new page. % \def\page{\par\vfill\supereject} % @exdent text.... % outputs text on separate line in roman font, starting at standard page margin % This records the amount of indent in the innermost environment. % That's how much \exdent should take out. \newskip\exdentamount % This defn is used inside fill environments such as @defun. \parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break} % This defn is used inside nofill environments such as @example. \parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount \leftline{\hskip\leftskip{\rm#1}}}} % @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current % paragraph. For more general purposes, use the \margin insertion % class. WHICH is `l' or `r'. Not documented, written for gawk manual. % \newskip\inmarginspacing \inmarginspacing=1cm \def\strutdepth{\dp\strutbox} % \def\doinmargin#1#2{\strut\vadjust{% \nobreak \kern-\strutdepth \vtop to \strutdepth{% \baselineskip=\strutdepth \vss % if you have multiple lines of stuff to put here, you'll need to % make the vbox yourself of the appropriate size. \ifx#1l% \llap{\ignorespaces #2\hskip\inmarginspacing}% \else \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}% \fi \null }% }} \def\inleftmargin{\doinmargin l} \def\inrightmargin{\doinmargin r} % % @inmargin{TEXT [, RIGHT-TEXT]} % (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right; % else use TEXT for both). % \def\inmargin#1{\parseinmargin #1,,\finish} \def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing. \setbox0 = \hbox{\ignorespaces #2}% \ifdim\wd0 > 0pt \def\lefttext{#1}% have both texts \def\righttext{#2}% \else \def\lefttext{#1}% have only one text \def\righttext{#1}% \fi % \ifodd\pageno \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin \else \def\temp{\inleftmargin\lefttext}% \fi \temp } % @| inserts a changebar to the left of the current line. It should % surround any changed text. This approach does *not* work if the % change spans more than two lines of output. To handle that, we would % have adopt a much more difficult approach (putting marks into the main % vertical list for the beginning and end of each change). This command % is not documented, not supported, and doesn't work. % \def\|{% % \vadjust can only be used in horizontal mode. \leavevmode % % Append this vertical mode material after the current line in the output. \vadjust{% % We want to insert a rule with the height and depth of the current % leading; that is exactly what \strutbox is supposed to record. \vskip-\baselineskip % % \vadjust-items are inserted at the left edge of the type. So % the \llap here moves out into the left-hand margin. \llap{% % % For a thicker or thinner bar, change the `1pt'. \vrule height\baselineskip width1pt % % This is the space between the bar and the text. \hskip 12pt }% }% } % @include FILE -- \input text of FILE. % \def\include{\parseargusing\filenamecatcodes\includezzz} \def\includezzz#1{% \pushthisfilestack \def\thisfile{#1}% {% \makevalueexpandable % we want to expand any @value in FILE. \turnoffactive % and allow special characters in the expansion \indexnofonts % Allow `@@' and other weird things in file names. \wlog{texinfo.tex: doing @include of #1^^J}% \edef\temp{\noexpand\input #1 }% % % This trickery is to read FILE outside of a group, in case it makes % definitions, etc. \expandafter }\temp \popthisfilestack } \def\filenamecatcodes{% \catcode`\\=\other \catcode`~=\other \catcode`^=\other \catcode`_=\other \catcode`|=\other \catcode`<=\other \catcode`>=\other \catcode`+=\other \catcode`-=\other \catcode`\`=\other \catcode`\'=\other } \def\pushthisfilestack{% \expandafter\pushthisfilestackX\popthisfilestack\StackTerm } \def\pushthisfilestackX{% \expandafter\pushthisfilestackY\thisfile\StackTerm } \def\pushthisfilestackY #1\StackTerm #2\StackTerm {% \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}% } \def\popthisfilestack{\errthisfilestackempty} \def\errthisfilestackempty{\errmessage{Internal error: the stack of filenames is empty.}} % \def\thisfile{} % @center line % outputs that line, centered. % \parseargdef\center{% \ifhmode \let\centersub\centerH \else \let\centersub\centerV \fi \centersub{\hfil \ignorespaces#1\unskip \hfil}% \let\centersub\relax % don't let the definition persist, just in case } \def\centerH#1{{% \hfil\break \advance\hsize by -\leftskip \advance\hsize by -\rightskip \line{#1}% \break }} % \newcount\centerpenalty \def\centerV#1{% % The idea here is the same as in \startdefun, \cartouche, etc.: if % @center is the first thing after a section heading, we need to wipe % out the negative parskip inserted by \sectionheading, but still % prevent a page break here. \centerpenalty = \lastpenalty \ifnum\centerpenalty>10000 \vskip\parskip \fi \ifnum\centerpenalty>9999 \penalty\centerpenalty \fi \line{\kern\leftskip #1\kern\rightskip}% } % @sp n outputs n lines of vertical space % \parseargdef\sp{\vskip #1\baselineskip} % @comment ...line which is ignored... % @c is the same as @comment % @ignore ... @end ignore is another way to write a comment % \def\comment{\begingroup \catcode`\^^M=\other% \catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% \commentxxx} {\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} % \let\c=\comment % @paragraphindent NCHARS % We'll use ems for NCHARS, close enough. % NCHARS can also be the word `asis' or `none'. % We cannot feasibly implement @paragraphindent asis, though. % \def\asisword{asis} % no translation, these are keywords \def\noneword{none} % \parseargdef\paragraphindent{% \def\temp{#1}% \ifx\temp\asisword \else \ifx\temp\noneword \defaultparindent = 0pt \else \defaultparindent = #1em \fi \fi \parindent = \defaultparindent } % @exampleindent NCHARS % We'll use ems for NCHARS like @paragraphindent. % It seems @exampleindent asis isn't necessary, but % I preserve it to make it similar to @paragraphindent. \parseargdef\exampleindent{% \def\temp{#1}% \ifx\temp\asisword \else \ifx\temp\noneword \lispnarrowing = 0pt \else \lispnarrowing = #1em \fi \fi } % @firstparagraphindent WORD % If WORD is `none', then suppress indentation of the first paragraph % after a section heading. If WORD is `insert', then do indent at such % paragraphs. % % The paragraph indentation is suppressed or not by calling % \suppressfirstparagraphindent, which the sectioning commands do. % We switch the definition of this back and forth according to WORD. % By default, we suppress indentation. % \def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent} \def\insertword{insert} % \parseargdef\firstparagraphindent{% \def\temp{#1}% \ifx\temp\noneword \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent \else\ifx\temp\insertword \let\suppressfirstparagraphindent = \relax \else \errhelp = \EMsimple \errmessage{Unknown @firstparagraphindent option `\temp'}% \fi\fi } % Here is how we actually suppress indentation. Redefine \everypar to % \kern backwards by \parindent, and then reset itself to empty. % % We also make \indent itself not actually do anything until the next % paragraph. % \gdef\dosuppressfirstparagraphindent{% \gdef\indent{% \restorefirstparagraphindent \indent }% \gdef\noindent{% \restorefirstparagraphindent \noindent }% \global\everypar = {% \kern -\parindent \restorefirstparagraphindent }% } \gdef\restorefirstparagraphindent{% \global \let \indent = \ptexindent \global \let \noindent = \ptexnoindent \global \everypar = {}% } % @refill is a no-op. \let\refill=\relax % If working on a large document in chapters, it is convenient to % be able to disable indexing, cross-referencing, and contents, for test runs. % This is done with @novalidate (before @setfilename). % \newif\iflinks \linkstrue % by default we want the aux files. \let\novalidate = \linksfalse % @setfilename is done at the beginning of every texinfo file. % So open here the files we need to have open while reading the input. % This makes it possible to make a .fmt file for texinfo. \def\setfilename{% \fixbackslash % Turn off hack to swallow `\input texinfo'. \iflinks \tryauxfile % Open the new aux file. TeX will close it automatically at exit. \immediate\openout\auxfile=\jobname.aux \fi % \openindices needs to do some work in any case. \openindices \let\setfilename=\comment % Ignore extra @setfilename cmds. % % If texinfo.cnf is present on the system, read it. % Useful for site-wide @afourpaper, etc. \openin 1 texinfo.cnf \ifeof 1 \else \input texinfo.cnf \fi \closein 1 % \comment % Ignore the actual filename. } % Called from \setfilename. % \def\openindices{% \newindex{cp}% \newcodeindex{fn}% \newcodeindex{vr}% \newcodeindex{tp}% \newcodeindex{ky}% \newcodeindex{pg}% } % @bye. \outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} \message{pdf,} % adobe `portable' document format \newcount\tempnum \newcount\lnkcount \newtoks\filename \newcount\filenamelength \newcount\pgn \newtoks\toksA \newtoks\toksB \newtoks\toksC \newtoks\toksD \newbox\boxA \newcount\countA \newif\ifpdf \newif\ifpdfmakepagedest % when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1 % can be set). So we test for \relax and 0 as well as being undefined. \ifx\pdfoutput\thisisundefined \else \ifx\pdfoutput\relax \else \ifcase\pdfoutput \else \pdftrue \fi \fi \fi % PDF uses PostScript string constants for the names of xref targets, % for display in the outlines, and in other places. Thus, we have to % double any backslashes. Otherwise, a name like "\node" will be % interpreted as a newline (\n), followed by o, d, e. Not good. % % See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and % related messages. The final outcome is that it is up to the TeX user % to double the backslashes and otherwise make the string valid, so % that's what we do. pdftex 1.30.0 (ca.2005) introduced a primitive to % do this reliably, so we use it. % #1 is a control sequence in which to do the replacements, % which we \xdef. \def\txiescapepdf#1{% \ifx\pdfescapestring\thisisundefined % No primitive available; should we give a warning or log? % Many times it won't matter. \else % The expandable \pdfescapestring primitive escapes parentheses, % backslashes, and other special chars. \xdef#1{\pdfescapestring{#1}}% \fi } \newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images with PDF output, and none of those formats could be found. (.eps cannot be supported due to the design of the PDF format; use regular TeX (DVI output) for that.)} \ifpdf % % Color manipulation macros based on pdfcolor.tex, % except using rgb instead of cmyk; the latter is said to render as a % very dark gray on-screen and a very dark halftone in print, instead % of actual black. \def\rgbDarkRed{0.50 0.09 0.12} \def\rgbBlack{0 0 0} % % k sets the color for filling (usual text, etc.); % K sets the color for stroking (thin rules, e.g., normal _'s). \def\pdfsetcolor#1{\pdfliteral{#1 rg #1 RG}} % % Set color, and create a mark which defines \thiscolor accordingly, % so that \makeheadline knows which color to restore. \def\setcolor#1{% \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}% \domark \pdfsetcolor{#1}% } % \def\maincolor{\rgbBlack} \pdfsetcolor{\maincolor} \edef\thiscolor{\maincolor} \def\lastcolordefs{} % \def\makefootline{% \baselineskip24pt \line{\pdfsetcolor{\maincolor}\the\footline}% } % \def\makeheadline{% \vbox to 0pt{% \vskip-22.5pt \line{% \vbox to8.5pt{}% % Extract \thiscolor definition from the marks. \getcolormarks % Typeset the headline with \maincolor, then restore the color. \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}% }% \vss }% \nointerlineskip } % % \pdfcatalog{/PageMode /UseOutlines} % % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto). \def\dopdfimage#1#2#3{% \def\pdfimagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% \def\pdfimageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% % % pdftex (and the PDF format) support .pdf, .png, .jpg (among % others). Let's try in that order, PDF first since if % someone has a scalable image, presumably better to use that than a % bitmap. \let\pdfimgext=\empty \begingroup \openin 1 #1.pdf \ifeof 1 \openin 1 #1.PDF \ifeof 1 \openin 1 #1.png \ifeof 1 \openin 1 #1.jpg \ifeof 1 \openin 1 #1.jpeg \ifeof 1 \openin 1 #1.JPG \ifeof 1 \errhelp = \nopdfimagehelp \errmessage{Could not find image file #1 for pdf}% \else \gdef\pdfimgext{JPG}% \fi \else \gdef\pdfimgext{jpeg}% \fi \else \gdef\pdfimgext{jpg}% \fi \else \gdef\pdfimgext{png}% \fi \else \gdef\pdfimgext{PDF}% \fi \else \gdef\pdfimgext{pdf}% \fi \closein 1 \endgroup % % without \immediate, ancient pdftex seg faults when the same image is % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.) \ifnum\pdftexversion < 14 \immediate\pdfimage \else \immediate\pdfximage \fi \ifdim \wd0 >0pt width \pdfimagewidth \fi \ifdim \wd2 >0pt height \pdfimageheight \fi \ifnum\pdftexversion<13 #1.\pdfimgext \else {#1.\pdfimgext}% \fi \ifnum\pdftexversion < 14 \else \pdfrefximage \pdflastximage \fi} % \def\pdfmkdest#1{{% % We have to set dummies so commands such as @code, and characters % such as \, aren't expanded when present in a section title. \indexnofonts \turnoffactive \makevalueexpandable \def\pdfdestname{#1}% \txiescapepdf\pdfdestname \safewhatsit{\pdfdest name{\pdfdestname} xyz}% }} % % used to mark target names; must be expandable. \def\pdfmkpgn#1{#1} % % by default, use a color that is dark enough to print on paper as % nearly black, but still distinguishable for online viewing. \def\urlcolor{\rgbDarkRed} \def\linkcolor{\rgbDarkRed} \def\endlink{\setcolor{\maincolor}\pdfendlink} % % Adding outlines to PDF; macros for calculating structure of outlines % come from Petr Olsak \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% \else \csname#1\endcsname \fi} \def\advancenumber#1{\tempnum=\expnumber{#1}\relax \advance\tempnum by 1 \expandafter\xdef\csname#1\endcsname{\the\tempnum}} % % #1 is the section text, which is what will be displayed in the % outline by the pdf viewer. #2 is the pdf expression for the number % of subentries (or empty, for subsubsections). #3 is the node text, % which might be empty if this toc entry had no corresponding node. % #4 is the page number % \def\dopdfoutline#1#2#3#4{% % Generate a link to the node text if that exists; else, use the % page number. We could generate a destination for the section % text in the case where a section has no node, but it doesn't % seem worth the trouble, since most documents are normally structured. \edef\pdfoutlinedest{#3}% \ifx\pdfoutlinedest\empty \def\pdfoutlinedest{#4}% \else \txiescapepdf\pdfoutlinedest \fi % % Also escape PDF chars in the display string. \edef\pdfoutlinetext{#1}% \txiescapepdf\pdfoutlinetext % \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}% } % \def\pdfmakeoutlines{% \begingroup % Read toc silently, to get counts of subentries for \pdfoutline. \def\partentry##1##2##3##4{}% ignore parts in the outlines \def\numchapentry##1##2##3##4{% \def\thischapnum{##2}% \def\thissecnum{0}% \def\thissubsecnum{0}% }% \def\numsecentry##1##2##3##4{% \advancenumber{chap\thischapnum}% \def\thissecnum{##2}% \def\thissubsecnum{0}% }% \def\numsubsecentry##1##2##3##4{% \advancenumber{sec\thissecnum}% \def\thissubsecnum{##2}% }% \def\numsubsubsecentry##1##2##3##4{% \advancenumber{subsec\thissubsecnum}% }% \def\thischapnum{0}% \def\thissecnum{0}% \def\thissubsecnum{0}% % % use \def rather than \let here because we redefine \chapentry et % al. a second time, below. \def\appentry{\numchapentry}% \def\appsecentry{\numsecentry}% \def\appsubsecentry{\numsubsecentry}% \def\appsubsubsecentry{\numsubsubsecentry}% \def\unnchapentry{\numchapentry}% \def\unnsecentry{\numsecentry}% \def\unnsubsecentry{\numsubsecentry}% \def\unnsubsubsecentry{\numsubsubsecentry}% \readdatafile{toc}% % % Read toc second time, this time actually producing the outlines. % The `-' means take the \expnumber as the absolute number of % subentries, which we calculated on our first read of the .toc above. % % We use the node names as the destinations. \def\numchapentry##1##2##3##4{% \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}% \def\numsecentry##1##2##3##4{% \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}% \def\numsubsecentry##1##2##3##4{% \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}% \def\numsubsubsecentry##1##2##3##4{% count is always zero \dopdfoutline{##1}{}{##3}{##4}}% % % PDF outlines are displayed using system fonts, instead of % document fonts. Therefore we cannot use special characters, % since the encoding is unknown. For example, the eogonek from % Latin 2 (0xea) gets translated to a | character. Info from % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100. % % TODO this right, we have to translate 8-bit characters to % their "best" equivalent, based on the @documentencoding. Too % much work for too little return. Just use the ASCII equivalents % we use for the index sort strings. % \indexnofonts \setupdatafile % We can have normal brace characters in the PDF outlines, unlike % Texinfo index files. So set that up. \def\{{\lbracecharliteral}% \def\}{\rbracecharliteral}% \catcode`\\=\active \otherbackslash \input \tocreadfilename \endgroup } {\catcode`[=1 \catcode`]=2 \catcode`{=\other \catcode`}=\other \gdef\lbracecharliteral[{]% \gdef\rbracecharliteral[}]% ] % \def\skipspaces#1{\def\PP{#1}\def\D{|}% \ifx\PP\D\let\nextsp\relax \else\let\nextsp\skipspaces \addtokens{\filename}{\PP}% \advance\filenamelength by 1 \fi \nextsp} \def\getfilename#1{% \filenamelength=0 % If we don't expand the argument now, \skipspaces will get % snagged on things like "@value{foo}". \edef\temp{#1}% \expandafter\skipspaces\temp|\relax } \ifnum\pdftexversion < 14 \let \startlink \pdfannotlink \else \let \startlink \pdfstartlink \fi % make a live url in pdf output. \def\pdfurl#1{% \begingroup % it seems we really need yet another set of dummies; have not % tried to figure out what each command should do in the context % of @url. for now, just make @/ a no-op, that's the only one % people have actually reported a problem with. % \normalturnoffactive \def\@{@}% \let\/=\empty \makevalueexpandable % do we want to go so far as to use \indexnofonts instead of just % special-casing \var here? \def\var##1{##1}% % \leavevmode\setcolor{\urlcolor}% \startlink attr{/Border [0 0 0]}% user{/Subtype /Link /A << /S /URI /URI (#1) >>}% \endgroup} \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} \def\maketoks{% \expandafter\poptoks\the\toksA|ENDTOKS|\relax \ifx\first0\adn0 \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 \else \ifnum0=\countA\else\makelink\fi \ifx\first.\let\next=\done\else \let\next=\maketoks \addtokens{\toksB}{\the\toksD} \ifx\first,\addtokens{\toksB}{\space}\fi \fi \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next} \def\makelink{\addtokens{\toksB}% {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} \def\pdflink#1{% \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}} \setcolor{\linkcolor}#1\endlink} \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} \else % non-pdf mode \let\pdfmkdest = \gobble \let\pdfurl = \gobble \let\endlink = \relax \let\setcolor = \gobble \let\pdfsetcolor = \gobble \let\pdfmakeoutlines = \relax \fi % \ifx\pdfoutput \message{fonts,} % Change the current font style to #1, remembering it in \curfontstyle. % For now, we do not accumulate font styles: @b{@i{foo}} prints foo in % italics, not bold italics. % \def\setfontstyle#1{% \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd. \csname ten#1\endcsname % change the current font } % Select #1 fonts with the current style. % \def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname} \def\rm{\fam=0 \setfontstyle{rm}} \def\it{\fam=\itfam \setfontstyle{it}} \def\sl{\fam=\slfam \setfontstyle{sl}} \def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf} \def\tt{\fam=\ttfam \setfontstyle{tt}} % Unfortunately, we have to override this for titles and the like, since % in those cases "rm" is bold. Sigh. \def\rmisbold{\rm\def\curfontstyle{bf}} % Texinfo sort of supports the sans serif font style, which plain TeX does not. % So we set up a \sf. \newfam\sffam \def\sf{\fam=\sffam \setfontstyle{sf}} \let\li = \sf % Sometimes we call it \li, not \sf. % We don't need math for this font style. \def\ttsl{\setfontstyle{ttsl}} % Set the baselineskip to #1, and the lineskip and strut size % correspondingly. There is no deep meaning behind these magic numbers % used as factors; they just match (closely enough) what Knuth defined. % \def\lineskipfactor{.08333} \def\strutheightpercent{.70833} \def\strutdepthpercent {.29167} % % can get a sort of poor man's double spacing by redefining this. \def\baselinefactor{1} % \newdimen\textleading \def\setleading#1{% \dimen0 = #1\relax \normalbaselineskip = \baselinefactor\dimen0 \normallineskip = \lineskipfactor\normalbaselineskip \normalbaselines \setbox\strutbox =\hbox{% \vrule width0pt height\strutheightpercent\baselineskip depth \strutdepthpercent \baselineskip }% } % PDF CMaps. See also LaTeX's t1.cmap. % % do nothing with this by default. \expandafter\let\csname cmapOT1\endcsname\gobble \expandafter\let\csname cmapOT1IT\endcsname\gobble \expandafter\let\csname cmapOT1TT\endcsname\gobble % if we are producing pdf, and we have \pdffontattr, then define cmaps. % (\pdffontattr was introduced many years ago, but people still run % older pdftex's; it's easy to conditionalize, so we do.) \ifpdf \ifx\pdffontattr\thisisundefined \else \begingroup \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap %%DocumentNeededResources: ProcSet (CIDInit) %%IncludeResource: ProcSet (CIDInit) %%BeginResource: CMap (TeX-OT1-0) %%Title: (TeX-OT1-0 TeX OT1 0) %%Version: 1.000 %%EndComments /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (TeX) /Ordering (OT1) /Supplement 0 >> def /CMapName /TeX-OT1-0 def /CMapType 2 def 1 begincodespacerange <00> <7F> endcodespacerange 8 beginbfrange <00> <01> <0393> <09> <0A> <03A8> <23> <26> <0023> <28> <3B> <0028> <3F> <5B> <003F> <5D> <5E> <005D> <61> <7A> <0061> <7B> <7C> <2013> endbfrange 40 beginbfchar <02> <0398> <03> <039B> <04> <039E> <05> <03A0> <06> <03A3> <07> <03D2> <08> <03A6> <0B> <00660066> <0C> <00660069> <0D> <0066006C> <0E> <006600660069> <0F> <00660066006C> <10> <0131> <11> <0237> <12> <0060> <13> <00B4> <14> <02C7> <15> <02D8> <16> <00AF> <17> <02DA> <18> <00B8> <19> <00DF> <1A> <00E6> <1B> <0153> <1C> <00F8> <1D> <00C6> <1E> <0152> <1F> <00D8> <21> <0021> <22> <201D> <27> <2019> <3C> <00A1> <3D> <003D> <3E> <00BF> <5C> <201C> <5F> <02D9> <60> <2018> <7D> <02DD> <7E> <007E> <7F> <00A8> endbfchar endcmap CMapName currentdict /CMap defineresource pop end end %%EndResource %%EOF }\endgroup \expandafter\edef\csname cmapOT1\endcsname#1{% \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% }% % % \cmapOT1IT \begingroup \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap %%DocumentNeededResources: ProcSet (CIDInit) %%IncludeResource: ProcSet (CIDInit) %%BeginResource: CMap (TeX-OT1IT-0) %%Title: (TeX-OT1IT-0 TeX OT1IT 0) %%Version: 1.000 %%EndComments /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (TeX) /Ordering (OT1IT) /Supplement 0 >> def /CMapName /TeX-OT1IT-0 def /CMapType 2 def 1 begincodespacerange <00> <7F> endcodespacerange 8 beginbfrange <00> <01> <0393> <09> <0A> <03A8> <25> <26> <0025> <28> <3B> <0028> <3F> <5B> <003F> <5D> <5E> <005D> <61> <7A> <0061> <7B> <7C> <2013> endbfrange 42 beginbfchar <02> <0398> <03> <039B> <04> <039E> <05> <03A0> <06> <03A3> <07> <03D2> <08> <03A6> <0B> <00660066> <0C> <00660069> <0D> <0066006C> <0E> <006600660069> <0F> <00660066006C> <10> <0131> <11> <0237> <12> <0060> <13> <00B4> <14> <02C7> <15> <02D8> <16> <00AF> <17> <02DA> <18> <00B8> <19> <00DF> <1A> <00E6> <1B> <0153> <1C> <00F8> <1D> <00C6> <1E> <0152> <1F> <00D8> <21> <0021> <22> <201D> <23> <0023> <24> <00A3> <27> <2019> <3C> <00A1> <3D> <003D> <3E> <00BF> <5C> <201C> <5F> <02D9> <60> <2018> <7D> <02DD> <7E> <007E> <7F> <00A8> endbfchar endcmap CMapName currentdict /CMap defineresource pop end end %%EndResource %%EOF }\endgroup \expandafter\edef\csname cmapOT1IT\endcsname#1{% \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% }% % % \cmapOT1TT \begingroup \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap %%DocumentNeededResources: ProcSet (CIDInit) %%IncludeResource: ProcSet (CIDInit) %%BeginResource: CMap (TeX-OT1TT-0) %%Title: (TeX-OT1TT-0 TeX OT1TT 0) %%Version: 1.000 %%EndComments /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (TeX) /Ordering (OT1TT) /Supplement 0 >> def /CMapName /TeX-OT1TT-0 def /CMapType 2 def 1 begincodespacerange <00> <7F> endcodespacerange 5 beginbfrange <00> <01> <0393> <09> <0A> <03A8> <21> <26> <0021> <28> <5F> <0028> <61> <7E> <0061> endbfrange 32 beginbfchar <02> <0398> <03> <039B> <04> <039E> <05> <03A0> <06> <03A3> <07> <03D2> <08> <03A6> <0B> <2191> <0C> <2193> <0D> <0027> <0E> <00A1> <0F> <00BF> <10> <0131> <11> <0237> <12> <0060> <13> <00B4> <14> <02C7> <15> <02D8> <16> <00AF> <17> <02DA> <18> <00B8> <19> <00DF> <1A> <00E6> <1B> <0153> <1C> <00F8> <1D> <00C6> <1E> <0152> <1F> <00D8> <20> <2423> <27> <2019> <60> <2018> <7F> <00A8> endbfchar endcmap CMapName currentdict /CMap defineresource pop end end %%EndResource %%EOF }\endgroup \expandafter\edef\csname cmapOT1TT\endcsname#1{% \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% }% \fi\fi % Set the font macro #1 to the font named \fontprefix#2. % #3 is the font's design size, #4 is a scale factor, #5 is the CMap % encoding (only OT1, OT1IT and OT1TT are allowed, or empty to omit). % Example: % #1 = \textrm % #2 = \rmshape % #3 = 10 % #4 = \mainmagstep % #5 = OT1 % \def\setfont#1#2#3#4#5{% \font#1=\fontprefix#2#3 scaled #4 \csname cmap#5\endcsname#1% } % This is what gets called when #5 of \setfont is empty. \let\cmap\gobble % % (end of cmaps) % Use cm as the default font prefix. % To specify the font prefix, you must define \fontprefix % before you read in texinfo.tex. \ifx\fontprefix\thisisundefined \def\fontprefix{cm} \fi % Support font families that don't use the same naming scheme as CM. \def\rmshape{r} \def\rmbshape{bx} % where the normal face is bold \def\bfshape{b} \def\bxshape{bx} \def\ttshape{tt} \def\ttbshape{tt} \def\ttslshape{sltt} \def\itshape{ti} \def\itbshape{bxti} \def\slshape{sl} \def\slbshape{bxsl} \def\sfshape{ss} \def\sfbshape{ss} \def\scshape{csc} \def\scbshape{csc} % Definitions for a main text size of 11pt. (The default in Texinfo.) % \def\definetextfontsizexi{% % Text fonts (11.2pt, magstep1). \def\textnominalsize{11pt} \edef\mainmagstep{\magstephalf} \setfont\textrm\rmshape{10}{\mainmagstep}{OT1} \setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT} \setfont\textbf\bfshape{10}{\mainmagstep}{OT1} \setfont\textit\itshape{10}{\mainmagstep}{OT1IT} \setfont\textsl\slshape{10}{\mainmagstep}{OT1} \setfont\textsf\sfshape{10}{\mainmagstep}{OT1} \setfont\textsc\scshape{10}{\mainmagstep}{OT1} \setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT} \font\texti=cmmi10 scaled \mainmagstep \font\textsy=cmsy10 scaled \mainmagstep \def\textecsize{1095} % A few fonts for @defun names and args. \setfont\defbf\bfshape{10}{\magstep1}{OT1} \setfont\deftt\ttshape{10}{\magstep1}{OT1TT} \setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT} \def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} % Fonts for indices, footnotes, small examples (9pt). \def\smallnominalsize{9pt} \setfont\smallrm\rmshape{9}{1000}{OT1} \setfont\smalltt\ttshape{9}{1000}{OT1TT} \setfont\smallbf\bfshape{10}{900}{OT1} \setfont\smallit\itshape{9}{1000}{OT1IT} \setfont\smallsl\slshape{9}{1000}{OT1} \setfont\smallsf\sfshape{9}{1000}{OT1} \setfont\smallsc\scshape{10}{900}{OT1} \setfont\smallttsl\ttslshape{10}{900}{OT1TT} \font\smalli=cmmi9 \font\smallsy=cmsy9 \def\smallecsize{0900} % Fonts for small examples (8pt). \def\smallernominalsize{8pt} \setfont\smallerrm\rmshape{8}{1000}{OT1} \setfont\smallertt\ttshape{8}{1000}{OT1TT} \setfont\smallerbf\bfshape{10}{800}{OT1} \setfont\smallerit\itshape{8}{1000}{OT1IT} \setfont\smallersl\slshape{8}{1000}{OT1} \setfont\smallersf\sfshape{8}{1000}{OT1} \setfont\smallersc\scshape{10}{800}{OT1} \setfont\smallerttsl\ttslshape{10}{800}{OT1TT} \font\smalleri=cmmi8 \font\smallersy=cmsy8 \def\smallerecsize{0800} % Fonts for title page (20.4pt): \def\titlenominalsize{20pt} \setfont\titlerm\rmbshape{12}{\magstep3}{OT1} \setfont\titleit\itbshape{10}{\magstep4}{OT1IT} \setfont\titlesl\slbshape{10}{\magstep4}{OT1} \setfont\titlett\ttbshape{12}{\magstep3}{OT1TT} \setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT} \setfont\titlesf\sfbshape{17}{\magstep1}{OT1} \let\titlebf=\titlerm \setfont\titlesc\scbshape{10}{\magstep4}{OT1} \font\titlei=cmmi12 scaled \magstep3 \font\titlesy=cmsy10 scaled \magstep4 \def\titleecsize{2074} % Chapter (and unnumbered) fonts (17.28pt). \def\chapnominalsize{17pt} \setfont\chaprm\rmbshape{12}{\magstep2}{OT1} \setfont\chapit\itbshape{10}{\magstep3}{OT1IT} \setfont\chapsl\slbshape{10}{\magstep3}{OT1} \setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT} \setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT} \setfont\chapsf\sfbshape{17}{1000}{OT1} \let\chapbf=\chaprm \setfont\chapsc\scbshape{10}{\magstep3}{OT1} \font\chapi=cmmi12 scaled \magstep2 \font\chapsy=cmsy10 scaled \magstep3 \def\chapecsize{1728} % Section fonts (14.4pt). \def\secnominalsize{14pt} \setfont\secrm\rmbshape{12}{\magstep1}{OT1} \setfont\secit\itbshape{10}{\magstep2}{OT1IT} \setfont\secsl\slbshape{10}{\magstep2}{OT1} \setfont\sectt\ttbshape{12}{\magstep1}{OT1TT} \setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT} \setfont\secsf\sfbshape{12}{\magstep1}{OT1} \let\secbf\secrm \setfont\secsc\scbshape{10}{\magstep2}{OT1} \font\seci=cmmi12 scaled \magstep1 \font\secsy=cmsy10 scaled \magstep2 \def\sececsize{1440} % Subsection fonts (13.15pt). \def\ssecnominalsize{13pt} \setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1} \setfont\ssecit\itbshape{10}{1315}{OT1IT} \setfont\ssecsl\slbshape{10}{1315}{OT1} \setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT} \setfont\ssecttsl\ttslshape{10}{1315}{OT1TT} \setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1} \let\ssecbf\ssecrm \setfont\ssecsc\scbshape{10}{1315}{OT1} \font\sseci=cmmi12 scaled \magstephalf \font\ssecsy=cmsy10 scaled 1315 \def\ssececsize{1200} % Reduced fonts for @acro in text (10pt). \def\reducednominalsize{10pt} \setfont\reducedrm\rmshape{10}{1000}{OT1} \setfont\reducedtt\ttshape{10}{1000}{OT1TT} \setfont\reducedbf\bfshape{10}{1000}{OT1} \setfont\reducedit\itshape{10}{1000}{OT1IT} \setfont\reducedsl\slshape{10}{1000}{OT1} \setfont\reducedsf\sfshape{10}{1000}{OT1} \setfont\reducedsc\scshape{10}{1000}{OT1} \setfont\reducedttsl\ttslshape{10}{1000}{OT1TT} \font\reducedi=cmmi10 \font\reducedsy=cmsy10 \def\reducedecsize{1000} \textleading = 13.2pt % line spacing for 11pt CM \textfonts % reset the current fonts \rm } % end of 11pt text font size definitions, \definetextfontsizexi % Definitions to make the main text be 10pt Computer Modern, with % section, chapter, etc., sizes following suit. This is for the GNU % Press printing of the Emacs 22 manual. Maybe other manuals in the % future. Used with @smallbook, which sets the leading to 12pt. % \def\definetextfontsizex{% % Text fonts (10pt). \def\textnominalsize{10pt} \edef\mainmagstep{1000} \setfont\textrm\rmshape{10}{\mainmagstep}{OT1} \setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT} \setfont\textbf\bfshape{10}{\mainmagstep}{OT1} \setfont\textit\itshape{10}{\mainmagstep}{OT1IT} \setfont\textsl\slshape{10}{\mainmagstep}{OT1} \setfont\textsf\sfshape{10}{\mainmagstep}{OT1} \setfont\textsc\scshape{10}{\mainmagstep}{OT1} \setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT} \font\texti=cmmi10 scaled \mainmagstep \font\textsy=cmsy10 scaled \mainmagstep \def\textecsize{1000} % A few fonts for @defun names and args. \setfont\defbf\bfshape{10}{\magstephalf}{OT1} \setfont\deftt\ttshape{10}{\magstephalf}{OT1TT} \setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT} \def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} % Fonts for indices, footnotes, small examples (9pt). \def\smallnominalsize{9pt} \setfont\smallrm\rmshape{9}{1000}{OT1} \setfont\smalltt\ttshape{9}{1000}{OT1TT} \setfont\smallbf\bfshape{10}{900}{OT1} \setfont\smallit\itshape{9}{1000}{OT1IT} \setfont\smallsl\slshape{9}{1000}{OT1} \setfont\smallsf\sfshape{9}{1000}{OT1} \setfont\smallsc\scshape{10}{900}{OT1} \setfont\smallttsl\ttslshape{10}{900}{OT1TT} \font\smalli=cmmi9 \font\smallsy=cmsy9 \def\smallecsize{0900} % Fonts for small examples (8pt). \def\smallernominalsize{8pt} \setfont\smallerrm\rmshape{8}{1000}{OT1} \setfont\smallertt\ttshape{8}{1000}{OT1TT} \setfont\smallerbf\bfshape{10}{800}{OT1} \setfont\smallerit\itshape{8}{1000}{OT1IT} \setfont\smallersl\slshape{8}{1000}{OT1} \setfont\smallersf\sfshape{8}{1000}{OT1} \setfont\smallersc\scshape{10}{800}{OT1} \setfont\smallerttsl\ttslshape{10}{800}{OT1TT} \font\smalleri=cmmi8 \font\smallersy=cmsy8 \def\smallerecsize{0800} % Fonts for title page (20.4pt): \def\titlenominalsize{20pt} \setfont\titlerm\rmbshape{12}{\magstep3}{OT1} \setfont\titleit\itbshape{10}{\magstep4}{OT1IT} \setfont\titlesl\slbshape{10}{\magstep4}{OT1} \setfont\titlett\ttbshape{12}{\magstep3}{OT1TT} \setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT} \setfont\titlesf\sfbshape{17}{\magstep1}{OT1} \let\titlebf=\titlerm \setfont\titlesc\scbshape{10}{\magstep4}{OT1} \font\titlei=cmmi12 scaled \magstep3 \font\titlesy=cmsy10 scaled \magstep4 \def\titleecsize{2074} % Chapter fonts (14.4pt). \def\chapnominalsize{14pt} \setfont\chaprm\rmbshape{12}{\magstep1}{OT1} \setfont\chapit\itbshape{10}{\magstep2}{OT1IT} \setfont\chapsl\slbshape{10}{\magstep2}{OT1} \setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT} \setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT} \setfont\chapsf\sfbshape{12}{\magstep1}{OT1} \let\chapbf\chaprm \setfont\chapsc\scbshape{10}{\magstep2}{OT1} \font\chapi=cmmi12 scaled \magstep1 \font\chapsy=cmsy10 scaled \magstep2 \def\chapecsize{1440} % Section fonts (12pt). \def\secnominalsize{12pt} \setfont\secrm\rmbshape{12}{1000}{OT1} \setfont\secit\itbshape{10}{\magstep1}{OT1IT} \setfont\secsl\slbshape{10}{\magstep1}{OT1} \setfont\sectt\ttbshape{12}{1000}{OT1TT} \setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT} \setfont\secsf\sfbshape{12}{1000}{OT1} \let\secbf\secrm \setfont\secsc\scbshape{10}{\magstep1}{OT1} \font\seci=cmmi12 \font\secsy=cmsy10 scaled \magstep1 \def\sececsize{1200} % Subsection fonts (10pt). \def\ssecnominalsize{10pt} \setfont\ssecrm\rmbshape{10}{1000}{OT1} \setfont\ssecit\itbshape{10}{1000}{OT1IT} \setfont\ssecsl\slbshape{10}{1000}{OT1} \setfont\ssectt\ttbshape{10}{1000}{OT1TT} \setfont\ssecttsl\ttslshape{10}{1000}{OT1TT} \setfont\ssecsf\sfbshape{10}{1000}{OT1} \let\ssecbf\ssecrm \setfont\ssecsc\scbshape{10}{1000}{OT1} \font\sseci=cmmi10 \font\ssecsy=cmsy10 \def\ssececsize{1000} % Reduced fonts for @acro in text (9pt). \def\reducednominalsize{9pt} \setfont\reducedrm\rmshape{9}{1000}{OT1} \setfont\reducedtt\ttshape{9}{1000}{OT1TT} \setfont\reducedbf\bfshape{10}{900}{OT1} \setfont\reducedit\itshape{9}{1000}{OT1IT} \setfont\reducedsl\slshape{9}{1000}{OT1} \setfont\reducedsf\sfshape{9}{1000}{OT1} \setfont\reducedsc\scshape{10}{900}{OT1} \setfont\reducedttsl\ttslshape{10}{900}{OT1TT} \font\reducedi=cmmi9 \font\reducedsy=cmsy9 \def\reducedecsize{0900} \divide\parskip by 2 % reduce space between paragraphs \textleading = 12pt % line spacing for 10pt CM \textfonts % reset the current fonts \rm } % end of 10pt text font size definitions, \definetextfontsizex % We provide the user-level command % @fonttextsize 10 % (or 11) to redefine the text font size. pt is assumed. % \def\xiword{11} \def\xword{10} \def\xwordpt{10pt} % \parseargdef\fonttextsize{% \def\textsizearg{#1}% %\wlog{doing @fonttextsize \textsizearg}% % % Set \globaldefs so that documents can use this inside @tex, since % makeinfo 4.8 does not support it, but we need it nonetheless. % \begingroup \globaldefs=1 \ifx\textsizearg\xword \definetextfontsizex \else \ifx\textsizearg\xiword \definetextfontsizexi \else \errhelp=\EMsimple \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'} \fi\fi \endgroup } % In order for the font changes to affect most math symbols and letters, % we have to define the \textfont of the standard families. Since % texinfo doesn't allow for producing subscripts and superscripts except % in the main text, we don't bother to reset \scriptfont and % \scriptscriptfont (which would also require loading a lot more fonts). % \def\resetmathfonts{% \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf \textfont\ttfam=\tentt \textfont\sffam=\tensf } % The font-changing commands redefine the meanings of \tenSTYLE, instead % of just \STYLE. We do this because \STYLE needs to also set the % current \fam for math mode. Our \STYLE (e.g., \rm) commands hardwire % \tenSTYLE to set the current font. % % Each font-changing command also sets the names \lsize (one size lower) % and \lllsize (three sizes lower). These relative commands are used in % the LaTeX logo and acronyms. % % This all needs generalizing, badly. % \def\textfonts{% \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl \def\curfontsize{text}% \def\lsize{reduced}\def\lllsize{smaller}% \resetmathfonts \setleading{\textleading}} \def\titlefonts{% \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy \let\tenttsl=\titlettsl \def\curfontsize{title}% \def\lsize{chap}\def\lllsize{subsec}% \resetmathfonts \setleading{27pt}} \def\titlefont#1{{\titlefonts\rmisbold #1}} \def\chapfonts{% \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl \def\curfontsize{chap}% \def\lsize{sec}\def\lllsize{text}% \resetmathfonts \setleading{19pt}} \def\secfonts{% \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl \def\curfontsize{sec}% \def\lsize{subsec}\def\lllsize{reduced}% \resetmathfonts \setleading{16pt}} \def\subsecfonts{% \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl \def\curfontsize{ssec}% \def\lsize{text}\def\lllsize{small}% \resetmathfonts \setleading{15pt}} \let\subsubsecfonts = \subsecfonts \def\reducedfonts{% \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy \let\tenttsl=\reducedttsl \def\curfontsize{reduced}% \def\lsize{small}\def\lllsize{smaller}% \resetmathfonts \setleading{10.5pt}} \def\smallfonts{% \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy \let\tenttsl=\smallttsl \def\curfontsize{small}% \def\lsize{smaller}\def\lllsize{smaller}% \resetmathfonts \setleading{10.5pt}} \def\smallerfonts{% \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy \let\tenttsl=\smallerttsl \def\curfontsize{smaller}% \def\lsize{smaller}\def\lllsize{smaller}% \resetmathfonts \setleading{9.5pt}} % Fonts for short table of contents. \setfont\shortcontrm\rmshape{12}{1000}{OT1} \setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12 \setfont\shortcontsl\slshape{12}{1000}{OT1} \setfont\shortconttt\ttshape{12}{1000}{OT1TT} % Define these just so they can be easily changed for other fonts. \def\angleleft{$\langle$} \def\angleright{$\rangle$} % Set the fonts to use with the @small... environments. \let\smallexamplefonts = \smallfonts % About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample % can fit this many characters: % 8.5x11=86 smallbook=72 a4=90 a5=69 % If we use \scriptfonts (8pt), then we can fit this many characters: % 8.5x11=90+ smallbook=80 a4=90+ a5=77 % For me, subjectively, the few extra characters that fit aren't worth % the additional smallness of 8pt. So I'm making the default 9pt. % % By the way, for comparison, here's what fits with @example (10pt): % 8.5x11=71 smallbook=60 a4=75 a5=58 % --karl, 24jan03. % Set up the default fonts, so we can use them for creating boxes. % \definetextfontsizexi \message{markup,} % Check if we are currently using a typewriter font. Since all the % Computer Modern typewriter fonts have zero interword stretch (and % shrink), and it is reasonable to expect all typewriter fonts to have % this property, we can check that font parameter. % \def\ifmonospace{\ifdim\fontdimen3\font=0pt } % Markup style infrastructure. \defmarkupstylesetup\INITMACRO will % define and register \INITMACRO to be called on markup style changes. % \INITMACRO can check \currentmarkupstyle for the innermost % style and the set of \ifmarkupSTYLE switches for all styles % currently in effect. \newif\ifmarkupvar \newif\ifmarkupsamp \newif\ifmarkupkey %\newif\ifmarkupfile % @file == @samp. %\newif\ifmarkupoption % @option == @samp. \newif\ifmarkupcode \newif\ifmarkupkbd %\newif\ifmarkupenv % @env == @code. %\newif\ifmarkupcommand % @command == @code. \newif\ifmarkuptex % @tex (and part of @math, for now). \newif\ifmarkupexample \newif\ifmarkupverb \newif\ifmarkupverbatim \let\currentmarkupstyle\empty \def\setupmarkupstyle#1{% \csname markup#1true\endcsname \def\currentmarkupstyle{#1}% \markupstylesetup } \let\markupstylesetup\empty \def\defmarkupstylesetup#1{% \expandafter\def\expandafter\markupstylesetup \expandafter{\markupstylesetup #1}% \def#1% } % Markup style setup for left and right quotes. \defmarkupstylesetup\markupsetuplq{% \expandafter\let\expandafter \temp \csname markupsetuplq\currentmarkupstyle\endcsname \ifx\temp\relax \markupsetuplqdefault \else \temp \fi } \defmarkupstylesetup\markupsetuprq{% \expandafter\let\expandafter \temp \csname markupsetuprq\currentmarkupstyle\endcsname \ifx\temp\relax \markupsetuprqdefault \else \temp \fi } { \catcode`\'=\active \catcode`\`=\active \gdef\markupsetuplqdefault{\let`\lq} \gdef\markupsetuprqdefault{\let'\rq} \gdef\markupsetcodequoteleft{\let`\codequoteleft} \gdef\markupsetcodequoteright{\let'\codequoteright} } \let\markupsetuplqcode \markupsetcodequoteleft \let\markupsetuprqcode \markupsetcodequoteright % \let\markupsetuplqexample \markupsetcodequoteleft \let\markupsetuprqexample \markupsetcodequoteright % \let\markupsetuplqkbd \markupsetcodequoteleft \let\markupsetuprqkbd \markupsetcodequoteright % \let\markupsetuplqsamp \markupsetcodequoteleft \let\markupsetuprqsamp \markupsetcodequoteright % \let\markupsetuplqverb \markupsetcodequoteleft \let\markupsetuprqverb \markupsetcodequoteright % \let\markupsetuplqverbatim \markupsetcodequoteleft \let\markupsetuprqverbatim \markupsetcodequoteright % Allow an option to not use regular directed right quote/apostrophe % (char 0x27), but instead the undirected quote from cmtt (char 0x0d). % The undirected quote is ugly, so don't make it the default, but it % works for pasting with more pdf viewers (at least evince), the % lilypond developers report. xpdf does work with the regular 0x27. % \def\codequoteright{% \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax '% \else \char'15 \fi \else \char'15 \fi } % % and a similar option for the left quote char vs. a grave accent. % Modern fonts display ASCII 0x60 as a grave accent, so some people like % the code environments to do likewise. % \def\codequoteleft{% \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax % [Knuth] pp. 380,381,391 % \relax disables Spanish ligatures ?` and !` of \tt font. \relax`% \else \char'22 \fi \else \char'22 \fi } % Commands to set the quote options. % \parseargdef\codequoteundirected{% \def\temp{#1}% \ifx\temp\onword \expandafter\let\csname SETtxicodequoteundirected\endcsname = t% \else\ifx\temp\offword \expandafter\let\csname SETtxicodequoteundirected\endcsname = \relax \else \errhelp = \EMsimple \errmessage{Unknown @codequoteundirected value `\temp', must be on|off}% \fi\fi } % \parseargdef\codequotebacktick{% \def\temp{#1}% \ifx\temp\onword \expandafter\let\csname SETtxicodequotebacktick\endcsname = t% \else\ifx\temp\offword \expandafter\let\csname SETtxicodequotebacktick\endcsname = \relax \else \errhelp = \EMsimple \errmessage{Unknown @codequotebacktick value `\temp', must be on|off}% \fi\fi } % [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font. \def\noligaturesquoteleft{\relax\lq} % Count depth in font-changes, for error checks \newcount\fontdepth \fontdepth=0 % Font commands. % #1 is the font command (\sl or \it), #2 is the text to slant. % If we are in a monospaced environment, however, 1) always use \ttsl, % and 2) do not add an italic correction. \def\dosmartslant#1#2{% \ifusingtt {{\ttsl #2}\let\next=\relax}% {\def\next{{#1#2}\futurelet\next\smartitaliccorrection}}% \next } \def\smartslanted{\dosmartslant\sl} \def\smartitalic{\dosmartslant\it} % Output an italic correction unless \next (presumed to be the following % character) is such as not to need one. \def\smartitaliccorrection{% \ifx\next,% \else\ifx\next-% \else\ifx\next.% \else\ptexslash \fi\fi\fi \aftersmartic } % Unconditional use \ttsl, and no ic. @var is set to this for defuns. \def\ttslanted#1{{\ttsl #1}} % @cite is like \smartslanted except unconditionally use \sl. We never want % ttsl for book titles, do we? \def\cite#1{{\sl #1}\futurelet\next\smartitaliccorrection} \def\aftersmartic{} \def\var#1{% \let\saveaftersmartic = \aftersmartic \def\aftersmartic{\null\let\aftersmartic=\saveaftersmartic}% \smartslanted{#1}% } \let\i=\smartitalic \let\slanted=\smartslanted \let\dfn=\smartslanted \let\emph=\smartitalic % Explicit font changes: @r, @sc, undocumented @ii. \def\r#1{{\rm #1}} % roman font \def\sc#1{{\smallcaps#1}} % smallcaps font \def\ii#1{{\it #1}} % italic font % @b, explicit bold. Also @strong. \def\b#1{{\bf #1}} \let\strong=\b % @sansserif, explicit sans. \def\sansserif#1{{\sf #1}} % We can't just use \exhyphenpenalty, because that only has effect at % the end of a paragraph. Restore normal hyphenation at the end of the % group within which \nohyphenation is presumably called. % \def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} \def\restorehyphenation{\hyphenchar\font = `- } % Set sfcode to normal for the chars that usually have another value. % Can't use plain's \frenchspacing because it uses the `\x notation, and % sometimes \x has an active definition that messes things up. % \catcode`@=11 \def\plainfrenchspacing{% \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m \def\endofsentencespacefactor{1000}% for @. and friends } \def\plainnonfrenchspacing{% \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000 \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250 \def\endofsentencespacefactor{3000}% for @. and friends } \catcode`@=\other \def\endofsentencespacefactor{3000}% default % @t, explicit typewriter. \def\t#1{% {\tt \rawbackslash \plainfrenchspacing #1}% \null } % @samp. \def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}} % @indicateurl is \samp, that is, with quotes. \let\indicateurl=\samp % @code (and similar) prints in typewriter, but with spaces the same % size as normal in the surrounding text, without hyphenation, etc. % This is a subroutine for that. \def\tclose#1{% {% % Change normal interword space to be same as for the current font. \spaceskip = \fontdimen2\font % % Switch to typewriter. \tt % % But `\ ' produces the large typewriter interword space. \def\ {{\spaceskip = 0pt{} }}% % % Turn off hyphenation. \nohyphenation % \rawbackslash \plainfrenchspacing #1% }% \null % reset spacefactor to 1000 } % We *must* turn on hyphenation at `-' and `_' in @code. % Otherwise, it is too hard to avoid overfull hboxes % in the Emacs manual, the Library manual, etc. % % Unfortunately, TeX uses one parameter (\hyphenchar) to control % both hyphenation at - and hyphenation within words. % We must therefore turn them both off (\tclose does that) % and arrange explicitly to hyphenate at a dash. % -- rms. { \catcode`\-=\active \catcode`\_=\active \catcode`\'=\active \catcode`\`=\active \global\let'=\rq \global\let`=\lq % default definitions % \global\def\code{\begingroup \setupmarkupstyle{code}% % The following should really be moved into \setupmarkupstyle handlers. \catcode\dashChar=\active \catcode\underChar=\active \ifallowcodebreaks \let-\codedash \let_\codeunder \else \let-\normaldash \let_\realunder \fi \codex } } \def\codex #1{\tclose{#1}\endgroup} \def\normaldash{-} \def\codedash{-\discretionary{}{}{}} \def\codeunder{% % this is all so @math{@code{var_name}+1} can work. In math mode, _ % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.) % will therefore expand the active definition of _, which is us % (inside @code that is), therefore an endless loop. \ifusingtt{\ifmmode \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_. \else\normalunderscore \fi \discretionary{}{}{}}% {\_}% } % An additional complication: the above will allow breaks after, e.g., % each of the four underscores in __typeof__. This is bad. % @allowcodebreaks provides a document-level way to turn breaking at - % and _ on and off. % \newif\ifallowcodebreaks \allowcodebreakstrue \def\keywordtrue{true} \def\keywordfalse{false} \parseargdef\allowcodebreaks{% \def\txiarg{#1}% \ifx\txiarg\keywordtrue \allowcodebreakstrue \else\ifx\txiarg\keywordfalse \allowcodebreaksfalse \else \errhelp = \EMsimple \errmessage{Unknown @allowcodebreaks option `\txiarg', must be true|false}% \fi\fi } % For @command, @env, @file, @option quotes seem unnecessary, % so use \code rather than \samp. \let\command=\code \let\env=\code \let\file=\code \let\option=\code % @uref (abbreviation for `urlref') takes an optional (comma-separated) % second argument specifying the text to display and an optional third % arg as text to display instead of (rather than in addition to) the url % itself. First (mandatory) arg is the url. % (This \urefnobreak definition isn't used now, leaving it for a while % for comparison.) \def\urefnobreak#1{\dourefnobreak #1,,,\finish} \def\dourefnobreak#1,#2,#3,#4\finish{\begingroup \unsepspaces \pdfurl{#1}% \setbox0 = \hbox{\ignorespaces #3}% \ifdim\wd0 > 0pt \unhbox0 % third arg given, show only that \else \setbox0 = \hbox{\ignorespaces #2}% \ifdim\wd0 > 0pt \ifpdf \unhbox0 % PDF: 2nd arg given, show only it \else \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url \fi \else \code{#1}% only url given, so show it \fi \fi \endlink \endgroup} % This \urefbreak definition is the active one. \def\urefbreak{\begingroup \urefcatcodes \dourefbreak} \let\uref=\urefbreak \def\dourefbreak#1{\urefbreakfinish #1,,,\finish} \def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example \unsepspaces \pdfurl{#1}% \setbox0 = \hbox{\ignorespaces #3}% \ifdim\wd0 > 0pt \unhbox0 % third arg given, show only that \else \setbox0 = \hbox{\ignorespaces #2}% \ifdim\wd0 > 0pt \ifpdf \unhbox0 % PDF: 2nd arg given, show only it \else \unhbox0\ (\urefcode{#1})% DVI: 2nd arg given, show both it and url \fi \else \urefcode{#1}% only url given, so show it \fi \fi \endlink \endgroup} % Allow line breaks around only a few characters (only). \def\urefcatcodes{% \catcode\ampChar=\active \catcode\dotChar=\active \catcode\hashChar=\active \catcode\questChar=\active \catcode\slashChar=\active } { \urefcatcodes % \global\def\urefcode{\begingroup \setupmarkupstyle{code}% \urefcatcodes \let&\urefcodeamp \let.\urefcodedot \let#\urefcodehash \let?\urefcodequest \let/\urefcodeslash \codex } % % By default, they are just regular characters. \global\def&{\normalamp} \global\def.{\normaldot} \global\def#{\normalhash} \global\def?{\normalquest} \global\def/{\normalslash} } % we put a little stretch before and after the breakable chars, to help % line breaking of long url's. The unequal skips make look better in % cmtt at least, especially for dots. \def\urefprestretch{\urefprebreak \hskip0pt plus.13em } \def\urefpoststretch{\urefpostbreak \hskip0pt plus.1em } % \def\urefcodeamp{\urefprestretch \&\urefpoststretch} \def\urefcodedot{\urefprestretch .\urefpoststretch} \def\urefcodehash{\urefprestretch \#\urefpoststretch} \def\urefcodequest{\urefprestretch ?\urefpoststretch} \def\urefcodeslash{\futurelet\next\urefcodeslashfinish} { \catcode`\/=\active \global\def\urefcodeslashfinish{% \urefprestretch \slashChar % Allow line break only after the final / in a sequence of % slashes, to avoid line break between the slashes in http://. \ifx\next/\else \urefpoststretch \fi } } % One more complication: by default we'll break after the special % characters, but some people like to break before the special chars, so % allow that. Also allow no breaking at all, for manual control. % \parseargdef\urefbreakstyle{% \def\txiarg{#1}% \ifx\txiarg\wordnone \def\urefprebreak{\nobreak}\def\urefpostbreak{\nobreak} \else\ifx\txiarg\wordbefore \def\urefprebreak{\allowbreak}\def\urefpostbreak{\nobreak} \else\ifx\txiarg\wordafter \def\urefprebreak{\nobreak}\def\urefpostbreak{\allowbreak} \else \errhelp = \EMsimple \errmessage{Unknown @urefbreakstyle setting `\txiarg'}% \fi\fi\fi } \def\wordafter{after} \def\wordbefore{before} \def\wordnone{none} \urefbreakstyle after % @url synonym for @uref, since that's how everyone uses it. % \let\url=\uref % rms does not like angle brackets --karl, 17may97. % So now @email is just like @uref, unless we are pdf. % %\def\email#1{\angleleft{\tt #1}\angleright} \ifpdf \def\email#1{\doemail#1,,\finish} \def\doemail#1,#2,#3\finish{\begingroup \unsepspaces \pdfurl{mailto:#1}% \setbox0 = \hbox{\ignorespaces #2}% \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi \endlink \endgroup} \else \let\email=\uref \fi % @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), % `example' (@kbd uses ttsl only inside of @example and friends), % or `code' (@kbd uses normal tty font always). \parseargdef\kbdinputstyle{% \def\txiarg{#1}% \ifx\txiarg\worddistinct \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% \else\ifx\txiarg\wordexample \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% \else\ifx\txiarg\wordcode \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% \else \errhelp = \EMsimple \errmessage{Unknown @kbdinputstyle setting `\txiarg'}% \fi\fi\fi } \def\worddistinct{distinct} \def\wordexample{example} \def\wordcode{code} % Default is `distinct'. \kbdinputstyle distinct % @kbd is like @code, except that if the argument is just one @key command, % then @kbd has no effect. \def\kbd#1{{\def\look{#1}\expandafter\kbdsub\look??\par}} \def\xkey{\key} \def\kbdsub#1#2#3\par{% \def\one{#1}\def\three{#3}\def\threex{??}% \ifx\one\xkey\ifx\threex\three \key{#2}% \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi } % definition of @key that produces a lozenge. Doesn't adjust to text size. %\setfont\keyrm\rmshape{8}{1000}{OT1} %\font\keysy=cmsy9 %\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% % \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% % \vbox{\hrule\kern-0.4pt % \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% % \kern-0.4pt\hrule}% % \kern-.06em\raise0.4pt\hbox{\angleright}}}} % definition of @key with no lozenge. If the current font is already % monospace, don't change it; that way, we respect @kbdinputstyle. But % if it isn't monospace, then use \tt. % \def\key#1{{\setupmarkupstyle{key}% \nohyphenation \ifmonospace\else\tt\fi #1}\null} % @clicksequence{File @click{} Open ...} \def\clicksequence#1{\begingroup #1\endgroup} % @clickstyle @arrow (by default) \parseargdef\clickstyle{\def\click{#1}} \def\click{\arrow} % Typeset a dimension, e.g., `in' or `pt'. The only reason for the % argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. % \def\dmn#1{\thinspace #1} % @l was never documented to mean ``switch to the Lisp font'', % and it is not used as such in any manual I can find. We need it for % Polish suppressed-l. --karl, 22sep96. %\def\l#1{{\li #1}\null} % @acronym for "FBI", "NATO", and the like. % We print this one point size smaller, since it's intended for % all-uppercase. % \def\acronym#1{\doacronym #1,,\finish} \def\doacronym#1,#2,#3\finish{% {\selectfonts\lsize #1}% \def\temp{#2}% \ifx\temp\empty \else \space ({\unsepspaces \ignorespaces \temp \unskip})% \fi \null % reset \spacefactor=1000 } % @abbr for "Comput. J." and the like. % No font change, but don't do end-of-sentence spacing. % \def\abbr#1{\doabbr #1,,\finish} \def\doabbr#1,#2,#3\finish{% {\plainfrenchspacing #1}% \def\temp{#2}% \ifx\temp\empty \else \space ({\unsepspaces \ignorespaces \temp \unskip})% \fi \null % reset \spacefactor=1000 } % @asis just yields its argument. Used with @table, for example. % \def\asis#1{#1} % @math outputs its argument in math mode. % % One complication: _ usually means subscripts, but it could also mean % an actual _ character, as in @math{@var{some_variable} + 1}. So make % _ active, and distinguish by seeing if the current family is \slfam, % which is what @var uses. { \catcode`\_ = \active \gdef\mathunderscore{% \catcode`\_=\active \def_{\ifnum\fam=\slfam \_\else\sb\fi}% } } % Another complication: we want \\ (and @\) to output a math (or tt) \. % FYI, plain.tex uses \\ as a temporary control sequence (for no % particular reason), but this is not advertised and we don't care. % % The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. \def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} % \def\math{% \tex \mathunderscore \let\\ = \mathbackslash \mathactive % make the texinfo accent commands work in math mode \let\"=\ddot \let\'=\acute \let\==\bar \let\^=\hat \let\`=\grave \let\u=\breve \let\v=\check \let\~=\tilde \let\dotaccent=\dot $\finishmath } \def\finishmath#1{#1$\endgroup} % Close the group opened by \tex. % Some active characters (such as <) are spaced differently in math. % We have to reset their definitions in case the @math was an argument % to a command which sets the catcodes (such as @item or @section). % { \catcode`^ = \active \catcode`< = \active \catcode`> = \active \catcode`+ = \active \catcode`' = \active \gdef\mathactive{% \let^ = \ptexhat \let< = \ptexless \let> = \ptexgtr \let+ = \ptexplus \let' = \ptexquoteright } } % ctrl is no longer a Texinfo command, but leave this definition for fun. \def\ctrl #1{{\tt \rawbackslash \hat}#1} % @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}. % Ignore unless FMTNAME == tex; then it is like @iftex and @tex, % except specified as a normal braced arg, so no newlines to worry about. % \def\outfmtnametex{tex} % \long\def\inlinefmt#1{\doinlinefmt #1,\finish} \long\def\doinlinefmt#1,#2,\finish{% \def\inlinefmtname{#1}% \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi } % For raw, must switch into @tex before parsing the argument, to avoid % setting catcodes prematurely. Doing it this way means that, for % example, @inlineraw{html, foo{bar} gets a parse error instead of being % ignored. But this isn't important because if people want a literal % *right* brace they would have to use a command anyway, so they may as % well use a command to get a left brace too. We could re-use the % delimiter character idea from \verb, but it seems like overkill. % \long\def\inlineraw{\tex \doinlineraw} \long\def\doinlineraw#1{\doinlinerawtwo #1,\finish} \def\doinlinerawtwo#1,#2,\finish{% \def\inlinerawname{#1}% \ifx\inlinerawname\outfmtnametex \ignorespaces #2\fi \endgroup % close group opened by \tex. } \message{glyphs,} % and logos. % @@ prints an @, as does @atchar{}. \def\@{\char64 } \let\atchar=\@ % @{ @} @lbracechar{} @rbracechar{} all generate brace characters. % Unless we're in typewriter, use \ecfont because the CM text fonts do % not have braces, and we don't want to switch into math. \def\mylbrace{{\ifmonospace\else\ecfont\fi \char123}} \def\myrbrace{{\ifmonospace\else\ecfont\fi \char125}} \let\{=\mylbrace \let\lbracechar=\{ \let\}=\myrbrace \let\rbracechar=\} \begingroup % Definitions to produce \{ and \} commands for indices, % and @{ and @} for the aux/toc files. \catcode`\{ = \other \catcode`\} = \other \catcode`\[ = 1 \catcode`\] = 2 \catcode`\! = 0 \catcode`\\ = \other !gdef!lbracecmd[\{]% !gdef!rbracecmd[\}]% !gdef!lbraceatcmd[@{]% !gdef!rbraceatcmd[@}]% !endgroup % @comma{} to avoid , parsing problems. \let\comma = , % Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent % Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. \let\, = \ptexc \let\dotaccent = \ptexdot \def\ringaccent#1{{\accent23 #1}} \let\tieaccent = \ptext \let\ubaraccent = \ptexb \let\udotaccent = \d % Other special characters: @questiondown @exclamdown @ordf @ordm % Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. \def\questiondown{?`} \def\exclamdown{!`} \def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}} \def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}} % Dotless i and dotless j, used for accents. \def\imacro{i} \def\jmacro{j} \def\dotless#1{% \def\temp{#1}% \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi \else \errmessage{@dotless can be used only with i or j}% \fi\fi } % The \TeX{} logo, as in plain, but resetting the spacing so that a % period following counts as ending a sentence. (Idea found in latex.) % \edef\TeX{\TeX \spacefactor=1000 } % @LaTeX{} logo. Not quite the same results as the definition in % latex.ltx, since we use a different font for the raised A; it's most % convenient for us to use an explicitly smaller font, rather than using % the \scriptstyle font (since we don't reset \scriptstyle and % \scriptscriptstyle). % \def\LaTeX{% L\kern-.36em {\setbox0=\hbox{T}% \vbox to \ht0{\hbox{% \ifx\textnominalsize\xwordpt % for 10pt running text, \lllsize (8pt) is too small for the A in LaTeX. % Revert to plain's \scriptsize, which is 7pt. \count255=\the\fam $\fam\count255 \scriptstyle A$% \else % For 11pt, we can use our lllsize. \selectfonts\lllsize A% \fi }% \vss }}% \kern-.15em \TeX } % Some math mode symbols. \def\bullet{$\ptexbullet$} \def\geq{\ifmmode \ge\else $\ge$\fi} \def\leq{\ifmmode \le\else $\le$\fi} \def\minus{\ifmmode -\else $-$\fi} % @dots{} outputs an ellipsis using the current font. % We do .5em per period so that it has the same spacing in the cm % typewriter fonts as three actual period characters; on the other hand, % in other typewriter fonts three periods are wider than 1.5em. So do % whichever is larger. % \def\dots{% \leavevmode \setbox0=\hbox{...}% get width of three periods \ifdim\wd0 > 1.5em \dimen0 = \wd0 \else \dimen0 = 1.5em \fi \hbox to \dimen0{% \hskip 0pt plus.25fil .\hskip 0pt plus1fil .\hskip 0pt plus1fil .\hskip 0pt plus.5fil }% } % @enddots{} is an end-of-sentence ellipsis. % \def\enddots{% \dots \spacefactor=\endofsentencespacefactor } % @point{}, @result{}, @expansion{}, @print{}, @equiv{}. % % Since these characters are used in examples, they should be an even number of % \tt widths. Each \tt character is 1en, so two makes it 1em. % \def\point{$\star$} \def\arrow{\leavevmode\raise.05ex\hbox to 1em{\hfil$\rightarrow$\hfil}} \def\result{\leavevmode\raise.05ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} \def\expansion{\leavevmode\hbox to 1em{\hfil$\mapsto$\hfil}} \def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} \def\equiv{\leavevmode\hbox to 1em{\hfil$\ptexequiv$\hfil}} % The @error{} command. % Adapted from the TeXbook's \boxit. % \newbox\errorbox % {\tentt \global\dimen0 = 3em}% Width of the box. \dimen2 = .55pt % Thickness of rules % The text. (`r' is open on the right, `e' somewhat less so on the left.) \setbox0 = \hbox{\kern-.75pt \reducedsf \putworderror\kern-1.5pt} % \setbox\errorbox=\hbox to \dimen0{\hfil \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. \advance\hsize by -2\dimen2 % Rules. \vbox{% \hrule height\dimen2 \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. \kern3pt\vrule width\dimen2}% Space to right. \hrule height\dimen2} \hfil} % \def\error{\leavevmode\lower.7ex\copy\errorbox} % @pounds{} is a sterling sign, which Knuth put in the CM italic font. % \def\pounds{{\it\$}} % @euro{} comes from a separate font, depending on the current style. % We use the free feym* fonts from the eurosym package by Henrik % Theiling, which support regular, slanted, bold and bold slanted (and % "outlined" (blackboard board, sort of) versions, which we don't need). % It is available from http://www.ctan.org/tex-archive/fonts/eurosym. % % Although only regular is the truly official Euro symbol, we ignore % that. The Euro is designed to be slightly taller than the regular % font height. % % feymr - regular % feymo - slanted % feybr - bold % feybo - bold slanted % % There is no good (free) typewriter version, to my knowledge. % A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide. % Hmm. % % Also doesn't work in math. Do we need to do math with euro symbols? % Hope not. % % \def\euro{{\eurofont e}} \def\eurofont{% % We set the font at each command, rather than predefining it in % \textfonts and the other font-switching commands, so that % installations which never need the symbol don't have to have the % font installed. % % There is only one designed size (nominal 10pt), so we always scale % that to the current nominal size. % % By the way, simply using "at 1em" works for cmr10 and the like, but % does not work for cmbx10 and other extended/shrunken fonts. % \def\eurosize{\csname\curfontsize nominalsize\endcsname}% % \ifx\curfontstyle\bfstylename % bold: \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize \else % regular: \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize \fi \thiseurofont } % Glyphs from the EC fonts. We don't use \let for the aliases, because % sometimes we redefine the original macro, and the alias should reflect % the redefinition. % % Use LaTeX names for the Icelandic letters. \def\DH{{\ecfont \char"D0}} % Eth \def\dh{{\ecfont \char"F0}} % eth \def\TH{{\ecfont \char"DE}} % Thorn \def\th{{\ecfont \char"FE}} % thorn % \def\guillemetleft{{\ecfont \char"13}} \def\guillemotleft{\guillemetleft} \def\guillemetright{{\ecfont \char"14}} \def\guillemotright{\guillemetright} \def\guilsinglleft{{\ecfont \char"0E}} \def\guilsinglright{{\ecfont \char"0F}} \def\quotedblbase{{\ecfont \char"12}} \def\quotesinglbase{{\ecfont \char"0D}} % % This positioning is not perfect (see the ogonek LaTeX package), but % we have the precomposed glyphs for the most common cases. We put the % tests to use those glyphs in the single \ogonek macro so we have fewer % dummy definitions to worry about for index entries, etc. % % ogonek is also used with other letters in Lithuanian (IOU), but using % the precomposed glyphs for those is not so easy since they aren't in % the same EC font. \def\ogonek#1{{% \def\temp{#1}% \ifx\temp\macrocharA\Aogonek \else\ifx\temp\macrochara\aogonek \else\ifx\temp\macrocharE\Eogonek \else\ifx\temp\macrochare\eogonek \else \ecfont \setbox0=\hbox{#1}% \ifdim\ht0=1ex\accent"0C #1% \else\ooalign{\unhbox0\crcr\hidewidth\char"0C \hidewidth}% \fi \fi\fi\fi\fi }% } \def\Aogonek{{\ecfont \char"81}}\def\macrocharA{A} \def\aogonek{{\ecfont \char"A1}}\def\macrochara{a} \def\Eogonek{{\ecfont \char"86}}\def\macrocharE{E} \def\eogonek{{\ecfont \char"A6}}\def\macrochare{e} % % Use the ec* fonts (cm-super in outline format) for non-CM glyphs. \def\ecfont{% % We can't distinguish serif/sans and italic/slanted, but this % is used for crude hacks anyway (like adding French and German % quotes to documents typeset with CM, where we lose kerning), so % hopefully nobody will notice/care. \edef\ecsize{\csname\curfontsize ecsize\endcsname}% \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}% \ifmonospace % typewriter: \font\thisecfont = ectt\ecsize \space at \nominalsize \else \ifx\curfontstyle\bfstylename % bold: \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize \else % regular: \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize \fi \fi \thisecfont } % @registeredsymbol - R in a circle. The font for the R should really % be smaller yet, but lllsize is the best we can do for now. % Adapted from the plain.tex definition of \copyright. % \def\registeredsymbol{% $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}% \hfil\crcr\Orb}}% }$% } % @textdegree - the normal degrees sign. % \def\textdegree{$^\circ$} % Laurent Siebenmann reports \Orb undefined with: % Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38 % so we'll define it if necessary. % \ifx\Orb\thisisundefined \def\Orb{\mathhexbox20D} \fi % Quotes. \chardef\quotedblleft="5C \chardef\quotedblright=`\" \chardef\quoteleft=`\` \chardef\quoteright=`\' \message{page headings,} \newskip\titlepagetopglue \titlepagetopglue = 1.5in \newskip\titlepagebottomglue \titlepagebottomglue = 2pc % First the title page. Must do @settitle before @titlepage. \newif\ifseenauthor \newif\iffinishedtitlepage % Do an implicit @contents or @shortcontents after @end titlepage if the % user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. % \newif\ifsetcontentsaftertitlepage \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue \newif\ifsetshortcontentsaftertitlepage \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue \parseargdef\shorttitlepage{% \begingroup \hbox{}\vskip 1.5in \chaprm \centerline{#1}% \endgroup\page\hbox{}\page} \envdef\titlepage{% % Open one extra group, as we want to close it in the middle of \Etitlepage. \begingroup \parindent=0pt \textfonts % Leave some space at the very top of the page. \vglue\titlepagetopglue % No rule at page bottom unless we print one at the top with @title. \finishedtitlepagetrue % % Most title ``pages'' are actually two pages long, with space % at the top of the second. We don't want the ragged left on the second. \let\oldpage = \page \def\page{% \iffinishedtitlepage\else \finishtitlepage \fi \let\page = \oldpage \page \null }% } \def\Etitlepage{% \iffinishedtitlepage\else \finishtitlepage \fi % It is important to do the page break before ending the group, % because the headline and footline are only empty inside the group. % If we use the new definition of \page, we always get a blank page % after the title page, which we certainly don't want. \oldpage \endgroup % % Need this before the \...aftertitlepage checks so that if they are % in effect the toc pages will come out with page numbers. \HEADINGSon % % If they want short, they certainly want long too. \ifsetshortcontentsaftertitlepage \shortcontents \contents \global\let\shortcontents = \relax \global\let\contents = \relax \fi % \ifsetcontentsaftertitlepage \contents \global\let\contents = \relax \global\let\shortcontents = \relax \fi } \def\finishtitlepage{% \vskip4pt \hrule height 2pt width \hsize \vskip\titlepagebottomglue \finishedtitlepagetrue } % Settings used for typesetting titles: no hyphenation, no indentation, % don't worry much about spacing, ragged right. This should be used % inside a \vbox, and fonts need to be set appropriately first. Because % it is always used for titles, nothing else, we call \rmisbold. \par % should be specified before the end of the \vbox, since a vbox is a group. % \def\raggedtitlesettings{% \rmisbold \hyphenpenalty=10000 \parindent=0pt \tolerance=5000 \ptexraggedright } % Macros to be used within @titlepage: \let\subtitlerm=\tenrm \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines} \parseargdef\title{% \checkenv\titlepage \vbox{\titlefonts \raggedtitlesettings #1\par}% % print a rule at the page bottom also. \finishedtitlepagefalse \vskip4pt \hrule height 4pt width \hsize \vskip4pt } \parseargdef\subtitle{% \checkenv\titlepage {\subtitlefont \rightline{#1}}% } % @author should come last, but may come many times. % It can also be used inside @quotation. % \parseargdef\author{% \def\temp{\quotation}% \ifx\thisenv\temp \def\quotationauthor{#1}% printed in \Equotation. \else \checkenv\titlepage \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi {\secfonts\rmisbold \leftline{#1}}% \fi } % Set up page headings and footings. \let\thispage=\folio \newtoks\evenheadline % headline on even pages \newtoks\oddheadline % headline on odd pages \newtoks\evenfootline % footline on even pages \newtoks\oddfootline % footline on odd pages % Now make TeX use those variables \headline={{\textfonts\rm \ifodd\pageno \the\oddheadline \else \the\evenheadline \fi}} \footline={{\textfonts\rm \ifodd\pageno \the\oddfootline \else \the\evenfootline \fi}\HEADINGShook} \let\HEADINGShook=\relax % Commands to set those variables. % For example, this is what @headings on does % @evenheading @thistitle|@thispage|@thischapter % @oddheading @thischapter|@thispage|@thistitle % @evenfooting @thisfile|| % @oddfooting ||@thisfile \def\evenheading{\parsearg\evenheadingxxx} \def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish} \def\evenheadingyyy #1\|#2\|#3\|#4\finish{% \global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \def\oddheading{\parsearg\oddheadingxxx} \def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish} \def\oddheadingyyy #1\|#2\|#3\|#4\finish{% \global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}% \def\evenfooting{\parsearg\evenfootingxxx} \def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish} \def\evenfootingyyy #1\|#2\|#3\|#4\finish{% \global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \def\oddfooting{\parsearg\oddfootingxxx} \def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish} \def\oddfootingyyy #1\|#2\|#3\|#4\finish{% \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% % % Leave some space for the footline. Hopefully ok to assume % @evenfooting will not be used by itself. \global\advance\pageheight by -12pt \global\advance\vsize by -12pt } \parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}} % @evenheadingmarks top \thischapter <- chapter at the top of a page % @evenheadingmarks bottom \thischapter <- chapter at the bottom of a page % % The same set of arguments for: % % @oddheadingmarks % @evenfootingmarks % @oddfootingmarks % @everyheadingmarks % @everyfootingmarks \def\evenheadingmarks{\headingmarks{even}{heading}} \def\oddheadingmarks{\headingmarks{odd}{heading}} \def\evenfootingmarks{\headingmarks{even}{footing}} \def\oddfootingmarks{\headingmarks{odd}{footing}} \def\everyheadingmarks#1 {\headingmarks{even}{heading}{#1} \headingmarks{odd}{heading}{#1} } \def\everyfootingmarks#1 {\headingmarks{even}{footing}{#1} \headingmarks{odd}{footing}{#1} } % #1 = even/odd, #2 = heading/footing, #3 = top/bottom. \def\headingmarks#1#2#3 {% \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname \global\expandafter\let\csname get#1#2marks\endcsname \temp } \everyheadingmarks bottom \everyfootingmarks bottom % @headings double turns headings on for double-sided printing. % @headings single turns headings on for single-sided printing. % @headings off turns them off. % @headings on same as @headings double, retained for compatibility. % @headings after turns on double-sided headings after this page. % @headings doubleafter turns on double-sided headings after this page. % @headings singleafter turns on single-sided headings after this page. % By default, they are off at the start of a document, % and turned `on' after @end titlepage. \def\headings #1 {\csname HEADINGS#1\endcsname} \def\headingsoff{% non-global headings elimination \evenheadline={\hfil}\evenfootline={\hfil}% \oddheadline={\hfil}\oddfootline={\hfil}% } \def\HEADINGSoff{{\globaldefs=1 \headingsoff}} % global setting \HEADINGSoff % it's the default % When we turn headings on, set the page number to 1. % For double-sided printing, put current file name in lower left corner, % chapter name on inside top of right hand pages, document % title on inside top of left hand pages, and page numbers on outside top % edge of all pages. \def\HEADINGSdouble{% \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } \let\contentsalignmacro = \chappager % For single-sided printing, chapter title goes across top left of page, % page number on top right. \def\HEADINGSsingle{% \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\thischapter\hfil\folio}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chappager } \def\HEADINGSon{\HEADINGSdouble} \def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} \let\HEADINGSdoubleafter=\HEADINGSafter \def\HEADINGSdoublex{% \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } \def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} \def\HEADINGSsinglex{% \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\thischapter\hfil\folio}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chappager } % Subroutines used in generating headings % This produces Day Month Year style of output. % Only define if not already defined, in case a txi-??.tex file has set % up a different format (e.g., txi-cs.tex does this). \ifx\today\thisisundefined \def\today{% \number\day\space \ifcase\month \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec \fi \space\number\year} \fi % @settitle line... specifies the title of the document, for headings. % It generates no output of its own. \def\thistitle{\putwordNoTitle} \def\settitle{\parsearg{\gdef\thistitle}} \message{tables,} % Tables -- @table, @ftable, @vtable, @item(x). % default indentation of table text \newdimen\tableindent \tableindent=.8in % default indentation of @itemize and @enumerate text \newdimen\itemindent \itemindent=.3in % margin between end of table item and start of table text. \newdimen\itemmargin \itemmargin=.1in % used internally for \itemindent minus \itemmargin \newdimen\itemmax % Note @table, @ftable, and @vtable define @item, @itemx, etc., with % these defs. % They also define \itemindex % to index the item name in whatever manner is desired (perhaps none). \newif\ifitemxneedsnegativevskip \def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} \def\internalBitem{\smallbreak \parsearg\itemzzz} \def\internalBitemx{\itemxpar \parsearg\itemzzz} \def\itemzzz #1{\begingroup % \advance\hsize by -\rightskip \advance\hsize by -\tableindent \setbox0=\hbox{\itemindicate{#1}}% \itemindex{#1}% \nobreak % This prevents a break before @itemx. % % If the item text does not fit in the space we have, put it on a line % by itself, and do not allow a page break either before or after that % line. We do not start a paragraph here because then if the next % command is, e.g., @kindex, the whatsit would get put into the % horizontal list on a line by itself, resulting in extra blank space. \ifdim \wd0>\itemmax % % Make this a paragraph so we get the \parskip glue and wrapping, % but leave it ragged-right. \begingroup \advance\leftskip by-\tableindent \advance\hsize by\tableindent \advance\rightskip by0pt plus1fil\relax \leavevmode\unhbox0\par \endgroup % % We're going to be starting a paragraph, but we don't want the % \parskip glue -- logically it's part of the @item we just started. \nobreak \vskip-\parskip % % Stop a page break at the \parskip glue coming up. However, if % what follows is an environment such as @example, there will be no % \parskip glue; then the negative vskip we just inserted would % cause the example and the item to crash together. So we use this % bizarre value of 10001 as a signal to \aboveenvbreak to insert % \parskip glue after all. Section titles are handled this way also. % \penalty 10001 \endgroup \itemxneedsnegativevskipfalse \else % The item text fits into the space. Start a paragraph, so that the % following text (if any) will end up on the same line. \noindent % Do this with kerns and \unhbox so that if there is a footnote in % the item text, it can migrate to the main vertical list and % eventually be printed. \nobreak\kern-\tableindent \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 \unhbox0 \nobreak\kern\dimen0 \endgroup \itemxneedsnegativevskiptrue \fi } \def\item{\errmessage{@item while not in a list environment}} \def\itemx{\errmessage{@itemx while not in a list environment}} % @table, @ftable, @vtable. \envdef\table{% \let\itemindex\gobble \tablecheck{table}% } \envdef\ftable{% \def\itemindex ##1{\doind {fn}{\code{##1}}}% \tablecheck{ftable}% } \envdef\vtable{% \def\itemindex ##1{\doind {vr}{\code{##1}}}% \tablecheck{vtable}% } \def\tablecheck#1{% \ifnum \the\catcode`\^^M=\active \endgroup \errmessage{This command won't work in this context; perhaps the problem is that we are \inenvironment\thisenv}% \def\next{\doignore{#1}}% \else \let\next\tablex \fi \next } \def\tablex#1{% \def\itemindicate{#1}% \parsearg\tabley } \def\tabley#1{% {% \makevalueexpandable \edef\temp{\noexpand\tablez #1\space\space\space}% \expandafter }\temp \endtablez } \def\tablez #1 #2 #3 #4\endtablez{% \aboveenvbreak \ifnum 0#1>0 \advance \leftskip by #1\mil \fi \ifnum 0#2>0 \tableindent=#2\mil \fi \ifnum 0#3>0 \advance \rightskip by #3\mil \fi \itemmax=\tableindent \advance \itemmax by -\itemmargin \advance \leftskip by \tableindent \exdentamount=\tableindent \parindent = 0pt \parskip = \smallskipamount \ifdim \parskip=0pt \parskip=2pt \fi \let\item = \internalBitem \let\itemx = \internalBitemx } \def\Etable{\endgraf\afterenvbreak} \let\Eftable\Etable \let\Evtable\Etable \let\Eitemize\Etable \let\Eenumerate\Etable % This is the counter used by @enumerate, which is really @itemize \newcount \itemno \envdef\itemize{\parsearg\doitemize} \def\doitemize#1{% \aboveenvbreak \itemmax=\itemindent \advance\itemmax by -\itemmargin \advance\leftskip by \itemindent \exdentamount=\itemindent \parindent=0pt \parskip=\smallskipamount \ifdim\parskip=0pt \parskip=2pt \fi % % Try typesetting the item mark that if the document erroneously says % something like @itemize @samp (intending @table), there's an error % right away at the @itemize. It's not the best error message in the % world, but it's better than leaving it to the @item. This means if % the user wants an empty mark, they have to say @w{} not just @w. \def\itemcontents{#1}% \setbox0 = \hbox{\itemcontents}% % % @itemize with no arg is equivalent to @itemize @bullet. \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi % \let\item=\itemizeitem } % Definition of @item while inside @itemize and @enumerate. % \def\itemizeitem{% \advance\itemno by 1 % for enumerations {\let\par=\endgraf \smallbreak}% reasonable place to break {% % If the document has an @itemize directly after a section title, a % \nobreak will be last on the list, and \sectionheading will have % done a \vskip-\parskip. In that case, we don't want to zero % parskip, or the item text will crash with the heading. On the % other hand, when there is normal text preceding the item (as there % usually is), we do want to zero parskip, or there would be too much % space. In that case, we won't have a \nobreak before. At least % that's the theory. \ifnum\lastpenalty<10000 \parskip=0in \fi \noindent \hbox to 0pt{\hss \itemcontents \kern\itemmargin}% % \vadjust{\penalty 1200}}% not good to break after first line of item. \flushcr } % \splitoff TOKENS\endmark defines \first to be the first token in % TOKENS, and \rest to be the remainder. % \def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% % Allow an optional argument of an uppercase letter, lowercase letter, % or number, to specify the first label in the enumerated list. No % argument is the same as `1'. % \envparseargdef\enumerate{\enumeratey #1 \endenumeratey} \def\enumeratey #1 #2\endenumeratey{% % If we were given no argument, pretend we were given `1'. \def\thearg{#1}% \ifx\thearg\empty \def\thearg{1}\fi % % Detect if the argument is a single token. If so, it might be a % letter. Otherwise, the only valid thing it can be is a number. % (We will always have one token, because of the test we just made. % This is a good thing, since \splitoff doesn't work given nothing at % all -- the first parameter is undelimited.) \expandafter\splitoff\thearg\endmark \ifx\rest\empty % Only one token in the argument. It could still be anything. % A ``lowercase letter'' is one whose \lccode is nonzero. % An ``uppercase letter'' is one whose \lccode is both nonzero, and % not equal to itself. % Otherwise, we assume it's a number. % % We need the \relax at the end of the \ifnum lines to stop TeX from % continuing to look for a . % \ifnum\lccode\expandafter`\thearg=0\relax \numericenumerate % a number (we hope) \else % It's a letter. \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax \lowercaseenumerate % lowercase letter \else \uppercaseenumerate % uppercase letter \fi \fi \else % Multiple tokens in the argument. We hope it's a number. \numericenumerate \fi } % An @enumerate whose labels are integers. The starting integer is % given in \thearg. % \def\numericenumerate{% \itemno = \thearg \startenumeration{\the\itemno}% } % The starting (lowercase) letter is in \thearg. \def\lowercaseenumerate{% \itemno = \expandafter`\thearg \startenumeration{% % Be sure we're not beyond the end of the alphabet. \ifnum\itemno=0 \errmessage{No more lowercase letters in @enumerate; get a bigger alphabet}% \fi \char\lccode\itemno }% } % The starting (uppercase) letter is in \thearg. \def\uppercaseenumerate{% \itemno = \expandafter`\thearg \startenumeration{% % Be sure we're not beyond the end of the alphabet. \ifnum\itemno=0 \errmessage{No more uppercase letters in @enumerate; get a bigger alphabet} \fi \char\uccode\itemno }% } % Call \doitemize, adding a period to the first argument and supplying the % common last two arguments. Also subtract one from the initial value in % \itemno, since @item increments \itemno. % \def\startenumeration#1{% \advance\itemno by -1 \doitemize{#1.}\flushcr } % @alphaenumerate and @capsenumerate are abbreviations for giving an arg % to @enumerate. % \def\alphaenumerate{\enumerate{a}} \def\capsenumerate{\enumerate{A}} \def\Ealphaenumerate{\Eenumerate} \def\Ecapsenumerate{\Eenumerate} % @multitable macros % Amy Hendrickson, 8/18/94, 3/6/96 % % @multitable ... @end multitable will make as many columns as desired. % Contents of each column will wrap at width given in preamble. Width % can be specified either with sample text given in a template line, % or in percent of \hsize, the current width of text on page. % Table can continue over pages but will only break between lines. % To make preamble: % % Either define widths of columns in terms of percent of \hsize: % @multitable @columnfractions .25 .3 .45 % @item ... % % Numbers following @columnfractions are the percent of the total % current hsize to be used for each column. You may use as many % columns as desired. % Or use a template: % @multitable {Column 1 template} {Column 2 template} {Column 3 template} % @item ... % using the widest term desired in each column. % Each new table line starts with @item, each subsequent new column % starts with @tab. Empty columns may be produced by supplying @tab's % with nothing between them for as many times as empty columns are needed, % ie, @tab@tab@tab will produce two empty columns. % @item, @tab do not need to be on their own lines, but it will not hurt % if they are. % Sample multitable: % @multitable {Column 1 template} {Column 2 template} {Column 3 template} % @item first col stuff @tab second col stuff @tab third col % @item % first col stuff % @tab % second col stuff % @tab % third col % @item first col stuff @tab second col stuff % @tab Many paragraphs of text may be used in any column. % % They will wrap at the width determined by the template. % @item@tab@tab This will be in third column. % @end multitable % Default dimensions may be reset by user. % @multitableparskip is vertical space between paragraphs in table. % @multitableparindent is paragraph indent in table. % @multitablecolmargin is horizontal space to be left between columns. % @multitablelinespace is space to leave between table items, baseline % to baseline. % 0pt means it depends on current normal line spacing. % \newskip\multitableparskip \newskip\multitableparindent \newdimen\multitablecolspace \newskip\multitablelinespace \multitableparskip=0pt \multitableparindent=6pt \multitablecolspace=12pt \multitablelinespace=0pt % Macros used to set up halign preamble: % \let\endsetuptable\relax \def\xendsetuptable{\endsetuptable} \let\columnfractions\relax \def\xcolumnfractions{\columnfractions} \newif\ifsetpercent % #1 is the @columnfraction, usually a decimal number like .5, but might % be just 1. We just use it, whatever it is. % \def\pickupwholefraction#1 {% \global\advance\colcount by 1 \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}% \setuptable } \newcount\colcount \def\setuptable#1{% \def\firstarg{#1}% \ifx\firstarg\xendsetuptable \let\go = \relax \else \ifx\firstarg\xcolumnfractions \global\setpercenttrue \else \ifsetpercent \let\go\pickupwholefraction \else \global\advance\colcount by 1 \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a % separator; typically that is always in the input, anyway. \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% \fi \fi \ifx\go\pickupwholefraction % Put the argument back for the \pickupwholefraction call, so % we'll always have a period there to be parsed. \def\go{\pickupwholefraction#1}% \else \let\go = \setuptable \fi% \fi \go } % multitable-only commands. % % @headitem starts a heading row, which we typeset in bold. % Assignments have to be global since we are inside the implicit group % of an alignment entry. \everycr resets \everytab so we don't have to % undo it ourselves. \def\headitemfont{\b}% for people to use in the template row; not changeable \def\headitem{% \checkenv\multitable \crcr \global\everytab={\bf}% can't use \headitemfont since the parsing differs \the\everytab % for the first item }% % % A \tab used to include \hskip1sp. But then the space in a template % line is not enough. That is bad. So let's go back to just `&' until % we again encounter the problem the 1sp was intended to solve. % --karl, nathan@acm.org, 20apr99. \def\tab{\checkenv\multitable &\the\everytab}% % @multitable ... @end multitable definitions: % \newtoks\everytab % insert after every tab. % \envdef\multitable{% \vskip\parskip \startsavinginserts % % @item within a multitable starts a normal row. % We use \def instead of \let so that if one of the multitable entries % contains an @itemize, we don't choke on the \item (seen as \crcr aka % \endtemplate) expanding \doitemize. \def\item{\crcr}% % \tolerance=9500 \hbadness=9500 \setmultitablespacing \parskip=\multitableparskip \parindent=\multitableparindent \overfullrule=0pt \global\colcount=0 % \everycr = {% \noalign{% \global\everytab={}% \global\colcount=0 % Reset the column counter. % Check for saved footnotes, etc. \checkinserts % Keeps underfull box messages off when table breaks over pages. %\filbreak % Maybe so, but it also creates really weird page breaks when the % table breaks over pages. Wouldn't \vfil be better? Wait until the % problem manifests itself, so it can be fixed for real --karl. }% }% % \parsearg\domultitable } \def\domultitable#1{% % To parse everything between @multitable and @item: \setuptable#1 \endsetuptable % % This preamble sets up a generic column definition, which will % be used as many times as user calls for columns. % \vtop will set a single line and will also let text wrap and % continue for many paragraphs if desired. \halign\bgroup &% \global\advance\colcount by 1 \multistrut \vtop{% % Use the current \colcount to find the correct column width: \hsize=\expandafter\csname col\the\colcount\endcsname % % In order to keep entries from bumping into each other % we will add a \leftskip of \multitablecolspace to all columns after % the first one. % % If a template has been used, we will add \multitablecolspace % to the width of each template entry. % % If the user has set preamble in terms of percent of \hsize we will % use that dimension as the width of the column, and the \leftskip % will keep entries from bumping into each other. Table will start at % left margin and final column will justify at right margin. % % Make sure we don't inherit \rightskip from the outer environment. \rightskip=0pt \ifnum\colcount=1 % The first column will be indented with the surrounding text. \advance\hsize by\leftskip \else \ifsetpercent \else % If user has not set preamble in terms of percent of \hsize % we will advance \hsize by \multitablecolspace. \advance\hsize by \multitablecolspace \fi % In either case we will make \leftskip=\multitablecolspace: \leftskip=\multitablecolspace \fi % Ignoring space at the beginning and end avoids an occasional spurious % blank line, when TeX decides to break the line at the space before the % box from the multistrut, so the strut ends up on a line by itself. % For example: % @multitable @columnfractions .11 .89 % @item @code{#} % @tab Legal holiday which is valid in major parts of the whole country. % Is automatically provided with highlighting sequences respectively % marking characters. \noindent\ignorespaces##\unskip\multistrut }\cr } \def\Emultitable{% \crcr \egroup % end the \halign \global\setpercentfalse } \def\setmultitablespacing{% \def\multistrut{\strut}% just use the standard line spacing % % Compute \multitablelinespace (if not defined by user) for use in % \multitableparskip calculation. We used define \multistrut based on % this, but (ironically) that caused the spacing to be off. % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100. \ifdim\multitablelinespace=0pt \setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip \global\advance\multitablelinespace by-\ht0 \fi % Test to see if parskip is larger than space between lines of % table. If not, do nothing. % If so, set to same dimension as multitablelinespace. \ifdim\multitableparskip>\multitablelinespace \global\multitableparskip=\multitablelinespace \global\advance\multitableparskip-7pt % to keep parskip somewhat smaller % than skip between lines in the table. \fi% \ifdim\multitableparskip=0pt \global\multitableparskip=\multitablelinespace \global\advance\multitableparskip-7pt % to keep parskip somewhat smaller % than skip between lines in the table. \fi} \message{conditionals,} % @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext, % @ifnotxml always succeed. They currently do nothing; we don't % attempt to check whether the conditionals are properly nested. But we % have to remember that they are conditionals, so that @end doesn't % attempt to close an environment group. % \def\makecond#1{% \expandafter\let\csname #1\endcsname = \relax \expandafter\let\csname iscond.#1\endcsname = 1 } \makecond{iftex} \makecond{ifnotdocbook} \makecond{ifnothtml} \makecond{ifnotinfo} \makecond{ifnotplaintext} \makecond{ifnotxml} % Ignore @ignore, @ifhtml, @ifinfo, and the like. % \def\direntry{\doignore{direntry}} \def\documentdescription{\doignore{documentdescription}} \def\docbook{\doignore{docbook}} \def\html{\doignore{html}} \def\ifdocbook{\doignore{ifdocbook}} \def\ifhtml{\doignore{ifhtml}} \def\ifinfo{\doignore{ifinfo}} \def\ifnottex{\doignore{ifnottex}} \def\ifplaintext{\doignore{ifplaintext}} \def\ifxml{\doignore{ifxml}} \def\ignore{\doignore{ignore}} \def\menu{\doignore{menu}} \def\xml{\doignore{xml}} % Ignore text until a line `@end #1', keeping track of nested conditionals. % % A count to remember the depth of nesting. \newcount\doignorecount \def\doignore#1{\begingroup % Scan in ``verbatim'' mode: \obeylines \catcode`\@ = \other \catcode`\{ = \other \catcode`\} = \other % % Make sure that spaces turn into tokens that match what \doignoretext wants. \spaceisspace % % Count number of #1's that we've seen. \doignorecount = 0 % % Swallow text until we reach the matching `@end #1'. \dodoignore{#1}% } { \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source. \obeylines % % \gdef\dodoignore#1{% % #1 contains the command name as a string, e.g., `ifinfo'. % % Define a command to find the next `@end #1'. \long\def\doignoretext##1^^M@end #1{% \doignoretextyyy##1^^M@#1\_STOP_}% % % And this command to find another #1 command, at the beginning of a % line. (Otherwise, we would consider a line `@c @ifset', for % example, to count as an @ifset for nesting.) \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}% % % And now expand that command. \doignoretext ^^M% }% } \def\doignoreyyy#1{% \def\temp{#1}% \ifx\temp\empty % Nothing found. \let\next\doignoretextzzz \else % Found a nested condition, ... \advance\doignorecount by 1 \let\next\doignoretextyyy % ..., look for another. % If we're here, #1 ends with ^^M\ifinfo (for example). \fi \next #1% the token \_STOP_ is present just after this macro. } % We have to swallow the remaining "\_STOP_". % \def\doignoretextzzz#1{% \ifnum\doignorecount = 0 % We have just found the outermost @end. \let\next\enddoignore \else % Still inside a nested condition. \advance\doignorecount by -1 \let\next\doignoretext % Look for the next @end. \fi \next } % Finish off ignored text. { \obeylines% % Ignore anything after the last `@end #1'; this matters in verbatim % environments, where otherwise the newline after an ignored conditional % would result in a blank line in the output. \gdef\enddoignore#1^^M{\endgroup\ignorespaces}% } % @set VAR sets the variable VAR to an empty value. % @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. % % Since we want to separate VAR from REST-OF-LINE (which might be % empty), we can't just use \parsearg; we have to insert a space of our % own to delimit the rest of the line, and then take it out again if we % didn't need it. % We rely on the fact that \parsearg sets \catcode`\ =10. % \parseargdef\set{\setyyy#1 \endsetyyy} \def\setyyy#1 #2\endsetyyy{% {% \makevalueexpandable \def\temp{#2}% \edef\next{\gdef\makecsname{SET#1}}% \ifx\temp\empty \next{}% \else \setzzz#2\endsetzzz \fi }% } % Remove the trailing space \setxxx inserted. \def\setzzz#1 \endsetzzz{\next{#1}} % @clear VAR clears (i.e., unsets) the variable VAR. % \parseargdef\clear{% {% \makevalueexpandable \global\expandafter\let\csname SET#1\endcsname=\relax }% } % @value{foo} gets the text saved in variable foo. \def\value{\begingroup\makevalueexpandable\valuexxx} \def\valuexxx#1{\expandablevalue{#1}\endgroup} { \catcode`\- = \active \catcode`\_ = \active % \gdef\makevalueexpandable{% \let\value = \expandablevalue % We don't want these characters active, ... \catcode`\-=\other \catcode`\_=\other % ..., but we might end up with active ones in the argument if % we're called from @code, as @code{@value{foo-bar_}}, though. % So \let them to their normal equivalents. \let-\normaldash \let_\normalunderscore } } % We have this subroutine so that we can handle at least some @value's % properly in indexes (we call \makevalueexpandable in \indexdummies). % The command has to be fully expandable (if the variable is set), since % the result winds up in the index file. This means that if the % variable's value contains other Texinfo commands, it's almost certain % it will fail (although perhaps we could fix that with sufficient work % to do a one-level expansion on the result, instead of complete). % \def\expandablevalue#1{% \expandafter\ifx\csname SET#1\endcsname\relax {[No value for ``#1'']}% \message{Variable `#1', used in @value, is not set.}% \else \csname SET#1\endcsname \fi } % @ifset VAR ... @end ifset reads the `...' iff VAR has been defined % with @set. % % To get special treatment of `@end ifset,' call \makeond and the redefine. % \makecond{ifset} \def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}} \def\doifset#1#2{% {% \makevalueexpandable \let\next=\empty \expandafter\ifx\csname SET#2\endcsname\relax #1% If not set, redefine \next. \fi \expandafter }\next } \def\ifsetfail{\doignore{ifset}} % @ifclear VAR ... @end executes the `...' iff VAR has never been % defined with @set, or has been undefined with @clear. % % The `\else' inside the `\doifset' parameter is a trick to reuse the % above code: if the variable is not set, do nothing, if it is set, % then redefine \next to \ifclearfail. % \makecond{ifclear} \def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}} \def\ifclearfail{\doignore{ifclear}} % @ifcommandisdefined CMD ... @end executes the `...' if CMD (written % without the @) is in fact defined. We can only feasibly check at the % TeX level, so something like `mathcode' is going to considered % defined even though it is not a Texinfo command. % \makecond{ifcommanddefined} \def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}} % \def\doifcmddefined#1#2{{% \makevalueexpandable \let\next=\empty \expandafter\ifx\csname #2\endcsname\relax #1% If not defined, \let\next as above. \fi \expandafter }\next } \def\ifcmddefinedfail{\doignore{ifcommanddefined}} % @ifcommandnotdefined CMD ... handled similar to @ifclear above. \makecond{ifcommandnotdefined} \def\ifcommandnotdefined{% \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}} \def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}} % Set the `txicommandconditionals' variable, so documents have a way to % test if the @ifcommand...defined conditionals are available. \set txicommandconditionals % @dircategory CATEGORY -- specify a category of the dir file % which this file should belong to. Ignore this in TeX. \let\dircategory=\comment % @defininfoenclose. \let\definfoenclose=\comment \message{indexing,} % Index generation facilities % Define \newwrite to be identical to plain tex's \newwrite % except not \outer, so it can be used within macros and \if's. \edef\newwrite{\makecsname{ptexnewwrite}} % \newindex {foo} defines an index named foo. % It automatically defines \fooindex such that % \fooindex ...rest of line... puts an entry in the index foo. % It also defines \fooindfile to be the number of the output channel for % the file that accumulates this index. The file's extension is foo. % The name of an index should be no more than 2 characters long % for the sake of vms. % \def\newindex#1{% \iflinks \expandafter\newwrite \csname#1indfile\endcsname \openout \csname#1indfile\endcsname \jobname.#1 % Open the file \fi \expandafter\xdef\csname#1index\endcsname{% % Define @#1index \noexpand\doindex{#1}} } % @defindex foo == \newindex{foo} % \def\defindex{\parsearg\newindex} % Define @defcodeindex, like @defindex except put all entries in @code. % \def\defcodeindex{\parsearg\newcodeindex} % \def\newcodeindex#1{% \iflinks \expandafter\newwrite \csname#1indfile\endcsname \openout \csname#1indfile\endcsname \jobname.#1 \fi \expandafter\xdef\csname#1index\endcsname{% \noexpand\docodeindex{#1}}% } % @synindex foo bar makes index foo feed into index bar. % Do this instead of @defindex foo if you don't want it as a separate index. % % @syncodeindex foo bar similar, but put all entries made for index foo % inside @code. % \def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}} \def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}} % #1 is \doindex or \docodeindex, #2 the index getting redefined (foo), % #3 the target index (bar). \def\dosynindex#1#2#3{% % Only do \closeout if we haven't already done it, else we'll end up % closing the target index. \expandafter \ifx\csname donesynindex#2\endcsname \relax % The \closeout helps reduce unnecessary open files; the limit on the % Acorn RISC OS is a mere 16 files. \expandafter\closeout\csname#2indfile\endcsname \expandafter\let\csname donesynindex#2\endcsname = 1 \fi % redefine \fooindfile: \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname \expandafter\let\csname#2indfile\endcsname=\temp % redefine \fooindex: \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}% } % Define \doindex, the driver for all \fooindex macros. % Argument #1 is generated by the calling \fooindex macro, % and it is "foo", the name of the index. % \doindex just uses \parsearg; it calls \doind for the actual work. % This is because \doind is more useful to call from other macros. % There is also \dosubind {index}{topic}{subtopic} % which makes an entry in a two-level index such as the operation index. \def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} \def\singleindexer #1{\doind{\indexname}{#1}} % like the previous two, but they put @code around the argument. \def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} \def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} % Take care of Texinfo commands that can appear in an index entry. % Since there are some commands we want to expand, and others we don't, % we have to laboriously prevent expansion for those that we don't. % \def\indexdummies{% \escapechar = `\\ % use backslash in output files. \def\@{@}% change to @@ when we switch to @ as escape char in index files. \def\ {\realbackslash\space }% % % Need these unexpandable (because we define \tt as a dummy) % definitions when @{ or @} appear in index entry text. Also, more % complicated, when \tex is in effect and \{ is a \delimiter again. % We can't use \lbracecmd and \rbracecmd because texindex assumes % braces and backslashes are used only as delimiters. Perhaps we % should define @lbrace and @rbrace commands a la @comma. \def\{{{\tt\char123}}% \def\}{{\tt\char125}}% % % I don't entirely understand this, but when an index entry is % generated from a macro call, the \endinput which \scanmacro inserts % causes processing to be prematurely terminated. This is, % apparently, because \indexsorttmp is fully expanded, and \endinput % is an expandable command. The redefinition below makes \endinput % disappear altogether for that purpose -- although logging shows that % processing continues to some further point. On the other hand, it % seems \endinput does not hurt in the printed index arg, since that % is still getting written without apparent harm. % % Sample source (mac-idx3.tex, reported by Graham Percival to % help-texinfo, 22may06): % @macro funindex {WORD} % @findex xyz % @end macro % ... % @funindex commtest % % The above is not enough to reproduce the bug, but it gives the flavor. % % Sample whatsit resulting: % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}} % % So: \let\endinput = \empty % % Do the redefinitions. \commondummies } % For the aux and toc files, @ is the escape character. So we want to % redefine everything using @ as the escape character (instead of % \realbackslash, still used for index files). When everything uses @, % this will be simpler. % \def\atdummies{% \def\@{@@}% \def\ {@ }% \let\{ = \lbraceatcmd \let\} = \rbraceatcmd % % Do the redefinitions. \commondummies \otherbackslash } % Called from \indexdummies and \atdummies. % \def\commondummies{% % % \definedummyword defines \#1 as \string\#1\space, thus effectively % preventing its expansion. This is used only for control words, % not control letters, because the \space would be incorrect for % control characters, but is needed to separate the control word % from whatever follows. % % For control letters, we have \definedummyletter, which omits the % space. % % These can be used both for control words that take an argument and % those that do not. If it is followed by {arg} in the input, then % that will dutifully get written to the index (or wherever). % \def\definedummyword ##1{\def##1{\string##1\space}}% \def\definedummyletter##1{\def##1{\string##1}}% \let\definedummyaccent\definedummyletter % \commondummiesnofonts % \definedummyletter\_% \definedummyletter\-% % % Non-English letters. \definedummyword\AA \definedummyword\AE \definedummyword\DH \definedummyword\L \definedummyword\O \definedummyword\OE \definedummyword\TH \definedummyword\aa \definedummyword\ae \definedummyword\dh \definedummyword\exclamdown \definedummyword\l \definedummyword\o \definedummyword\oe \definedummyword\ordf \definedummyword\ordm \definedummyword\questiondown \definedummyword\ss \definedummyword\th % % Although these internal commands shouldn't show up, sometimes they do. \definedummyword\bf \definedummyword\gtr \definedummyword\hat \definedummyword\less \definedummyword\sf \definedummyword\sl \definedummyword\tclose \definedummyword\tt % \definedummyword\LaTeX \definedummyword\TeX % % Assorted special characters. \definedummyword\arrow \definedummyword\bullet \definedummyword\comma \definedummyword\copyright \definedummyword\registeredsymbol \definedummyword\dots \definedummyword\enddots \definedummyword\entrybreak \definedummyword\equiv \definedummyword\error \definedummyword\euro \definedummyword\expansion \definedummyword\geq \definedummyword\guillemetleft \definedummyword\guillemetright \definedummyword\guilsinglleft \definedummyword\guilsinglright \definedummyword\lbracechar \definedummyword\leq \definedummyword\minus \definedummyword\ogonek \definedummyword\pounds \definedummyword\point \definedummyword\print \definedummyword\quotedblbase \definedummyword\quotedblleft \definedummyword\quotedblright \definedummyword\quoteleft \definedummyword\quoteright \definedummyword\quotesinglbase \definedummyword\rbracechar \definedummyword\result \definedummyword\textdegree % % We want to disable all macros so that they are not expanded by \write. \macrolist % \normalturnoffactive % % Handle some cases of @value -- where it does not contain any % (non-fully-expandable) commands. \makevalueexpandable } % \commondummiesnofonts: common to \commondummies and \indexnofonts. % \def\commondummiesnofonts{% % Control letters and accents. \definedummyletter\!% \definedummyaccent\"% \definedummyaccent\'% \definedummyletter\*% \definedummyaccent\,% \definedummyletter\.% \definedummyletter\/% \definedummyletter\:% \definedummyaccent\=% \definedummyletter\?% \definedummyaccent\^% \definedummyaccent\`% \definedummyaccent\~% \definedummyword\u \definedummyword\v \definedummyword\H \definedummyword\dotaccent \definedummyword\ogonek \definedummyword\ringaccent \definedummyword\tieaccent \definedummyword\ubaraccent \definedummyword\udotaccent \definedummyword\dotless % % Texinfo font commands. \definedummyword\b \definedummyword\i \definedummyword\r \definedummyword\sansserif \definedummyword\sc \definedummyword\slanted \definedummyword\t % % Commands that take arguments. \definedummyword\abbr \definedummyword\acronym \definedummyword\anchor \definedummyword\cite \definedummyword\code \definedummyword\command \definedummyword\dfn \definedummyword\dmn \definedummyword\email \definedummyword\emph \definedummyword\env \definedummyword\file \definedummyword\image \definedummyword\indicateurl \definedummyword\inforef \definedummyword\kbd \definedummyword\key \definedummyword\math \definedummyword\option \definedummyword\pxref \definedummyword\ref \definedummyword\samp \definedummyword\strong \definedummyword\tie \definedummyword\uref \definedummyword\url \definedummyword\var \definedummyword\verb \definedummyword\w \definedummyword\xref } % \indexnofonts is used when outputting the strings to sort the index % by, and when constructing control sequence names. It eliminates all % control sequences and just writes whatever the best ASCII sort string % would be for a given command (usually its argument). % \def\indexnofonts{% % Accent commands should become @asis. \def\definedummyaccent##1{\let##1\asis}% % We can just ignore other control letters. \def\definedummyletter##1{\let##1\empty}% % All control words become @asis by default; overrides below. \let\definedummyword\definedummyaccent % \commondummiesnofonts % % Don't no-op \tt, since it isn't a user-level command % and is used in the definitions of the active chars like <, >, |, etc. % Likewise with the other plain tex font commands. %\let\tt=\asis % \def\ { }% \def\@{@}% \def\_{\normalunderscore}% \def\-{}% @- shouldn't affect sorting % % Unfortunately, texindex is not prepared to handle braces in the % content at all. So for index sorting, we map @{ and @} to strings % starting with |, since that ASCII character is between ASCII { and }. \def\{{|a}% \def\lbracechar{|a}% % \def\}{|b}% \def\rbracechar{|b}% % % Non-English letters. \def\AA{AA}% \def\AE{AE}% \def\DH{DZZ}% \def\L{L}% \def\OE{OE}% \def\O{O}% \def\TH{ZZZ}% \def\aa{aa}% \def\ae{ae}% \def\dh{dzz}% \def\exclamdown{!}% \def\l{l}% \def\oe{oe}% \def\ordf{a}% \def\ordm{o}% \def\o{o}% \def\questiondown{?}% \def\ss{ss}% \def\th{zzz}% % \def\LaTeX{LaTeX}% \def\TeX{TeX}% % % Assorted special characters. % (The following {} will end up in the sort string, but that's ok.) \def\arrow{->}% \def\bullet{bullet}% \def\comma{,}% \def\copyright{copyright}% \def\dots{...}% \def\enddots{...}% \def\equiv{==}% \def\error{error}% \def\euro{euro}% \def\expansion{==>}% \def\geq{>=}% \def\guillemetleft{<<}% \def\guillemetright{>>}% \def\guilsinglleft{<}% \def\guilsinglright{>}% \def\leq{<=}% \def\minus{-}% \def\point{.}% \def\pounds{pounds}% \def\print{-|}% \def\quotedblbase{"}% \def\quotedblleft{"}% \def\quotedblright{"}% \def\quoteleft{`}% \def\quoteright{'}% \def\quotesinglbase{,}% \def\registeredsymbol{R}% \def\result{=>}% \def\textdegree{o}% % \expandafter\ifx\csname SETtxiindexlquoteignore\endcsname\relax \else \indexlquoteignore \fi % % We need to get rid of all macros, leaving only the arguments (if present). % Of course this is not nearly correct, but it is the best we can do for now. % makeinfo does not expand macros in the argument to @deffn, which ends up % writing an index entry, and texindex isn't prepared for an index sort entry % that starts with \. % % Since macro invocations are followed by braces, we can just redefine them % to take a single TeX argument. The case of a macro invocation that % goes to end-of-line is not handled. % \macrolist } % Undocumented (for FSFS 2nd ed.): @set txiindexlquoteignore makes us % ignore left quotes in the sort term. {\catcode`\`=\active \gdef\indexlquoteignore{\let`=\empty}} \let\indexbackslash=0 %overridden during \printindex. \let\SETmarginindex=\relax % put index entries in margin (undocumented)? % Most index entries go through here, but \dosubind is the general case. % #1 is the index name, #2 is the entry text. \def\doind#1#2{\dosubind{#1}{#2}{}} % Workhorse for all \fooindexes. % #1 is name of index, #2 is stuff to put there, #3 is subentry -- % empty if called from \doind, as we usually are (the main exception % is with most defuns, which call us directly). % \def\dosubind#1#2#3{% \iflinks {% % Store the main index entry text (including the third arg). \toks0 = {#2}% % If third arg is present, precede it with a space. \def\thirdarg{#3}% \ifx\thirdarg\empty \else \toks0 = \expandafter{\the\toks0 \space #3}% \fi % \edef\writeto{\csname#1indfile\endcsname}% % \safewhatsit\dosubindwrite }% \fi } % Write the entry in \toks0 to the index file: % \def\dosubindwrite{% % Put the index entry in the margin if desired. \ifx\SETmarginindex\relax\else \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}% \fi % % Remember, we are within a group. \indexdummies % Must do this here, since \bf, etc expand at this stage \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now % so it will be output as is; and it will print as backslash. % % Process the index entry with all font commands turned off, to % get the string to sort by. {\indexnofonts \edef\temp{\the\toks0}% need full expansion \xdef\indexsorttmp{\temp}% }% % % Set up the complete index entry, with both the sort key and % the original text, including any font commands. We write % three arguments to \entry to the .?? file (four in the % subentry case), texindex reduces to two when writing the .??s % sorted result. \edef\temp{% \write\writeto{% \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}% }% \temp } % Take care of unwanted page breaks/skips around a whatsit: % % If a skip is the last thing on the list now, preserve it % by backing up by \lastskip, doing the \write, then inserting % the skip again. Otherwise, the whatsit generated by the % \write or \pdfdest will make \lastskip zero. The result is that % sequences like this: % @end defun % @tindex whatever % @defun ... % will have extra space inserted, because the \medbreak in the % start of the @defun won't see the skip inserted by the @end of % the previous defun. % % But don't do any of this if we're not in vertical mode. We % don't want to do a \vskip and prematurely end a paragraph. % % Avoid page breaks due to these extra skips, too. % % But wait, there is a catch there: % We'll have to check whether \lastskip is zero skip. \ifdim is not % sufficient for this purpose, as it ignores stretch and shrink parts % of the skip. The only way seems to be to check the textual % representation of the skip. % % The following is almost like \def\zeroskipmacro{0.0pt} except that % the ``p'' and ``t'' characters have catcode \other, not 11 (letter). % \edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname} % \newskip\whatsitskip \newcount\whatsitpenalty % % ..., ready, GO: % \def\safewhatsit#1{\ifhmode #1% \else % \lastskip and \lastpenalty cannot both be nonzero simultaneously. \whatsitskip = \lastskip \edef\lastskipmacro{\the\lastskip}% \whatsitpenalty = \lastpenalty % % If \lastskip is nonzero, that means the last item was a % skip. And since a skip is discardable, that means this % -\whatsitskip glue we're inserting is preceded by a % non-discardable item, therefore it is not a potential % breakpoint, therefore no \nobreak needed. \ifx\lastskipmacro\zeroskipmacro \else \vskip-\whatsitskip \fi % #1% % \ifx\lastskipmacro\zeroskipmacro % If \lastskip was zero, perhaps the last item was a penalty, and % perhaps it was >=10000, e.g., a \nobreak. In that case, we want % to re-insert the same penalty (values >10000 are used for various % signals); since we just inserted a non-discardable item, any % following glue (such as a \parskip) would be a breakpoint. For example: % @deffn deffn-whatever % @vindex index-whatever % Description. % would allow a break between the index-whatever whatsit % and the "Description." paragraph. \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi \else % On the other hand, if we had a nonzero \lastskip, % this make-up glue would be preceded by a non-discardable item % (the whatsit from the \write), so we must insert a \nobreak. \nobreak\vskip\whatsitskip \fi \fi} % The index entry written in the file actually looks like % \entry {sortstring}{page}{topic} % or % \entry {sortstring}{page}{topic}{subtopic} % The texindex program reads in these files and writes files % containing these kinds of lines: % \initial {c} % before the first topic whose initial is c % \entry {topic}{pagelist} % for a topic that is used without subtopics % \primary {topic} % for the beginning of a topic that is used with subtopics % \secondary {subtopic}{pagelist} % for each subtopic. % Define the user-accessible indexing commands % @findex, @vindex, @kindex, @cindex. \def\findex {\fnindex} \def\kindex {\kyindex} \def\cindex {\cpindex} \def\vindex {\vrindex} \def\tindex {\tpindex} \def\pindex {\pgindex} \def\cindexsub {\begingroup\obeylines\cindexsub} {\obeylines % \gdef\cindexsub "#1" #2^^M{\endgroup % \dosubind{cp}{#2}{#1}}} % Define the macros used in formatting output of the sorted index material. % @printindex causes a particular index (the ??s file) to get printed. % It does not print any chapter heading (usually an @unnumbered). % \parseargdef\printindex{\begingroup \dobreak \chapheadingskip{10000}% % \smallfonts \rm \tolerance = 9500 \plainfrenchspacing \everypar = {}% don't want the \kern\-parindent from indentation suppression. % % See if the index file exists and is nonempty. % Change catcode of @ here so that if the index file contains % \initial {@} % as its first line, TeX doesn't complain about mismatched braces % (because it thinks @} is a control sequence). \catcode`\@ = 11 \openin 1 \jobname.#1s \ifeof 1 % \enddoublecolumns gets confused if there is no text in the index, % and it loses the chapter title and the aux file entries for the % index. The easiest way to prevent this problem is to make sure % there is some text. \putwordIndexNonexistent \else % % If the index file exists but is empty, then \openin leaves \ifeof % false. We have to make TeX try to read something from the file, so % it can discover if there is anything in it. \read 1 to \temp \ifeof 1 \putwordIndexIsEmpty \else % Index files are almost Texinfo source, but we use \ as the escape % character. It would be better to use @, but that's too big a change % to make right now. \def\indexbackslash{\backslashcurfont}% \catcode`\\ = 0 \escapechar = `\\ \begindoublecolumns \input \jobname.#1s \enddoublecolumns \fi \fi \closein 1 \endgroup} % These macros are used by the sorted index file itself. % Change them to control the appearance of the index. \def\initial#1{{% % Some minor font changes for the special characters. \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt % % Remove any glue we may have, we'll be inserting our own. \removelastskip % % We like breaks before the index initials, so insert a bonus. \nobreak \vskip 0pt plus 3\baselineskip \penalty 0 \vskip 0pt plus -3\baselineskip % % Typeset the initial. Making this add up to a whole number of % baselineskips increases the chance of the dots lining up from column % to column. It still won't often be perfect, because of the stretch % we need before each entry, but it's better. % % No shrink because it confuses \balancecolumns. \vskip 1.67\baselineskip plus .5\baselineskip \leftline{\secbf #1}% % Do our best not to break after the initial. \nobreak \vskip .33\baselineskip plus .1\baselineskip }} % \entry typesets a paragraph consisting of the text (#1), dot leaders, and % then page number (#2) flushed to the right margin. It is used for index % and table of contents entries. The paragraph is indented by \leftskip. % % A straightforward implementation would start like this: % \def\entry#1#2{... % But this freezes the catcodes in the argument, and can cause problems to % @code, which sets - active. This problem was fixed by a kludge--- % ``-'' was active throughout whole index, but this isn't really right. % The right solution is to prevent \entry from swallowing the whole text. % --kasal, 21nov03 \def\entry{% \begingroup % % Start a new paragraph if necessary, so our assignments below can't % affect previous text. \par % % Do not fill out the last line with white space. \parfillskip = 0in % % No extra space above this paragraph. \parskip = 0in % % Do not prefer a separate line ending with a hyphen to fewer lines. \finalhyphendemerits = 0 % % \hangindent is only relevant when the entry text and page number % don't both fit on one line. In that case, bob suggests starting the % dots pretty far over on the line. Unfortunately, a large % indentation looks wrong when the entry text itself is broken across % lines. So we use a small indentation and put up with long leaders. % % \hangafter is reset to 1 (which is the value we want) at the start % of each paragraph, so we need not do anything with that. \hangindent = 2em % % When the entry text needs to be broken, just fill out the first line % with blank space. \rightskip = 0pt plus1fil % % A bit of stretch before each entry for the benefit of balancing % columns. \vskip 0pt plus1pt % % When reading the text of entry, convert explicit line breaks % from @* into spaces. The user might give these in long section % titles, for instance. \def\*{\unskip\space\ignorespaces}% \def\entrybreak{\hfil\break}% % % Swallow the left brace of the text (first parameter): \afterassignment\doentry \let\temp = } \def\entrybreak{\unskip\space\ignorespaces}% \def\doentry{% \bgroup % Instead of the swallowed brace. \noindent \aftergroup\finishentry % And now comes the text of the entry. } \def\finishentry#1{% % #1 is the page number. % % The following is kludged to not output a line of dots in the index if % there are no page numbers. The next person who breaks this will be % cursed by a Unix daemon. \setbox\boxA = \hbox{#1}% \ifdim\wd\boxA = 0pt \ % \else % % If we must, put the page number on a line of its own, and fill out % this line with blank space. (The \hfil is overwhelmed with the % fill leaders glue in \indexdotfill if the page number does fit.) \hfil\penalty50 \null\nobreak\indexdotfill % Have leaders before the page number. % % The `\ ' here is removed by the implicit \unskip that TeX does as % part of (the primitive) \par. Without it, a spurious underfull % \hbox ensues. \ifpdf \pdfgettoks#1.% \ \the\toksA \else \ #1% \fi \fi \par \endgroup } % Like plain.tex's \dotfill, except uses up at least 1 em. \def\indexdotfill{\cleaders \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1fill} \def\primary #1{\line{#1\hfil}} \newskip\secondaryindent \secondaryindent=0.5cm \def\secondary#1#2{{% \parfillskip=0in \parskip=0in \hangindent=1in \hangafter=1 \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill \ifpdf \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. \else #2 \fi \par }} % Define two-column mode, which we use to typeset indexes. % Adapted from the TeXbook, page 416, which is to say, % the manmac.tex format used to print the TeXbook itself. \catcode`\@=11 \newbox\partialpage \newdimen\doublecolumnhsize \def\begindoublecolumns{\begingroup % ended by \enddoublecolumns % Grab any single-column material above us. \output = {% % % Here is a possibility not foreseen in manmac: if we accumulate a % whole lot of material, we might end up calling this \output % routine twice in a row (see the doublecol-lose test, which is % essentially a couple of indexes with @setchapternewpage off). In % that case we just ship out what is in \partialpage with the normal % output routine. Generally, \partialpage will be empty when this % runs and this will be a no-op. See the indexspread.tex test case. \ifvoid\partialpage \else \onepageout{\pagecontents\partialpage}% \fi % \global\setbox\partialpage = \vbox{% % Unvbox the main output page. \unvbox\PAGE \kern-\topskip \kern\baselineskip }% }% \eject % run that output routine to set \partialpage % % Use the double-column output routine for subsequent pages. \output = {\doublecolumnout}% % % Change the page size parameters. We could do this once outside this % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 % format, but then we repeat the same computation. Repeating a couple % of assignments once per index is clearly meaningless for the % execution time, so we may as well do it in one place. % % First we halve the line length, less a little for the gutter between % the columns. We compute the gutter based on the line length, so it % changes automatically with the paper format. The magic constant % below is chosen so that the gutter has the same value (well, +-<1pt) % as it did when we hard-coded it. % % We put the result in a separate register, \doublecolumhsize, so we % can restore it in \pagesofar, after \hsize itself has (potentially) % been clobbered. % \doublecolumnhsize = \hsize \advance\doublecolumnhsize by -.04154\hsize \divide\doublecolumnhsize by 2 \hsize = \doublecolumnhsize % % Double the \vsize as well. (We don't need a separate register here, % since nobody clobbers \vsize.) \vsize = 2\vsize } % The double-column output routine for all double-column pages except % the last. % \def\doublecolumnout{% \splittopskip=\topskip \splitmaxdepth=\maxdepth % Get the available space for the double columns -- the normal % (undoubled) page height minus any material left over from the % previous page. \dimen@ = \vsize \divide\dimen@ by 2 \advance\dimen@ by -\ht\partialpage % % box0 will be the left-hand column, box2 the right. \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ \onepageout\pagesofar \unvbox255 \penalty\outputpenalty } % % Re-output the contents of the output page -- any previous material, % followed by the two boxes we just split, in box0 and box2. \def\pagesofar{% \unvbox\partialpage % \hsize = \doublecolumnhsize \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}% } % % All done with double columns. \def\enddoublecolumns{% % The following penalty ensures that the page builder is exercised % _before_ we change the output routine. This is necessary in the % following situation: % % The last section of the index consists only of a single entry. % Before this section, \pagetotal is less than \pagegoal, so no % break occurs before the last section starts. However, the last % section, consisting of \initial and the single \entry, does not % fit on the page and has to be broken off. Without the following % penalty the page builder will not be exercised until \eject % below, and by that time we'll already have changed the output % routine to the \balancecolumns version, so the next-to-last % double-column page will be processed with \balancecolumns, which % is wrong: The two columns will go to the main vertical list, with % the broken-off section in the recent contributions. As soon as % the output routine finishes, TeX starts reconsidering the page % break. The two columns and the broken-off section both fit on the % page, because the two columns now take up only half of the page % goal. When TeX sees \eject from below which follows the final % section, it invokes the new output routine that we've set after % \balancecolumns below; \onepageout will try to fit the two columns % and the final section into the vbox of \pageheight (see % \pagebody), causing an overfull box. % % Note that glue won't work here, because glue does not exercise the % page builder, unlike penalties (see The TeXbook, pp. 280-281). \penalty0 % \output = {% % Split the last of the double-column material. Leave it on the % current page, no automatic page break. \balancecolumns % % If we end up splitting too much material for the current page, % though, there will be another page break right after this \output % invocation ends. Having called \balancecolumns once, we do not % want to call it again. Therefore, reset \output to its normal % definition right away. (We hope \balancecolumns will never be % called on to balance too much material, but if it is, this makes % the output somewhat more palatable.) \global\output = {\onepageout{\pagecontents\PAGE}}% }% \eject \endgroup % started in \begindoublecolumns % % \pagegoal was set to the doubled \vsize above, since we restarted % the current page. We're now back to normal single-column % typesetting, so reset \pagegoal to the normal \vsize (after the % \endgroup where \vsize got restored). \pagegoal = \vsize } % % Called at the end of the double column material. \def\balancecolumns{% \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. \dimen@ = \ht0 \advance\dimen@ by \topskip \advance\dimen@ by-\baselineskip \divide\dimen@ by 2 % target to split to %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% \splittopskip = \topskip % Loop until we get a decent breakpoint. {% \vbadness = 10000 \loop \global\setbox3 = \copy0 \global\setbox1 = \vsplit3 to \dimen@ \ifdim\ht3>\dimen@ \global\advance\dimen@ by 1pt \repeat }% %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% \setbox0=\vbox to\dimen@{\unvbox1}% \setbox2=\vbox to\dimen@{\unvbox3}% % \pagesofar } \catcode`\@ = \other \message{sectioning,} % Chapters, sections, etc. % Let's start with @part. \outer\parseargdef\part{\partzzz{#1}} \def\partzzz#1{% \chapoddpage \null \vskip.3\vsize % move it down on the page a bit \begingroup \noindent \titlefonts\rmisbold #1\par % the text \let\lastnode=\empty % no node to associate with \writetocentry{part}{#1}{}% but put it in the toc \headingsoff % no headline or footline on the part page \chapoddpage \endgroup } % \unnumberedno is an oxymoron. But we count the unnumbered % sections so that we can refer to them unambiguously in the pdf % outlines by their "section number". We avoid collisions with chapter % numbers by starting them at 10000. (If a document ever has 10000 % chapters, we're in trouble anyway, I'm sure.) \newcount\unnumberedno \unnumberedno = 10000 \newcount\chapno \newcount\secno \secno=0 \newcount\subsecno \subsecno=0 \newcount\subsubsecno \subsubsecno=0 % This counter is funny since it counts through charcodes of letters A, B, ... \newcount\appendixno \appendixno = `\@ % % \def\appendixletter{\char\the\appendixno} % We do the following ugly conditional instead of the above simple % construct for the sake of pdftex, which needs the actual % letter in the expansion, not just typeset. % \def\appendixletter{% \ifnum\appendixno=`A A% \else\ifnum\appendixno=`B B% \else\ifnum\appendixno=`C C% \else\ifnum\appendixno=`D D% \else\ifnum\appendixno=`E E% \else\ifnum\appendixno=`F F% \else\ifnum\appendixno=`G G% \else\ifnum\appendixno=`H H% \else\ifnum\appendixno=`I I% \else\ifnum\appendixno=`J J% \else\ifnum\appendixno=`K K% \else\ifnum\appendixno=`L L% \else\ifnum\appendixno=`M M% \else\ifnum\appendixno=`N N% \else\ifnum\appendixno=`O O% \else\ifnum\appendixno=`P P% \else\ifnum\appendixno=`Q Q% \else\ifnum\appendixno=`R R% \else\ifnum\appendixno=`S S% \else\ifnum\appendixno=`T T% \else\ifnum\appendixno=`U U% \else\ifnum\appendixno=`V V% \else\ifnum\appendixno=`W W% \else\ifnum\appendixno=`X X% \else\ifnum\appendixno=`Y Y% \else\ifnum\appendixno=`Z Z% % The \the is necessary, despite appearances, because \appendixletter is % expanded while writing the .toc file. \char\appendixno is not % expandable, thus it is written literally, thus all appendixes come out % with the same letter (or @) in the toc without it. \else\char\the\appendixno \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} % Each @chapter defines these (using marks) as the number+name, number % and name of the chapter. Page headings and footings can use % these. @section does likewise. \def\thischapter{} \def\thischapternum{} \def\thischaptername{} \def\thissection{} \def\thissectionnum{} \def\thissectionname{} \newcount\absseclevel % used to calculate proper heading level \newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count % @raisesections: treat @section as chapter, @subsection as section, etc. \def\raisesections{\global\advance\secbase by -1} \let\up=\raisesections % original BFox name % @lowersections: treat @chapter as section, @section as subsection, etc. \def\lowersections{\global\advance\secbase by 1} \let\down=\lowersections % original BFox name % we only have subsub. \chardef\maxseclevel = 3 % % A numbered section within an unnumbered changes to unnumbered too. % To achieve this, remember the "biggest" unnum. sec. we are currently in: \chardef\unnlevel = \maxseclevel % % Trace whether the current chapter is an appendix or not: % \chapheadtype is "N" or "A", unnumbered chapters are ignored. \def\chapheadtype{N} % Choose a heading macro % #1 is heading type % #2 is heading level % #3 is text for heading \def\genhead#1#2#3{% % Compute the abs. sec. level: \absseclevel=#2 \advance\absseclevel by \secbase % Make sure \absseclevel doesn't fall outside the range: \ifnum \absseclevel < 0 \absseclevel = 0 \else \ifnum \absseclevel > 3 \absseclevel = 3 \fi \fi % The heading type: \def\headtype{#1}% \if \headtype U% \ifnum \absseclevel < \unnlevel \chardef\unnlevel = \absseclevel \fi \else % Check for appendix sections: \ifnum \absseclevel = 0 \edef\chapheadtype{\headtype}% \else \if \headtype A\if \chapheadtype N% \errmessage{@appendix... within a non-appendix chapter}% \fi\fi \fi % Check for numbered within unnumbered: \ifnum \absseclevel > \unnlevel \def\headtype{U}% \else \chardef\unnlevel = 3 \fi \fi % Now print the heading: \if \headtype U% \ifcase\absseclevel \unnumberedzzz{#3}% \or \unnumberedseczzz{#3}% \or \unnumberedsubseczzz{#3}% \or \unnumberedsubsubseczzz{#3}% \fi \else \if \headtype A% \ifcase\absseclevel \appendixzzz{#3}% \or \appendixsectionzzz{#3}% \or \appendixsubseczzz{#3}% \or \appendixsubsubseczzz{#3}% \fi \else \ifcase\absseclevel \chapterzzz{#3}% \or \seczzz{#3}% \or \numberedsubseczzz{#3}% \or \numberedsubsubseczzz{#3}% \fi \fi \fi \suppressfirstparagraphindent } % an interface: \def\numhead{\genhead N} \def\apphead{\genhead A} \def\unnmhead{\genhead U} % @chapter, @appendix, @unnumbered. Increment top-level counter, reset % all lower-level sectioning counters to zero. % % Also set \chaplevelprefix, which we prepend to @float sequence numbers % (e.g., figures), q.v. By default (before any chapter), that is empty. \let\chaplevelprefix = \empty % \outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz \def\chapterzzz#1{% % section resetting is \global in case the chapter is in a group, such % as an @include file. \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 \global\advance\chapno by 1 % % Used for \float. \gdef\chaplevelprefix{\the\chapno.}% \resetallfloatnos % % \putwordChapter can contain complex things in translations. \toks0=\expandafter{\putwordChapter}% \message{\the\toks0 \space \the\chapno}% % % Write the actual heading. \chapmacro{#1}{Ynumbered}{\the\chapno}% % % So @section and the like are numbered underneath this chapter. \global\let\section = \numberedsec \global\let\subsection = \numberedsubsec \global\let\subsubsection = \numberedsubsubsec } \outer\parseargdef\appendix{\apphead0{#1}} % normally calls appendixzzz % \def\appendixzzz#1{% \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 \global\advance\appendixno by 1 \gdef\chaplevelprefix{\appendixletter.}% \resetallfloatnos % % \putwordAppendix can contain complex things in translations. \toks0=\expandafter{\putwordAppendix}% \message{\the\toks0 \space \appendixletter}% % \chapmacro{#1}{Yappendix}{\appendixletter}% % \global\let\section = \appendixsec \global\let\subsection = \appendixsubsec \global\let\subsubsection = \appendixsubsubsec } % normally unnmhead0 calls unnumberedzzz: \outer\parseargdef\unnumbered{\unnmhead0{#1}} \def\unnumberedzzz#1{% \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 \global\advance\unnumberedno by 1 % % Since an unnumbered has no number, no prefix for figures. \global\let\chaplevelprefix = \empty \resetallfloatnos % % This used to be simply \message{#1}, but TeX fully expands the % argument to \message. Therefore, if #1 contained @-commands, TeX % expanded them. For example, in `@unnumbered The @cite{Book}', TeX % expanded @cite (which turns out to cause errors because \cite is meant % to be executed, not expanded). % % Anyway, we don't want the fully-expanded definition of @cite to appear % as a result of the \message, we just want `@cite' itself. We use % \the to achieve this: TeX expands \the only once, % simply yielding the contents of . (We also do this for % the toc entries.) \toks0 = {#1}% \message{(\the\toks0)}% % \chapmacro{#1}{Ynothing}{\the\unnumberedno}% % \global\let\section = \unnumberedsec \global\let\subsection = \unnumberedsubsec \global\let\subsubsection = \unnumberedsubsubsec } % @centerchap is like @unnumbered, but the heading is centered. \outer\parseargdef\centerchap{% % Well, we could do the following in a group, but that would break % an assumption that \chapmacro is called at the outermost level. % Thus we are safer this way: --kasal, 24feb04 \let\centerparametersmaybe = \centerparameters \unnmhead0{#1}% \let\centerparametersmaybe = \relax } % @top is like @unnumbered. \let\top\unnumbered % Sections. % \outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz \def\seczzz#1{% \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}% } % normally calls appendixsectionzzz: \outer\parseargdef\appendixsection{\apphead1{#1}} \def\appendixsectionzzz#1{% \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}% } \let\appendixsec\appendixsection % normally calls unnumberedseczzz: \outer\parseargdef\unnumberedsec{\unnmhead1{#1}} \def\unnumberedseczzz#1{% \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}% } % Subsections. % % normally calls numberedsubseczzz: \outer\parseargdef\numberedsubsec{\numhead2{#1}} \def\numberedsubseczzz#1{% \global\subsubsecno=0 \global\advance\subsecno by 1 \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}% } % normally calls appendixsubseczzz: \outer\parseargdef\appendixsubsec{\apphead2{#1}} \def\appendixsubseczzz#1{% \global\subsubsecno=0 \global\advance\subsecno by 1 \sectionheading{#1}{subsec}{Yappendix}% {\appendixletter.\the\secno.\the\subsecno}% } % normally calls unnumberedsubseczzz: \outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} \def\unnumberedsubseczzz#1{% \global\subsubsecno=0 \global\advance\subsecno by 1 \sectionheading{#1}{subsec}{Ynothing}% {\the\unnumberedno.\the\secno.\the\subsecno}% } % Subsubsections. % % normally numberedsubsubseczzz: \outer\parseargdef\numberedsubsubsec{\numhead3{#1}} \def\numberedsubsubseczzz#1{% \global\advance\subsubsecno by 1 \sectionheading{#1}{subsubsec}{Ynumbered}% {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}% } % normally appendixsubsubseczzz: \outer\parseargdef\appendixsubsubsec{\apphead3{#1}} \def\appendixsubsubseczzz#1{% \global\advance\subsubsecno by 1 \sectionheading{#1}{subsubsec}{Yappendix}% {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}% } % normally unnumberedsubsubseczzz: \outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} \def\unnumberedsubsubseczzz#1{% \global\advance\subsubsecno by 1 \sectionheading{#1}{subsubsec}{Ynothing}% {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}% } % These macros control what the section commands do, according % to what kind of chapter we are in (ordinary, appendix, or unnumbered). % Define them by default for a numbered chapter. \let\section = \numberedsec \let\subsection = \numberedsubsec \let\subsubsection = \numberedsubsubsec % Define @majorheading, @heading and @subheading \def\majorheading{% {\advance\chapheadingskip by 10pt \chapbreak }% \parsearg\chapheadingzzz } \def\chapheading{\chapbreak \parsearg\chapheadingzzz} \def\chapheadingzzz#1{% \vbox{\chapfonts \raggedtitlesettings #1\par}% \nobreak\bigskip \nobreak \suppressfirstparagraphindent } % @heading, @subheading, @subsubheading. \parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{} \suppressfirstparagraphindent} \parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{} \suppressfirstparagraphindent} \parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{} \suppressfirstparagraphindent} % These macros generate a chapter, section, etc. heading only % (including whitespace, linebreaking, etc. around it), % given all the information in convenient, parsed form. % Args are the skip and penalty (usually negative) \def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} % Parameter controlling skip before chapter headings (if needed) \newskip\chapheadingskip % Define plain chapter starts, and page on/off switching for it. \def\chapbreak{\dobreak \chapheadingskip {-4000}} \def\chappager{\par\vfill\supereject} % Because \domark is called before \chapoddpage, the filler page will % get the headings for the next chapter, which is wrong. But we don't % care -- we just disable all headings on the filler page. \def\chapoddpage{% \chappager \ifodd\pageno \else \begingroup \headingsoff \null \chappager \endgroup \fi } \def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} \def\CHAPPAGoff{% \global\let\contentsalignmacro = \chappager \global\let\pchapsepmacro=\chapbreak \global\let\pagealignmacro=\chappager} \def\CHAPPAGon{% \global\let\contentsalignmacro = \chappager \global\let\pchapsepmacro=\chappager \global\let\pagealignmacro=\chappager \global\def\HEADINGSon{\HEADINGSsingle}} \def\CHAPPAGodd{% \global\let\contentsalignmacro = \chapoddpage \global\let\pchapsepmacro=\chapoddpage \global\let\pagealignmacro=\chapoddpage \global\def\HEADINGSon{\HEADINGSdouble}} \CHAPPAGon % Chapter opening. % % #1 is the text, #2 is the section type (Ynumbered, Ynothing, % Yappendix, Yomitfromtoc), #3 the chapter number. % % To test against our argument. \def\Ynothingkeyword{Ynothing} \def\Yomitfromtockeyword{Yomitfromtoc} \def\Yappendixkeyword{Yappendix} % \def\chapmacro#1#2#3{% % Insert the first mark before the heading break (see notes for \domark). \let\prevchapterdefs=\lastchapterdefs \let\prevsectiondefs=\lastsectiondefs \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}% \gdef\thissection{}}% % \def\temptype{#2}% \ifx\temptype\Ynothingkeyword \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}% \gdef\thischapter{\thischaptername}}% \else\ifx\temptype\Yomitfromtockeyword \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}% \gdef\thischapter{}}% \else\ifx\temptype\Yappendixkeyword \toks0={#1}% \xdef\lastchapterdefs{% \gdef\noexpand\thischaptername{\the\toks0}% \gdef\noexpand\thischapternum{\appendixletter}% % \noexpand\putwordAppendix avoids expanding indigestible % commands in some of the translations. \gdef\noexpand\thischapter{\noexpand\putwordAppendix{} \noexpand\thischapternum: \noexpand\thischaptername}% }% \else \toks0={#1}% \xdef\lastchapterdefs{% \gdef\noexpand\thischaptername{\the\toks0}% \gdef\noexpand\thischapternum{\the\chapno}% % \noexpand\putwordChapter avoids expanding indigestible % commands in some of the translations. \gdef\noexpand\thischapter{\noexpand\putwordChapter{} \noexpand\thischapternum: \noexpand\thischaptername}% }% \fi\fi\fi % % Output the mark. Pass it through \safewhatsit, to take care of % the preceding space. \safewhatsit\domark % % Insert the chapter heading break. \pchapsepmacro % % Now the second mark, after the heading break. No break points % between here and the heading. \let\prevchapterdefs=\lastchapterdefs \let\prevsectiondefs=\lastsectiondefs \domark % {% \chapfonts \rmisbold % % Have to define \lastsection before calling \donoderef, because the % xref code eventually uses it. On the other hand, it has to be called % after \pchapsepmacro, or the headline will change too soon. \gdef\lastsection{#1}% % % Only insert the separating space if we have a chapter/appendix % number, and don't print the unnumbered ``number''. \ifx\temptype\Ynothingkeyword \setbox0 = \hbox{}% \def\toctype{unnchap}% \else\ifx\temptype\Yomitfromtockeyword \setbox0 = \hbox{}% contents like unnumbered, but no toc entry \def\toctype{omit}% \else\ifx\temptype\Yappendixkeyword \setbox0 = \hbox{\putwordAppendix{} #3\enspace}% \def\toctype{app}% \else \setbox0 = \hbox{#3\enspace}% \def\toctype{numchap}% \fi\fi\fi % % Write the toc entry for this chapter. Must come before the % \donoderef, because we include the current node name in the toc % entry, and \donoderef resets it to empty. \writetocentry{\toctype}{#1}{#3}% % % For pdftex, we have to write out the node definition (aka, make % the pdfdest) after any page break, but before the actual text has % been typeset. If the destination for the pdf outline is after the % text, then jumping from the outline may wind up with the text not % being visible, for instance under high magnification. \donoderef{#2}% % % Typeset the actual heading. \nobreak % Avoid page breaks at the interline glue. \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe \unhbox0 #1\par}% }% \nobreak\bigskip % no page break after a chapter title \nobreak } % @centerchap -- centered and unnumbered. \let\centerparametersmaybe = \relax \def\centerparameters{% \advance\rightskip by 3\rightskip \leftskip = \rightskip \parfillskip = 0pt } % I don't think this chapter style is supported any more, so I'm not % updating it with the new noderef stuff. We'll see. --karl, 11aug03. % \def\setchapterstyle #1 {\csname CHAPF#1\endcsname} % \def\unnchfopen #1{% \chapoddpage \vbox{\chapfonts \raggedtitlesettings #1\par}% \nobreak\bigskip\nobreak } \def\chfopen #1#2{\chapoddpage {\chapfonts \vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% \par\penalty 5000 % } \def\centerchfopen #1{% \chapoddpage \vbox{\chapfonts \raggedtitlesettings \hfill #1\hfill}% \nobreak\bigskip \nobreak } \def\CHAPFopen{% \global\let\chapmacro=\chfopen \global\let\centerchapmacro=\centerchfopen} % Section titles. These macros combine the section number parts and % call the generic \sectionheading to do the printing. % \newskip\secheadingskip \def\secheadingbreak{\dobreak \secheadingskip{-1000}} % Subsection titles. \newskip\subsecheadingskip \def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}} % Subsubsection titles. \def\subsubsecheadingskip{\subsecheadingskip} \def\subsubsecheadingbreak{\subsecheadingbreak} % Print any size, any type, section title. % % #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is % the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the % section number. % \def\seckeyword{sec} % \def\sectionheading#1#2#3#4{% {% \checkenv{}% should not be in an environment. % % Switch to the right set of fonts. \csname #2fonts\endcsname \rmisbold % \def\sectionlevel{#2}% \def\temptype{#3}% % % Insert first mark before the heading break (see notes for \domark). \let\prevsectiondefs=\lastsectiondefs \ifx\temptype\Ynothingkeyword \ifx\sectionlevel\seckeyword \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}% \gdef\thissection{\thissectionname}}% \fi \else\ifx\temptype\Yomitfromtockeyword % Don't redefine \thissection. \else\ifx\temptype\Yappendixkeyword \ifx\sectionlevel\seckeyword \toks0={#1}% \xdef\lastsectiondefs{% \gdef\noexpand\thissectionname{\the\toks0}% \gdef\noexpand\thissectionnum{#4}% % \noexpand\putwordSection avoids expanding indigestible % commands in some of the translations. \gdef\noexpand\thissection{\noexpand\putwordSection{} \noexpand\thissectionnum: \noexpand\thissectionname}% }% \fi \else \ifx\sectionlevel\seckeyword \toks0={#1}% \xdef\lastsectiondefs{% \gdef\noexpand\thissectionname{\the\toks0}% \gdef\noexpand\thissectionnum{#4}% % \noexpand\putwordSection avoids expanding indigestible % commands in some of the translations. \gdef\noexpand\thissection{\noexpand\putwordSection{} \noexpand\thissectionnum: \noexpand\thissectionname}% }% \fi \fi\fi\fi % % Go into vertical mode. Usually we'll already be there, but we % don't want the following whatsit to end up in a preceding paragraph % if the document didn't happen to have a blank line. \par % % Output the mark. Pass it through \safewhatsit, to take care of % the preceding space. \safewhatsit\domark % % Insert space above the heading. \csname #2headingbreak\endcsname % % Now the second mark, after the heading break. No break points % between here and the heading. \let\prevsectiondefs=\lastsectiondefs \domark % % Only insert the space after the number if we have a section number. \ifx\temptype\Ynothingkeyword \setbox0 = \hbox{}% \def\toctype{unn}% \gdef\lastsection{#1}% \else\ifx\temptype\Yomitfromtockeyword % for @headings -- no section number, don't include in toc, % and don't redefine \lastsection. \setbox0 = \hbox{}% \def\toctype{omit}% \let\sectionlevel=\empty \else\ifx\temptype\Yappendixkeyword \setbox0 = \hbox{#4\enspace}% \def\toctype{app}% \gdef\lastsection{#1}% \else \setbox0 = \hbox{#4\enspace}% \def\toctype{num}% \gdef\lastsection{#1}% \fi\fi\fi % % Write the toc entry (before \donoderef). See comments in \chapmacro. \writetocentry{\toctype\sectionlevel}{#1}{#4}% % % Write the node reference (= pdf destination for pdftex). % Again, see comments in \chapmacro. \donoderef{#3}% % % Interline glue will be inserted when the vbox is completed. % That glue will be a valid breakpoint for the page, since it'll be % preceded by a whatsit (usually from the \donoderef, or from the % \writetocentry if there was no node). We don't want to allow that % break, since then the whatsits could end up on page n while the % section is on page n+1, thus toc/etc. are wrong. Debian bug 276000. \nobreak % % Output the actual section heading. \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright \hangindent=\wd0 % zero if no section number \unhbox0 #1}% }% % Add extra space after the heading -- half of whatever came above it. % Don't allow stretch, though. \kern .5 \csname #2headingskip\endcsname % % Do not let the kern be a potential breakpoint, as it would be if it % was followed by glue. \nobreak % % We'll almost certainly start a paragraph next, so don't let that % glue accumulate. (Not a breakpoint because it's preceded by a % discardable item.) However, when a paragraph is not started next % (\startdefun, \cartouche, \center, etc.), this needs to be wiped out % or the negative glue will cause weirdly wrong output, typically % obscuring the section heading with something else. \vskip-\parskip % % This is so the last item on the main vertical list is a known % \penalty > 10000, so \startdefun, etc., can recognize the situation % and do the needful. \penalty 10001 } \message{toc,} % Table of contents. \newwrite\tocfile % Write an entry to the toc file, opening it if necessary. % Called from @chapter, etc. % % Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno} % We append the current node name (if any) and page number as additional % arguments for the \{chap,sec,...}entry macros which will eventually % read this. The node name is used in the pdf outlines as the % destination to jump to. % % We open the .toc file for writing here instead of at @setfilename (or % any other fixed time) so that @contents can be anywhere in the document. % But if #1 is `omit', then we don't do anything. This is used for the % table of contents chapter openings themselves. % \newif\iftocfileopened \def\omitkeyword{omit}% % \def\writetocentry#1#2#3{% \edef\writetoctype{#1}% \ifx\writetoctype\omitkeyword \else \iftocfileopened\else \immediate\openout\tocfile = \jobname.toc \global\tocfileopenedtrue \fi % \iflinks {\atdummies \edef\temp{% \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}% \temp }% \fi \fi % % Tell \shipout to create a pdf destination on each page, if we're % writing pdf. These are used in the table of contents. We can't % just write one on every page because the title pages are numbered % 1 and 2 (the page numbers aren't printed), and so are the first % two pages of the document. Thus, we'd have two destinations named % `1', and two named `2'. \ifpdf \global\pdfmakepagedesttrue \fi } % These characters do not print properly in the Computer Modern roman % fonts, so we must take special care. This is more or less redundant % with the Texinfo input format setup at the end of this file. % \def\activecatcodes{% \catcode`\"=\active \catcode`\$=\active \catcode`\<=\active \catcode`\>=\active \catcode`\\=\active \catcode`\^=\active \catcode`\_=\active \catcode`\|=\active \catcode`\~=\active } % Read the toc file, which is essentially Texinfo input. \def\readtocfile{% \setupdatafile \activecatcodes \input \tocreadfilename } \newskip\contentsrightmargin \contentsrightmargin=1in \newcount\savepageno \newcount\lastnegativepageno \lastnegativepageno = -1 % Prepare to read what we've written to \tocfile. % \def\startcontents#1{% % If @setchapternewpage on, and @headings double, the contents should % start on an odd page, unlike chapters. Thus, we maintain % \contentsalignmacro in parallel with \pagealignmacro. % From: Torbjorn Granlund \contentsalignmacro \immediate\closeout\tocfile % % Don't need to put `Contents' or `Short Contents' in the headline. % It is abundantly clear what they are. \chapmacro{#1}{Yomitfromtoc}{}% % \savepageno = \pageno \begingroup % Set up to handle contents files properly. \raggedbottom % Worry more about breakpoints than the bottom. \advance\hsize by -\contentsrightmargin % Don't use the full line length. % % Roman numerals for page numbers. \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi } % redefined for the two-volume lispref. We always output on % \jobname.toc even if this is redefined. % \def\tocreadfilename{\jobname.toc} % Normal (long) toc. % \def\contents{% \startcontents{\putwordTOC}% \openin 1 \tocreadfilename\space \ifeof 1 \else \readtocfile \fi \vfill \eject \contentsalignmacro % in case @setchapternewpage odd is in effect \ifeof 1 \else \pdfmakeoutlines \fi \closein 1 \endgroup \lastnegativepageno = \pageno \global\pageno = \savepageno } % And just the chapters. \def\summarycontents{% \startcontents{\putwordShortTOC}% % \let\partentry = \shortpartentry \let\numchapentry = \shortchapentry \let\appentry = \shortchapentry \let\unnchapentry = \shortunnchapentry % We want a true roman here for the page numbers. \secfonts \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl \let\tt=\shortconttt \rm \hyphenpenalty = 10000 \advance\baselineskip by 1pt % Open it up a little. \def\numsecentry##1##2##3##4{} \let\appsecentry = \numsecentry \let\unnsecentry = \numsecentry \let\numsubsecentry = \numsecentry \let\appsubsecentry = \numsecentry \let\unnsubsecentry = \numsecentry \let\numsubsubsecentry = \numsecentry \let\appsubsubsecentry = \numsecentry \let\unnsubsubsecentry = \numsecentry \openin 1 \tocreadfilename\space \ifeof 1 \else \readtocfile \fi \closein 1 \vfill \eject \contentsalignmacro % in case @setchapternewpage odd is in effect \endgroup \lastnegativepageno = \pageno \global\pageno = \savepageno } \let\shortcontents = \summarycontents % Typeset the label for a chapter or appendix for the short contents. % The arg is, e.g., `A' for an appendix, or `3' for a chapter. % \def\shortchaplabel#1{% % This space should be enough, since a single number is .5em, and the % widest letter (M) is 1em, at least in the Computer Modern fonts. % But use \hss just in case. % (This space doesn't include the extra space that gets added after % the label; that gets put in by \shortchapentry above.) % % We'd like to right-justify chapter numbers, but that looks strange % with appendix letters. And right-justifying numbers and % left-justifying letters looks strange when there is less than 10 % chapters. Have to read the whole toc once to know how many chapters % there are before deciding ... \hbox to 1em{#1\hss}% } % These macros generate individual entries in the table of contents. % The first argument is the chapter or section name. % The last argument is the page number. % The arguments in between are the chapter number, section number, ... % Parts, in the main contents. Replace the part number, which doesn't % exist, with an empty box. Let's hope all the numbers have the same width. % Also ignore the page number, which is conventionally not printed. \def\numeralbox{\setbox0=\hbox{8}\hbox to \wd0{\hfil}} \def\partentry#1#2#3#4{\dochapentry{\numeralbox\labelspace#1}{}} % % Parts, in the short toc. \def\shortpartentry#1#2#3#4{% \penalty-300 \vskip.5\baselineskip plus.15\baselineskip minus.1\baselineskip \shortchapentry{{\bf #1}}{\numeralbox}{}{}% } % Chapters, in the main contents. \def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}} % % Chapters, in the short toc. % See comments in \dochapentry re vbox and related settings. \def\shortchapentry#1#2#3#4{% \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}% } % Appendices, in the main contents. % Need the word Appendix, and a fixed-size box. % \def\appendixbox#1{% % We use M since it's probably the widest letter. \setbox0 = \hbox{\putwordAppendix{} M}% \hbox to \wd0{\putwordAppendix{} #1\hss}} % \def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}} % Unnumbered chapters. \def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}} \def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}} % Sections. \def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}} \let\appsecentry=\numsecentry \def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}} % Subsections. \def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}} \let\appsubsecentry=\numsubsecentry \def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}} % And subsubsections. \def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}} \let\appsubsubsecentry=\numsubsubsecentry \def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}} % This parameter controls the indentation of the various levels. % Same as \defaultparindent. \newdimen\tocindent \tocindent = 15pt % Now for the actual typesetting. In all these, #1 is the text and #2 is the % page number. % % If the toc has to be broken over pages, we want it to be at chapters % if at all possible; hence the \penalty. \def\dochapentry#1#2{% \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip \begingroup \chapentryfonts \tocentry{#1}{\dopageno\bgroup#2\egroup}% \endgroup \nobreak\vskip .25\baselineskip plus.1\baselineskip } \def\dosecentry#1#2{\begingroup \secentryfonts \leftskip=\tocindent \tocentry{#1}{\dopageno\bgroup#2\egroup}% \endgroup} \def\dosubsecentry#1#2{\begingroup \subsecentryfonts \leftskip=2\tocindent \tocentry{#1}{\dopageno\bgroup#2\egroup}% \endgroup} \def\dosubsubsecentry#1#2{\begingroup \subsubsecentryfonts \leftskip=3\tocindent \tocentry{#1}{\dopageno\bgroup#2\egroup}% \endgroup} % We use the same \entry macro as for the index entries. \let\tocentry = \entry % Space between chapter (or whatever) number and the title. \def\labelspace{\hskip1em \relax} \def\dopageno#1{{\rm #1}} \def\doshortpageno#1{{\rm #1}} \def\chapentryfonts{\secfonts \rm} \def\secentryfonts{\textfonts} \def\subsecentryfonts{\textfonts} \def\subsubsecentryfonts{\textfonts} \message{environments,} % @foo ... @end foo. % @tex ... @end tex escapes into raw TeX temporarily. % One exception: @ is still an escape character, so that @end tex works. % But \@ or @@ will get a plain @ character. \envdef\tex{% \setupmarkupstyle{tex}% \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie \catcode `\%=14 \catcode `\+=\other \catcode `\"=\other \catcode `\|=\other \catcode `\<=\other \catcode `\>=\other \catcode`\`=\other \catcode`\'=\other \escapechar=`\\ % % ' is active in math mode (mathcode"8000). So reset it, and all our % other math active characters (just in case), to plain's definitions. \mathactive % \let\b=\ptexb \let\bullet=\ptexbullet \let\c=\ptexc \let\,=\ptexcomma \let\.=\ptexdot \let\dots=\ptexdots \let\equiv=\ptexequiv \let\!=\ptexexclam \let\i=\ptexi \let\indent=\ptexindent \let\noindent=\ptexnoindent \let\{=\ptexlbrace \let\+=\tabalign \let\}=\ptexrbrace \let\/=\ptexslash \let\*=\ptexstar \let\t=\ptext \expandafter \let\csname top\endcsname=\ptextop % outer \let\frenchspacing=\plainfrenchspacing % \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% \def\@{@}% } % There is no need to define \Etex. % Define @lisp ... @end lisp. % @lisp environment forms a group so it can rebind things, % including the definition of @end lisp (which normally is erroneous). % Amount to narrow the margins by for @lisp. \newskip\lispnarrowing \lispnarrowing=0.4in % This is the definition that ^^M gets inside @lisp, @example, and other % such environments. \null is better than a space, since it doesn't % have any width. \def\lisppar{\null\endgraf} % This space is always present above and below environments. \newskip\envskipamount \envskipamount = 0pt % Make spacing and below environment symmetrical. We use \parskip here % to help in doing that, since in @example-like environments \parskip % is reset to zero; thus the \afterenvbreak inserts no space -- but the % start of the next paragraph will insert \parskip. % \def\aboveenvbreak{{% % =10000 instead of <10000 because of a special case in \itemzzz and % \sectionheading, q.v. \ifnum \lastpenalty=10000 \else \advance\envskipamount by \parskip \endgraf \ifdim\lastskip<\envskipamount \removelastskip % it's not a good place to break if the last penalty was \nobreak % or better ... \ifnum\lastpenalty<10000 \penalty-50 \fi \vskip\envskipamount \fi \fi }} \let\afterenvbreak = \aboveenvbreak % \nonarrowing is a flag. If "set", @lisp etc don't narrow margins; it will % also clear it, so that its embedded environments do the narrowing again. \let\nonarrowing=\relax % @cartouche ... @end cartouche: draw rectangle w/rounded corners around % environment contents. \font\circle=lcircle10 \newdimen\circthick \newdimen\cartouter\newdimen\cartinner \newskip\normbskip\newskip\normpskip\newskip\normlskip \circthick=\fontdimen8\circle % \def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth \def\ctr{{\hskip 6pt\circle\char'010}} \def\cbl{{\circle\char'012\hskip -6pt}} \def\cbr{{\hskip 6pt\circle\char'011}} \def\carttop{\hbox to \cartouter{\hskip\lskip \ctl\leaders\hrule height\circthick\hfil\ctr \hskip\rskip}} \def\cartbot{\hbox to \cartouter{\hskip\lskip \cbl\leaders\hrule height\circthick\hfil\cbr \hskip\rskip}} % \newskip\lskip\newskip\rskip \envdef\cartouche{% \ifhmode\par\fi % can't be in the midst of a paragraph. \startsavinginserts \lskip=\leftskip \rskip=\rightskip \leftskip=0pt\rightskip=0pt % we want these *outside*. \cartinner=\hsize \advance\cartinner by-\lskip \advance\cartinner by-\rskip \cartouter=\hsize \advance\cartouter by 18.4pt % allow for 3pt kerns on either % side, and for 6pt waste from % each corner char, and rule thickness \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip % Flag to tell @lisp, etc., not to narrow margin. \let\nonarrowing = t% % % If this cartouche directly follows a sectioning command, we need the % \parskip glue (backspaced over by default) or the cartouche can % collide with the section heading. \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi % \vbox\bgroup \baselineskip=0pt\parskip=0pt\lineskip=0pt \carttop \hbox\bgroup \hskip\lskip \vrule\kern3pt \vbox\bgroup \kern3pt \hsize=\cartinner \baselineskip=\normbskip \lineskip=\normlskip \parskip=\normpskip \vskip -\parskip \comment % For explanation, see the end of def\group. } \def\Ecartouche{% \ifhmode\par\fi \kern3pt \egroup \kern3pt\vrule \hskip\rskip \egroup \cartbot \egroup \checkinserts } % This macro is called at the beginning of all the @example variants, % inside a group. \newdimen\nonfillparindent \def\nonfillstart{% \aboveenvbreak \hfuzz = 12pt % Don't be fussy \sepspaces % Make spaces be word-separators rather than space tokens. \let\par = \lisppar % don't ignore blank lines \obeylines % each line of input is a line of output \parskip = 0pt % Turn off paragraph indentation but redefine \indent to emulate % the normal \indent. \nonfillparindent=\parindent \parindent = 0pt \let\indent\nonfillindent % \emergencystretch = 0pt % don't try to avoid overfull boxes \ifx\nonarrowing\relax \advance \leftskip by \lispnarrowing \exdentamount=\lispnarrowing \else \let\nonarrowing = \relax \fi \let\exdent=\nofillexdent } \begingroup \obeyspaces % We want to swallow spaces (but not other tokens) after the fake % @indent in our nonfill-environments, where spaces are normally % active and set to @tie, resulting in them not being ignored after % @indent. \gdef\nonfillindent{\futurelet\temp\nonfillindentcheck}% \gdef\nonfillindentcheck{% \ifx\temp % \expandafter\nonfillindentgobble% \else% \leavevmode\nonfillindentbox% \fi% }% \endgroup \def\nonfillindentgobble#1{\nonfillindent} \def\nonfillindentbox{\hbox to \nonfillparindent{\hss}} % If you want all examples etc. small: @set dispenvsize small. % If you want even small examples the full size: @set dispenvsize nosmall. % This affects the following displayed environments: % @example, @display, @format, @lisp % \def\smallword{small} \def\nosmallword{nosmall} \let\SETdispenvsize\relax \def\setnormaldispenv{% \ifx\SETdispenvsize\smallword % end paragraph for sake of leading, in case document has no blank % line. This is redundant with what happens in \aboveenvbreak, but % we need to do it before changing the fonts, and it's inconvenient % to change the fonts afterward. \ifnum \lastpenalty=10000 \else \endgraf \fi \smallexamplefonts \rm \fi } \def\setsmalldispenv{% \ifx\SETdispenvsize\nosmallword \else \ifnum \lastpenalty=10000 \else \endgraf \fi \smallexamplefonts \rm \fi } % We often define two environments, @foo and @smallfoo. % Let's do it in one command. #1 is the env name, #2 the definition. \def\makedispenvdef#1#2{% \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}% \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}% \expandafter\let\csname E#1\endcsname \afterenvbreak \expandafter\let\csname Esmall#1\endcsname \afterenvbreak } % Define two environment synonyms (#1 and #2) for an environment. \def\maketwodispenvdef#1#2#3{% \makedispenvdef{#1}{#3}% \makedispenvdef{#2}{#3}% } % % @lisp: indented, narrowed, typewriter font; % @example: same as @lisp. % % @smallexample and @smalllisp: use smaller fonts. % Originally contributed by Pavel@xerox. % \maketwodispenvdef{lisp}{example}{% \nonfillstart \tt\setupmarkupstyle{example}% \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. \gobble % eat return } % @display/@smalldisplay: same as @lisp except keep current font. % \makedispenvdef{display}{% \nonfillstart \gobble } % @format/@smallformat: same as @display except don't narrow margins. % \makedispenvdef{format}{% \let\nonarrowing = t% \nonfillstart \gobble } % @flushleft: same as @format, but doesn't obey \SETdispenvsize. \envdef\flushleft{% \let\nonarrowing = t% \nonfillstart \gobble } \let\Eflushleft = \afterenvbreak % @flushright. % \envdef\flushright{% \let\nonarrowing = t% \nonfillstart \advance\leftskip by 0pt plus 1fill\relax \gobble } \let\Eflushright = \afterenvbreak % @raggedright does more-or-less normal line breaking but no right % justification. From plain.tex. \envdef\raggedright{% \rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax } \let\Eraggedright\par \envdef\raggedleft{% \parindent=0pt \leftskip0pt plus2em \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt \hbadness=10000 % Last line will usually be underfull, so turn off % badness reporting. } \let\Eraggedleft\par \envdef\raggedcenter{% \parindent=0pt \rightskip0pt plus1em \leftskip0pt plus1em \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt \hbadness=10000 % Last line will usually be underfull, so turn off % badness reporting. } \let\Eraggedcenter\par % @quotation does normal linebreaking (hence we can't use \nonfillstart) % and narrows the margins. We keep \parskip nonzero in general, since % we're doing normal filling. So, when using \aboveenvbreak and % \afterenvbreak, temporarily make \parskip 0. % \makedispenvdef{quotation}{\quotationstart} % \def\quotationstart{% \indentedblockstart % same as \indentedblock, but increase right margin too. \ifx\nonarrowing\relax \advance\rightskip by \lispnarrowing \fi \parsearg\quotationlabel } % We have retained a nonzero parskip for the environment, since we're % doing normal filling. % \def\Equotation{% \par \ifx\quotationauthor\thisisundefined\else % indent a bit. \leftline{\kern 2\leftskip \sl ---\quotationauthor}% \fi {\parskip=0pt \afterenvbreak}% } \def\Esmallquotation{\Equotation} % If we're given an argument, typeset it in bold with a colon after. \def\quotationlabel#1{% \def\temp{#1}% \ifx\temp\empty \else {\bf #1: }% \fi } % @indentedblock is like @quotation, but indents only on the left and % has no optional argument. % \makedispenvdef{indentedblock}{\indentedblockstart} % \def\indentedblockstart{% {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip \parindent=0pt % % @cartouche defines \nonarrowing to inhibit narrowing at next level down. \ifx\nonarrowing\relax \advance\leftskip by \lispnarrowing \exdentamount = \lispnarrowing \else \let\nonarrowing = \relax \fi } % Keep a nonzero parskip for the environment, since we're doing normal filling. % \def\Eindentedblock{% \par {\parskip=0pt \afterenvbreak}% } \def\Esmallindentedblock{\Eindentedblock} % LaTeX-like @verbatim...@end verbatim and @verb{...} % If we want to allow any as delimiter, % we need the curly braces so that makeinfo sees the @verb command, eg: % `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org % % [Knuth]: Donald Ervin Knuth, 1996. The TeXbook. % % [Knuth] p.344; only we need to do the other characters Texinfo sets % active too. Otherwise, they get lost as the first character on a % verbatim line. \def\dospecials{% \do\ \do\\\do\{\do\}\do\$\do\&% \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~% \do\<\do\>\do\|\do\@\do+\do\"% % Don't do the quotes -- if we do, @set txicodequoteundirected and % @set txicodequotebacktick will not have effect on @verb and % @verbatim, and ?` and !` ligatures won't get disabled. %\do\`\do\'% } % % [Knuth] p. 380 \def\uncatcodespecials{% \def\do##1{\catcode`##1=\other}\dospecials} % % Setup for the @verb command. % % Eight spaces for a tab \begingroup \catcode`\^^I=\active \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }} \endgroup % \def\setupverb{% \tt % easiest (and conventionally used) font for verbatim \def\par{\leavevmode\endgraf}% \setupmarkupstyle{verb}% \tabeightspaces % Respect line breaks, % print special symbols as themselves, and % make each space count % must do in this order: \obeylines \uncatcodespecials \sepspaces } % Setup for the @verbatim environment % % Real tab expansion. \newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount % % We typeset each line of the verbatim in an \hbox, so we can handle % tabs. The \global is in case the verbatim line starts with an accent, % or some other command that starts with a begin-group. Otherwise, the % entire \verbbox would disappear at the corresponding end-group, before % it is typeset. Meanwhile, we can't have nested verbatim commands % (can we?), so the \global won't be overwriting itself. \newbox\verbbox \def\starttabbox{\global\setbox\verbbox=\hbox\bgroup} % \begingroup \catcode`\^^I=\active \gdef\tabexpand{% \catcode`\^^I=\active \def^^I{\leavevmode\egroup \dimen\verbbox=\wd\verbbox % the width so far, or since the previous tab \divide\dimen\verbbox by\tabw \multiply\dimen\verbbox by\tabw % compute previous multiple of \tabw \advance\dimen\verbbox by\tabw % advance to next multiple of \tabw \wd\verbbox=\dimen\verbbox \box\verbbox \starttabbox }% } \endgroup % start the verbatim environment. \def\setupverbatim{% \let\nonarrowing = t% \nonfillstart \tt % easiest (and conventionally used) font for verbatim % The \leavevmode here is for blank lines. Otherwise, we would % never \starttabox and the \egroup would end verbatim mode. \def\par{\leavevmode\egroup\box\verbbox\endgraf}% \tabexpand \setupmarkupstyle{verbatim}% % Respect line breaks, % print special symbols as themselves, and % make each space count. % Must do in this order: \obeylines \uncatcodespecials \sepspaces \everypar{\starttabbox}% } % Do the @verb magic: verbatim text is quoted by unique % delimiter characters. Before first delimiter expect a % right brace, after last delimiter expect closing brace: % % \def\doverb'{'#1'}'{#1} % % [Knuth] p. 382; only eat outer {} \begingroup \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next] \endgroup % \def\verb{\begingroup\setupverb\doverb} % % % Do the @verbatim magic: define the macro \doverbatim so that % the (first) argument ends when '@end verbatim' is reached, ie: % % \def\doverbatim#1@end verbatim{#1} % % For Texinfo it's a lot easier than for LaTeX, % because texinfo's \verbatim doesn't stop at '\end{verbatim}': % we need not redefine '\', '{' and '}'. % % Inspired by LaTeX's verbatim command set [latex.ltx] % \begingroup \catcode`\ =\active \obeylines % % ignore everything up to the first ^^M, that's the newline at the end % of the @verbatim input line itself. Otherwise we get an extra blank % line in the output. \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}% % We really want {...\end verbatim} in the body of the macro, but % without the active space; thus we have to use \xdef and \gobble. \endgroup % \envdef\verbatim{% \setupverbatim\doverbatim } \let\Everbatim = \afterenvbreak % @verbatiminclude FILE - insert text of file in verbatim environment. % \def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude} % \def\doverbatiminclude#1{% {% \makevalueexpandable \setupverbatim \indexnofonts % Allow `@@' and other weird things in file names. \wlog{texinfo.tex: doing @verbatiminclude of #1^^J}% \input #1 \afterenvbreak }% } % @copying ... @end copying. % Save the text away for @insertcopying later. % % We save the uninterpreted tokens, rather than creating a box. % Saving the text in a box would be much easier, but then all the % typesetting commands (@smallbook, font changes, etc.) have to be done % beforehand -- and a) we want @copying to be done first in the source % file; b) letting users define the frontmatter in as flexible order as % possible is very desirable. % \def\copying{\checkenv{}\begingroup\scanargctxt\docopying} \def\docopying#1@end copying{\endgroup\def\copyingtext{#1}} % \def\insertcopying{% \begingroup \parindent = 0pt % paragraph indentation looks wrong on title page \scanexp\copyingtext \endgroup } \message{defuns,} % @defun etc. \newskip\defbodyindent \defbodyindent=.4in \newskip\defargsindent \defargsindent=50pt \newskip\deflastargmargin \deflastargmargin=18pt \newcount\defunpenalty % Start the processing of @deffn: \def\startdefun{% \ifnum\lastpenalty<10000 \medbreak \defunpenalty=10003 % Will keep this @deffn together with the % following @def command, see below. \else % If there are two @def commands in a row, we'll have a \nobreak, % which is there to keep the function description together with its % header. But if there's nothing but headers, we need to allow a % break somewhere. Check specifically for penalty 10002, inserted % by \printdefunline, instead of 10000, since the sectioning % commands also insert a nobreak penalty, and we don't want to allow % a break between a section heading and a defun. % % As a further refinement, we avoid "club" headers by signalling % with penalty of 10003 after the very first @deffn in the % sequence (see above), and penalty of 10002 after any following % @def command. \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi % % Similarly, after a section heading, do not allow a break. % But do insert the glue. \medskip % preceded by discardable penalty, so not a breakpoint \fi % \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent } \def\dodefunx#1{% % First, check whether we are in the right environment: \checkenv#1% % % As above, allow line break if we have multiple x headers in a row. % It's not a great place, though. \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi % % And now, it's time to reuse the body of the original defun: \expandafter\gobbledefun#1% } \def\gobbledefun#1\startdefun{} % \printdefunline \deffnheader{text} % \def\printdefunline#1#2{% \begingroup % call \deffnheader: #1#2 \endheader % common ending: \interlinepenalty = 10000 \advance\rightskip by 0pt plus 1fil\relax \endgraf \nobreak\vskip -\parskip \penalty\defunpenalty % signal to \startdefun and \dodefunx % Some of the @defun-type tags do not enable magic parentheses, % rendering the following check redundant. But we don't optimize. \checkparencounts \endgroup } \def\Edefun{\endgraf\medbreak} % \makedefun{deffn} creates \deffn, \deffnx and \Edeffn; % the only thing remaining is to define \deffnheader. % \def\makedefun#1{% \expandafter\let\csname E#1\endcsname = \Edefun \edef\temp{\noexpand\domakedefun \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}% \temp } % \domakedefun \deffn \deffnx \deffnheader % % Define \deffn and \deffnx, without parameters. % \deffnheader has to be defined explicitly. % \def\domakedefun#1#2#3{% \envdef#1{% \startdefun \doingtypefnfalse % distinguish typed functions from all else \parseargusing\activeparens{\printdefunline#3}% }% \def#2{\dodefunx#1}% \def#3% } \newif\ifdoingtypefn % doing typed function? \newif\ifrettypeownline % typeset return type on its own line? % @deftypefnnewline on|off says whether the return type of typed functions % are printed on their own line. This affects @deftypefn, @deftypefun, % @deftypeop, and @deftypemethod. % \parseargdef\deftypefnnewline{% \def\temp{#1}% \ifx\temp\onword \expandafter\let\csname SETtxideftypefnnl\endcsname = \empty \else\ifx\temp\offword \expandafter\let\csname SETtxideftypefnnl\endcsname = \relax \else \errhelp = \EMsimple \errmessage{Unknown @txideftypefnnl value `\temp', must be on|off}% \fi\fi } % Untyped functions: % @deffn category name args \makedefun{deffn}{\deffngeneral{}} % @deffn category class name args \makedefun{defop}#1 {\defopon{#1\ \putwordon}} % \defopon {category on}class name args \def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } % \deffngeneral {subind}category name args % \def\deffngeneral#1#2 #3 #4\endheader{% % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}. \dosubind{fn}{\code{#3}}{#1}% \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}% } % Typed functions: % @deftypefn category type name args \makedefun{deftypefn}{\deftypefngeneral{}} % @deftypeop category class type name args \makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}} % \deftypeopon {category on}class type name args \def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } % \deftypefngeneral {subind}category type name args % \def\deftypefngeneral#1#2 #3 #4 #5\endheader{% \dosubind{fn}{\code{#4}}{#1}% \doingtypefntrue \defname{#2}{#3}{#4}\defunargs{#5\unskip}% } % Typed variables: % @deftypevr category type var args \makedefun{deftypevr}{\deftypecvgeneral{}} % @deftypecv category class type var args \makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}} % \deftypecvof {category of}class type var args \def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} } % \deftypecvgeneral {subind}category type var args % \def\deftypecvgeneral#1#2 #3 #4 #5\endheader{% \dosubind{vr}{\code{#4}}{#1}% \defname{#2}{#3}{#4}\defunargs{#5\unskip}% } % Untyped variables: % @defvr category var args \makedefun{defvr}#1 {\deftypevrheader{#1} {} } % @defcv category class var args \makedefun{defcv}#1 {\defcvof{#1\ \putwordof}} % \defcvof {category of}class var args \def\defcvof#1#2 {\deftypecvof{#1}#2 {} } % Types: % @deftp category name args \makedefun{deftp}#1 #2 #3\endheader{% \doind{tp}{\code{#2}}% \defname{#1}{}{#2}\defunargs{#3\unskip}% } % Remaining @defun-like shortcuts: \makedefun{defun}{\deffnheader{\putwordDeffunc} } \makedefun{defmac}{\deffnheader{\putwordDefmac} } \makedefun{defspec}{\deffnheader{\putwordDefspec} } \makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} } \makedefun{defvar}{\defvrheader{\putwordDefvar} } \makedefun{defopt}{\defvrheader{\putwordDefopt} } \makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} } \makedefun{defmethod}{\defopon\putwordMethodon} \makedefun{deftypemethod}{\deftypeopon\putwordMethodon} \makedefun{defivar}{\defcvof\putwordInstanceVariableof} \makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof} % \defname, which formats the name of the @def (not the args). % #1 is the category, such as "Function". % #2 is the return type, if any. % #3 is the function name. % % We are followed by (but not passed) the arguments, if any. % \def\defname#1#2#3{% \par % Get the values of \leftskip and \rightskip as they were outside the @def... \advance\leftskip by -\defbodyindent % % Determine if we are typesetting the return type of a typed function % on a line by itself. \rettypeownlinefalse \ifdoingtypefn % doing a typed function specifically? % then check user option for putting return type on its own line: \expandafter\ifx\csname SETtxideftypefnnl\endcsname\relax \else \rettypeownlinetrue \fi \fi % % How we'll format the category name. Putting it in brackets helps % distinguish it from the body text that may end up on the next line % just below it. \def\temp{#1}% \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi} % % Figure out line sizes for the paragraph shape. We'll always have at % least two. \tempnum = 2 % % The first line needs space for \box0; but if \rightskip is nonzero, % we need only space for the part of \box0 which exceeds it: \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip % % If doing a return type on its own line, we'll have another line. \ifrettypeownline \advance\tempnum by 1 \def\maybeshapeline{0in \hsize}% \else \def\maybeshapeline{}% \fi % % The continuations: \dimen2=\hsize \advance\dimen2 by -\defargsindent % % The final paragraph shape: \parshape \tempnum 0in \dimen0 \maybeshapeline \defargsindent \dimen2 % % Put the category name at the right margin. \noindent \hbox to 0pt{% \hfil\box0 \kern-\hsize % \hsize has to be shortened this way: \kern\leftskip % Intentionally do not respect \rightskip, since we need the space. }% % % Allow all lines to be underfull without complaint: \tolerance=10000 \hbadness=10000 \exdentamount=\defbodyindent {% % defun fonts. We use typewriter by default (used to be bold) because: % . we're printing identifiers, they should be in tt in principle. % . in languages with many accents, such as Czech or French, it's % common to leave accents off identifiers. The result looks ok in % tt, but exceedingly strange in rm. % . we don't want -- and --- to be treated as ligatures. % . this still does not fix the ?` and !` ligatures, but so far no % one has made identifiers using them :). \df \tt \def\temp{#2}% text of the return type \ifx\temp\empty\else \tclose{\temp}% typeset the return type \ifrettypeownline % put return type on its own line; prohibit line break following: \hfil\vadjust{\nobreak}\break \else \space % type on same line, so just followed by a space \fi \fi % no return type #3% output function name }% {\rm\enskip}% hskip 0.5 em of \tenrm % \boldbrax % arguments will be output next, if any. } % Print arguments in slanted roman (not ttsl), inconsistently with using % tt for the name. This is because literal text is sometimes needed in % the argument list (groff manual), and ttsl and tt are not very % distinguishable. Prevent hyphenation at `-' chars. % \def\defunargs#1{% % use sl by default (not ttsl), % tt for the names. \df \sl \hyphenchar\font=0 % % On the other hand, if an argument has two dashes (for instance), we % want a way to get ttsl. We used to recommend @var for that, so % leave the code in, but it's strange for @var to lead to typewriter. % Nowadays we recommend @code, since the difference between a ttsl hyphen % and a tt hyphen is pretty tiny. @code also disables ?` !`. \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}% #1% \sl\hyphenchar\font=45 } % We want ()&[] to print specially on the defun line. % \def\activeparens{% \catcode`\(=\active \catcode`\)=\active \catcode`\[=\active \catcode`\]=\active \catcode`\&=\active } % Make control sequences which act like normal parenthesis chars. \let\lparen = ( \let\rparen = ) % Be sure that we always have a definition for `(', etc. For example, % if the fn name has parens in it, \boldbrax will not be in effect yet, % so TeX would otherwise complain about undefined control sequence. { \activeparens \global\let(=\lparen \global\let)=\rparen \global\let[=\lbrack \global\let]=\rbrack \global\let& = \& \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} \gdef\magicamp{\let&=\amprm} } \newcount\parencount % If we encounter &foo, then turn on ()-hacking afterwards \newif\ifampseen \def\amprm#1 {\ampseentrue{\bf\ }} \def\parenfont{% \ifampseen % At the first level, print parens in roman, % otherwise use the default font. \ifnum \parencount=1 \rm \fi \else % The \sf parens (in \boldbrax) actually are a little bolder than % the contained text. This is especially needed for [ and ] . \sf \fi } \def\infirstlevel#1{% \ifampseen \ifnum\parencount=1 #1% \fi \fi } \def\bfafterword#1 {#1 \bf} \def\opnr{% \global\advance\parencount by 1 {\parenfont(}% \infirstlevel \bfafterword } \def\clnr{% {\parenfont)}% \infirstlevel \sl \global\advance\parencount by -1 } \newcount\brackcount \def\lbrb{% \global\advance\brackcount by 1 {\bf[}% } \def\rbrb{% {\bf]}% \global\advance\brackcount by -1 } \def\checkparencounts{% \ifnum\parencount=0 \else \badparencount \fi \ifnum\brackcount=0 \else \badbrackcount \fi } % these should not use \errmessage; the glibc manual, at least, actually % has such constructs (when documenting function pointers). \def\badparencount{% \message{Warning: unbalanced parentheses in @def...}% \global\parencount=0 } \def\badbrackcount{% \message{Warning: unbalanced square brackets in @def...}% \global\brackcount=0 } \message{macros,} % @macro. % To do this right we need a feature of e-TeX, \scantokens, % which we arrange to emulate with a temporary file in ordinary TeX. \ifx\eTeXversion\thisisundefined \newwrite\macscribble \def\scantokens#1{% \toks0={#1}% \immediate\openout\macscribble=\jobname.tmp \immediate\write\macscribble{\the\toks0}% \immediate\closeout\macscribble \input \jobname.tmp } \fi \def\scanmacro#1{\begingroup \newlinechar`\^^M \let\xeatspaces\eatspaces % % Undo catcode changes of \startcontents and \doprintindex % When called from @insertcopying or (short)caption, we need active % backslash to get it printed correctly. Previously, we had % \catcode`\\=\other instead. We'll see whether a problem appears % with macro expansion. --kasal, 19aug04 \catcode`\@=0 \catcode`\\=\active \escapechar=`\@ % % ... and for \example: \spaceisspace % % The \empty here causes a following catcode 5 newline to be eaten as % part of reading whitespace after a control sequence. It does not % eat a catcode 13 newline. There's no good way to handle the two % cases (untried: maybe e-TeX's \everyeof could help, though plain TeX % would then have different behavior). See the Macro Details node in % the manual for the workaround we recommend for macros and % line-oriented commands. % \scantokens{#1\empty}% \endgroup} \def\scanexp#1{% \edef\temp{\noexpand\scanmacro{#1}}% \temp } \newcount\paramno % Count of parameters \newtoks\macname % Macro name \newif\ifrecursive % Is it recursive? % List of all defined macros in the form % \definedummyword\macro1\definedummyword\macro2... % Currently is also contains all @aliases; the list can be split % if there is a need. \def\macrolist{} % Add the macro to \macrolist \def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname} \def\addtomacrolistxxx#1{% \toks0 = \expandafter{\macrolist\definedummyword#1}% \xdef\macrolist{\the\toks0}% } % Utility routines. % This does \let #1 = #2, with \csnames; that is, % \let \csname#1\endcsname = \csname#2\endcsname % (except of course we have to play expansion games). % \def\cslet#1#2{% \expandafter\let \csname#1\expandafter\endcsname \csname#2\endcsname } % Trim leading and trailing spaces off a string. % Concepts from aro-bend problem 15 (see CTAN). {\catcode`\@=11 \gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} \gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} \gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} \def\unbrace#1{#1} \unbrace{\gdef\trim@@@ #1 } #2@{#1} } % Trim a single trailing ^^M off a string. {\catcode`\^^M=\other \catcode`\Q=3% \gdef\eatcr #1{\eatcra #1Q^^MQ}% \gdef\eatcra#1^^MQ{\eatcrb#1Q}% \gdef\eatcrb#1Q#2Q{#1}% } % Macro bodies are absorbed as an argument in a context where % all characters are catcode 10, 11 or 12, except \ which is active % (as in normal texinfo). It is necessary to change the definition of \ % to recognize macro arguments; this is the job of \mbodybackslash. % % Non-ASCII encodings make 8-bit characters active, so un-activate % them to avoid their expansion. Must do this non-globally, to % confine the change to the current group. % % It's necessary to have hard CRs when the macro is executed. This is % done by making ^^M (\endlinechar) catcode 12 when reading the macro % body, and then making it the \newlinechar in \scanmacro. % \def\scanctxt{% used as subroutine \catcode`\"=\other \catcode`\+=\other \catcode`\<=\other \catcode`\>=\other \catcode`\@=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other \catcode`\~=\other \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi } \def\scanargctxt{% used for copying and captions, not macros. \scanctxt \catcode`\\=\other \catcode`\^^M=\other } \def\macrobodyctxt{% used for @macro definitions \scanctxt \catcode`\{=\other \catcode`\}=\other \catcode`\^^M=\other \usembodybackslash } \def\macroargctxt{% used when scanning invocations \scanctxt \catcode`\\=0 } % why catcode 0 for \ in the above? To recognize \\ \{ \} as "escapes" % for the single characters \ { }. Thus, we end up with the "commands" % that would be written @\ @{ @} in a Texinfo document. % % We already have @{ and @}. For @\, we define it here, and only for % this purpose, to produce a typewriter backslash (so, the @\ that we % define for @math can't be used with @macro calls): % \def\\{\normalbackslash}% % % We would like to do this for \, too, since that is what makeinfo does. % But it is not possible, because Texinfo already has a command @, for a % cedilla accent. Documents must use @comma{} instead. % % \anythingelse will almost certainly be an error of some kind. % \mbodybackslash is the definition of \ in @macro bodies. % It maps \foo\ => \csname macarg.foo\endcsname => #N % where N is the macro parameter number. % We define \csname macarg.\endcsname to be \realbackslash, so % \\ in macro replacement text gets you a backslash. % {\catcode`@=0 @catcode`@\=@active @gdef@usembodybackslash{@let\=@mbodybackslash} @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} } \expandafter\def\csname macarg.\endcsname{\realbackslash} \def\margbackslash#1{\char`\#1 } \def\macro{\recursivefalse\parsearg\macroxxx} \def\rmacro{\recursivetrue\parsearg\macroxxx} \def\macroxxx#1{% \getargs{#1}% now \macname is the macname and \argl the arglist \ifx\argl\empty % no arguments \paramno=0\relax \else \expandafter\parsemargdef \argl;% \if\paramno>256\relax \ifx\eTeXversion\thisisundefined \errhelp = \EMsimple \errmessage{You need eTeX to compile a file with macros with more than 256 arguments} \fi \fi \fi \if1\csname ismacro.\the\macname\endcsname \message{Warning: redefining \the\macname}% \else \expandafter\ifx\csname \the\macname\endcsname \relax \else \errmessage{Macro name \the\macname\space already defined}\fi \global\cslet{macsave.\the\macname}{\the\macname}% \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% \addtomacrolist{\the\macname}% \fi \begingroup \macrobodyctxt \ifrecursive \expandafter\parsermacbody \else \expandafter\parsemacbody \fi} \parseargdef\unmacro{% \if1\csname ismacro.#1\endcsname \global\cslet{#1}{macsave.#1}% \global\expandafter\let \csname ismacro.#1\endcsname=0% % Remove the macro name from \macrolist: \begingroup \expandafter\let\csname#1\endcsname \relax \let\definedummyword\unmacrodo \xdef\macrolist{\macrolist}% \endgroup \else \errmessage{Macro #1 not defined}% \fi } % Called by \do from \dounmacro on each macro. The idea is to omit any % macro definitions that have been changed to \relax. % \def\unmacrodo#1{% \ifx #1\relax % remove this \else \noexpand\definedummyword \noexpand#1% \fi } % This makes use of the obscure feature that if the last token of a % is #, then the preceding argument is delimited by % an opening brace, and that opening brace is not consumed. \def\getargs#1{\getargsxxx#1{}} \def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} \def\getmacname#1 #2\relax{\macname={#1}} \def\getmacargs#1{\def\argl{#1}} % For macro processing make @ a letter so that we can make Texinfo private macro names. \edef\texiatcatcode{\the\catcode`\@} \catcode `@=11\relax % Parse the optional {params} list. Set up \paramno and \paramlist % so \defmacro knows what to do. Define \macarg.BLAH for each BLAH % in the params list to some hook where the argument si to be expanded. If % there are less than 10 arguments that hook is to be replaced by ##N where N % is the position in that list, that is to say the macro arguments are to be % defined `a la TeX in the macro body. % % That gets used by \mbodybackslash (above). % % We need to get `macro parameter char #' into several definitions. % The technique used is stolen from LaTeX: let \hash be something % unexpandable, insert that wherever you need a #, and then redefine % it to # just before using the token list produced. % % The same technique is used to protect \eatspaces till just before % the macro is used. % % If there are 10 or more arguments, a different technique is used, where the % hook remains in the body, and when macro is to be expanded the body is % processed again to replace the arguments. % % In that case, the hook is \the\toks N-1, and we simply set \toks N-1 to the % argument N value and then \edef the body (nothing else will expand because of % the catcode regime underwhich the body was input). % % If you compile with TeX (not eTeX), and you have macros with 10 or more % arguments, you need that no macro has more than 256 arguments, otherwise an % error is produced. \def\parsemargdef#1;{% \paramno=0\def\paramlist{}% \let\hash\relax \let\xeatspaces\relax \parsemargdefxxx#1,;,% % In case that there are 10 or more arguments we parse again the arguments % list to set new definitions for the \macarg.BLAH macros corresponding to % each BLAH argument. It was anyhow needed to parse already once this list % in order to count the arguments, and as macros with at most 9 arguments % are by far more frequent than macro with 10 or more arguments, defining % twice the \macarg.BLAH macros does not cost too much processing power. \ifnum\paramno<10\relax\else \paramno0\relax \parsemmanyargdef@@#1,;,% 10 or more arguments \fi } \def\parsemargdefxxx#1,{% \if#1;\let\next=\relax \else \let\next=\parsemargdefxxx \advance\paramno by 1 \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname {\xeatspaces{\hash\the\paramno}}% \edef\paramlist{\paramlist\hash\the\paramno,}% \fi\next} \def\parsemmanyargdef@@#1,{% \if#1;\let\next=\relax \else \let\next=\parsemmanyargdef@@ \edef\tempb{\eatspaces{#1}}% \expandafter\def\expandafter\tempa \expandafter{\csname macarg.\tempb\endcsname}% % Note that we need some extra \noexpand\noexpand, this is because we % don't want \the to be expanded in the \parsermacbody as it uses an % \xdef . \expandafter\edef\tempa {\noexpand\noexpand\noexpand\the\toks\the\paramno}% \advance\paramno by 1\relax \fi\next} % These two commands read recursive and nonrecursive macro bodies. % (They're different since rec and nonrec macros end differently.) % \catcode `\@\texiatcatcode \long\def\parsemacbody#1@end macro% {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% \long\def\parsermacbody#1@end rmacro% {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% \catcode `\@=11\relax \let\endargs@\relax \let\nil@\relax \def\nilm@{\nil@}% \long\def\nillm@{\nil@}% % This macro is expanded during the Texinfo macro expansion, not during its % definition. It gets all the arguments values and assigns them to macros % macarg.ARGNAME % % #1 is the macro name % #2 is the list of argument names % #3 is the list of argument values \def\getargvals@#1#2#3{% \def\macargdeflist@{}% \def\saveparamlist@{#2}% Need to keep a copy for parameter expansion. \def\paramlist{#2,\nil@}% \def\macroname{#1}% \begingroup \macroargctxt \def\argvaluelist{#3,\nil@}% \def\@tempa{#3}% \ifx\@tempa\empty \setemptyargvalues@ \else \getargvals@@ \fi } % \def\getargvals@@{% \ifx\paramlist\nilm@ % Some sanity check needed here that \argvaluelist is also empty. \ifx\argvaluelist\nillm@ \else \errhelp = \EMsimple \errmessage{Too many arguments in macro `\macroname'!}% \fi \let\next\macargexpandinbody@ \else \ifx\argvaluelist\nillm@ % No more arguments values passed to macro. Set remaining named-arg % macros to empty. \let\next\setemptyargvalues@ \else % pop current arg name into \@tempb \def\@tempa##1{\pop@{\@tempb}{\paramlist}##1\endargs@}% \expandafter\@tempa\expandafter{\paramlist}% % pop current argument value into \@tempc \def\@tempa##1{\longpop@{\@tempc}{\argvaluelist}##1\endargs@}% \expandafter\@tempa\expandafter{\argvaluelist}% % Here \@tempb is the current arg name and \@tempc is the current arg value. % First place the new argument macro definition into \@tempd \expandafter\macname\expandafter{\@tempc}% \expandafter\let\csname macarg.\@tempb\endcsname\relax \expandafter\def\expandafter\@tempe\expandafter{% \csname macarg.\@tempb\endcsname}% \edef\@tempd{\long\def\@tempe{\the\macname}}% \push@\@tempd\macargdeflist@ \let\next\getargvals@@ \fi \fi \next } \def\push@#1#2{% \expandafter\expandafter\expandafter\def \expandafter\expandafter\expandafter#2% \expandafter\expandafter\expandafter{% \expandafter#1#2}% } % Replace arguments by their values in the macro body, and place the result % in macro \@tempa \def\macvalstoargs@{% % To do this we use the property that token registers that are \the'ed % within an \edef expand only once. So we are going to place all argument % values into respective token registers. % % First we save the token context, and initialize argument numbering. \begingroup \paramno0\relax % Then, for each argument number #N, we place the corresponding argument % value into a new token list register \toks#N \expandafter\putargsintokens@\saveparamlist@,;,% % Then, we expand the body so that argument are replaced by their % values. The trick for values not to be expanded themselves is that they % are within tokens and that tokens expand only once in an \edef . \edef\@tempc{\csname mac.\macroname .body\endcsname}% % Now we restore the token stack pointer to free the token list registers % which we have used, but we make sure that expanded body is saved after % group. \expandafter \endgroup \expandafter\def\expandafter\@tempa\expandafter{\@tempc}% } \def\macargexpandinbody@{% %% Define the named-macro outside of this group and then close this group. \expandafter \endgroup \macargdeflist@ % First the replace in body the macro arguments by their values, the result % is in \@tempa . \macvalstoargs@ % Then we point at the \norecurse or \gobble (for recursive) macro value % with \@tempb . \expandafter\let\expandafter\@tempb\csname mac.\macroname .recurse\endcsname % Depending on whether it is recursive or not, we need some tailing % \egroup . \ifx\@tempb\gobble \let\@tempc\relax \else \let\@tempc\egroup \fi % And now we do the real job: \edef\@tempd{\noexpand\@tempb{\macroname}\noexpand\scanmacro{\@tempa}\@tempc}% \@tempd } \def\putargsintokens@#1,{% \if#1;\let\next\relax \else \let\next\putargsintokens@ % First we allocate the new token list register, and give it a temporary % alias \@tempb . \toksdef\@tempb\the\paramno % Then we place the argument value into that token list register. \expandafter\let\expandafter\@tempa\csname macarg.#1\endcsname \expandafter\@tempb\expandafter{\@tempa}% \advance\paramno by 1\relax \fi \next } % Save the token stack pointer into macro #1 \def\texisavetoksstackpoint#1{\edef#1{\the\@cclvi}} % Restore the token stack pointer from number in macro #1 \def\texirestoretoksstackpoint#1{\expandafter\mathchardef\expandafter\@cclvi#1\relax} % newtoks that can be used non \outer . \def\texinonouternewtoks{\alloc@ 5\toks \toksdef \@cclvi} % Tailing missing arguments are set to empty \def\setemptyargvalues@{% \ifx\paramlist\nilm@ \let\next\macargexpandinbody@ \else \expandafter\setemptyargvaluesparser@\paramlist\endargs@ \let\next\setemptyargvalues@ \fi \next } \def\setemptyargvaluesparser@#1,#2\endargs@{% \expandafter\def\expandafter\@tempa\expandafter{% \expandafter\def\csname macarg.#1\endcsname{}}% \push@\@tempa\macargdeflist@ \def\paramlist{#2}% } % #1 is the element target macro % #2 is the list macro % #3,#4\endargs@ is the list value \def\pop@#1#2#3,#4\endargs@{% \def#1{#3}% \def#2{#4}% } \long\def\longpop@#1#2#3,#4\endargs@{% \long\def#1{#3}% \long\def#2{#4}% } % This defines a Texinfo @macro. There are eight cases: recursive and % nonrecursive macros of zero, one, up to nine, and many arguments. % Much magic with \expandafter here. % \xdef is used so that macro definitions will survive the file % they're defined in; @include reads the file inside a group. % \def\defmacro{% \let\hash=##% convert placeholders to macro parameter chars \ifrecursive \ifcase\paramno % 0 \expandafter\xdef\csname\the\macname\endcsname{% \noexpand\scanmacro{\temp}}% \or % 1 \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \noexpand\braceorline \expandafter\noexpand\csname\the\macname xxx\endcsname}% \expandafter\xdef\csname\the\macname xxx\endcsname##1{% \egroup\noexpand\scanmacro{\temp}}% \else \ifnum\paramno<10\relax % at most 9 \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \noexpand\csname\the\macname xx\endcsname}% \expandafter\xdef\csname\the\macname xx\endcsname##1{% \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% \expandafter\expandafter \expandafter\xdef \expandafter\expandafter \csname\the\macname xxx\endcsname \paramlist{\egroup\noexpand\scanmacro{\temp}}% \else % 10 or more \expandafter\xdef\csname\the\macname\endcsname{% \noexpand\getargvals@{\the\macname}{\argl}% }% \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\gobble \fi \fi \else \ifcase\paramno % 0 \expandafter\xdef\csname\the\macname\endcsname{% \noexpand\norecurse{\the\macname}% \noexpand\scanmacro{\temp}\egroup}% \or % 1 \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \noexpand\braceorline \expandafter\noexpand\csname\the\macname xxx\endcsname}% \expandafter\xdef\csname\the\macname xxx\endcsname##1{% \egroup \noexpand\norecurse{\the\macname}% \noexpand\scanmacro{\temp}\egroup}% \else % at most 9 \ifnum\paramno<10\relax \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \expandafter\noexpand\csname\the\macname xx\endcsname}% \expandafter\xdef\csname\the\macname xx\endcsname##1{% \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% \expandafter\expandafter \expandafter\xdef \expandafter\expandafter \csname\the\macname xxx\endcsname \paramlist{% \egroup \noexpand\norecurse{\the\macname}% \noexpand\scanmacro{\temp}\egroup}% \else % 10 or more: \expandafter\xdef\csname\the\macname\endcsname{% \noexpand\getargvals@{\the\macname}{\argl}% }% \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\norecurse \fi \fi \fi} \catcode `\@\texiatcatcode\relax \def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} % \braceorline decides whether the next nonwhitespace character is a % {. If so it reads up to the closing }, if not, it reads the whole % line. Whatever was read is then fed to the next control sequence % as an argument (by \parsebrace or \parsearg). % \def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx} \def\braceorlinexxx{% \ifx\nchar\bgroup\else \expandafter\parsearg \fi \macnamexxx} % @alias. % We need some trickery to remove the optional spaces around the equal % sign. Make them active and then expand them all to nothing. % \def\alias{\parseargusing\obeyspaces\aliasxxx} \def\aliasxxx #1{\aliasyyy#1\relax} \def\aliasyyy #1=#2\relax{% {% \expandafter\let\obeyedspace=\empty \addtomacrolist{#1}% \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}% }% \next } \message{cross references,} \newwrite\auxfile \newif\ifhavexrefs % True if xref values are known. \newif\ifwarnedxrefs % True if we warned once that they aren't known. % @inforef is relatively simple. \def\inforef #1{\inforefzzz #1,,,,**} \def\inforefzzz #1,#2,#3,#4**{% \putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, node \samp{\ignorespaces#1{}}} % @node's only job in TeX is to define \lastnode, which is used in % cross-references. The @node line might or might not have commas, and % might or might not have spaces before the first comma, like: % @node foo , bar , ... % We don't want such trailing spaces in the node name. % \parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse} % % also remove a trailing comma, in case of something like this: % @node Help-Cross, , , Cross-refs \def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse} \def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}} \let\nwnode=\node \let\lastnode=\empty % Write a cross-reference definition for the current node. #1 is the % type (Ynumbered, Yappendix, Ynothing). % \def\donoderef#1{% \ifx\lastnode\empty\else \setref{\lastnode}{#1}% \global\let\lastnode=\empty \fi } % @anchor{NAME} -- define xref target at arbitrary point. % \newcount\savesfregister % \def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} \def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} \def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} % \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an % anchor), which consists of three parts: % 1) NAME-title - the current sectioning name taken from \lastsection, % or the anchor name. % 2) NAME-snt - section number and type, passed as the SNT arg, or % empty for anchors. % 3) NAME-pg - the page number. % % This is called from \donoderef, \anchor, and \dofloat. In the case of % floats, there is an additional part, which is not written here: % 4) NAME-lof - the text as it should appear in a @listoffloats. % \def\setref#1#2{% \pdfmkdest{#1}% \iflinks {% \atdummies % preserve commands, but don't expand them \edef\writexrdef##1##2{% \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef ##1}{##2}}% these are parameters of \writexrdef }% \toks0 = \expandafter{\lastsection}% \immediate \writexrdef{title}{\the\toks0 }% \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc. \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout }% \fi } % @xrefautosectiontitle on|off says whether @section(ing) names are used % automatically in xrefs, if the third arg is not explicitly specified. % This was provided as a "secret" @set xref-automatic-section-title % variable, now it's official. % \parseargdef\xrefautomaticsectiontitle{% \def\temp{#1}% \ifx\temp\onword \expandafter\let\csname SETxref-automatic-section-title\endcsname = \empty \else\ifx\temp\offword \expandafter\let\csname SETxref-automatic-section-title\endcsname = \relax \else \errhelp = \EMsimple \errmessage{Unknown @xrefautomaticsectiontitle value `\temp', must be on|off}% \fi\fi } % % @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is % the node name, #2 the name of the Info cross-reference, #3 the printed % node name, #4 the name of the Info file, #5 the name of the printed % manual. All but the node name can be omitted. % \def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} \def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} \def\ref#1{\xrefX[#1,,,,,,,]} % \newbox\toprefbox \newbox\printedrefnamebox \newbox\infofilenamebox \newbox\printedmanualbox % \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup \unsepspaces % % Get args without leading/trailing spaces. \def\printedrefname{\ignorespaces #3}% \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}% % \def\infofilename{\ignorespaces #4}% \setbox\infofilenamebox = \hbox{\infofilename\unskip}% % \def\printedmanual{\ignorespaces #5}% \setbox\printedmanualbox = \hbox{\printedmanual\unskip}% % % If the printed reference name (arg #3) was not explicitly given in % the @xref, figure out what we want to use. \ifdim \wd\printedrefnamebox = 0pt % No printed node name was explicitly given. \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax % Not auto section-title: use node name inside the square brackets. \def\printedrefname{\ignorespaces #1}% \else % Auto section-title: use chapter/section title inside % the square brackets if we have it. \ifdim \wd\printedmanualbox > 0pt % It is in another manual, so we don't have it; use node name. \def\printedrefname{\ignorespaces #1}% \else \ifhavexrefs % We (should) know the real title if we have the xref values. \def\printedrefname{\refx{#1-title}{}}% \else % Otherwise just copy the Info node name. \def\printedrefname{\ignorespaces #1}% \fi% \fi \fi \fi % % Make link in pdf output. \ifpdf {\indexnofonts \turnoffactive \makevalueexpandable % This expands tokens, so do it after making catcode changes, so _ % etc. don't get their TeX definitions. This ignores all spaces in % #4, including (wrongly) those in the middle of the filename. \getfilename{#4}% % % This (wrongly) does not take account of leading or trailing % spaces in #1, which should be ignored. \edef\pdfxrefdest{#1}% \ifx\pdfxrefdest\empty \def\pdfxrefdest{Top}% no empty targets \else \txiescapepdf\pdfxrefdest % escape PDF special chars \fi % \leavevmode \startlink attr{/Border [0 0 0]}% \ifnum\filenamelength>0 goto file{\the\filename.pdf} name{\pdfxrefdest}% \else goto name{\pdfmkpgn{\pdfxrefdest}}% \fi }% \setcolor{\linkcolor}% \fi % % Float references are printed completely differently: "Figure 1.2" % instead of "[somenode], p.3". We distinguish them by the % LABEL-title being set to a magic string. {% % Have to otherify everything special to allow the \csname to % include an _ in the xref name, etc. \indexnofonts \turnoffactive \expandafter\global\expandafter\let\expandafter\Xthisreftitle \csname XR#1-title\endcsname }% \iffloat\Xthisreftitle % If the user specified the print name (third arg) to the ref, % print it instead of our usual "Figure 1.2". \ifdim\wd\printedrefnamebox = 0pt \refx{#1-snt}{}% \else \printedrefname \fi % % If the user also gave the printed manual name (fifth arg), append % "in MANUALNAME". \ifdim \wd\printedmanualbox > 0pt \space \putwordin{} \cite{\printedmanual}% \fi \else % node/anchor (non-float) references. % % If we use \unhbox to print the node names, TeX does not insert % empty discretionaries after hyphens, which means that it will not % find a line break at a hyphen in a node names. Since some manuals % are best written with fairly long node names, containing hyphens, % this is a loss. Therefore, we give the text of the node name % again, so it is as if TeX is seeing it for the first time. % \ifdim \wd\printedmanualbox > 0pt % Cross-manual reference with a printed manual name. % \crossmanualxref{\cite{\printedmanual\unskip}}% % \else\ifdim \wd\infofilenamebox > 0pt % Cross-manual reference with only an info filename (arg 4), no % printed manual name (arg 5). This is essentially the same as % the case above; we output the filename, since we have nothing else. % \crossmanualxref{\code{\infofilename\unskip}}% % \else % Reference within this manual. % % _ (for example) has to be the character _ for the purposes of the % control sequence corresponding to the node, but it has to expand % into the usual \leavevmode...\vrule stuff for purposes of % printing. So we \turnoffactive for the \refx-snt, back on for the % printing, back off for the \refx-pg. {\turnoffactive % Only output a following space if the -snt ref is nonempty; for % @unnumbered and @anchor, it won't be. \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi }% % output the `[mynode]' via the macro below so it can be overridden. \xrefprintnodename\printedrefname % % But we always want a comma and a space: ,\space % % output the `page 3'. \turnoffactive \putwordpage\tie\refx{#1-pg}{}% \fi\fi \fi \endlink \endgroup} % Output a cross-manual xref to #1. Used just above (twice). % % Only include the text "Section ``foo'' in" if the foo is neither % missing or Top. Thus, @xref{,,,foo,The Foo Manual} outputs simply % "see The Foo Manual", the idea being to refer to the whole manual. % % But, this being TeX, we can't easily compare our node name against the % string "Top" while ignoring the possible spaces before and after in % the input. By adding the arbitrary 7sp below, we make it much less % likely that a real node name would have the same width as "Top" (e.g., % in a monospaced font). Hopefully it will never happen in practice. % % For the same basic reason, we retypeset the "Top" at every % reference, since the current font is indeterminate. % \def\crossmanualxref#1{% \setbox\toprefbox = \hbox{Top\kern7sp}% \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}% \ifdim \wd2 > 7sp % nonempty? \ifdim \wd2 = \wd\toprefbox \else % same as Top? \putwordSection{} ``\printedrefname'' \putwordin{}\space \fi \fi #1% } % This macro is called from \xrefX for the `[nodename]' part of xref % output. It's a separate macro only so it can be changed more easily, % since square brackets don't work well in some documents. Particularly % one that Bob is working on :). % \def\xrefprintnodename#1{[#1]} % Things referred to by \setref. % \def\Ynothing{} \def\Yomitfromtoc{} \def\Ynumbered{% \ifnum\secno=0 \putwordChapter@tie \the\chapno \else \ifnum\subsecno=0 \putwordSection@tie \the\chapno.\the\secno \else \ifnum\subsubsecno=0 \putwordSection@tie \the\chapno.\the\secno.\the\subsecno \else \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno \fi\fi\fi } \def\Yappendix{% \ifnum\secno=0 \putwordAppendix@tie @char\the\appendixno{}% \else \ifnum\subsecno=0 \putwordSection@tie @char\the\appendixno.\the\secno \else \ifnum\subsubsecno=0 \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno \else \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno \fi\fi\fi } % Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. % If its value is nonempty, SUFFIX is output afterward. % \def\refx#1#2{% {% \indexnofonts \otherbackslash \expandafter\global\expandafter\let\expandafter\thisrefX \csname XR#1\endcsname }% \ifx\thisrefX\relax % If not defined, say something at least. \angleleft un\-de\-fined\angleright \iflinks \ifhavexrefs {\toks0 = {#1}% avoid expansion of possibly-complex value \message{\linenumber Undefined cross reference `\the\toks0'.}}% \else \ifwarnedxrefs\else \global\warnedxrefstrue \message{Cross reference values unknown; you must run TeX again.}% \fi \fi \fi \else % It's defined, so just use it. \thisrefX \fi #2% Output the suffix in any case. } % This is the macro invoked by entries in the aux file. Usually it's % just a \def (we prepend XR to the control sequence name to avoid % collisions). But if this is a float type, we have more work to do. % \def\xrdef#1#2{% {% The node name might contain 8-bit characters, which in our current % implementation are changed to commands like @'e. Don't let these % mess up the control sequence name. \indexnofonts \turnoffactive \xdef\safexrefname{#1}% }% % \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref % % Was that xref control sequence that we just defined for a float? \expandafter\iffloat\csname XR\safexrefname\endcsname % it was a float, and we have the (safe) float type in \iffloattype. \expandafter\let\expandafter\floatlist \csname floatlist\iffloattype\endcsname % % Is this the first time we've seen this float type? \expandafter\ifx\floatlist\relax \toks0 = {\do}% yes, so just \do \else % had it before, so preserve previous elements in list. \toks0 = \expandafter{\floatlist\do}% \fi % % Remember this xref in the control sequence \floatlistFLOATTYPE, % for later use in \listoffloats. \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0 {\safexrefname}}% \fi } % Read the last existing aux file, if any. No error if none exists. % \def\tryauxfile{% \openin 1 \jobname.aux \ifeof 1 \else \readdatafile{aux}% \global\havexrefstrue \fi \closein 1 } \def\setupdatafile{% \catcode`\^^@=\other \catcode`\^^A=\other \catcode`\^^B=\other \catcode`\^^C=\other \catcode`\^^D=\other \catcode`\^^E=\other \catcode`\^^F=\other \catcode`\^^G=\other \catcode`\^^H=\other \catcode`\^^K=\other \catcode`\^^L=\other \catcode`\^^N=\other \catcode`\^^P=\other \catcode`\^^Q=\other \catcode`\^^R=\other \catcode`\^^S=\other \catcode`\^^T=\other \catcode`\^^U=\other \catcode`\^^V=\other \catcode`\^^W=\other \catcode`\^^X=\other \catcode`\^^Z=\other \catcode`\^^[=\other \catcode`\^^\=\other \catcode`\^^]=\other \catcode`\^^^=\other \catcode`\^^_=\other % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc. % in xref tags, i.e., node names. But since ^^e4 notation isn't % supported in the main text, it doesn't seem desirable. Furthermore, % that is not enough: for node names that actually contain a ^ % character, we would end up writing a line like this: 'xrdef {'hat % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first % argument, and \hat is not an expandable control sequence. It could % all be worked out, but why? Either we support ^^ or we don't. % % The other change necessary for this was to define \auxhat: % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter % and then to call \auxhat in \setq. % \catcode`\^=\other % % Special characters. Should be turned off anyway, but... \catcode`\~=\other \catcode`\[=\other \catcode`\]=\other \catcode`\"=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\$=\other \catcode`\#=\other \catcode`\&=\other \catcode`\%=\other \catcode`+=\other % avoid \+ for paranoia even though we've turned it off % % This is to support \ in node names and titles, since the \ % characters end up in a \csname. It's easier than % leaving it active and making its active definition an actual \ % character. What I don't understand is why it works in the *value* % of the xrdef. Seems like it should be a catcode12 \, and that % should not typeset properly. But it works, so I'm moving on for % now. --karl, 15jan04. \catcode`\\=\other % % Make the characters 128-255 be printing characters. {% \count1=128 \def\loop{% \catcode\count1=\other \advance\count1 by 1 \ifnum \count1<256 \loop \fi }% }% % % @ is our escape character in .aux files, and we need braces. \catcode`\{=1 \catcode`\}=2 \catcode`\@=0 } \def\readdatafile#1{% \begingroup \setupdatafile \input\jobname.#1 \endgroup} \message{insertions,} % including footnotes. \newcount \footnoteno % The trailing space in the following definition for supereject is % vital for proper filling; pages come out unaligned when you do a % pagealignmacro call if that space before the closing brace is % removed. (Generally, numeric constants should always be followed by a % space to prevent strange expansion errors.) \def\supereject{\par\penalty -20000\footnoteno =0 } % @footnotestyle is meaningful for Info output only. \let\footnotestyle=\comment {\catcode `\@=11 % % Auto-number footnotes. Otherwise like plain. \gdef\footnote{% \let\indent=\ptexindent \let\noindent=\ptexnoindent \global\advance\footnoteno by \@ne \edef\thisfootno{$^{\the\footnoteno}$}% % % In case the footnote comes at the end of a sentence, preserve the % extra spacing after we do the footnote number. \let\@sf\empty \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi % % Remove inadvertent blank space before typesetting the footnote number. \unskip \thisfootno\@sf \dofootnote }% % Don't bother with the trickery in plain.tex to not require the % footnote text as a parameter. Our footnotes don't need to be so general. % % Oh yes, they do; otherwise, @ifset (and anything else that uses % \parseargline) fails inside footnotes because the tokens are fixed when % the footnote is read. --karl, 16nov96. % \gdef\dofootnote{% \insert\footins\bgroup % We want to typeset this text as a normal paragraph, even if the % footnote reference occurs in (for example) a display environment. % So reset some parameters. \hsize=\pagewidth \interlinepenalty\interfootnotelinepenalty \splittopskip\ht\strutbox % top baseline for broken footnotes \splitmaxdepth\dp\strutbox \floatingpenalty\@MM \leftskip\z@skip \rightskip\z@skip \spaceskip\z@skip \xspaceskip\z@skip \parindent\defaultparindent % \smallfonts \rm % % Because we use hanging indentation in footnotes, a @noindent appears % to exdent this text, so make it be a no-op. makeinfo does not use % hanging indentation so @noindent can still be needed within footnote % text after an @example or the like (not that this is good style). \let\noindent = \relax % % Hang the footnote text off the number. Use \everypar in case the % footnote extends for more than one paragraph. \everypar = {\hang}% \textindent{\thisfootno}% % % Don't crash into the line above the footnote text. Since this % expands into a box, it must come within the paragraph, lest it % provide a place where TeX can split the footnote. \footstrut % % Invoke rest of plain TeX footnote routine. \futurelet\next\fo@t } }%end \catcode `\@=11 % In case a @footnote appears in a vbox, save the footnote text and create % the real \insert just after the vbox finished. Otherwise, the insertion % would be lost. % Similarly, if a @footnote appears inside an alignment, save the footnote % text to a box and make the \insert when a row of the table is finished. % And the same can be done for other insert classes. --kasal, 16nov03. % Replace the \insert primitive by a cheating macro. % Deeper inside, just make sure that the saved insertions are not spilled % out prematurely. % \def\startsavinginserts{% \ifx \insert\ptexinsert \let\insert\saveinsert \else \let\checkinserts\relax \fi } % This \insert replacement works for both \insert\footins{foo} and % \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}. % \def\saveinsert#1{% \edef\next{\noexpand\savetobox \makeSAVEname#1}% \afterassignment\next % swallow the left brace \let\temp = } \def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}} \def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1} \def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi} \def\placesaveins#1{% \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname {\box#1}% } % eat @SAVE -- beware, all of them have catcode \other: { \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials % ;-) \gdef\gobblesave @SAVE{} } % initialization: \def\newsaveins #1{% \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}% \next } \def\newsaveinsX #1{% \csname newbox\endcsname #1% \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts \checksaveins #1}% } % initialize: \let\checkinserts\empty \newsaveins\footins \newsaveins\margin % @image. We use the macros from epsf.tex to support this. % If epsf.tex is not installed and @image is used, we complain. % % Check for and read epsf.tex up front. If we read it only at @image % time, we might be inside a group, and then its definitions would get % undone and the next image would fail. \openin 1 = epsf.tex \ifeof 1 \else % Do not bother showing banner with epsf.tex v2.7k (available in % doc/epsf.tex and on ctan). \def\epsfannounce{\toks0 = }% \input epsf.tex \fi \closein 1 % % We will only complain once about lack of epsf.tex. \newif\ifwarnednoepsf \newhelp\noepsfhelp{epsf.tex must be installed for images to work. It is also included in the Texinfo distribution, or you can get it from ftp://tug.org/tex/epsf.tex.} % \def\image#1{% \ifx\epsfbox\thisisundefined \ifwarnednoepsf \else \errhelp = \noepsfhelp \errmessage{epsf.tex not found, images will be ignored}% \global\warnednoepsftrue \fi \else \imagexxx #1,,,,,\finish \fi } % % Arguments to @image: % #1 is (mandatory) image filename; we tack on .eps extension. % #2 is (optional) width, #3 is (optional) height. % #4 is (ignored optional) html alt text. % #5 is (ignored optional) extension. % #6 is just the usual extra ignored arg for parsing stuff. \newif\ifimagevmode \def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup \catcode`\^^M = 5 % in case we're inside an example \normalturnoffactive % allow _ et al. in names % If the image is by itself, center it. \ifvmode \imagevmodetrue \else \ifx\centersub\centerV % for @center @image, we need a vbox so we can have our vertical space \imagevmodetrue \vbox\bgroup % vbox has better behavior than vtop herev \fi\fi % \ifimagevmode \nobreak\medskip % Usually we'll have text after the image which will insert % \parskip glue, so insert it here too to equalize the space % above and below. \nobreak\vskip\parskip \nobreak \fi % % Leave vertical mode so that indentation from an enclosing % environment such as @quotation is respected. % However, if we're at the top level, we don't want the % normal paragraph indentation. % On the other hand, if we are in the case of @center @image, we don't % want to start a paragraph, which will create a hsize-width box and % eradicate the centering. \ifx\centersub\centerV\else \noindent \fi % % Output the image. \ifpdf \dopdfimage{#1}{#2}{#3}% \else % \epsfbox itself resets \epsf?size at each figure. \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi \epsfbox{#1.eps}% \fi % \ifimagevmode \medskip % space after a standalone image \fi \ifx\centersub\centerV \egroup \fi \endgroup} % @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables, % etc. We don't actually implement floating yet, we always include the % float "here". But it seemed the best name for the future. % \envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish} % There may be a space before second and/or third parameter; delete it. \def\eatcommaspace#1, {#1,} % #1 is the optional FLOATTYPE, the text label for this float, typically % "Figure", "Table", "Example", etc. Can't contain commas. If omitted, % this float will not be numbered and cannot be referred to. % % #2 is the optional xref label. Also must be present for the float to % be referable. % % #3 is the optional positioning argument; for now, it is ignored. It % will somehow specify the positions allowed to float to (here, top, bottom). % % We keep a separate counter for each FLOATTYPE, which we reset at each % chapter-level command. \let\resetallfloatnos=\empty % \def\dofloat#1,#2,#3,#4\finish{% \let\thiscaption=\empty \let\thisshortcaption=\empty % % don't lose footnotes inside @float. % % BEWARE: when the floats start float, we have to issue warning whenever an % insert appears inside a float which could possibly float. --kasal, 26may04 % \startsavinginserts % % We can't be used inside a paragraph. \par % \vtop\bgroup \def\floattype{#1}% \def\floatlabel{#2}% \def\floatloc{#3}% we do nothing with this yet. % \ifx\floattype\empty \let\safefloattype=\empty \else {% % the floattype might have accents or other special characters, % but we need to use it in a control sequence name. \indexnofonts \turnoffactive \xdef\safefloattype{\floattype}% }% \fi % % If label is given but no type, we handle that as the empty type. \ifx\floatlabel\empty \else % We want each FLOATTYPE to be numbered separately (Figure 1, % Table 1, Figure 2, ...). (And if no label, no number.) % \expandafter\getfloatno\csname\safefloattype floatno\endcsname \global\advance\floatno by 1 % {% % This magic value for \lastsection is output by \setref as the % XREFLABEL-title value. \xrefX uses it to distinguish float % labels (which have a completely different output format) from % node and anchor labels. And \xrdef uses it to construct the % lists of floats. % \edef\lastsection{\floatmagic=\safefloattype}% \setref{\floatlabel}{Yfloat}% }% \fi % % start with \parskip glue, I guess. \vskip\parskip % % Don't suppress indentation if a float happens to start a section. \restorefirstparagraphindent } % we have these possibilities: % @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap % @float Foo,lbl & no caption: Foo 1.1 % @float Foo & @caption{Cap}: Foo: Cap % @float Foo & no caption: Foo % @float ,lbl & Caption{Cap}: 1.1: Cap % @float ,lbl & no caption: 1.1 % @float & @caption{Cap}: Cap % @float & no caption: % \def\Efloat{% \let\floatident = \empty % % In all cases, if we have a float type, it comes first. \ifx\floattype\empty \else \def\floatident{\floattype}\fi % % If we have an xref label, the number comes next. \ifx\floatlabel\empty \else \ifx\floattype\empty \else % if also had float type, need tie first. \appendtomacro\floatident{\tie}% \fi % the number. \appendtomacro\floatident{\chaplevelprefix\the\floatno}% \fi % % Start the printed caption with what we've constructed in % \floatident, but keep it separate; we need \floatident again. \let\captionline = \floatident % \ifx\thiscaption\empty \else \ifx\floatident\empty \else \appendtomacro\captionline{: }% had ident, so need a colon between \fi % % caption text. \appendtomacro\captionline{\scanexp\thiscaption}% \fi % % If we have anything to print, print it, with space before. % Eventually this needs to become an \insert. \ifx\captionline\empty \else \vskip.5\parskip \captionline % % Space below caption. \vskip\parskip \fi % % If have an xref label, write the list of floats info. Do this % after the caption, to avoid chance of it being a breakpoint. \ifx\floatlabel\empty \else % Write the text that goes in the lof to the aux file as % \floatlabel-lof. Besides \floatident, we include the short % caption if specified, else the full caption if specified, else nothing. {% \atdummies % % since we read the caption text in the macro world, where ^^M % is turned into a normal character, we have to scan it back, so % we don't write the literal three characters "^^M" into the aux file. \scanexp{% \xdef\noexpand\gtemp{% \ifx\thisshortcaption\empty \thiscaption \else \thisshortcaption \fi }% }% \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident \ifx\gtemp\empty \else : \gtemp \fi}}% }% \fi \egroup % end of \vtop % % place the captured inserts % % BEWARE: when the floats start floating, we have to issue warning % whenever an insert appears inside a float which could possibly % float. --kasal, 26may04 % \checkinserts } % Append the tokens #2 to the definition of macro #1, not expanding either. % \def\appendtomacro#1#2{% \expandafter\def\expandafter#1\expandafter{#1#2}% } % @caption, @shortcaption % \def\caption{\docaption\thiscaption} \def\shortcaption{\docaption\thisshortcaption} \def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption} \def\defcaption#1#2{\egroup \def#1{#2}} % The parameter is the control sequence identifying the counter we are % going to use. Create it if it doesn't exist and assign it to \floatno. \def\getfloatno#1{% \ifx#1\relax % Haven't seen this figure type before. \csname newcount\endcsname #1% % % Remember to reset this floatno at the next chap. \expandafter\gdef\expandafter\resetallfloatnos \expandafter{\resetallfloatnos #1=0 }% \fi \let\floatno#1% } % \setref calls this to get the XREFLABEL-snt value. We want an @xref % to the FLOATLABEL to expand to "Figure 3.1". We call \setref when we % first read the @float command. % \def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}% % Magic string used for the XREFLABEL-title value, so \xrefX can % distinguish floats from other xref types. \def\floatmagic{!!float!!} % #1 is the control sequence we are passed; we expand into a conditional % which is true if #1 represents a float ref. That is, the magic % \lastsection value which we \setref above. % \def\iffloat#1{\expandafter\doiffloat#1==\finish} % % #1 is (maybe) the \floatmagic string. If so, #2 will be the % (safe) float type for this float. We set \iffloattype to #2. % \def\doiffloat#1=#2=#3\finish{% \def\temp{#1}% \def\iffloattype{#2}% \ifx\temp\floatmagic } % @listoffloats FLOATTYPE - print a list of floats like a table of contents. % \parseargdef\listoffloats{% \def\floattype{#1}% floattype {% % the floattype might have accents or other special characters, % but we need to use it in a control sequence name. \indexnofonts \turnoffactive \xdef\safefloattype{\floattype}% }% % % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE. \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax \ifhavexrefs % if the user said @listoffloats foo but never @float foo. \message{\linenumber No `\safefloattype' floats to list.}% \fi \else \begingroup \leftskip=\tocindent % indent these entries like a toc \let\do=\listoffloatsdo \csname floatlist\safefloattype\endcsname \endgroup \fi } % This is called on each entry in a list of floats. We're passed the % xref label, in the form LABEL-title, which is how we save it in the % aux file. We strip off the -title and look up \XRLABEL-lof, which % has the text we're supposed to typeset here. % % Figures without xref labels will not be included in the list (since % they won't appear in the aux file). % \def\listoffloatsdo#1{\listoffloatsdoentry#1\finish} \def\listoffloatsdoentry#1-title\finish{{% % Can't fully expand XR#1-lof because it can contain anything. Just % pass the control sequence. On the other hand, XR#1-pg is just the % page number, and we want to fully expand that so we can get a link % in pdf output. \toksA = \expandafter{\csname XR#1-lof\endcsname}% % % use the same \entry macro we use to generate the TOC and index. \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}% \writeentry }} \message{localization,} % For single-language documents, @documentlanguage is usually given very % early, just after @documentencoding. Single argument is the language % (de) or locale (de_DE) abbreviation. % { \catcode`\_ = \active \globaldefs=1 \parseargdef\documentlanguage{\begingroup \let_=\normalunderscore % normal _ character for filenames \tex % read txi-??.tex file in plain TeX. % Read the file by the name they passed if it exists. \openin 1 txi-#1.tex \ifeof 1 \documentlanguagetrywithoutunderscore{#1_\finish}% \else \globaldefs = 1 % everything in the txi-LL files needs to persist \input txi-#1.tex \fi \closein 1 \endgroup % end raw TeX \endgroup} % % If they passed de_DE, and txi-de_DE.tex doesn't exist, % try txi-de.tex. % \gdef\documentlanguagetrywithoutunderscore#1_#2\finish{% \openin 1 txi-#1.tex \ifeof 1 \errhelp = \nolanghelp \errmessage{Cannot read language file txi-#1.tex}% \else \globaldefs = 1 % everything in the txi-LL files needs to persist \input txi-#1.tex \fi \closein 1 } }% end of special _ catcode % \newhelp\nolanghelp{The given language definition file cannot be found or is empty. Maybe you need to install it? Putting it in the current directory should work if nowhere else does.} % This macro is called from txi-??.tex files; the first argument is the % \language name to set (without the "\lang@" prefix), the second and % third args are \{left,right}hyphenmin. % % The language names to pass are determined when the format is built. % See the etex.log file created at that time, e.g., % /usr/local/texlive/2008/texmf-var/web2c/pdftex/etex.log. % % With TeX Live 2008, etex now includes hyphenation patterns for all % available languages. This means we can support hyphenation in % Texinfo, at least to some extent. (This still doesn't solve the % accented characters problem.) % \catcode`@=11 \def\txisetlanguage#1#2#3{% % do not set the language if the name is undefined in the current TeX. \expandafter\ifx\csname lang@#1\endcsname \relax \message{no patterns for #1}% \else \global\language = \csname lang@#1\endcsname \fi % but there is no harm in adjusting the hyphenmin values regardless. \global\lefthyphenmin = #2\relax \global\righthyphenmin = #3\relax } % Helpers for encodings. % Set the catcode of characters 128 through 255 to the specified number. % \def\setnonasciicharscatcode#1{% \count255=128 \loop\ifnum\count255<256 \global\catcode\count255=#1\relax \advance\count255 by 1 \repeat } \def\setnonasciicharscatcodenonglobal#1{% \count255=128 \loop\ifnum\count255<256 \catcode\count255=#1\relax \advance\count255 by 1 \repeat } % @documentencoding sets the definition of non-ASCII characters % according to the specified encoding. % \parseargdef\documentencoding{% % Encoding being declared for the document. \def\declaredencoding{\csname #1.enc\endcsname}% % % Supported encodings: names converted to tokens in order to be able % to compare them with \ifx. \def\ascii{\csname US-ASCII.enc\endcsname}% \def\latnine{\csname ISO-8859-15.enc\endcsname}% \def\latone{\csname ISO-8859-1.enc\endcsname}% \def\lattwo{\csname ISO-8859-2.enc\endcsname}% \def\utfeight{\csname UTF-8.enc\endcsname}% % \ifx \declaredencoding \ascii \asciichardefs % \else \ifx \declaredencoding \lattwo \setnonasciicharscatcode\active \lattwochardefs % \else \ifx \declaredencoding \latone \setnonasciicharscatcode\active \latonechardefs % \else \ifx \declaredencoding \latnine \setnonasciicharscatcode\active \latninechardefs % \else \ifx \declaredencoding \utfeight \setnonasciicharscatcode\active \utfeightchardefs % \else \message{Unknown document encoding #1, ignoring.}% % \fi % utfeight \fi % latnine \fi % latone \fi % lattwo \fi % ascii } % A message to be logged when using a character that isn't available % the default font encoding (OT1). % \def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}} % Take account of \c (plain) vs. \, (Texinfo) difference. \def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi} % First, make active non-ASCII characters in order for them to be % correctly categorized when TeX reads the replacement text of % macros containing the character definitions. \setnonasciicharscatcode\active % % Latin1 (ISO-8859-1) character definitions. \def\latonechardefs{% \gdef^^a0{\tie} \gdef^^a1{\exclamdown} \gdef^^a2{\missingcharmsg{CENT SIGN}} \gdef^^a3{{\pounds}} \gdef^^a4{\missingcharmsg{CURRENCY SIGN}} \gdef^^a5{\missingcharmsg{YEN SIGN}} \gdef^^a6{\missingcharmsg{BROKEN BAR}} \gdef^^a7{\S} \gdef^^a8{\"{}} \gdef^^a9{\copyright} \gdef^^aa{\ordf} \gdef^^ab{\guillemetleft} \gdef^^ac{$\lnot$} \gdef^^ad{\-} \gdef^^ae{\registeredsymbol} \gdef^^af{\={}} % \gdef^^b0{\textdegree} \gdef^^b1{$\pm$} \gdef^^b2{$^2$} \gdef^^b3{$^3$} \gdef^^b4{\'{}} \gdef^^b5{$\mu$} \gdef^^b6{\P} % \gdef^^b7{$^.$} \gdef^^b8{\cedilla\ } \gdef^^b9{$^1$} \gdef^^ba{\ordm} % \gdef^^bb{\guillemetright} \gdef^^bc{$1\over4$} \gdef^^bd{$1\over2$} \gdef^^be{$3\over4$} \gdef^^bf{\questiondown} % \gdef^^c0{\`A} \gdef^^c1{\'A} \gdef^^c2{\^A} \gdef^^c3{\~A} \gdef^^c4{\"A} \gdef^^c5{\ringaccent A} \gdef^^c6{\AE} \gdef^^c7{\cedilla C} \gdef^^c8{\`E} \gdef^^c9{\'E} \gdef^^ca{\^E} \gdef^^cb{\"E} \gdef^^cc{\`I} \gdef^^cd{\'I} \gdef^^ce{\^I} \gdef^^cf{\"I} % \gdef^^d0{\DH} \gdef^^d1{\~N} \gdef^^d2{\`O} \gdef^^d3{\'O} \gdef^^d4{\^O} \gdef^^d5{\~O} \gdef^^d6{\"O} \gdef^^d7{$\times$} \gdef^^d8{\O} \gdef^^d9{\`U} \gdef^^da{\'U} \gdef^^db{\^U} \gdef^^dc{\"U} \gdef^^dd{\'Y} \gdef^^de{\TH} \gdef^^df{\ss} % \gdef^^e0{\`a} \gdef^^e1{\'a} \gdef^^e2{\^a} \gdef^^e3{\~a} \gdef^^e4{\"a} \gdef^^e5{\ringaccent a} \gdef^^e6{\ae} \gdef^^e7{\cedilla c} \gdef^^e8{\`e} \gdef^^e9{\'e} \gdef^^ea{\^e} \gdef^^eb{\"e} \gdef^^ec{\`{\dotless i}} \gdef^^ed{\'{\dotless i}} \gdef^^ee{\^{\dotless i}} \gdef^^ef{\"{\dotless i}} % \gdef^^f0{\dh} \gdef^^f1{\~n} \gdef^^f2{\`o} \gdef^^f3{\'o} \gdef^^f4{\^o} \gdef^^f5{\~o} \gdef^^f6{\"o} \gdef^^f7{$\div$} \gdef^^f8{\o} \gdef^^f9{\`u} \gdef^^fa{\'u} \gdef^^fb{\^u} \gdef^^fc{\"u} \gdef^^fd{\'y} \gdef^^fe{\th} \gdef^^ff{\"y} } % Latin9 (ISO-8859-15) encoding character definitions. \def\latninechardefs{% % Encoding is almost identical to Latin1. \latonechardefs % \gdef^^a4{\euro} \gdef^^a6{\v S} \gdef^^a8{\v s} \gdef^^b4{\v Z} \gdef^^b8{\v z} \gdef^^bc{\OE} \gdef^^bd{\oe} \gdef^^be{\"Y} } % Latin2 (ISO-8859-2) character definitions. \def\lattwochardefs{% \gdef^^a0{\tie} \gdef^^a1{\ogonek{A}} \gdef^^a2{\u{}} \gdef^^a3{\L} \gdef^^a4{\missingcharmsg{CURRENCY SIGN}} \gdef^^a5{\v L} \gdef^^a6{\'S} \gdef^^a7{\S} \gdef^^a8{\"{}} \gdef^^a9{\v S} \gdef^^aa{\cedilla S} \gdef^^ab{\v T} \gdef^^ac{\'Z} \gdef^^ad{\-} \gdef^^ae{\v Z} \gdef^^af{\dotaccent Z} % \gdef^^b0{\textdegree} \gdef^^b1{\ogonek{a}} \gdef^^b2{\ogonek{ }} \gdef^^b3{\l} \gdef^^b4{\'{}} \gdef^^b5{\v l} \gdef^^b6{\'s} \gdef^^b7{\v{}} \gdef^^b8{\cedilla\ } \gdef^^b9{\v s} \gdef^^ba{\cedilla s} \gdef^^bb{\v t} \gdef^^bc{\'z} \gdef^^bd{\H{}} \gdef^^be{\v z} \gdef^^bf{\dotaccent z} % \gdef^^c0{\'R} \gdef^^c1{\'A} \gdef^^c2{\^A} \gdef^^c3{\u A} \gdef^^c4{\"A} \gdef^^c5{\'L} \gdef^^c6{\'C} \gdef^^c7{\cedilla C} \gdef^^c8{\v C} \gdef^^c9{\'E} \gdef^^ca{\ogonek{E}} \gdef^^cb{\"E} \gdef^^cc{\v E} \gdef^^cd{\'I} \gdef^^ce{\^I} \gdef^^cf{\v D} % \gdef^^d0{\DH} \gdef^^d1{\'N} \gdef^^d2{\v N} \gdef^^d3{\'O} \gdef^^d4{\^O} \gdef^^d5{\H O} \gdef^^d6{\"O} \gdef^^d7{$\times$} \gdef^^d8{\v R} \gdef^^d9{\ringaccent U} \gdef^^da{\'U} \gdef^^db{\H U} \gdef^^dc{\"U} \gdef^^dd{\'Y} \gdef^^de{\cedilla T} \gdef^^df{\ss} % \gdef^^e0{\'r} \gdef^^e1{\'a} \gdef^^e2{\^a} \gdef^^e3{\u a} \gdef^^e4{\"a} \gdef^^e5{\'l} \gdef^^e6{\'c} \gdef^^e7{\cedilla c} \gdef^^e8{\v c} \gdef^^e9{\'e} \gdef^^ea{\ogonek{e}} \gdef^^eb{\"e} \gdef^^ec{\v e} \gdef^^ed{\'{\dotless{i}}} \gdef^^ee{\^{\dotless{i}}} \gdef^^ef{\v d} % \gdef^^f0{\dh} \gdef^^f1{\'n} \gdef^^f2{\v n} \gdef^^f3{\'o} \gdef^^f4{\^o} \gdef^^f5{\H o} \gdef^^f6{\"o} \gdef^^f7{$\div$} \gdef^^f8{\v r} \gdef^^f9{\ringaccent u} \gdef^^fa{\'u} \gdef^^fb{\H u} \gdef^^fc{\"u} \gdef^^fd{\'y} \gdef^^fe{\cedilla t} \gdef^^ff{\dotaccent{}} } % UTF-8 character definitions. % % This code to support UTF-8 is based on LaTeX's utf8.def, with some % changes for Texinfo conventions. It is included here under the GPL by % permission from Frank Mittelbach and the LaTeX team. % \newcount\countUTFx \newcount\countUTFy \newcount\countUTFz \gdef\UTFviiiTwoOctets#1#2{\expandafter \UTFviiiDefined\csname u8:#1\string #2\endcsname} % \gdef\UTFviiiThreeOctets#1#2#3{\expandafter \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname} % \gdef\UTFviiiFourOctets#1#2#3#4{\expandafter \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname} \gdef\UTFviiiDefined#1{% \ifx #1\relax \message{\linenumber Unicode char \string #1 not defined for Texinfo}% \else \expandafter #1% \fi } \begingroup \catcode`\~13 \catcode`\"12 \def\UTFviiiLoop{% \global\catcode\countUTFx\active \uccode`\~\countUTFx \uppercase\expandafter{\UTFviiiTmp}% \advance\countUTFx by 1 \ifnum\countUTFx < \countUTFy \expandafter\UTFviiiLoop \fi} \countUTFx = "C2 \countUTFy = "E0 \def\UTFviiiTmp{% \xdef~{\noexpand\UTFviiiTwoOctets\string~}} \UTFviiiLoop \countUTFx = "E0 \countUTFy = "F0 \def\UTFviiiTmp{% \xdef~{\noexpand\UTFviiiThreeOctets\string~}} \UTFviiiLoop \countUTFx = "F0 \countUTFy = "F4 \def\UTFviiiTmp{% \xdef~{\noexpand\UTFviiiFourOctets\string~}} \UTFviiiLoop \endgroup \begingroup \catcode`\"=12 \catcode`\<=12 \catcode`\.=12 \catcode`\,=12 \catcode`\;=12 \catcode`\!=12 \catcode`\~=13 \gdef\DeclareUnicodeCharacter#1#2{% \countUTFz = "#1\relax %\wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}% \begingroup \parseXMLCharref \def\UTFviiiTwoOctets##1##2{% \csname u8:##1\string ##2\endcsname}% \def\UTFviiiThreeOctets##1##2##3{% \csname u8:##1\string ##2\string ##3\endcsname}% \def\UTFviiiFourOctets##1##2##3##4{% \csname u8:##1\string ##2\string ##3\string ##4\endcsname}% \expandafter\expandafter\expandafter\expandafter \expandafter\expandafter\expandafter \gdef\UTFviiiTmp{#2}% \endgroup} \gdef\parseXMLCharref{% \ifnum\countUTFz < "A0\relax \errhelp = \EMsimple \errmessage{Cannot define Unicode char value < 00A0}% \else\ifnum\countUTFz < "800\relax \parseUTFviiiA,% \parseUTFviiiB C\UTFviiiTwoOctets.,% \else\ifnum\countUTFz < "10000\relax \parseUTFviiiA;% \parseUTFviiiA,% \parseUTFviiiB E\UTFviiiThreeOctets.{,;}% \else \parseUTFviiiA;% \parseUTFviiiA,% \parseUTFviiiA!% \parseUTFviiiB F\UTFviiiFourOctets.{!,;}% \fi\fi\fi } \gdef\parseUTFviiiA#1{% \countUTFx = \countUTFz \divide\countUTFz by 64 \countUTFy = \countUTFz \multiply\countUTFz by 64 \advance\countUTFx by -\countUTFz \advance\countUTFx by 128 \uccode `#1\countUTFx \countUTFz = \countUTFy} \gdef\parseUTFviiiB#1#2#3#4{% \advance\countUTFz by "#10\relax \uccode `#3\countUTFz \uppercase{\gdef\UTFviiiTmp{#2#3#4}}} \endgroup \def\utfeightchardefs{% \DeclareUnicodeCharacter{00A0}{\tie} \DeclareUnicodeCharacter{00A1}{\exclamdown} \DeclareUnicodeCharacter{00A3}{\pounds} \DeclareUnicodeCharacter{00A8}{\"{ }} \DeclareUnicodeCharacter{00A9}{\copyright} \DeclareUnicodeCharacter{00AA}{\ordf} \DeclareUnicodeCharacter{00AB}{\guillemetleft} \DeclareUnicodeCharacter{00AD}{\-} \DeclareUnicodeCharacter{00AE}{\registeredsymbol} \DeclareUnicodeCharacter{00AF}{\={ }} \DeclareUnicodeCharacter{00B0}{\ringaccent{ }} \DeclareUnicodeCharacter{00B4}{\'{ }} \DeclareUnicodeCharacter{00B8}{\cedilla{ }} \DeclareUnicodeCharacter{00BA}{\ordm} \DeclareUnicodeCharacter{00BB}{\guillemetright} \DeclareUnicodeCharacter{00BF}{\questiondown} \DeclareUnicodeCharacter{00C0}{\`A} \DeclareUnicodeCharacter{00C1}{\'A} \DeclareUnicodeCharacter{00C2}{\^A} \DeclareUnicodeCharacter{00C3}{\~A} \DeclareUnicodeCharacter{00C4}{\"A} \DeclareUnicodeCharacter{00C5}{\AA} \DeclareUnicodeCharacter{00C6}{\AE} \DeclareUnicodeCharacter{00C7}{\cedilla{C}} \DeclareUnicodeCharacter{00C8}{\`E} \DeclareUnicodeCharacter{00C9}{\'E} \DeclareUnicodeCharacter{00CA}{\^E} \DeclareUnicodeCharacter{00CB}{\"E} \DeclareUnicodeCharacter{00CC}{\`I} \DeclareUnicodeCharacter{00CD}{\'I} \DeclareUnicodeCharacter{00CE}{\^I} \DeclareUnicodeCharacter{00CF}{\"I} \DeclareUnicodeCharacter{00D0}{\DH} \DeclareUnicodeCharacter{00D1}{\~N} \DeclareUnicodeCharacter{00D2}{\`O} \DeclareUnicodeCharacter{00D3}{\'O} \DeclareUnicodeCharacter{00D4}{\^O} \DeclareUnicodeCharacter{00D5}{\~O} \DeclareUnicodeCharacter{00D6}{\"O} \DeclareUnicodeCharacter{00D8}{\O} \DeclareUnicodeCharacter{00D9}{\`U} \DeclareUnicodeCharacter{00DA}{\'U} \DeclareUnicodeCharacter{00DB}{\^U} \DeclareUnicodeCharacter{00DC}{\"U} \DeclareUnicodeCharacter{00DD}{\'Y} \DeclareUnicodeCharacter{00DE}{\TH} \DeclareUnicodeCharacter{00DF}{\ss} \DeclareUnicodeCharacter{00E0}{\`a} \DeclareUnicodeCharacter{00E1}{\'a} \DeclareUnicodeCharacter{00E2}{\^a} \DeclareUnicodeCharacter{00E3}{\~a} \DeclareUnicodeCharacter{00E4}{\"a} \DeclareUnicodeCharacter{00E5}{\aa} \DeclareUnicodeCharacter{00E6}{\ae} \DeclareUnicodeCharacter{00E7}{\cedilla{c}} \DeclareUnicodeCharacter{00E8}{\`e} \DeclareUnicodeCharacter{00E9}{\'e} \DeclareUnicodeCharacter{00EA}{\^e} \DeclareUnicodeCharacter{00EB}{\"e} \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}} \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}} \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}} \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}} \DeclareUnicodeCharacter{00F0}{\dh} \DeclareUnicodeCharacter{00F1}{\~n} \DeclareUnicodeCharacter{00F2}{\`o} \DeclareUnicodeCharacter{00F3}{\'o} \DeclareUnicodeCharacter{00F4}{\^o} \DeclareUnicodeCharacter{00F5}{\~o} \DeclareUnicodeCharacter{00F6}{\"o} \DeclareUnicodeCharacter{00F8}{\o} \DeclareUnicodeCharacter{00F9}{\`u} \DeclareUnicodeCharacter{00FA}{\'u} \DeclareUnicodeCharacter{00FB}{\^u} \DeclareUnicodeCharacter{00FC}{\"u} \DeclareUnicodeCharacter{00FD}{\'y} \DeclareUnicodeCharacter{00FE}{\th} \DeclareUnicodeCharacter{00FF}{\"y} \DeclareUnicodeCharacter{0100}{\=A} \DeclareUnicodeCharacter{0101}{\=a} \DeclareUnicodeCharacter{0102}{\u{A}} \DeclareUnicodeCharacter{0103}{\u{a}} \DeclareUnicodeCharacter{0104}{\ogonek{A}} \DeclareUnicodeCharacter{0105}{\ogonek{a}} \DeclareUnicodeCharacter{0106}{\'C} \DeclareUnicodeCharacter{0107}{\'c} \DeclareUnicodeCharacter{0108}{\^C} \DeclareUnicodeCharacter{0109}{\^c} \DeclareUnicodeCharacter{0118}{\ogonek{E}} \DeclareUnicodeCharacter{0119}{\ogonek{e}} \DeclareUnicodeCharacter{010A}{\dotaccent{C}} \DeclareUnicodeCharacter{010B}{\dotaccent{c}} \DeclareUnicodeCharacter{010C}{\v{C}} \DeclareUnicodeCharacter{010D}{\v{c}} \DeclareUnicodeCharacter{010E}{\v{D}} \DeclareUnicodeCharacter{0112}{\=E} \DeclareUnicodeCharacter{0113}{\=e} \DeclareUnicodeCharacter{0114}{\u{E}} \DeclareUnicodeCharacter{0115}{\u{e}} \DeclareUnicodeCharacter{0116}{\dotaccent{E}} \DeclareUnicodeCharacter{0117}{\dotaccent{e}} \DeclareUnicodeCharacter{011A}{\v{E}} \DeclareUnicodeCharacter{011B}{\v{e}} \DeclareUnicodeCharacter{011C}{\^G} \DeclareUnicodeCharacter{011D}{\^g} \DeclareUnicodeCharacter{011E}{\u{G}} \DeclareUnicodeCharacter{011F}{\u{g}} \DeclareUnicodeCharacter{0120}{\dotaccent{G}} \DeclareUnicodeCharacter{0121}{\dotaccent{g}} \DeclareUnicodeCharacter{0124}{\^H} \DeclareUnicodeCharacter{0125}{\^h} \DeclareUnicodeCharacter{0128}{\~I} \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}} \DeclareUnicodeCharacter{012A}{\=I} \DeclareUnicodeCharacter{012B}{\={\dotless{i}}} \DeclareUnicodeCharacter{012C}{\u{I}} \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}} \DeclareUnicodeCharacter{0130}{\dotaccent{I}} \DeclareUnicodeCharacter{0131}{\dotless{i}} \DeclareUnicodeCharacter{0132}{IJ} \DeclareUnicodeCharacter{0133}{ij} \DeclareUnicodeCharacter{0134}{\^J} \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}} \DeclareUnicodeCharacter{0139}{\'L} \DeclareUnicodeCharacter{013A}{\'l} \DeclareUnicodeCharacter{0141}{\L} \DeclareUnicodeCharacter{0142}{\l} \DeclareUnicodeCharacter{0143}{\'N} \DeclareUnicodeCharacter{0144}{\'n} \DeclareUnicodeCharacter{0147}{\v{N}} \DeclareUnicodeCharacter{0148}{\v{n}} \DeclareUnicodeCharacter{014C}{\=O} \DeclareUnicodeCharacter{014D}{\=o} \DeclareUnicodeCharacter{014E}{\u{O}} \DeclareUnicodeCharacter{014F}{\u{o}} \DeclareUnicodeCharacter{0150}{\H{O}} \DeclareUnicodeCharacter{0151}{\H{o}} \DeclareUnicodeCharacter{0152}{\OE} \DeclareUnicodeCharacter{0153}{\oe} \DeclareUnicodeCharacter{0154}{\'R} \DeclareUnicodeCharacter{0155}{\'r} \DeclareUnicodeCharacter{0158}{\v{R}} \DeclareUnicodeCharacter{0159}{\v{r}} \DeclareUnicodeCharacter{015A}{\'S} \DeclareUnicodeCharacter{015B}{\'s} \DeclareUnicodeCharacter{015C}{\^S} \DeclareUnicodeCharacter{015D}{\^s} \DeclareUnicodeCharacter{015E}{\cedilla{S}} \DeclareUnicodeCharacter{015F}{\cedilla{s}} \DeclareUnicodeCharacter{0160}{\v{S}} \DeclareUnicodeCharacter{0161}{\v{s}} \DeclareUnicodeCharacter{0162}{\cedilla{t}} \DeclareUnicodeCharacter{0163}{\cedilla{T}} \DeclareUnicodeCharacter{0164}{\v{T}} \DeclareUnicodeCharacter{0168}{\~U} \DeclareUnicodeCharacter{0169}{\~u} \DeclareUnicodeCharacter{016A}{\=U} \DeclareUnicodeCharacter{016B}{\=u} \DeclareUnicodeCharacter{016C}{\u{U}} \DeclareUnicodeCharacter{016D}{\u{u}} \DeclareUnicodeCharacter{016E}{\ringaccent{U}} \DeclareUnicodeCharacter{016F}{\ringaccent{u}} \DeclareUnicodeCharacter{0170}{\H{U}} \DeclareUnicodeCharacter{0171}{\H{u}} \DeclareUnicodeCharacter{0174}{\^W} \DeclareUnicodeCharacter{0175}{\^w} \DeclareUnicodeCharacter{0176}{\^Y} \DeclareUnicodeCharacter{0177}{\^y} \DeclareUnicodeCharacter{0178}{\"Y} \DeclareUnicodeCharacter{0179}{\'Z} \DeclareUnicodeCharacter{017A}{\'z} \DeclareUnicodeCharacter{017B}{\dotaccent{Z}} \DeclareUnicodeCharacter{017C}{\dotaccent{z}} \DeclareUnicodeCharacter{017D}{\v{Z}} \DeclareUnicodeCharacter{017E}{\v{z}} \DeclareUnicodeCharacter{01C4}{D\v{Z}} \DeclareUnicodeCharacter{01C5}{D\v{z}} \DeclareUnicodeCharacter{01C6}{d\v{z}} \DeclareUnicodeCharacter{01C7}{LJ} \DeclareUnicodeCharacter{01C8}{Lj} \DeclareUnicodeCharacter{01C9}{lj} \DeclareUnicodeCharacter{01CA}{NJ} \DeclareUnicodeCharacter{01CB}{Nj} \DeclareUnicodeCharacter{01CC}{nj} \DeclareUnicodeCharacter{01CD}{\v{A}} \DeclareUnicodeCharacter{01CE}{\v{a}} \DeclareUnicodeCharacter{01CF}{\v{I}} \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}} \DeclareUnicodeCharacter{01D1}{\v{O}} \DeclareUnicodeCharacter{01D2}{\v{o}} \DeclareUnicodeCharacter{01D3}{\v{U}} \DeclareUnicodeCharacter{01D4}{\v{u}} \DeclareUnicodeCharacter{01E2}{\={\AE}} \DeclareUnicodeCharacter{01E3}{\={\ae}} \DeclareUnicodeCharacter{01E6}{\v{G}} \DeclareUnicodeCharacter{01E7}{\v{g}} \DeclareUnicodeCharacter{01E8}{\v{K}} \DeclareUnicodeCharacter{01E9}{\v{k}} \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}} \DeclareUnicodeCharacter{01F1}{DZ} \DeclareUnicodeCharacter{01F2}{Dz} \DeclareUnicodeCharacter{01F3}{dz} \DeclareUnicodeCharacter{01F4}{\'G} \DeclareUnicodeCharacter{01F5}{\'g} \DeclareUnicodeCharacter{01F8}{\`N} \DeclareUnicodeCharacter{01F9}{\`n} \DeclareUnicodeCharacter{01FC}{\'{\AE}} \DeclareUnicodeCharacter{01FD}{\'{\ae}} \DeclareUnicodeCharacter{01FE}{\'{\O}} \DeclareUnicodeCharacter{01FF}{\'{\o}} \DeclareUnicodeCharacter{021E}{\v{H}} \DeclareUnicodeCharacter{021F}{\v{h}} \DeclareUnicodeCharacter{0226}{\dotaccent{A}} \DeclareUnicodeCharacter{0227}{\dotaccent{a}} \DeclareUnicodeCharacter{0228}{\cedilla{E}} \DeclareUnicodeCharacter{0229}{\cedilla{e}} \DeclareUnicodeCharacter{022E}{\dotaccent{O}} \DeclareUnicodeCharacter{022F}{\dotaccent{o}} \DeclareUnicodeCharacter{0232}{\=Y} \DeclareUnicodeCharacter{0233}{\=y} \DeclareUnicodeCharacter{0237}{\dotless{j}} \DeclareUnicodeCharacter{02DB}{\ogonek{ }} \DeclareUnicodeCharacter{1E02}{\dotaccent{B}} \DeclareUnicodeCharacter{1E03}{\dotaccent{b}} \DeclareUnicodeCharacter{1E04}{\udotaccent{B}} \DeclareUnicodeCharacter{1E05}{\udotaccent{b}} \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}} \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}} \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}} \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}} \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}} \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}} \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}} \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}} \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}} \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}} \DeclareUnicodeCharacter{1E20}{\=G} \DeclareUnicodeCharacter{1E21}{\=g} \DeclareUnicodeCharacter{1E22}{\dotaccent{H}} \DeclareUnicodeCharacter{1E23}{\dotaccent{h}} \DeclareUnicodeCharacter{1E24}{\udotaccent{H}} \DeclareUnicodeCharacter{1E25}{\udotaccent{h}} \DeclareUnicodeCharacter{1E26}{\"H} \DeclareUnicodeCharacter{1E27}{\"h} \DeclareUnicodeCharacter{1E30}{\'K} \DeclareUnicodeCharacter{1E31}{\'k} \DeclareUnicodeCharacter{1E32}{\udotaccent{K}} \DeclareUnicodeCharacter{1E33}{\udotaccent{k}} \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}} \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}} \DeclareUnicodeCharacter{1E36}{\udotaccent{L}} \DeclareUnicodeCharacter{1E37}{\udotaccent{l}} \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}} \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}} \DeclareUnicodeCharacter{1E3E}{\'M} \DeclareUnicodeCharacter{1E3F}{\'m} \DeclareUnicodeCharacter{1E40}{\dotaccent{M}} \DeclareUnicodeCharacter{1E41}{\dotaccent{m}} \DeclareUnicodeCharacter{1E42}{\udotaccent{M}} \DeclareUnicodeCharacter{1E43}{\udotaccent{m}} \DeclareUnicodeCharacter{1E44}{\dotaccent{N}} \DeclareUnicodeCharacter{1E45}{\dotaccent{n}} \DeclareUnicodeCharacter{1E46}{\udotaccent{N}} \DeclareUnicodeCharacter{1E47}{\udotaccent{n}} \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}} \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}} \DeclareUnicodeCharacter{1E54}{\'P} \DeclareUnicodeCharacter{1E55}{\'p} \DeclareUnicodeCharacter{1E56}{\dotaccent{P}} \DeclareUnicodeCharacter{1E57}{\dotaccent{p}} \DeclareUnicodeCharacter{1E58}{\dotaccent{R}} \DeclareUnicodeCharacter{1E59}{\dotaccent{r}} \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}} \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}} \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}} \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}} \DeclareUnicodeCharacter{1E60}{\dotaccent{S}} \DeclareUnicodeCharacter{1E61}{\dotaccent{s}} \DeclareUnicodeCharacter{1E62}{\udotaccent{S}} \DeclareUnicodeCharacter{1E63}{\udotaccent{s}} \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}} \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}} \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}} \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}} \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}} \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}} \DeclareUnicodeCharacter{1E7C}{\~V} \DeclareUnicodeCharacter{1E7D}{\~v} \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}} \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}} \DeclareUnicodeCharacter{1E80}{\`W} \DeclareUnicodeCharacter{1E81}{\`w} \DeclareUnicodeCharacter{1E82}{\'W} \DeclareUnicodeCharacter{1E83}{\'w} \DeclareUnicodeCharacter{1E84}{\"W} \DeclareUnicodeCharacter{1E85}{\"w} \DeclareUnicodeCharacter{1E86}{\dotaccent{W}} \DeclareUnicodeCharacter{1E87}{\dotaccent{w}} \DeclareUnicodeCharacter{1E88}{\udotaccent{W}} \DeclareUnicodeCharacter{1E89}{\udotaccent{w}} \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}} \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}} \DeclareUnicodeCharacter{1E8C}{\"X} \DeclareUnicodeCharacter{1E8D}{\"x} \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}} \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}} \DeclareUnicodeCharacter{1E90}{\^Z} \DeclareUnicodeCharacter{1E91}{\^z} \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}} \DeclareUnicodeCharacter{1E93}{\udotaccent{z}} \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}} \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}} \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}} \DeclareUnicodeCharacter{1E97}{\"t} \DeclareUnicodeCharacter{1E98}{\ringaccent{w}} \DeclareUnicodeCharacter{1E99}{\ringaccent{y}} \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}} \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}} \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}} \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}} \DeclareUnicodeCharacter{1EBC}{\~E} \DeclareUnicodeCharacter{1EBD}{\~e} \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}} \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}} \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}} \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}} \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}} \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}} \DeclareUnicodeCharacter{1EF2}{\`Y} \DeclareUnicodeCharacter{1EF3}{\`y} \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}} \DeclareUnicodeCharacter{1EF8}{\~Y} \DeclareUnicodeCharacter{1EF9}{\~y} \DeclareUnicodeCharacter{2013}{--} \DeclareUnicodeCharacter{2014}{---} \DeclareUnicodeCharacter{2018}{\quoteleft} \DeclareUnicodeCharacter{2019}{\quoteright} \DeclareUnicodeCharacter{201A}{\quotesinglbase} \DeclareUnicodeCharacter{201C}{\quotedblleft} \DeclareUnicodeCharacter{201D}{\quotedblright} \DeclareUnicodeCharacter{201E}{\quotedblbase} \DeclareUnicodeCharacter{2022}{\bullet} \DeclareUnicodeCharacter{2026}{\dots} \DeclareUnicodeCharacter{2039}{\guilsinglleft} \DeclareUnicodeCharacter{203A}{\guilsinglright} \DeclareUnicodeCharacter{20AC}{\euro} \DeclareUnicodeCharacter{2192}{\expansion} \DeclareUnicodeCharacter{21D2}{\result} \DeclareUnicodeCharacter{2212}{\minus} \DeclareUnicodeCharacter{2217}{\point} \DeclareUnicodeCharacter{2261}{\equiv} }% end of \utfeightchardefs % US-ASCII character definitions. \def\asciichardefs{% nothing need be done \relax } % Make non-ASCII characters printable again for compatibility with % existing Texinfo documents that may use them, even without declaring a % document encoding. % \setnonasciicharscatcode \other \message{formatting,} \newdimen\defaultparindent \defaultparindent = 15pt \chapheadingskip = 15pt plus 4pt minus 2pt \secheadingskip = 12pt plus 3pt minus 2pt \subsecheadingskip = 9pt plus 2pt minus 2pt % Prevent underfull vbox error messages. \vbadness = 10000 % Don't be very finicky about underfull hboxes, either. \hbadness = 6666 % Following George Bush, get rid of widows and orphans. \widowpenalty=10000 \clubpenalty=10000 % Use TeX 3.0's \emergencystretch to help line breaking, but if we're % using an old version of TeX, don't do anything. We want the amount of % stretch added to depend on the line length, hence the dependence on % \hsize. We call this whenever the paper size is set. % \def\setemergencystretch{% \ifx\emergencystretch\thisisundefined % Allow us to assign to \emergencystretch anyway. \def\emergencystretch{\dimen0}% \else \emergencystretch = .15\hsize \fi } % Parameters in order: 1) textheight; 2) textwidth; % 3) voffset; 4) hoffset; 5) binding offset; 6) topskip; % 7) physical page height; 8) physical page width. % % We also call \setleading{\textleading}, so the caller should define % \textleading. The caller should also set \parskip. % \def\internalpagesizes#1#2#3#4#5#6#7#8{% \voffset = #3\relax \topskip = #6\relax \splittopskip = \topskip % \vsize = #1\relax \advance\vsize by \topskip \outervsize = \vsize \advance\outervsize by 2\topandbottommargin \pageheight = \vsize % \hsize = #2\relax \outerhsize = \hsize \advance\outerhsize by 0.5in \pagewidth = \hsize % \normaloffset = #4\relax \bindingoffset = #5\relax % \ifpdf \pdfpageheight #7\relax \pdfpagewidth #8\relax % if we don't reset these, they will remain at "1 true in" of % whatever layout pdftex was dumped with. \pdfhorigin = 1 true in \pdfvorigin = 1 true in \fi % \setleading{\textleading} % \parindent = \defaultparindent \setemergencystretch } % @letterpaper (the default). \def\letterpaper{{\globaldefs = 1 \parskip = 3pt plus 2pt minus 1pt \textleading = 13.2pt % % If page is nothing but text, make it come out even. \internalpagesizes{607.2pt}{6in}% that's 46 lines {\voffset}{.25in}% {\bindingoffset}{36pt}% {11in}{8.5in}% }} % Use @smallbook to reset parameters for 7x9.25 trim size. \def\smallbook{{\globaldefs = 1 \parskip = 2pt plus 1pt \textleading = 12pt % \internalpagesizes{7.5in}{5in}% {-.2in}{0in}% {\bindingoffset}{16pt}% {9.25in}{7in}% % \lispnarrowing = 0.3in \tolerance = 700 \hfuzz = 1pt \contentsrightmargin = 0pt \defbodyindent = .5cm }} % Use @smallerbook to reset parameters for 6x9 trim size. % (Just testing, parameters still in flux.) \def\smallerbook{{\globaldefs = 1 \parskip = 1.5pt plus 1pt \textleading = 12pt % \internalpagesizes{7.4in}{4.8in}% {-.2in}{-.4in}% {0pt}{14pt}% {9in}{6in}% % \lispnarrowing = 0.25in \tolerance = 700 \hfuzz = 1pt \contentsrightmargin = 0pt \defbodyindent = .4cm }} % Use @afourpaper to print on European A4 paper. \def\afourpaper{{\globaldefs = 1 \parskip = 3pt plus 2pt minus 1pt \textleading = 13.2pt % % Double-side printing via postscript on Laserjet 4050 % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm. % To change the settings for a different printer or situation, adjust % \normaloffset until the front-side and back-side texts align. Then % do the same for \bindingoffset. You can set these for testing in % your texinfo source file like this: % @tex % \global\normaloffset = -6mm % \global\bindingoffset = 10mm % @end tex \internalpagesizes{673.2pt}{160mm}% that's 51 lines {\voffset}{\hoffset}% {\bindingoffset}{44pt}% {297mm}{210mm}% % \tolerance = 700 \hfuzz = 1pt \contentsrightmargin = 0pt \defbodyindent = 5mm }} % Use @afivepaper to print on European A5 paper. % From romildo@urano.iceb.ufop.br, 2 July 2000. % He also recommends making @example and @lisp be small. \def\afivepaper{{\globaldefs = 1 \parskip = 2pt plus 1pt minus 0.1pt \textleading = 12.5pt % \internalpagesizes{160mm}{120mm}% {\voffset}{\hoffset}% {\bindingoffset}{8pt}% {210mm}{148mm}% % \lispnarrowing = 0.2in \tolerance = 800 \hfuzz = 1.2pt \contentsrightmargin = 0pt \defbodyindent = 2mm \tableindent = 12mm }} % A specific text layout, 24x15cm overall, intended for A4 paper. \def\afourlatex{{\globaldefs = 1 \afourpaper \internalpagesizes{237mm}{150mm}% {\voffset}{4.6mm}% {\bindingoffset}{7mm}% {297mm}{210mm}% % % Must explicitly reset to 0 because we call \afourpaper. \globaldefs = 0 }} % Use @afourwide to print on A4 paper in landscape format. \def\afourwide{{\globaldefs = 1 \afourpaper \internalpagesizes{241mm}{165mm}% {\voffset}{-2.95mm}% {\bindingoffset}{7mm}% {297mm}{210mm}% \globaldefs = 0 }} % @pagesizes TEXTHEIGHT[,TEXTWIDTH] % Perhaps we should allow setting the margins, \topskip, \parskip, % and/or leading, also. Or perhaps we should compute them somehow. % \parseargdef\pagesizes{\pagesizesyyy #1,,\finish} \def\pagesizesyyy#1,#2,#3\finish{{% \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi \globaldefs = 1 % \parskip = 3pt plus 2pt minus 1pt \setleading{\textleading}% % \dimen0 = #1\relax \advance\dimen0 by \voffset % \dimen2 = \hsize \advance\dimen2 by \normaloffset % \internalpagesizes{#1}{\hsize}% {\voffset}{\normaloffset}% {\bindingoffset}{44pt}% {\dimen0}{\dimen2}% }} % Set default to letter. % \letterpaper \message{and turning on texinfo input format.} \def^^L{\par} % remove \outer, so ^L can appear in an @comment % DEL is a comment character, in case @c does not suffice. \catcode`\^^? = 14 % Define macros to output various characters with catcode for normal text. \catcode`\"=\other \def\normaldoublequote{"} \catcode`\$=\other \def\normaldollar{$}%$ font-lock fix \catcode`\+=\other \def\normalplus{+} \catcode`\<=\other \def\normalless{<} \catcode`\>=\other \def\normalgreater{>} \catcode`\^=\other \def\normalcaret{^} \catcode`\_=\other \def\normalunderscore{_} \catcode`\|=\other \def\normalverticalbar{|} \catcode`\~=\other \def\normaltilde{~} % This macro is used to make a character print one way in \tt % (where it can probably be output as-is), and another way in other fonts, % where something hairier probably needs to be done. % % #1 is what to print if we are indeed using \tt; #2 is what to print % otherwise. Since all the Computer Modern typewriter fonts have zero % interword stretch (and shrink), and it is reasonable to expect all % typewriter fonts to have this, we can check that font parameter. % \def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi} % Same as above, but check for italic font. Actually this also catches % non-italic slanted fonts since it is impossible to distinguish them from % italic fonts. But since this is only used by $ and it uses \sl anyway % this is not a problem. \def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} % Turn off all special characters except @ % (and those which the user can use as if they were ordinary). % Most of these we simply print from the \tt font, but for some, we can % use math or other variants that look better in normal text. \catcode`\"=\active \def\activedoublequote{{\tt\char34}} \let"=\activedoublequote \catcode`\~=\active \def~{{\tt\char126}} \chardef\hat=`\^ \catcode`\^=\active \def^{{\tt \hat}} \catcode`\_=\active \def_{\ifusingtt\normalunderscore\_} \let\realunder=_ % Subroutine for the previous macro. \def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em } \catcode`\|=\active \def|{{\tt\char124}} \chardef \less=`\< \catcode`\<=\active \def<{{\tt \less}} \chardef \gtr=`\> \catcode`\>=\active \def>{{\tt \gtr}} \catcode`\+=\active \def+{{\tt \char 43}} \catcode`\$=\active \def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix % If a .fmt file is being used, characters that might appear in a file % name cannot be active until we have parsed the command line. % So turn them off again, and have \everyjob (or @setfilename) turn them on. % \otherifyactive is called near the end of this file. \def\otherifyactive{\catcode`+=\other \catcode`\_=\other} % Used sometimes to turn off (effectively) the active characters even after % parsing them. \def\turnoffactive{% \normalturnoffactive \otherbackslash } \catcode`\@=0 % \backslashcurfont outputs one backslash character in current font, % as in \char`\\. \global\chardef\backslashcurfont=`\\ \global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work % \realbackslash is an actual character `\' with catcode other, and % \doublebackslash is two of them (for the pdf outlines). {\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}} % In texinfo, backslash is an active character; it prints the backslash % in fixed width font. \catcode`\\=\active % @ for escape char from now on. % The story here is that in math mode, the \char of \backslashcurfont % ends up printing the roman \ from the math symbol font (because \char % in math mode uses the \mathcode, and plain.tex sets % \mathcode`\\="026E). It seems better for @backslashchar{} to always % print a typewriter backslash, hence we use an explicit \mathchar, % which is the decimal equivalent of "715c (class 7, e.g., use \fam; % ignored family value; char position "5C). We can't use " for the % usual hex value because it has already been made active. @def@normalbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}} @let@backslashchar = @normalbackslash % @backslashchar{} is for user documents. % On startup, @fixbackslash assigns: % @let \ = @normalbackslash % \rawbackslash defines an active \ to do \backslashcurfont. % \otherbackslash defines an active \ to be a literal `\' character with % catcode other. We switch back and forth between these. @gdef@rawbackslash{@let\=@backslashcurfont} @gdef@otherbackslash{@let\=@realbackslash} % Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of % the literal character `\'. Also revert - to its normal character, in % case the active - from code has slipped in. % {@catcode`- = @active @gdef@normalturnoffactive{% @let-=@normaldash @let"=@normaldoublequote @let$=@normaldollar %$ font-lock fix @let+=@normalplus @let<=@normalless @let>=@normalgreater @let\=@normalbackslash @let^=@normalcaret @let_=@normalunderscore @let|=@normalverticalbar @let~=@normaltilde @markupsetuplqdefault @markupsetuprqdefault @unsepspaces } } % Make _ and + \other characters, temporarily. % This is canceled by @fixbackslash. @otherifyactive % If a .fmt file is being used, we don't want the `\input texinfo' to show up. % That is what \eatinput is for; after that, the `\' should revert to printing % a backslash. % @gdef@eatinput input texinfo{@fixbackslash} @global@let\ = @eatinput % On the other hand, perhaps the file did not have a `\input texinfo'. Then % the first `\' in the file would cause an error. This macro tries to fix % that, assuming it is called before the first `\' could plausibly occur. % Also turn back on active characters that might appear in the input % file name, in case not using a pre-dumped format. % @gdef@fixbackslash{% @ifx\@eatinput @let\ = @normalbackslash @fi @catcode`+=@active @catcode`@_=@active } % Say @foo, not \foo, in error messages. @escapechar = `@@ % These (along with & and #) are made active for url-breaking, so need % active definitions as the normal characters. @def@normaldot{.} @def@normalquest{?} @def@normalslash{/} % These look ok in all fonts, so just make them not special. % @hashchar{} gets its own user-level command, because of #line. @catcode`@& = @other @def@normalamp{&} @catcode`@# = @other @def@normalhash{#} @catcode`@% = @other @def@normalpercent{%} @let @hashchar = @normalhash @c Finally, make ` and ' active, so that txicodequoteundirected and @c txicodequotebacktick work right in, e.g., @w{@code{`foo'}}. If we @c don't make ` and ' active, @code will not get them as active chars. @c Do this last of all since we use ` in the previous @catcode assignments. @catcode`@'=@active @catcode`@`=@active @markupsetuplqdefault @markupsetuprqdefault @c Local variables: @c eval: (add-hook 'write-file-hooks 'time-stamp) @c page-delimiter: "^\\\\message" @c time-stamp-start: "def\\\\texinfoversion{" @c time-stamp-format: "%:y-%02m-%02d.%02H" @c time-stamp-end: "}" @c End: @c vim:sw=2: @ignore arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115 @end ignore gri/doc/cmdrefcard.pl0000755000175000017500000000060313147557614013216 0ustar psgpsg#!/usr/bin/perl -w # Scan for commands in gri.cmd # Usage: # ./cmdrefcard.pl ../gri.cmd while(<>) { if (/^\`(.*)\'$/) { $a = $1; $a =~ s/^\`//; $a =~ s/\'\$//; $a =~ s/\\/\$\\backslash\$/g; $a =~ s/\{/\$\\lbrace\$/g; $a =~ s/\}/\$\\rbrace\$/g; $a =~ s/\|/\$\\mid\$/g; $a =~ s/_/\\_/g; print "$a\n\n"; } } gri/doc/install-sh0000755000175000017500000001124313147557614012572 0ustar psgpsg#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" tranformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 gri/doc/make_html_commandindex0000644000175000017500000000155313147557614015203 0ustar psgpsg#!/usr/local/bin/perl # Create HTML index from index of pre-installed info page. # Bug: the @code{} items get lost, too bad. open(IN, "info -f ./gri.info 'Index of Commands' |") || die "Cannot get 'Index of Commands'\n"; # Following is kludge, really print " \@c HTML \@c HTML

    Command index

    \@node Index of Commands, Index of Builtins, License, Top \@c HTML Navigation: \@c HTML next, \@c HTML previous, \@c HTML parent. \@itemize \@bullet "; while() { next if (/\*\s*Menu:\s*$/); if (/\* .*\./) { s/\* //; s/\.$//; s/:\s*/\n ... \@xref{/; s/$/}./; print "\@item\n $_"; } } print "\n\@end itemize\n"; #print "\n\@c HTML Dan Kelley\n"; gri/doc/examples/0000755000175000017500000000000013147560320012367 5ustar psgpsggri/doc/examples/example6histogram.txt0000644000175000017500000000002613147557614016601 0ustar psgpsgexample6histogram.gri gri/doc/examples/FEM.png0000644000175000017500000001745713147557614013536 0ustar psgpsg‰PNG  IHDRQMéò€ábKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk> vpAgQM0b6IDATxÚíÝ=rãÊzàá½'™*'£È±Nd'.߈ZÂLêLZÂp Ò4pYZ‚9–§®’b;Ñ$®:!´?ë4†ÿtxž¤…A$øêHÍÖëõz½þ½úKé `šÑŽÍf³Ùl¶X”Þó4?ó4¿±û<Ç>¿©Ìsìókkž‚(EŒ6ˆFBOãËK×ë|ùë×ÒÛ 0U£ ¢ÉÝ]¯¯Ó›²f³Xο@ßFD#€®Vù×þLã—/¥·`ª~+½]iÐt*þñ1-ÅEµ··Ç®ÿ°‹sçótûÒ÷Jׯ>Ͼç÷·¿¥ñ?ÿ3ÿõ_ãœgßÌoÆ>ϱÏo*óûüÂ?ÿó¾óü%ŸMõsDÓöý{Zúò%ÝËe7ÿÏb±¹™…\z¼DSÿò’Ƈ‡ôø‰KJ §æœÑžšOwÌÍͶï§;,ѤPƒx<þø‘ÆxÓÝùyé-€6öÔ|òõkTÅÍÆ3ªšJÊÊ›Ðø4‡‹‹4¾¾¦1ªf€qm#š|û–Æh”âã›âb„h˜¼°Sƒšq*þçÏ4jF§Ñ6¢éüù9-E³uù¸ mj^Jâ(†mä( Á¯MhóšQÆH…67¡û~œ˜7Ù0‚(³» mÒŒ0&‚(ôè´&´I3 À° ¢Ð»Ã›Ð&Í(c ˆBÚmB›4£ “ ½9½ mÒŒ0d‚(t¨Û&´I3 À°¢Ð¹ö›Ð&Í(C$ˆBúmB›4£ ƒ é¾ mÒŒ0$‚(´¨lÚ¤ n‚(´®ÿ&´I3 À¢Ð‚ºšÐ&Í(uD¡5å›Ð&Í(5Dáu7¡MšQê"ˆÂÉêkB›4£ÔH…# « mÒŒPAŽVÚ¤ &‚(`ØMh“f€²ª ¢Ñ̤ñþ>ëu>>>¦q>ßo}óy_^òõÄòîõÀ¯†×„6iF¨A5A4¹¹É—ÏÎÒ æl––ŸŸÓxw·ßúÓx}¯çú:ÿ>|l\Mh“f€2~+½¹××4þøÑlšÒòrÍfé-eІ߄6E3šŸ)8?O_ç#t£š AsÛ÷Ó d4¦û6Q——iŒSúÑh…ã­´¾Åb¿[;å9T››Ð‹‹ÒÛÕf3gà#q)äî[¦¼·ZÅò,}¡ô~•&tu•–b\­vÖüç›§ú›ÁóýTä¾ë=n‹EóŽgš£®'µˆf4-]^jFøÈ©9§š š¿Yâþ>1¡ÛÛCO…Æ)üüÚÐãowÚ¼ѡɛЧ§4^\Œå”üÇóŽ_üæó4_Í(›šs*{³R¼ )®Á[.w½ðǰùÔûjV|?£éÙd|ׄîâÝôô©² ×\Fpl~|Óû˜ÿ\¼û½ùqLÑäÄ éÛ[>Æ×5>$ã~wü¡¼›€nUöf¥ÃOoû¹üÚ¶oßJÏ!™^ÚäÝôô¡²FÊЄ~D3 @7QøšÐ&׌Ð%A”IÓ„B3 @»QЄî¤  ‚(“¤ =…f€v¢L˜&ôPšQÚ$ˆ2)šÐ6iF8 ÊiBO¥  ‚(“  í’f€ã¢Lˆ&´mšQN!ˆ2jšÐ>iF8Œ ÊhB»¦à‚(£¤ -I3 À~QFLÚ7Í(‡DMhM4£|Le„4¡¥iF؇ Ê(hBk¦`3A”Ñ„ÖF3 ÀGQM:$šQrÕÑhJÒxŸÆõ:Ó8Ÿ¶Þ››4¾½å뻹)=oÚ  ­f€Mª ¢I3ž¥°Ù,-??§ñînךò /x¿ÿëMãׯévWW¥gÎa4¡C¦ ù­ôä^_ÓøãG³ÙJËËe4šû­o±Hãõõæ¦,‚)ä šhFÓóøå%šÑôõxþ0ÕÑšÛ¾Ÿ7œû6_q ?šÏÇÇ´MÚÃC¬/ýÿѸî–ÖAw§ Û²¹ ½¸(½]£ÙŒ^_—Þ"Ž1Ÿ§×çÝ·LykµŠåj‚hS~Ê<ÆÕjW`Ý,‚Ëï¿Gs–Û//÷]cóŽüxûVö£ :Í(À˜iBa;Í(@WQþD ¦è– :qšPØ—f m‚(Ÿ4¡ð1Í(@7щ҄±4£mD'M ‡ÐŒ´KM(´E3 p*At’4¡p Í(@;щЄBW4£ÇD'E mÒŒœF9M(ôE3 p(At4¡Ð%Í(Àqª ¢qàNãý}×ë|||Lã|Þ÷ú†F ¥hFöUMMnnòå³³Ô4Ìfiùù9wweÖ74šPè“fà0¿•Þ€Üëküh§´¼\F£Yf}õÛÜ„^\”Þ.˜žf3z}]z‹j3K¬ôf챡³Ùl6{o8#H–Z_úùÅb¿[ŸŸçMÉpî'àxéùøò’–./Óó1~A¾tœ‹_¸ãLóvé8¸ZýÿÏ×DÓÄ®®ÒRŒ«Õ±Áªíõöÿ.Í;¾›ÿ'šÐ§§4^\8%åäÇù<=5£Àxœšsª95Ÿ_KuŸÆ˜P4 ûª¶×7 ® …šÄ™hF㸤H*{³R¼i(‚Ôr¹+PEÏÁã×74ÞCáÝôMÕœš?ôMCñî÷üç¢é\­Ž]_7óêîÔ¼kBa8\3 ŒÍhNÍ·ý\WÁ²ÞCåÝô¡²SóÆ5¡0$>g 'ˆŒkBa,\3 ˆ’&†L3 ¢¡ …±ÒŒÓ%ˆŠ&ÆD3 L Z9M(L…f˜At4¡0fšQ`ªÑJiBaª4£Àt¢Uӄ”hF©D+£ Í(0~‚h•4¡0ešQ`*ÑJhBÍ4£Àx ¢UÑ„ï4£ÀØ ¢…iBýhFñD«  ¶ÓŒc%ˆ¢ Ž£ÆC-J ìO3 Œ Ú3M(ÐÍ(0|‚hšPàxšQ`,FDãÀœÆûû4®×ùøø˜Æù¼ŸíÑ„mÓŒõ3ˆ¦usÓW`k×ÍM¾|v–š„Ù,-??§ñíÑ„íÑŒC÷Ûa7f1ÔÃCŒé€øúZzB¹Øž?šÁ/-/—Ñv»÷wiŒ&ôâ¢ô=ŒM³½¾.½E»ÌR ;à²f4‚UŒÑ0®Vi¬·ù‹¦7–#˜vóÿü뿦¥¿þ5Ñ`´íþ>——é¸Çe€ö¥œ³X¤ãMä¿ý؈†–Ñ8Æn±Hc\ §ô—ËüR©;êê*-ŸZ@ãŽßïÖÿôOiü‡Èï7€¶Åñ8®3W··už¹†o>OǛݷlÖhZqœê‰æ3®AŠ\ºX~³PZzyɯÍì^þÿGCr÷Mmڎ浨„£±¨¯1†'?ÓÇ»8Æq¼yLãÚˆîù®ù8Å+Þôs}Ý  !?À]^–¹{"øÅ%ÑÌöüòF8Æh,¢AhOwÒøûïé«ÍÆôîΛœ€RvÑ]s¿Ÿ?Ã’WãõJ0¥.QÌ{¼©ìÔ|Û¾€(#x¾RŽã”=@»œÊg D#‰o<«U4ù»ðc|oJÏc,R€n¦ŒÑàƒhï~ožúŽ7;Å2>*Æøº7EµM è–`ÊTóf¥mv]ºíûùµ3ß¾•žÇTyS@?¼ù‰!I#Jí4¤ýÒ˜2‚(½HÊL©‘ J)@Y‚)5D)J ¨ƒ`J ‚(UHê"˜ÒA”ª¤uLé‚ J•R€º ¦´A¥j)À0¦CeR€aLÙ‡ Ê ¤Ã$˜²‰ Ê ¤Ã&˜òé“ ÊÀ ¤ã ˜N“ Ê(¤ã"˜Nƒ ʨ¤ã$˜Ž“ Ê( ¤ã&˜Žƒ ʨ ¤Ó ˜“ Ê$¤Ó"˜ƒ ʤ¤Ó$˜ÖIe’R€iLëPm@Æ··ÓÖssëIãz_/=OÊHøôI0-¥š ;6ˆOOi<<äë‰L<°ÎÎÒøõkºÝÕUéùS–@ ÀŸ ¦ý¨&ˆ&?¦qµJãõõië[,Òx{›H?æãï¿ç„©HØD0íÆo¥7 D@LKD£ÙäEÇ÷ïiüú5Ñ„^\4_wò×§Ã ¢0)m:6x¶M…H8F-Á³I…HøH­Á³I…Høôi8Á³I…H¦e¨Á³I…HÆi,Á³I…H†m¬Á³I…H†a*Á³©Ú¿¬”¢ÿÛ[;ë;?ok}0$þR@]öûËE<—˱ÐPM#A1-Åß.ßÚz¡Œß0¼ð2MR€2¦ÚxîRY#wüj•ÆëëSטv|ìðØÑ0mR€ni<÷SM#šï€¢Çÿ ÓôsóyZšÏÓúooOý›¨ùú‹ýnýùs×÷CC ÐŽi7žóù¾ù*Íÿ=çUD»¿œÞ¬65ïÈmÒŽùãÒ÷|D 8Ì´ƒgÓó󾹨©²Só§Ë›Ê_^Ò××ëüvëuKo7ÔÀ){€ÍœjïÆàÑR`ê4žýI#f\ ´AC L…ƳŒêÑ]Íå¡Í¦&§!ÆFãY‡êƒ(P*Á³N‚(p0¨à9 ‚(p4¨…à9L‚(p2è›à9‚(ÐèŠà9N‚(Ð:8•à9 ‚(ÐØ—à9M‚(Ð9h<ùôIz$Ât žl"ˆ½HaüOö!ˆÅ¤0‚'ÇDâRÁ“6¢@5R¨—àIQ :)”'xÒA¨–@ ý<)Aª'BûOj ˆƒ!ÂñOj$ˆƒ#Ân‚'C ˆƒ%Â;Á“!úKé Ø&žPi|{;îçÏÏÓxŸÆõ:ãk>/=_àxHÓRŒñüŽf—üuòæ&}õé)¿UÏåR¥FÕÑ<86ŸPǾÄzÂÙYz"FwòüœÆ»»ÒóN'2f‚'cTÙ©ùx¬VùøøxÜú^_ÓøãGó OÔhHKÏhSöŒSíLA5A4"E'â±ë[.·}?ÿòööÐõ§Ÿ_,ö»õçÏ]ÞwÀf)C"x2\óù¾y-=~ßs^5A´k麺JK1®V»ë6Í;òãÿ÷?JϦL ¥F‚'ãñü¼o.jmkNÓÒý}ãòÂS$R’à ¿|ÍO‘G"'p¼ éá!}ýðSðÀø¤ôAð„ݪy×üiâÍLÍaŠ€zs³ùã›ÞÇÒ3úç]ö´É»ÚápÕ7¢ùÇ-íÿý]?4¤Cã §«>ˆôE å#‚'´OhHùôIð„>¢[¤Ó"xBÿQ€Òq<¡Nã”Þó3OóûÿHã¿ý[ÿçJoY»"h¿¾–Þó3ÏéÎ/Ä/¼ÏÏ»n™ò×û™›‘7¢ÝiÞ‘ÛDS±ïí‡*‚ùXç9öùMežæ7cŸçØç7•yŽ}~ù<Ï9)=¦I A€"&DO}“í˜Ü»æ¨ÃäQê ˆP„ @‚(E¢!ˆP„ Ú±ô7X¿|IãÛ[éí9nû_^N›÷Ý]Ì?ëuÓ8Ÿ—ßÓS»ë›ÏkÛßÇîÇüçon6ïÇûûØßeçwü~Ì÷ÛËK>¿X.÷8ýx»ÏÏóýÛ]Ïóìãíßö¸:|»Û^_;óënÿäë/w¼éf?6_?Ê=ÛÞC=ÞäÛ¿X|¼ý_¿î½ÂøQc;cr~žÆ››4FX¯Koß~ÛÛýøxìv'ß¿§1Âùùæÿçå¥ßù-i¼»kk¿$ÄÚ[oû1Öû1æãý}Ì»ßù]]:¿|}ñB¾Xl~¼¼½•ÚŸowÜÿ1~ù²mÿ•ÞÞ|»â…6ŽÇÚ^ßPöOéãMW÷{þsï÷[#à w?õx“ogìïÓ·¿ø„Æ6æO˜Ø!1®×¥·o¿í?}»“ ïÔÍ·ëï~‰eÛû%?ŹÜþnw?FÏKÍgóvÅý|ú~ê Cþ¸{›owüýÓÍvÇýzuuêv·½¾Ú÷O¿è—{}éê~¯í¸Óö~êñ¦¹?ÑêÆÚ^JowþÄî¯Ik{~Iü†~sSëþ>-ˆÆ¿bÅ4¾ A¹ŒvöcÌ/¾cÌ·ü âióz|Ö>¶}|¨åxsêþ‰Ça<ïò¯¯×¥çÓÖý¾ù¸ËÑÄÕó|~ýºïz\#J/⚑浊éx}]zûŽ›O4«Ñ,—¥·«[qÀ¹¸HóÍÒòósã@<qm[þÕ³³|üñ#Ñð×+ÍçêªyÍlíÏüš³¸Ô"¾Ým¯¯ÝyžºâñZßþl÷~ÿù3«U~¼‰çcü\jž§îÇ(0b>ÍãζãS=Ò|›û'æÀñ²t¢žÊøç{»†íéz»“¸D!Hq-ÓöSÚ߶mÛXî7ÜÓæ¿8lßþÒïÓæ·ûçJÏïãíŠ_ˆâ1—ï×°Õ:æÛÁâøãCÛë«eÿ$Ûš§mããã°÷ã{ã»ùûëõÐöã¡Û_Ûq'¶wÉ]ñ‰Me¬íÕÖvDZùÀÌŸ¨õžb8v~CÛßûÍ30Û/Âo¾Àäßïï…¯­ýÛÝ|aÉÇòóûx^±ýß¿—ޞö;oû߯ïÇÃ×WëþÙö|üøöëõÐ÷cþýxÞm{]é;h··‡z܉ùç¯Û^/xsZé‰Me,u èz»ó'Úûíò'Z|eû8´ù mï7ÏøWóÀÿë§äã¯ï"­s~Û§ÑtÄ<¶Í¯ž&ó~«÷y¶y»÷?£°ß~<|}µîŸmÏÇcÿCÙù÷›gÔâ;±Üß5¢mïÇqw¶í÷Ã÷Ï,_1ôÛ•(B A€"QŠD(B A€"QŠDj6›Íf³¯_Óøô”Æ/_ò1¾É þ²ÀÀ¥ Ùü›ÕáçÏtœ_.Ko'@“ 0pÑ€¦¥ø[Ïñ·œ/.JoÀ6NÍŒÊ{#šT€úhD.Îûû´ôðÆù<_¾¤ãüõuéíhÒˆ T  ß¿Çr œù5¡óy¼©©ôö4iD(B# @‚(E¢!ˆPÄÿ#^D>÷õc%tEXtcreate-date2009-12-13T11:44:15-04:00­å`%tEXtmodify-date2009-12-13T11:44:15-04:00òThT#tEXtps:HiResBoundingBox337x333+126+130³èqÆtEXtps:LevelAdobe-2.0 EPSF-1.2 ÞÙÈoIEND®B`‚gri/doc/examples/example7b.dat0000644000175000017500000001111313147557614014756 0ustar psgpsg 0.440 -0.357 0.218 -0.662 0.314 -0.503 0.274 -0.562 0.429 -0.368 0.387 -0.412 0.277 -0.558 0.298 -0.526 0.191 -0.719 0.154 -0.812 0.293 -0.533 0.287 -0.542 0.231 -0.636 0.255 -0.593 0.740 -0.131 0.288 -0.541 0.207 -0.684 0.526 -0.279 0.566 -0.247 0.317 -0.499 0.376 -0.425 1.704 0.231 1.016 0.007 0.264 -0.578 0.318 -0.498 0.244 -0.613 0.237 -0.625 0.188 -0.726 0.343 -0.465 0.173 -0.762 0.328 -0.484 0.202 -0.695 0.210 -0.678 0.535 -0.272 0.174 -0.759 0.296 -0.529 0.421 -0.376 0.774 -0.111 0.493 -0.307 0.391 -0.408 0.128 -0.893 0.098 -1.009 0.743 -0.129 0.170 -0.770 0.262 -0.582 0.495 -0.305 0.243 -0.614 0.389 -0.410 0.120 -0.921 0.289 -0.539 0.244 -0.613 0.466 -0.332 0.301 -0.521 0.274 -0.562 0.114 -0.943 0.354 -0.451 0.519 -0.285 0.335 -0.475 0.269 -0.570 0.287 -0.542 0.736 -0.133 0.146 -0.836 0.166 -0.780 0.242 -0.616 0.858 -0.067 0.316 -0.500 0.133 -0.876 0.212 -0.674 0.416 -0.381 0.480 -0.319 0.095 -1.022 0.264 -0.578 0.117 -0.932 0.341 -0.467 0.346 -0.461 0.166 -0.780 0.642 -0.192 0.264 -0.578 0.271 -0.567 0.458 -0.339 0.241 -0.618 0.122 -0.914 5.465 0.738 4.503 0.654 0.793 -0.101 0.200 -0.699 0.179 -0.747 0.170 -0.770 0.155 -0.810 0.313 -0.504 0.237 -0.625 0.261 -0.583 0.332 -0.479 0.399 -0.399 0.373 -0.428 0.609 -0.215 0.227 -0.644 0.264 -0.578 0.222 -0.654 0.168 -0.775 0.164 -0.785 0.271 -0.567 0.363 -0.440 0.238 -0.623 0.249 -0.604 0.162 -0.790 0.111 -0.955 0.240 -0.620 0.256 -0.592 0.253 -0.597 0.201 -0.697 0.432 -0.365 0.280 -0.553 0.199 -0.701 0.205 -0.688 0.357 -0.447 0.178 -0.750 0.197 -0.706 0.521 -0.283 0.257 -0.590 0.555 -0.256 0.426 -0.371 0.367 -0.435 0.334 -0.476 0.346 -0.461 0.264 -0.578 0.161 -0.793 0.284 -0.547 0.209 -0.680 0.283 -0.548 0.451 -0.346 0.685 -0.164 0.294 -0.532 0.216 -0.666 0.737 -0.133 0.577 -0.239 0.500 -0.301 0.264 -0.578 0.318 -0.498 0.226 -0.646 0.102 -0.991 0.525 -0.280 0.191 -0.719 0.669 -0.175 0.251 -0.600 0.408 -0.389 0.378 -0.423 0.462 -0.335 0.317 -0.499 0.193 -0.714 0.558 -0.253 0.070 -1.155 0.297 -0.527 0.499 -0.302 0.284 -0.547 0.175 -0.757 0.376 -0.425 0.724 -0.140 0.150 -0.824 0.387 -0.412 0.558 -0.253 1.103 0.043 0.354 -0.451 0.312 -0.506 0.221 -0.656 0.300 -0.523 0.688 -0.162 0.218 -0.662 0.376 -0.425 0.228 -0.642 0.261 -0.583 0.275 -0.561 0.215 -0.668 0.291 -0.536 0.422 -0.375 0.263 -0.580 0.405 -0.393 0.214 -0.670 0.438 -0.359 0.324 -0.489 0.262 -0.582 0.336 -0.474 0.357 -0.447 0.336 -0.474 0.674 -0.171 0.482 -0.317 0.430 -0.367 0.259 -0.587 0.384 -0.416 0.613 -0.213 0.230 -0.638 0.234 -0.631 0.541 -0.267 0.270 -0.569 0.473 -0.325 0.341 -0.467 0.534 -0.272 0.224 -0.650 0.226 -0.646 0.581 -0.236 0.291 -0.536 0.258 -0.588 0.175 -0.757 0.165 -0.783 2.214 0.345 0.514 -0.289 0.264 -0.578 0.307 -0.513 0.252 -0.599 0.263 -0.580 0.338 -0.471 0.184 -0.735 0.181 -0.742 0.135 -0.870 0.377 -0.424 0.214 -0.670 0.363 -0.440 0.360 -0.444 0.480 -0.319 0.354 -0.451 0.337 -0.472 0.475 -0.323 1.345 0.129 gri/doc/examples/FEM.pl0000755000175000017500000000305513147557614013355 0ustar psgpsg#!/usr/bin/perl -w $missing = -99.99; # missing value $debug = 0; # set to 1 to debug $node_file = $ARGV[0]; $element_file = $ARGV[1]; open (NODE, $node_file) or die "Cannot open '$node_file' file"; open (ELEM, $element_file) or die "Cannot open '$element_file' file"; # Read in node information, creating arrays $node_x[] and $node_y[]. # While reading, check that the first column (the index) makes sense. $max_node = 1; while() { ($index, $node_x[$max_node], $node_y[$max_node]) = split; if ($debug) { chop; print "NODE $index data: '$_'\n"; } die "Node index mismatch at index=$index" if ($index != $max_node); $max_node++; } # Read in triangle elements, into arrays, $a[], $b[], and $c[]. # While reading, check that the first column (the index) makes sense. $max_elem = 1; while() { ($index, $a[$max_elem], $b[$max_elem], $c[$max_elem]) = split; if ($debug) { chop; print "ELEM $index data: '$_' a[$max_elem]=$a[$max_elem] etc\n"; } die "Element index mismatch at index=$index" if ($index != $max_elem); $max_elem++; } # Print out triangles suitable for plotting in gri. for ($i = 1; $i < $max_elem; $i++) { if ($debug) { print "i=", $i," c[i]=", $c[$i], " node_x[]=", $node_x[$c[$i]], "\n"; } print $node_x[$a[$i]], " ", $node_y[$a[$i]], "\n"; print $node_x[$b[$i]], " ", $node_y[$b[$i]], "\n"; print $node_x[$c[$i]], " ", $node_y[$c[$i]], "\n"; # Repeat first, to close the triangle. print $node_x[$a[$i]], " ", $node_y[$a[$i]], "\n"; print $missing, " ", $missing, "\n"; } gri/doc/examples/example10.ps0000644000175000017500000033741413147557614014557 0ustar psgpsg%!PS-Adobe-2.0 EPSF-1.2 %%Creator: Gri2.2.4 (released 1999-Oct-20). User=kelley, commandfile=example10.gri %%Title: example10.ps %%CreationDate: Thu Oct 21 11:30:29 1999 %%Pages: (atend) %%BoundingBox: (atend) %%TemplateBox: 0 0 612 792 %%DocumentFonts: (atend) %%Endcomments % NOTE: The Gri postscript dictionary is being converted to the Adobe % Illustrator 3.0 dialect of PostScript, as described in the Adobe % documents stored at URL % http://www.adobe.com/Support/TechNotes.html % (as of Jan 1996, this doc is number 5007). When the conversion % is complete, the Adobe Illustrator drawing program -- and any % program compatible with AI -- will be able to edit Gri output. % % The IslandDraw (TM) program is able to read Gri output % at this time; remarkably, it can read/edit arbitrary PostScript. % % The definitions below are presented in the same order as the Adobe % manual. The stack configuration before and after is shown in curly % brackets. All the operators are listed, but only some are defined % here. Most things are faithful, except that no distinction is made % between colors for stroking and filling paths. The string 'WRONGLY' % appears with commands that are approximations. % % PDF-style abbreviations: /rg {setrgbcolor} def % {red green blue} {-} set RGB color /RG {setrgbcolor} def % {red green blue} {-} set RGB color /q {gsave} def /Q {grestore} def /W {clip} def /W* {eoclip} def % % Gri-specific abbreviations: /hsb {sethsbcolor} def % {hue saturation brightness} {-} set HSB color % % Following all try to mimic Adobe Illustrator % % Mimicking section 5.1 of Adobe manual: %A % {flag A} {-} Determine whether % following object can % be selected. Flag=1 % prevents selection; % flag=0 allows it. % Mimicking section 5.2 of Adobe manual: %u % {u} {-} start group %U % end group %q % as 'u' but first item is a clip path %Q % as 'U' but first item is a clip path % Mimicking section 5.3 of Adobe manual: /g {setgray} def % {gray g} {-} Set gray for fill % path, WRONGLY used % for stroking also. /G {setgray} def % As 'g', but for filling path. %k % Set cmyk color for filling path. %K % As 'k', but for stroking path. %x % Set cmyk custom color for filling path. %X % As 'x' but for stroking path. %p % Define pattern for filling path. %P % As 'p' but for stroking path. %O % Specify whether overprinting for fill paths %R % As 'O' but for stroking path. % Mimicking section 5.4 of Adobe manual: /d {setdash} def % {[array] phase d} {-} Set dash. /i {setflat} def % {flatness i} {-} Set flatness. /j {setlinejoin} def % {linejoin j} {-} Set line join. /J {setlinecap} def % {linecap J} {-} Set line cap. /M {setmiterlimit} def % {miterlimit M} {-} Set miter limit. /w {setlinewidth} def % {linewidth w} {-} Set line width. % Mimicking section 5.5 of Adobe manual: /m {moveto} def % {x y m} {-} Move to locn /l {lineto} def % {x y l} {-} Draw line to locn % not a smooth point. % WRONGLY, no % distinction is made % between smooth and % corner. %L % {x y L} {-} As 'l' but a corner %c % Bezier curve to smooth point. %C % As 'c' but to corner point. %v % Something else to do with Bezier. %V % %y % %Y % % Mimicking section 5.6 of Adobe manual: %N % {N} {-} As 'n' for nondrawn stuff /n {newpath} def % {n} {-} WRONGLY interpreted % as path constructor /F {fill} def % {F} {-} Fill current path. %f % {f} {-} 'F' but close first /S {stroke} def % {S} {-} Stroke current path. %s % {s} {-} 'S' but close first %B % {B} {-} As 's' but don't empty path. %b % {b} {-} As 'f' but don't empty path. %H % no-op (weird huh?) /h {closepath} def % {h} {-} Close current path %W % Used to create masks. % Mimicking section 5.7 of Adobe manual: %a % Begin text block ... %e % Similar to 'a' but ... %I % Similar to 'a' but ... %o % Similar to 'a' but ... %r % Similar to 'a' but ... %t % {len (string) t} {-} Render string. %T % End block of text % That's the end of the Illustrator stuff. Following are some Gri % definitions which provide a temporary way of handling fonts. /sf {setfont} def % {fontname sf} {-} Set font name. /sh {show} def % {(text) sh} {-} Show text. /sc {scalefont} def % {size sc} {-} Scale font. % Gri items which should be translated to Illustrator format: /rl {rlineto} def /rm {rmoveto} def % Procedures /cimdict 7 dict def /cim { cimdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def q xll yll translate xur xll sub yur yll sub scale /do cl 3 mul string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop} false 3 colorimage Q end } def /imdict 14 dict def /im { imdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def /imagemap exch def q % Add the mapping to the transfer function (ref: white book, p 743. [{255 mul cvi imagemap exch get} /exec load currenttransfer /exec load] cvx settransfer xll yll translate xur xll sub yur yll sub scale /do cl string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop}image Q end } def /frdict 5 dict def /fr { frdict begin /yt exch def /xr exch def /yb exch def /xl exch def n xl yb m xl yt l xr yt l xr yb l h F n end } def /plusdict 3 dict def /_plus { plusdict begin dup 0.5 mul /t0 exch def /t1 exch def 0 t0 rm 0 t1 neg rl t0 neg t0 rm t1 0 rl t0 neg 0 rm end } def /timesdict 3 dict def /_times { timesdict begin dup 0.353553 mul /t0 exch def 0.707106 mul /t1 exch def t0 neg t0 rm t1 dup neg rl t1 neg 0 rm t1 dup rl t0 neg dup rm end } def /boxdict 3 dict def /_box { boxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm end } def /filledboxdict 3 dict def /_filledbox { filledboxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm F end } def /diamonddict 2 dict def /_diamond { diamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm end } def /filleddiamonddict 2 dict def /_filleddiamond { filleddiamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm F end } def /triangleupdict 5 dict def /_triangleup { triangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm end } def /filledtriangleupdict 5 dict def /_filledtriangleup { filledtriangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm F end } def /trianglerightdict 5 dict def /_triangleright { trianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm end } def /filledtrianglerightdict 5 dict def /_filledtriangleright { filledtrianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm F end } def /triangledowndict 5 dict def /_triangledown { triangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm end } def /filledtriangledowndict 5 dict def /_filledtriangledown { filledtriangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm F end } def /triangleleftdict 5 dict def /_triangleleft { triangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm end } def /filledtriangleleftdict 5 dict def /_filledtriangleleft { filledtriangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm F end } def /circdict 5 dict def /_circ { circdict begin 0.5 mul /t0 exch def currentpoint /t2 exch def /t1 exch def S n t1 t2 t0 0 360 arc t1 t2 m end } def /bulldict 3 dict def /_bull { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 360 arc h F S end } def /filledhalfmoonupdict 3 dict def /_filledhalfmoonup { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 180 arc h F S end } def /filledhalfmoondowndict 3 dict def /_filledhalfmoondown { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 180 360 arc h F S end } def 1 1 scale 10.0 M 1 j /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-ISOLatin1 exch definefont pop /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Bold-ISOLatin1 exch definefont pop /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-ISOLatin1 exch definefont pop /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Bold-ISOLatin1 exch definefont pop /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Roman-ISOLatin1 exch definefont pop /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Bold-ISOLatin1 exch definefont pop /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Italic-ISOLatin1 exch definefont pop /Symbol findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Symbol-ISOLatin1 exch definefont pop /Times findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-ISOLatin1 exch definefont pop /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Bold-ISOLatin1 exch definefont pop /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Roman-ISOLatin1 exch definefont pop %%EndProlog %%Page: 1 1 /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:# Example 10 -- Draw image plot of flushing of dye out of cove %gri:# $Id: example10.ps,v 1.2 2000/05/29 19:45:11 psg Exp $ %gri: %gri:if !..publication.. %gri: draw time stamp %gri:end if %gri:\file = "example10.dat" %gri:query \contours "Superimpose contours? (yes|no)" ("yes") %gri:query \file "Input file name " ("\file") %gri:open \file %gri:read line \header %gri:read \D %gri:read .nx. %gri:read .ny. %gri:set x name "distance along cove" %gri:set y name "time" %gri:set x grid 0 1 /.nx. %gri:set x axis 0 1 0.5 0.1 %gri:set y grid 0 .ny. / .ny. %gri:set y axis 0 .ny. %gri:read grid data * * .ny. .nx. %gri:set image range 0 20 %gri:set image grayscale black 20 white 0 increment 5 %gri:convert grid to image %gri:draw image %^ scale 1 170.7 0 284.5 1 170.7 0 3.51235 % Push map onto stack, then image stuff. [ 1.0000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.0000 ] %BEGIN_IMAGE 169.579921 169.579921 456.320079 456.320079 128 128 im FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFEFEFEFEFEFEFEFCFCFCFCFCFBFAF7F6F6F6F6F5F1ECECECECECE8E2DFDFDFDFDED8FFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFEFEFEFEFDFDFDFCFBFBFAF9F8F7F5F3F0EDEBEAE7E1DBD5D0CBC8C2B8AEA4 9A9590887D72675D58FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFEFEFEFEFEFEFDFDFDFDFCFBFBFBFAFAF8F7F6F5F4F3F1EFEDEBE9E7E4E1DCD8D5D1CDC9 C2BCB5AFA9A39C938B837A726A625B5349423A33FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFEFEFEFEFEFEFEFEFDFDFDFDFCFCFBFBFAFAF9F8F7F6F5F4F3F1EEECEAE8E6E4E0DCD8 D4D0CDC9C3BEB8B2ADA7A19B948D868079736D67615A544E4A46423E3A3633FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFEFEFEFEFEFEFEFDFDFDFDFCFCFBFBFBFAF9F8F7F6F6F5F4F2F0EEEDECEAE8E5E2DF DCDAD7D4CFCBC7C3C0BBB6B1ABA6A29D97928C87817C76716C68635D5854504D4A46423F3C3A39 383633FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFEFEFEFEFEFEFEFEFDFDFDFDFCFCFBFBFBFAFAF9F8F7F6F6F5F4F3F1EFEEEDEBE9E7 E4E1DFDDDAD8D4D0CDC9C6C2BEBAB5B0ACA7A39E99948F8A85807B77726D68635F5C5954504C49 464543403D3B3938383735343433FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFEFDFDFDFDFDFCFCFBFBFAFAF9F8F7F6F6F5F4F3F1EFEE ECEAE8E7E4E1DFDCD9D6D4D0CCC8C4C1BDB9B4B0ABA6A29D99948F8A85817C77736F6A66625E5A 5754514D4A474543413F3D3B3A393837373635353434343333FFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFEFEFEFEFDFDFDFCFCFCFBFBFAFAF9F8F8F7F6F5F4F3F2 F1F0EEECEAE8E7E5E3E0DEDBD8D6D3D0CCC9C5C2BEBAB6B2AEAAA6A29D9994908B87837E7A7672 6E6A66625F5C5955524F4C4A484643413F3E3D3C3A393837373636353434343434333333FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFEFEFDFDFDFDFCFCFCFBFAFAFAF9F9F8F7 F6F5F4F3F2F1EFEDECEAE9E7E5E2E0DEDBD9D6D3D0CDC9C6C3BFBBB7B3AFACA7A39F9B96928E89 85817D7974706D6966625F5B585553504D4A48464443413F3E3C3B3A3938383736363535353434 3434333333333333FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFEFEFEFDFDFDFDFCFCFCFBFBFA FAF9F9F8F7F6F5F4F3F3F1F0EEEDEBEAE8E6E4E1DFDDDBD8D5D2CFCCC9C6C3BFBBB7B4B0ACA8A4 A09C9894908C8884807C7773706D6966625E5B595653514E4B4947464442403F3E3D3C3B3A3838 37373636353535343434343433333333333333FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFDFDFDFDFD FCFCFBFBFBFAFAF9F9F8F7F6F6F5F4F3F1F0EFEEECEBE9E7E5E3E1DFDDDAD8D5D3D0CDCAC7C3C0 BDB9B6B2AEAAA7A39F9B97938F8B8884807C7875716D6A6764615E5A575553504E4C4947464443 413F3E3D3C3B3A3938383737363635353534343434343433333333333333FEFEFEFEFEFEFEFEFD FDFDFDFDFDFCFCFCFCFBFBFBFAFAF9F8F8F7F7F6F5F4F3F2F1EFEEECEBE9E8E6E4E2E0DEDCDAD7 D4D2CFCCC9C6C3C0BDB9B6B2AFACA8A4A09D9995928E8A86837F7B7875716E6A6764615F5C5956 5452504D4B494745444341403F3D3C3C3B3A393838373736363635353534343434343433333333 3333FDFDFDFDFDFDFDFDFCFCFCFCFCFBFBFBFAFAFAF9F9F8F7F7F6F5F4F4F3F2F0EFEEEDECEAE8 E7E5E3E2E0DDDBD9D7D4D2CFCCCAC7C4C1BEBBB7B4B1AEAAA7A3A09D9996928E8B8884817D7A77 73706D6A6764625F5C5A575553514F4D4B494746444342403F3E3D3C3B3B3A3938383737363636 35353535343434343433333333FCFCFCFCFCFCFCFBFBFBFBFBFAFAFAF9F9F8F8F7F7F6F5F5F4F3 F2F1F0EFEEEDEBEAE9E7E5E4E2E0DFDDDAD8D6D4D1CFCCCAC7C4C2BFBCB9B6B3B0ADA9A6A3A09C 9996938F8C8986827F7C797673706D6A686563605E5B59575553514F4D4B4A484745444241403F 3E3D3C3B3B3A3A3938383737373636353535353434343433FAFAFAFAFAFAFAFAFAFAF9F9F9F9F8 F8F7F7F6F6F5F4F4F3F2F1F0EFEEEDECEAE9E8E7E5E3E2E0DEDDDBD9D6D4D2D0CECBC9C6C4C1BF BCB9B6B4B1AEABA8A5A29F9C999693908D8A8784817E7B787673706D6B696664615F5D5B595654 52514F4D4C4A49474645434241403F3E3D3D3C3B3A3A39393838373736363535353434F9F9F9F9 F9F9F9F9F8F8F8F8F8F7F7F6F6F5F5F4F4F3F2F2F1F0EFEEEDECEBEAE9E8E6E5E3E2E0DFDDDBD9 D7D6D4D2D0CDCBC9C7C5C2C0BDBBB8B6B3B1AEABA8A6A3A09D9B989592908D8A8785827F7D7A77 7573706E6B69676563605E5C5A5957555351504E4D4C4A4947464544434241403F3E3E3D3C3B3B 3A3A3938383737F7F7F7F7F7F7F7F7F7F7F7F6F6F6F6F5F5F4F4F3F3F2F1F1F0EFEEEEEDECEBE9 E8E7E6E5E4E2E1DFDEDDDBD9D7D6D4D2D0CECCCAC8C6C4C2C0BDBBB9B7B4B2B0ADAAA8A6A3A19E 9B999694928F8C8A878583807E7B79777472706E6C6A67656362605E5C5A5857555452514F4E4D 4B4A494846454444434241403F3E3D3D3C3BF6F6F6F6F6F6F6F6F6F6F6F5F5F5F5F4F4F3F3F2F2 F1F1F0EFEFEEEDECECEBEAE9E8E7E6E4E3E2E1E0DEDDDBDAD9D7D6D4D2D0CFCDCBC9C7C6C4C2C0 BEBCB9B7B5B3B1AFACAAA8A6A4A19F9D9A989693918F8D8A888684817F7D7B79777572716F6D6B 6967656362605E5C5B595856555352504F4E4D4B4A4948474645444342F5F5F5F5F5F5F5F5F5F5 F5F4F4F4F4F3F3F3F2F2F1F1F0F0EFEFEEEDEDECEBEAE9E9E8E7E6E5E4E3E2E0DFDEDDDBDAD9D7 D6D4D3D2D0CFCDCBC9C8C6C4C3C1BFBDBBB9B7B5B3B1B0AEACA9A7A5A3A19F9D9B99979593918F 8D8B88878482807F7D7B7977757371706E6C6A6867656462605F5D5C5B59585655545351504F4E 4CF4F4F4F4F4F4F4F4F4F4F4F3F3F3F3F3F2F2F2F1F1F0F0EFEFEEEEEDEDECEBEBEAE9E9E8E7E6 E5E4E3E2E1E0DFDEDDDCDBDAD8D7D6D4D3D2D0CFCDCCCBC9C8C6C4C3C1BFBEBCBAB9B7B5B3B2B0 AEACAAA8A7A5A3A19F9D9B9A98969492908E8C8A89878583817F7E7C7A7877757372706E6D6B69 6866656362605F5E5C5B5A58F3F3F3F3F3F3F3F3F3F3F3F3F3F2F2F2F2F1F1F1F0F0F0EFEFEEEE EDEDECECEBEBEAE9E9E8E7E6E6E5E4E3E2E1E0E0DFDDDCDBDAD9D8D7D6D5D3D2D1D0CECDCCCAC9 C8C6C4C3C2C0BFBDBCBAB8B7B5B4B2B0AFADABAAA8A6A5A3A19F9E9C9A9997959492908E8D8B89 88868482817F7E7C7A797776747371706E6D6B6A686765F3F3F3F3F3F3F3F3F2F2F2F2F2F2F2F1 F1F1F1F0F0F0EFEFEFEEEEEDEDEDECEBEBEBEAE9E9E8E7E7E6E5E4E4E3E2E1E1E0DFDEDDDCDBDA D9D8D7D6D5D4D2D1D0CFCECCCBCAC9C7C6C5C3C2C1BFBEBCBBBAB8B7B5B4B2B1AFAEACAAA9A7A6 A4A3A1A09E9C9B999896949391908E8D8B898886858382807F7D7C7A797776747371F2F2F2F2F2 F2F2F2F2F2F2F1F1F1F1F1F1F0F0F0F0EFEFEFEEEEEEEDEDEDECECEBEBEAEAE9E9E8E7E7E6E6E5 E4E3E3E2E1E0E0DFDEDDDCDBDADAD9D8D7D6D5D4D3D2D0CFCECDCCCBCAC9C7C6C5C4C2C1C0BFBD BCBBB9B8B7B5B4B2B1B0AEADABAAA8A7A5A4A3A1A09E9D9B9A9897959492918F8E8C8B8A888785 8482817F7E7CF1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F0F0F0F0F0EFEFEFEEEEEEEEEDEDECECECEB EBEAEAE9E9E8E8E7E7E6E5E5E4E3E3E2E1E0E0DFDEDDDDDCDBDAD9D8D7D6D6D5D4D3D2D1D0CFCE CCCBCAC9C8C7C6C5C3C2C1C0BEBDBCBBB9B8B7B6B4B3B2B0AFAEACABAAA8A7A5A4A3A1A09E9D9C 9A999796959392908F8E8C8B8988878584F1F1F1F1F1F1F1F1F1F1F0F0F0F0F0F0F0EFEFEFEFEF EEEEEEEDEDEDECECECEBEBEBEAEAE9E9E8E8E7E7E6E5E5E4E4E3E2E2E1E0DFDFDEDDDDDCDBDAD9 D8D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C4C3C2C1C0BFBDBCBBBAB9B7B6B5B4B2B1B0AE ADACABA9A8A7A5A4A3A1A09E9D9C9A99989695949291908E8D8C8A89F0F0F0F0F0F0F0F0F0F0F0 F0F0F0F0EFEFEFEFEFEEEEEEEEEDEDEDECECECEBEBEBEAEAE9E9E8E8E7E7E6E6E5E5E4E3E3E2E1 E1E0DFDFDEDDDDDCDBDAD9D9D8D7D6D5D4D3D2D1D0D0CFCECDCCCBC9C8C7C6C5C4C3C2C1C0BFBD BCBBBAB9B7B6B5B4B2B1B0AFADACABAAA8A7A6A4A3A2A19F9E9D9B9A999796959392918F8E8D8B F0F0F0F0F0F0F0F0F0EFEFEFEFEFEFEFEFEEEEEEEEEDEDEDEDECECECEBEBEBEAEAE9E9E8E8E7E7 E7E6E5E5E4E4E3E2E2E1E1E0DFDEDEDDDCDBDBDAD9D8D7D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8 C7C6C5C4C3C1C0BFBEBDBCBAB9B8B7B5B4B2B1AFAEACABA9A7A6A3A1A09E9B989692908D8A8783 7F7B7774706D6964605D59EFEFEFEFEFEFEFEFEFEFEFEFEFEEEEEEEEEEEDEDEDEDECECECECEBEB EAEAEAE9E9E8E8E7E7E6E6E5E5E4E4E3E2E2E1E1E0DFDEDEDDDCDBDBDAD9D8D7D7D6D5D4D3D2D1 D0CFCECDCCCBCAC9C8C7C5C4C3C2C1BFBEBDBCBBB9B7B6B5B3B2B0AEACAAA9A7A5A3A09D9B9996 93908C8985817D7975706B65605A56524D47423C3733EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEDED EDEDECECECECEBEBEBEAEAE9E9E9E8E8E7E7E6E6E5E4E4E3E3E2E1E1E0DFDFDEDDDCDBDBDAD9D8 D7D6D5D5D4D3D2D1D0CFCECDCCCAC9C8C7C6C5C3C2C1BFBEBDBBBAB8B6B5B3B1B0AEABA9A7A5A3 A09E9B9895928F8C8885817D7A76726E6A66625E5A56534F4C4743403E3C393733EEEEEEEEEEEE EEEEEEEDEDEDEDEDEDECECECECEBEBEBEAEAEAE9E9E8E8E7E7E6E6E5E5E4E4E3E2E2E1E0E0DFDE DDDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBC9C8C7C5C4C2C1C0BEBDBBB9B8B6B4B2B0AEAC AAA8A5A3A09E9B999693908D8A8784807D7A76736F6C6865625E5B5754514E4B494643403E3C3B 3937363433EDEDEDEDEDEDEDEDEDEDECECECECECEBEBEBEBEAEAE9E9E9E8E8E7E7E6E6E5E5E4E3 E3E2E1E1E0DFDEDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCDCCCBCAC8C7C5C4C2C1BFBDBCBAB8B6 B5B2B0AEACAAA7A5A2A09D9A9795928F8B8885827F7B7875716E6A6764615E5A5754514F4C4A47 4542403F3D3C3A393737363535343433ECECECECECECECECECEBEBEBEBEBEBEAEAE9E9E9E8E8E7 E7E6E6E5E5E4E4E3E2E1E1E0DFDEDDDCDCDBDAD9D8D7D5D4D3D2D1D0CECDCCCAC9C7C6C4C2C1BF BDBBB9B7B5B3B1AFACAAA7A5A3A09D9A9795928F8C898683807D797673706D6A6764615E5B5855 53504E4C4A47454341403F3E3C3A39383837363535343434343333EBEBEBEBEBEBEBEBEAEAEAEA EAE9E9E9E8E8E8E7E7E6E5E5E4E4E3E2E2E1E0DFDEDEDDDBDADAD9D7D6D5D4D2D1D0CFCDCCCAC8 C7C5C4C2C0BEBCBAB8B6B4B1AFADAAA8A5A3A09D9B9895928F8C898683807D7A7773706D6A6765 625E5C595654524F4D4A4847454342403E3D3C3B3A3938373736363535343434343433333333E9 E9E9E9E9E9E9E9E9E9E9E8E8E8E8E7E7E6E6E5E5E4E3E3E2E1E0E0DFDEDDDCDBDAD9D8D6D5D4D2 D1D0CECCCBC9C8C6C4C2C0BEBCBAB8B6B3B1AEACAAA7A4A19F9C999693908D8A8784817D7A7774 716E6B6865625F5D5A575553504E4C4A4846454341403E3D3C3B3A393838373736363535343434 34343333333333333333E8E8E8E8E8E8E8E8E7E7E7E6E6E6E6E5E4E4E3E3E2E1E1E0DFDEDDDCDB DAD9D8D6D5D4D3D1CFCECCCBC9C7C5C3C1C0BEBCB9B7B4B2B0AEABA8A5A3A09D9B9895928F8C89 8683807D7A7774716E6B686562605D5B585653514F4D4B494745444241403F3D3C3B3A3A393837 373636363535343434343434333333333333333333E6E6E6E6E6E6E6E6E5E5E5E5E4E4E3E3E2E2 E1E0E0DFDEDDDCDBDAD9D7D6D5D4D2D1CFCDCCCAC8C7C5C3C1BFBCBAB8B6B3B1AEACA9A7A4A19E 9B999693908D8A8784817E7B7875726F6C6A6764625F5C5A575553514F4D4B494746444341403F 3E3D3C3B3A393938373736363535353534343434343433333333333333333333E4E4E4E4E4E4E4 E4E3E3E3E2E2E2E1E0E0DFDEDDDDDCDBDAD8D7D6D5D4D2D1CFCECCCBC9C7C5C3C1BFBDBBB8B6B4 B1AFACAAA7A4A29F9C999794918E8B8885827F7D7A7774716E6C696663615F5C5A585553514F4D 4C4A484645444241403E3D3D3C3B3A393938383737363635353535343434343434343333333333 33333333E2E2E2E2E2E2E2E2E1E1E0E0E0DFDFDEDDDCDCDBDAD9D8D7D6D4D3D2D0CFCDCCCAC9C7 C5C3C1BFBDBBB9B7B4B2B0ADABA8A6A3A09E9B989693908D8A8885827F7C7A7774716F6C6A6764 62605D5B59575453514F4D4B4A484745444341403F3E3D3C3C3B3A393938383737363636353535 353434343434343333333333333333DFDFDFDFDFDFDFDFDFDFDEDEDDDDDCDCDBDAD9D8D8D6D5D4 D3D2D1CFCECCCBC9C7C6C4C2C0BEBCBAB8B6B4B1AFADAAA8A6A3A09E9B999694918E8B89868481 7E7B797674716F6C6A676563605E5C5A58565452504F4D4B4A48474644434241403F3E3D3C3B3B 3A3A393938373737363636353535353434343434343433333333DDDDDDDDDDDDDDDDDDDCDCDBDB DBDAD9D9D8D7D6D6D4D3D2D1D0CFCDCCCAC9C7C6C4C3C1BFBDBBB9B8B5B3B1AFADABA8A6A3A19F 9C9A979592908E8B888683817E7C79777572706E6B69676462605E5C5A5856555351504E4D4B4A 48474645444341403F3E3E3D3C3C3B3A3A3939383837373736363635353535343434343433DBDB DBDBDBDBDBDBDBDADAD9D9D9D8D7D7D6D5D5D4D3D2D1D0CFCECCCBCAC8C7C5C4C2C1BFBDBBBAB8 B6B4B2B0AEACAAA8A6A3A19F9D9B989694918F8D8A888683817F7C7A787673716F6D6B69676563 605F5D5B595856545351504E4D4B4A494847464443424241403F3E3D3D3C3C3B3A3A3939383838 373736363636353535D9D9D9D9D9D9D9D9D9D8D8D8D7D7D6D6D5D4D4D3D3D2D1D0CFCECDCCCBC9 C8C7C5C4C3C1C0BEBDBBB9B8B6B4B2B0AFADABA9A7A5A3A19F9D9B99969492908E8C8A87858381 7F7D7B78767472706E6C6A68666563615F5E5C5A595756545251504E4D4C4B4948474645444342 4141403F3E3E3D3C3C3B3B3A3939393838373736D7D7D7D7D7D7D7D7D7D7D6D6D6D6D5D4D4D3D3 D2D2D1D0CFCECECDCCCBCAC8C7C6C5C4C2C1C0BFBDBCBAB9B7B6B4B2B1AFADABAAA8A6A4A2A09F 9D9B99979593918F8D8B8987858482807E7C7A78767472706F6D6B696866646361605E5C5B5A58 5755545351504F4E4D4B4A4948474646454443424141403F3F3E3D3D3C3B3BD6D6D6D6D6D6D6D6 D5D5D5D5D5D4D4D3D3D2D2D1D1D0D0CFCECDCDCCCBCAC9C8C7C6C5C4C3C2C0BFBEBDBCBAB9B7B6 B5B3B2B0AEADABAAA8A6A5A3A1A09E9C9A9997959392908E8C8A8987858382807E7C7B79777574 72706F6D6C6A6867656462615F5E5D5B5A59575655545251504F4E4D4C4B4A4948474645454443 424241D4D4D4D4D4D4D4D4D4D4D4D4D3D3D3D2D2D2D1D1D0D0CFCFCECDCDCCCBCBCAC9C8C7C6C5 C4C3C2C1C0BFBEBDBCBBB9B8B7B6B4B3B2B0AFADACABA9A8A6A5A3A2A09F9D9B9A989795939290 8E8D8B8A8886858382807E7D7B7A7877757372706F6D6C6A696866656362615F5E5D5C5A595857 5655535251504F4E4D4C4B4A4949D3D3D3D3D3D3D3D3D3D3D3D3D3D2D2D2D1D1D1D0D0CFCFCECE CDCDCCCCCBCACAC9C8C7C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B4B3B2B1AFAEADACAAA9A7 A6A5A3A2A19F9E9C9B999896959492918F8E8C8B898886858382807F7D7C7B797876757472716F 6E6D6B6A69676665646261605F5E5D5B5A5958575655545352D3D3D3D3D3D3D3D3D2D2D2D2D2D2 D1D1D1D0D0D0D0CFCFCECECDCDCCCCCBCBCAC9C9C8C8C7C6C5C5C4C3C2C1C0C0BFBEBDBCBBBAB9 B8B7B6B5B4B2B1B0AFAEADABAAA9A8A7A5A4A3A1A09F9E9C9B9A989796949392908F8E8C8B8988 8785848381807F7D7C7B79787775747372706F6E6C6B6A6968666564636261605F5D5C5BD2D2D2 D2D2D2D2D2D2D1D1D1D1D1D1D0D0D0D0CFCFCFCECECECDCDCCCCCBCBCACAC9C9C8C8C7C6C6C5C4 C3C3C2C1C0C0BFBEBDBCBBBAB9B8B7B7B6B5B4B2B1B0AFAEADACABAAA9A8A7A5A4A3A2A19F9E9D 9C9A99989796949392918F8E8D8C8A89888785848381807F7E7D7B7A79787675747372706F6E6D 6C6B6A6867666564D1D1D1D1D1D1D1D1D1D1D1D1D0D0D0D0D0CFCFCFCFCECECECDCDCDCCCCCBCB CACACAC9C8C8C7C7C6C6C5C4C4C3C2C1C1C0BFBEBEBDBCBBBAB9B9B8B7B6B5B4B3B2B1B0AFAEAD ACABAAA9A8A7A6A5A3A2A1A09F9E9D9C9A9998979695939291908F8D8C8B8A8988868584838280 7F7E7D7C7B7978777675747271706F6E6D6C6BD0D0D0D0D0D0D0D0D0D0D0D0D0D0D0CFCFCFCFCF CECECECDCDCDCCCCCCCBCBCACACAC9C9C8C8C7C6C6C5C5C4C3C3C2C2C1C0BFBFBEBDBCBCBBBAB9 B8B7B7B6B5B4B3B2B1B0AFAEADACACABAAA8A7A6A5A4A3A2A1A09F9E9D9C9B9A99979695949392 91908E8D8C8B8A8988868584838281807F7D7C7B7A797877767573727170D0D0D0D0D0D0D0D0D0 D0CFCFCFCFCFCFCFCECECECECECDCDCDCCCCCCCBCBCACACAC9C9C8C8C7C7C6C6C5C4C4C3C3C2C1 C1C0BFBFBEBDBCBCBBBAB9B9B8B7B6B5B4B3B3B2B1B0AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F 9E9D9C9B9A9998979594939291908F8E8D8C8A8988878685848382807F7E7D7C7B7A7978777574 7372CFCFCFCFCFCFCFCFCFCFCFCFCFCFCECECECECECDCDCDCDCCCCCCCBCBCBCACAC9C9C9C8C8C7 C7C6C6C5C5C4C3C3C2C1C1C0BFBFBEBDBDBCBBBABAB9B8B7B6B6B5B4B3B2B1B0AFAFAEADACABAA A9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A98979695949392908F8E8C8B8A8987868482807F7E7C7A 77757473706E6B68676664625FCFCFCFCFCFCFCFCFCECECECECECECECECDCDCDCDCCCCCCCCCBCB CBCACAC9C9C9C8C8C7C7C6C6C5C5C4C4C3C2C2C1C0C0BFBEBEBDBCBCBBBAB9B9B8B7B6B5B4B4B3 B2B1B0AFAEADACABAAA9A8A7A7A6A5A4A3A1A09F9E9D9C9B9A99989695949391908F8D8C8A8886 8483817F7C797673706E6B67635F5B57534F4B47433E3A37CECECECECECECECECECECECDCDCDCD CDCDCCCCCCCCCBCBCBCACACAC9C9C8C8C7C7C7C6C5C5C4C4C3C3C2C1C1C0BFBFBEBDBDBCBBBAB9 B9B8B7B6B5B4B4B3B2B1B0AFAEADACABAAA9A8A7A6A5A4A3A2A09F9E9D9C9A999896959392908F 8D8C8A88868482807E7B797674726F6C696663605D5A5753504D4A4643403D3C393633CDCDCDCD CDCDCDCDCDCDCDCDCDCCCCCCCCCBCBCBCBCACAC9C9C9C8C8C7C7C7C6C6C5C4C4C3C3C2C1C1C0BF BFBEBDBDBCBBBAB9B9B8B7B6B5B4B3B2B1B0AFAEADACABAAA9A8A7A6A5A4A2A19F9E9D9C9B9997 96949391908E8C8A88868582807E7B797774726F6D6A6764615F5C595653504E4B494744413F3D 3C3A3937353433CCCCCCCCCCCCCCCCCCCCCCCCCCCBCBCBCBCACACACAC9C9C8C8C7C7C7C6C5C5C4 C4C3C3C2C1C0C0BFBEBEBDBCBBBABAB9B8B7B6B5B4B3B2B1B0AFAEADACABAAA8A7A6A5A3A2A19F 9E9C9B9998969492918F8D8B89878583817F7C7A777572706E6B686663615E5B595754524F4C4A 49474542403E3D3C3B3A3837363635353433CBCBCBCBCBCBCBCBCBCBCBCBCACACACAC9C9C9C8C8 C8C7C7C6C6C5C5C4C3C3C2C1C1C0BFBEBEBDBCBBBAB9B8B8B7B6B5B4B3B1B0AFAEADACAAA9A8A6 A5A4A2A19F9E9C9B9997959492908E8C8A888684827F7D7B787674716F6D6A686563605E5C5957 5552504E4C4A4846444341403E3D3B3A39393837363535353434343333CACACACACACACACACACA CAC9C9C9C9C8C8C8C7C7C6C6C5C5C4C4C3C2C2C1C0C0BFBEBDBCBBBABAB9B8B7B6B4B3B2B1B0AF ADACABAAA8A7A5A4A2A19F9D9B9A98969492908E8C8A888684817F7D7A787673716E6C69676462 605D5B58565452504E4C4A4846444341403E3D3C3B3A3938383736363535353434343433333333 33C9C9C9C9C9C9C9C9C9C8C8C8C8C8C7C7C6C6C5C5C4C4C3C3C2C1C1C0BFBEBDBCBCBBBAB9B8B6 B5B4B3B2B1AFAEACABAAA8A7A5A3A2A09F9D9B99979593918F8D8B89868482807D7B797674726F 6D6A686563615E5C5A58555351504E4C4A4846454442413F3E3D3C3B3A39383837373636353534 343434343333333333333333C7C7C7C7C7C7C7C7C7C7C7C6C6C6C5C5C4C4C3C3C2C2C1C0BFBFBE BDBCBBBAB9B8B7B6B5B3B2B1B0AEADABAAA8A7A5A3A1A09E9C9A98969492908E8C8A878583807E 7C79777572706D6B696664625F5D5B59575552504E4C4B494846444341403F3E3D3C3B3A393938 3737363636353535343434343433333333333333333333C6C6C6C6C6C6C6C6C5C5C5C5C4C4C4C3 C2C2C1C1C0BFBEBDBDBCBBBAB9B8B6B5B4B3B2B0AFADACAAA9A7A5A4A2A09E9D9A98969492908E 8C89878582807E7B797674726F6D6A686663615F5D5A58565452504E4D4B49484645434241403E 3D3C3C3B3A3938383737373636353535353434343434343333333333333333333333C4C4C4C4C4 C4C4C4C3C3C3C2C2C2C1C1C0BFBFBEBDBDBCBBBAB9B8B7B6B4B3B2B0AFAEACABA9A7A6A4A2A19F 9D9B99979593918E8C8A888683817F7C7A787573716E6C69676563615E5C5A58565452504E4D4B 4A484745444341403F3E3D3C3B3B3A393938373737363635353535343434343434343333333333 333333333333C2C2C2C2C2C2C2C2C1C1C1C0C0C0BFBEBEBDBCBCBBBAB9B8B7B6B5B4B3B1B0AFAD ACAAA9A7A5A4A2A09E9C9B99979593918E8C8A888683817F7C7A787673716F6C6A686664625F5D 5B5957555452504E4D4B4A48474544434241403F3E3D3C3B3A3A39393837373736363635353535 3434343434343434333333333333333333C0C0C0C0C0C0C0C0BFBFBFBEBEBEBDBCBCBBBABAB9B8 B7B6B5B4B3B1B0AFADACABA9A8A6A4A3A19F9E9C9A98969492908E8C8A888583817F7D7A787674 726F6D6B69676563615F5D5B5957555452504F4D4B4A4947464543424141403F3E3D3C3B3B3A39 39383837373736363635353535343434343434343433333333333333BEBEBEBEBEBEBEBEBDBDBD BCBCBCBBBABAB9B8B8B7B6B5B4B3B2B1B0AFADACABA9A8A6A5A3A2A09E9D9B9997959492908E8C 8A88868482807D7B79777573716F6D6B69676563615F5D5B5A5856555351504E4D4C4A49484645 44434241403F3F3E3D3C3C3B3A3A39393838373737363636353535353534343434343434333333 BCBCBCBCBCBCBCBCBBBBBBBABABAB9B9B8B7B7B6B5B4B3B3B2B1B0AFADACABAAA8A7A6A4A3A1A0 9E9D9B9997969492918F8D8B89878583817F7D7B7978767472706E6C6A68676563615F5E5C5A59 5755545251504E4D4C4A494847464544434241403F3F3E3D3C3C3B3B3A39393938383837373636 3636353535353434343434BABABABABABABABABAB9B9B9B8B8B8B7B7B6B5B5B4B3B2B2B1B0AFAE ADACABAAA9A7A6A5A3A2A19F9E9C9B9998969593918F8E8C8A8987858382807E7C7A7977757371 706E6C6A6967656462605F5D5C5A595756545352504F4E4D4B4A49484746454443424241403F3F 3E3D3D3C3C3B3A3A3939393838373737373636363535B8B8B8B8B8B8B8B8B8B8B8B7B7B7B6B6B5 B5B4B4B3B3B2B1B0B0AFAEADACABAAA9A8A7A6A5A3A2A1A09E9D9C9A999796949391908E8D8B8A 8886858381807E7D7B7978767473716F6E6C6B696866646361605F5D5C5A59585655545351504F 4E4D4C4B4A4948474645444343424140403F3E3E3D3D3C3C3B3B3A3A3939393838B7B7B7B7B7B7 B7B7B7B7B6B6B6B6B5B5B4B4B4B3B3B2B1B1B0AFAFAEADACACABAAA9A8A7A6A5A4A3A2A09F9E9D 9C9A99989795949291908E8D8B8A898786848381807E7D7B7A7877757472716F6E6C6B69686765 646261605E5D5C5A5958575654535251504F4E4D4C4B4A494847464645444343424141403F3F3E 3D3D3C3C3BB6B6B6B6B6B6B6B6B6B5B5B5B5B5B4B4B4B3B3B3B2B2B1B1B0AFAFAEADADACABABAA A9A8A7A6A5A5A4A3A1A09F9E9D9C9B9A99989795949391908F8E8D8B8A888786858382807F7E7C 7B7A787776747371706F6D6C6B6A68676664636261605E5D5C5B5A595856555453525150504F4E 4D4C4B4A494948474645454443434241B5B5B5B5B5B5B5B5B5B5B4B4B4B4B4B3B3B3B2B2B2B1B1 B0B0AFAFAEAEADADACABABAAA9A9A8A7A6A5A5A4A3A2A1A09F9E9D9C9B9A999897969594929190 8F8E8D8B8A89888785848382817F7E7D7C7A79787775747372706F6E6D6C6A6968676665636261 605F5E5D5C5B5A595857565554535251504F4E4E4D4C4B4A4A4948B4B4B4B4B4B4B4B4B4B4B4B4 B3B3B3B3B3B2B2B2B1B1B1B0B0AFAFAFAEAEADADACABABAAAAA9A8A8A7A6A5A5A4A3A2A2A1A09F 9E9D9C9B9A9A999897969594939291908E8D8C8B8A8988878685838281807F7E7D7C7A79787776 75747271706F6E6D6C6B6A6967666564636261605F5E5D5C5B5A595857575655545352515050B3 B3B3B3B3B3B3B3B3B3B3B3B3B3B3B2B2B2B2B1B1B1B0B0B0AFAFAFAEAEADADACACABABAAAAA9A9 A8A7A7A6A5A5A4A3A2A2A1A09F9F9E9D9C9B9A9A999897969594939291908F8E8D8C8B8A898887 868584838281807F7E7D7C7B7A7978777674737271706F6E6D6C6B6A6968676665646362616160 5F5E5D5C5B5A59585757B3B3B3B3B3B3B3B3B3B3B2B2B2B2B2B2B2B1B1B1B1B0B0B0B0AFAFAFAE AEADADADACACABABAAAAA9A9A8A8A7A6A6A5A5A4A3A3A2A1A0A09F9E9D9D9C9B9A9A9998979695 9594939291908F8E8D8C8B8B8A898887868584838281807F7E7D7C7B7A79787776757473727170 6F6E6D6C6B6B6A69686766656463626160605F5E5DB2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B1B1B1 B1B1B0B0B0B0AFAFAFAEAEAEADADADACACABABAAAAAAA9A8A8A7A7A6A6A5A5A4A3A3A2A2A1A09F 9F9E9D9D9C9B9A9A9998979796959493929291908F8E8D8C8C8B8A89888786858483828281807F 7E7D7C7B7A79787776757474737271706F6E6D6C6B6A69696867666564636261B2B2B2B2B2B2B2 B2B2B1B1B1B1B1B1B1B1B0B0B0B0B0AFAFAFAFAEAEAEADADADACACACABABAAAAA9A9A9A8A7A7A6 A6A5A5A4A4A3A2A2A1A1A09F9F9E9D9D9C9B9A9A9998979796959494939291908F8F8E8D8C8B8A 8A89888786858483828281807F7E7D7C7B7A7979787776757473727170706F6E6D6C6B6A696868 67666564B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B0B0B0B0B0B0AFAFAFAEAEAEAEADADADACACACAB ABAAAAAAA9A9A8A8A7A7A6A6A5A5A4A4A3A2A2A1A1A09F9F9E9D9D9C9B9B9A9998989796959594 93929291908F8E8E8D8C8B8A8988888786858483828181807F7E7D7C7B7A797978777575747372 716F6E6D6D6C6B6A68676665656462B1B1B1B1B1B1B1B1B1B0B0B0B0B0B0B0B0AFAFAFAFAFAEAE AEAEADADADACACACABABABAAAAA9A9A8A8A8A7A7A6A6A5A4A4A3A3A2A2A1A0A09F9E9E9D9C9C9B 9A9A999897979695949493929190908F8E8D8C8B8B8A89888786858484838281807F7E7C7B7A79 787775747271706E6C69676664625F5C59565452504D4A474543B0B0B0B0B0B0B0B0B0B0B0B0B0 B0AFAFAFAFAFAEAEAEAEADADADADACACACABABAAAAAAA9A9A8A8A7A7A6A6A5A5A4A4A3A3A2A1A1 A0A09F9E9E9D9C9C9B9A999998979696959493929291908F8E8D8D8C8B8A898887868584838281 807F7D7C7B797877767472706F6D6C6A686563615E5C5A5754524E4B484643413E3B383533AFAF AFAFAFAFAFAFAFAFAFAFAFAFAFAFAEAEAEAEADADADADACACACABABABAAAAA9A9A9A8A8A7A7A6A6 A5A5A4A3A3A2A2A1A0A09F9E9E9D9C9C9B9A999998979695959493929190908F8E8D8C8B8A8988 878685848381807F7E7C7B797876757371706E6C6A686664615F5D5B585653514F4C4A48464341 3F3D3B3A3937363533AFAFAFAFAFAFAFAFAFAFAEAEAEAEAEAEADADADADADACACACABABABAAAAA9 A9A8A8A8A7A6A6A5A5A4A4A3A2A2A1A0A09F9F9E9D9C9C9B9A99989897969594939291908F8F8D 8C8B8A89888786858382817F7E7D7B797877757372706E6C6A69676563615F5D5B58565452504E 4C4A48474543413F3E3D3C3A3938373635353433AEAEAEAEAEAEAEAEAEAEAEAEADADADADACACAC ACABABABAAAAAAA9A9A8A8A7A7A6A6A5A4A4A3A3A2A1A1A09F9F9E9D9C9B9B9A99989796959494 9392918F8E8D8C8B8A898786858482817F7E7C7B7978767473716F6D6C6A68666462605E5C5A58 565452504E4D4B4947454342413F3E3C3B3A3A393837363535353434343333ADADADADADADADAD ADADADADACACACACABABABAAAAAAA9A9A8A8A7A7A7A6A5A5A4A4A3A2A2A1A09F9F9E9D9C9B9A9A 9998979695949392918F8E8D8C8B898887858482817F7E7C7A7977767472706E6C6B6967656361 5F5D5B59575553514F4E4C4A494745444241403F3E3C3B3A3A3938373736363535353434343433 333333ACACACACACACACACACACACABABABABAAAAAAA9A9A9A8A8A7A7A6A6A5A4A4A3A2A2A1A09F 9F9E9D9C9B9A9998979695949392908F8E8D8C8A898786858382807E7D7B7978767472706F6D6B 69676563615F5E5C5A58565452514F4D4B4A484745444341403F3E3D3C3B3A3938383737363635 3535343434343433333333333333ABABABABABABABABABABAAAAAAAAA9A9A9A8A8A7A7A6A6A5A5 A4A4A3A2A1A0A09F9E9D9C9B9A9998979695949391908F8E8C8B898887858382807F7D7B797876 7472706E6C6A68666563615F5D5B5957555352504E4C4B49484645444241403F3E3D3C3B3A3939 38383736363635353534343434343433333333333333333333AAAAAAAAAAAAAAAAA9A9A9A9A8A8 A8A7A7A6A6A6A5A4A4A3A2A2A1A09F9F9E9D9C9B9A99989695949392918F8E8C8B8A8886858382 807E7D7B7977757372706E6C6A68666462605F5D5B5957555452504E4D4B4A4847464443424140 3F3D3C3C3B3A3A3938383737363635353535343434343434333333333333333333333333A8A8A8 A8A8A8A8A8A8A8A7A7A7A7A6A6A5A5A4A4A3A2A2A1A09F9F9E9D9C9B9A99989795949392908F8E 8C8B898886858381807E7C7A79777573716F6D6C6A68666462605E5D5B5957555452504F4D4B4A 49474645434241403F3E3D3C3B3B3A393938383737363636353535343434343434343333333333 3333333333333333A7A7A7A7A7A7A7A6A6A6A6A5A5A5A4A4A3A3A2A2A1A09F9F9E9D9C9B9A9998 9796959492918F8E8D8B8A8887858482807F7D7B7977767472706E6C6B69676563615F5E5C5A58 57555352504E4D4C4A49474645444341403F3E3E3D3C3B3A3A3939383837373636363535353534 34343434343434333333333333333333333333A5A5A5A5A5A5A5A5A4A4A4A4A3A3A3A2A2A1A0A0 9F9E9E9D9C9B9A9998979695949391908F8D8C8B898886858381807E7C7B7977767472706E6D6B 6967656462605E5D5B595856555351504E4D4C4A4948464544434241403F3E3D3D3C3B3A3A3939 383837373736363635353535353434343434343434333333333333333333A3A3A3A3A3A3A3A3A3 A3A2A2A2A1A1A0A09F9F9E9E9D9C9B9A999998979594939291908E8D8C8A898886858382807F7D 7B7A7876757371706E6C6A6967656462605F5D5B5A5857555452514F4E4D4B4A49484746444342 4140403F3E3D3C3C3B3B3A3A393838383737373636363535353535343434343434343433333333 3333A1A1A1A1A1A1A1A1A1A1A1A0A0A09F9F9E9E9D9D9C9B9B9A999897979594939291908F8E8C 8B8A898786858382807F7D7C7A7977767472716F6E6C6A6967666462615F5E5C5B595856555352 51504E4D4C4A49484746454443424141403F3E3E3D3C3C3B3A3A39393938383737373636363635 35353535343434343434333333A0A0A0A0A0A0A0A0A09F9F9F9F9E9E9E9D9D9C9C9B9A9A999897 97969594939291908F8E8D8C8B89888786848382807F7E7C7B797876757372716F6E6C6B696866 656362605F5D5C5B59585755545351504F4E4D4C4B4A48474746454443424141403F3E3E3D3D3C 3C3B3A3A3A393938383837373736363636353535353534349F9F9F9F9F9F9F9F9E9E9E9E9D9D9D 9C9C9C9B9B9A9A999898979696959493929190908F8E8C8B8A8988878685838281807F7D7C7B79 787775747371706F6D6C6A69686665646261605E5D5C5A5958575554535251504F4E4D4C4B4A49 48474645444443424141403F3F3E3D3D3C3C3B3B3A3A3A3939383838373737363636369D9D9D9D 9D9D9D9D9D9D9D9D9C9C9C9C9B9B9A9A9A99999897979696959493939291908F8F8E8D8C8B8A89 88878685848381807F7E7D7C7A7978777674737271706E6D6C6A69686766646362615F5E5D5C5B 5A5857565554535251504F4E4D4C4B4A49484847464545444342424141403F3F3E3E3D3D3C3C3B 3B3A3A3A3939389D9D9D9D9D9D9D9C9C9C9C9C9C9B9B9B9B9A9A9A999998989797969695959493 93929191908F8E8D8D8C8B8A898887868584838281807F7E7D7C7B7A7978777674737271706F6E 6C6B6A6968676665636261605F5E5D5C5B5A595857565554535251504F4E4D4C4C4B4A49484847 46464544444342424141403F3F3E3E3D3D3C9C9C9C9C9C9C9C9C9B9B9B9B9B9B9A9A9A9A999999 9898989797969696959494939392929190908F8E8E8D8C8B8A8A89888786858584838281807F7E 7D7C7B7A797877767574737271706F6E6D6C6B6A696867666564636261605F5E5D5C5B5A595857 56555453535251504F4E4E4D4C4B4B4A494848474646454444434342419B9B9B9B9B9B9B9B9B9B 9B9A9A9A9A9A9A99999999989898979797969695959494939392929191908F8F8E8D8D8C8C8B8A 898988878686858483828281807F7E7D7C7B7B7A797877767574737271706F6E6D6C6C6B6A6968 67666564636261605F5F5E5D5C5B5A595858575655545453525150504F4E4D4D4C4B4B4A494948 479A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9999999999989898979797979696959595949493939292 919190908F8F8E8E8D8D8C8B8B8A89898887878685848483828180807F7E7D7D7C7B7A79787877 76757473727271706F6E6D6C6B6B6A69686766656464636261605F5F5E5D5C5B5B5A5958575756 55545453525151504F4F4E4D9A9A9A9A9A9A9A9A9A9A9999999999999999989898989897979797 96969695959494949393939292919190908F8F8E8E8D8D8C8B8B8A8A8988888787868585848382 828180807F7E7D7D7C7B7A7A7978777676757473737271706F6E6E6D6C6B6A6A69686766666564 63626261605F5F5E5D5C5B5B5A5958585756565554535399999999999999999999999999999999 98989898989797979797969696959595959494939393929292919190908F8F8E8E8D8D8C8C8B8B 8A8A8988888787868585848383828181807F7F7E7D7D7C7B7A7A79787777767575747372727170 6F6E6E6D6C6B6B6A696868676665646463626261605F5F5E5D5C5C5B5A59595857579999999999 999999999999999898989898989898979797979796969696959595949494949393929292919190 90908F8F8E8E8D8D8C8C8B8B8A8A898988878786868585848383828181807F7F7E7D7D7C7B7B7A 79797877777675747473727271706F6F6E6D6C6C6B6A69696867676665646463626161605F5F5E 5D5C5C5B5A5A989898989898989898989898989898989897979797979796969696969595959594 949493939392929291919090908F8F8E8E8D8D8C8C8B8B8A8A8989888887878685858484838282 8181807F7F7E7D7D7C7B7B7A7979787777767575747372727170706F6E6D6D6C6B6B6A69686867 666665646363626161605F5E5E5D5C5C5B98989898989898989898989898989797979797979796 969696969595959594949493939392929291919190908F8F8F8E8E8D8D8C8C8B8B8A8A89898888 878786868584848383828181807F7F7E7E7D7C7C7B7A7A797877777675757473737271706F6F6E 6D6C6B6A6968676665646362605F5E5C5A595856555351504F4D4B4A9898989898989898979797 97979797979797969696969696959595959494949393939392929291919090908F8F8E8E8E8D8D 8C8C8B8B8A8A89898887878686858584838382828180807F7E7E7D7C7C7B7A7A79787877767575 7473727271706F6E6D6C6B6A69686765646361605E5C5A585654524F4C4A474543403D3B383533 979797979797979797979797979796969696969696959595959494949493939392929291919190 908F8F8F8E8E8D8D8C8C8B8B8A8A89898887878686858584838382818180807F7E7D7D7C7B7B7A 7978787776757473727171706E6D6C6B6A696866656362615F5E5C5A59575553514F4D4B494745 4442403E3C3A393837353397979797979797979796969696969696969595959595949494949393 9392929291919190908F8F8E8E8E8D8D8C8C8B8B8A898988888787868585848383828181807F7F 7E7D7C7C7B7A797877767675747372706F6F6E6C6B6A686766656362605F5D5C5A595755545250 4E4D4B4A4846444241403E3D3B3A39383736353434339696969696969696969696969595959595 95949494949393939392929291919090908F8F8E8E8D8D8C8C8B8B8A8A89898887878685858483 83828181807F7E7D7D7C7B7A797877767574737271706F6D6C6B6A686766646361605E5D5B5958 565453514F4E4C4B494746444341403F3E3D3B3A39393837363635353434343333959595959595 9595959595959595949494949393939392929291919190908F8F8E8E8E8D8C8C8B8B8A8A898888 87868685848383828180807F7E7D7C7B7A7978777675747372706F6E6D6B6A696766656362605F 5D5C5A5957555452514F4E4C4B49484745444341403F3E3D3C3B3A3A3938373636363535343434 34343333339595959595959595949494949494939393939292929291919090908F8F8E8E8D8D8C 8C8B8A8A898888878685858483828181807F7E7D7C7B7A7978777674737271706E6D6C6A696866 656362605F5D5C5A5957555452514F4E4C4B49484645444342403F3E3D3C3C3B3A393838373736 363535353434343433333333333333339494949494949494949393939393929292929191919090 8F8F8E8E8E8D8C8C8B8A8A8988888786858584838281807F7E7D7C7B7A79787776747372706F6E 6D6B6A6867656462615F5E5C5B595756545351504E4D4C4A49474645444341403F3E3D3C3C3B3A 393938383737363635353535343434343433333333333333333333939393939393939392929292 92929191919090908F8F8E8E8D8D8C8C8B8A8989888787868584838281807F7E7D7C7B7A797876 75747371706F6D6C6A696866656362605F5D5C5A5857555452514F4E4D4B4A4947464543424140 3F3E3D3C3C3B3A3A39383837373636363535353534343434343433333333333333333333333392 9292929292929191919191909090908F8F8E8E8E8D8C8C8B8B8A8A89888786868584838281807F 7E7D7C7B79787776747372706F6E6C6B696866656362605F5D5C5A595756545351504E4D4C4A49 47464544434241403F3E3D3C3C3B3A393938383737363636353535353434343434343433333333 33333333333333333333909090909090909090908F8F8F8F8E8E8E8D8D8C8C8B8B8A8989888787 868584838281807F7E7D7C7B7A79777675747271706E6D6B6A686765646361605E5D5B5A585755 5452514F4E4D4B4A4948474544434241403F3E3D3D3C3B3B3A3939383837373636363535353535 3434343434343433333333333333333333333333338F8F8F8F8F8F8F8F8F8E8E8E8E8D8D8D8C8C 8B8B8A8A8988888786868584838281807F7E7D7C7B7A79787675747271706F6D6C6A6967666563 62605F5D5C5A595856555352514F4E4D4B4A494847464443424241403F3E3D3C3C3B3B3A393938 38373737363636353535353534343434343434343333333333333333333333338E8E8E8E8E8E8E 8D8D8D8D8D8C8C8C8B8B8A8A89898888878686858483828180807F7E7D7B7A7978777675737271 706E6D6C6A696766656362605F5E5C5B5A585755545351504F4E4C4B4A49484746454443424140 3F3E3E3D3C3C3B3A3A393938383837373736363635353535353434343434343434343333333333 33333333 %END_IMAGE % gr_show_at() BEGIN 0 g 0 G 167.4 149.9 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 304.6 149.9 m (0.5) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 451.9 149.9 m (1) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 170.70 165.01 l 170.70 170.70 l 199.15 170.70 l 199.15 167.86 l 199.15 170.70 l 227.60 170.70 l 227.60 167.86 l 227.60 170.70 l 256.05 170.70 l 256.05 167.86 l 256.05 170.70 l 284.50 170.70 l 284.50 167.86 l 284.50 170.70 l 312.95 170.70 l 312.95 165.01 l 312.95 170.70 l 341.40 170.70 l 341.40 167.86 l 341.40 170.70 l 369.85 170.70 l 369.85 167.86 l 369.85 170.70 l 398.30 170.70 l 398.30 167.86 l 398.30 170.70 l 426.75 170.70 l 426.75 167.86 l 426.75 170.70 l 455.20 170.70 l 455.20 165.01 l 455.20 170.70 l 455.34 170.70 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 259.8 134.7 m (distance along cove) sh % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 455.20 m 170.70 455.20 l 170.70 460.89 l 170.70 455.20 l 199.15 455.20 l 199.15 458.05 l 199.15 455.20 l 227.60 455.20 l 227.60 458.05 l 227.60 455.20 l 256.05 455.20 l 256.05 458.05 l 256.05 455.20 l 284.50 455.20 l 284.50 458.05 l 284.50 455.20 l 312.95 455.20 l 312.95 460.89 l 312.95 455.20 l 341.40 455.20 l 341.40 458.05 l 341.40 455.20 l 369.85 455.20 l 369.85 458.05 l 369.85 455.20 l 398.30 455.20 l 398.30 458.05 l 398.30 455.20 l 426.75 455.20 l 426.75 458.05 l 426.75 455.20 l 455.20 455.20 l 455.20 460.89 l 455.20 455.20 l 455.34 455.20 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf % gr_show_at() BEGIN 0 g 0 G 152.5 166.4 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 450.9 m (81) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 165.01 170.70 l 170.70 170.70 l 170.70 455.20 l 165.01 455.20 l 170.70 455.20 l 170.70 455.20 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 139.9 301.6 m 90.00 rotate (time) sh -90.00 rotate % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 455.20 170.70 m 455.20 170.70 l 460.89 170.70 l 455.20 170.70 l 455.20 455.20 l 460.89 455.20 l 455.20 455.20 l 455.20 455.20 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:if {"\contours" == "yes"} %gri: set graylevel 1.0 %gri: draw contour 0 20 1 unlabelled %^ scale 1 170.7 0 284.5 1 170.7 0 3.51235 0.709 w 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 426.53 m 454.06 426.48 l 441.36 426.48 l 440.23 426.40 l 438.29 426.29 l 427.19 426.29 l 425.25 426.06 l 421.07 425.76 l 414.46 425.76 l 410.28 425.00 l 404.60 424.54 l 399.02 423.19 l 396.23 422.97 l 395.31 422.83 l 392.86 422.61 l 384.37 422.23 l 380.33 421.57 l 374.28 421.07 l 367.11 419.64 l 365.79 419.54 l 365.36 419.47 l 364.22 419.37 l 353.95 418.79 l 350.38 418.24 l 343.73 417.66 l 335.96 416.21 l 335.41 416.12 l 335.29 416.11 l 335.14 416.08 l 323.76 415.29 l 320.44 414.76 l 313.73 414.12 l 306.10 412.68 l 305.46 412.57 l 305.33 412.56 l 305.18 412.53 l 294.42 411.59 l 290.49 410.88 l 285.02 410.27 l 278.71 408.97 l 276.68 408.69 l 275.52 408.44 l 270.07 407.68 l 267.34 407.35 l 260.54 405.84 l 259.40 405.68 l 258.24 405.41 l 251.13 404.09 l 245.57 402.51 l 243.97 402.24 l 242.57 401.86 l 237.18 400.29 l 234.16 399.15 l 231.80 398.30 l 231.45 398.10 l 230.59 397.59 l 226.09 395.81 l 223.63 394.74 l 221.61 393.32 l 219.73 392.16 l 218.24 391.19 l 217.85 390.66 l 215.62 388.70 l 214.30 387.95 l 213.58 387.63 l 212.17 386.81 l 210.08 385.39 l 207.30 384.08 l 205.44 382.94 l 200.65 380.91 l 199.74 380.73 l 198.51 380.52 l 191.87 379.05 l 185.67 377.85 l 181.93 377.85 l 174.44 377.85 l 170.70 377.85 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 426.31 m 452.92 426.21 l 442.50 426.21 l 440.23 426.06 l 436.34 425.83 l 429.13 425.83 l 425.25 425.36 l 418.24 424.86 l 411.21 423.42 l 410.28 423.25 l 410.11 423.23 l 409.95 423.19 l 398.96 422.33 l 395.31 421.76 l 388.80 421.18 l 380.48 419.64 l 380.38 419.63 l 380.33 419.62 l 380.20 419.61 l 369.10 418.75 l 365.36 418.20 l 358.93 417.61 l 350.89 416.20 l 350.38 416.12 l 350.25 416.11 l 350.09 416.08 l 339.27 415.17 l 335.41 414.58 l 329.32 413.97 l 321.17 412.53 l 320.69 412.47 l 320.44 412.42 l 319.56 412.32 l 310.36 411.36 l 305.46 410.51 l 301.08 410.01 l 295.74 408.97 l 292.57 408.48 l 290.49 408.03 l 283.77 407.01 l 276.61 405.41 l 276.07 405.28 l 275.52 405.12 l 268.30 403.57 l 262.28 401.86 l 261.66 401.59 l 260.54 401.07 l 255.69 399.45 l 252.80 398.30 l 251.19 396.96 l 249.53 395.68 l 248.35 394.74 l 248.34 394.09 l 247.58 391.66 l 247.56 391.19 l 248.02 390.60 l 248.96 388.44 l 249.74 387.63 l 251.35 386.26 l 251.89 385.58 l 254.17 384.08 l 255.63 382.91 l 259.89 380.67 l 260.14 380.52 l 260.21 380.44 l 260.54 380.20 l 263.45 377.65 l 264.70 376.96 l 265.53 375.78 l 266.06 374.72 l 267.09 373.41 l 266.53 371.98 l 266.09 371.17 l 265.53 369.85 l 264.11 369.00 l 260.54 366.62 l 260.13 366.39 l 259.97 366.29 l 258.67 365.85 l 253.99 364.29 l 250.06 362.74 l 247.91 362.18 l 245.57 361.40 l 241.12 360.24 l 237.82 359.18 l 234.18 358.33 l 230.59 357.19 l 227.33 356.40 l 224.92 355.63 l 220.23 354.53 l 215.62 353.06 l 213.39 352.60 l 211.43 352.07 l 205.73 350.86 l 200.65 349.51 l 197.96 349.15 l 194.10 348.51 l 188.84 347.76 l 185.67 347.23 l 180.28 347.23 l 176.09 347.23 l 170.70 347.23 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 426.08 m 451.79 425.94 l 443.64 425.94 l 440.23 425.71 l 434.40 425.37 l 431.08 425.37 l 425.25 424.67 l 420.48 424.33 l 414.96 423.19 l 412.03 422.78 l 410.28 422.49 l 405.01 421.94 l 401.68 421.68 l 395.31 420.69 l 392.09 420.40 l 387.97 419.64 l 382.71 419.07 l 380.33 418.74 l 373.69 418.06 l 372.41 417.96 l 365.36 416.93 l 362.78 416.69 l 359.28 416.08 l 353.13 415.43 l 350.38 415.03 l 343.11 414.25 l 341.72 414.02 l 335.41 413.07 l 333.80 412.91 l 331.64 412.53 l 324.23 411.62 l 320.44 410.98 l 314.85 410.30 l 307.65 408.97 l 306.40 408.75 l 305.46 408.55 l 299.62 407.58 l 297.63 407.27 l 290.49 405.73 l 289.66 405.61 l 288.79 405.41 l 282.23 403.82 l 276.07 401.99 l 275.62 401.86 l 275.59 401.84 l 275.52 401.80 l 270.15 399.57 l 267.34 398.30 l 266.36 396.92 l 265.48 395.92 l 264.59 394.74 l 265.17 393.64 l 265.44 392.35 l 266.18 391.19 l 268.48 389.52 l 269.32 389.10 l 271.87 387.63 l 272.99 387.03 l 275.52 386.07 l 278.42 384.77 l 280.58 384.08 l 284.19 382.58 l 290.49 380.67 l 290.75 380.58 l 290.98 380.52 l 291.64 380.25 l 296.02 378.27 l 299.96 376.96 l 301.41 376.00 l 305.46 373.91 l 306.08 373.55 l 306.40 373.41 l 306.46 373.17 l 306.99 370.21 l 307.09 369.85 l 306.65 369.57 l 305.46 368.74 l 302.57 366.98 l 301.54 366.29 l 296.68 364.82 l 291.49 362.97 l 290.80 362.74 l 290.63 362.70 l 290.49 362.67 l 284.50 361.31 l 282.96 360.97 l 282.56 360.85 l 276.65 359.18 l 276.00 359.07 l 275.52 358.95 l 268.86 357.60 l 267.95 357.42 l 266.96 357.15 l 261.29 355.63 l 260.87 355.55 l 260.54 355.46 l 254.55 354.20 l 252.95 353.87 l 252.08 353.61 l 246.69 352.07 l 246.12 351.94 l 245.57 351.76 l 238.73 350.14 l 233.54 348.51 l 232.26 348.12 l 230.59 347.46 l 225.83 346.09 l 222.59 344.96 l 219.97 343.92 l 215.62 342.05 l 214.38 341.69 l 213.43 341.40 l 209.43 339.93 l 208.42 339.56 l 203.64 337.84 l 202.64 337.37 l 200.65 336.61 l 195.17 335.59 l 187.44 334.29 l 186.51 334.09 l 185.67 333.95 l 184.25 333.95 l 172.13 333.95 l 170.70 333.95 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 425.86 m 450.65 425.67 l 444.78 425.67 l 440.23 425.37 l 432.91 424.93 l 431.90 424.77 l 425.25 423.98 l 422.72 423.80 l 419.79 423.19 l 413.84 422.35 l 410.28 421.77 l 404.04 421.12 l 395.41 419.64 l 395.34 419.63 l 395.31 419.62 l 395.18 419.61 l 385.04 418.52 l 380.33 417.85 l 375.11 417.32 l 367.48 416.08 l 366.12 415.90 l 365.36 415.79 l 362.94 415.51 l 355.93 414.76 l 350.38 413.96 l 346.22 413.51 l 340.25 412.53 l 337.23 412.09 l 335.41 411.79 l 328.36 410.85 l 327.78 410.78 l 320.44 409.54 l 318.84 409.35 l 316.78 408.97 l 310.30 407.82 l 305.46 406.79 l 302.05 406.22 l 298.34 405.41 l 294.74 404.40 l 290.49 403.10 l 287.91 402.47 l 285.80 401.86 l 282.60 400.17 l 281.95 399.83 l 279.06 398.30 l 278.88 397.50 l 277.81 395.29 l 277.67 394.74 l 278.42 394.05 l 279.88 392.22 l 281.23 391.19 l 284.18 389.69 l 288.38 388.13 l 289.63 387.63 l 289.94 387.50 l 290.49 387.33 l 296.02 385.39 l 301.05 384.08 l 302.88 383.46 l 305.46 382.80 l 309.82 381.55 l 314.49 380.52 l 316.94 379.69 l 320.44 378.74 l 323.78 377.76 l 327.17 376.96 l 330.01 375.68 l 335.41 373.61 l 335.72 373.48 l 335.93 373.41 l 336.02 373.26 l 337.55 370.36 l 337.91 369.85 l 337.22 369.42 l 335.41 368.17 l 333.26 366.81 l 332.47 366.29 l 326.70 364.81 l 320.44 362.82 l 320.28 362.78 l 320.16 362.74 l 311.71 361.25 l 305.46 359.75 l 304.19 359.48 l 303.01 359.18 l 295.35 358.03 l 290.49 356.94 l 287.37 356.37 l 284.34 355.63 l 279.15 354.76 l 275.52 353.89 l 271.29 353.07 l 267.40 352.07 l 263.81 351.29 l 260.54 350.34 l 256.68 349.43 l 253.66 348.51 l 250.20 347.41 l 245.57 345.63 l 244.31 345.25 l 243.51 344.96 l 241.55 344.00 l 239.24 342.90 l 236.30 341.40 l 235.20 340.31 l 232.92 338.40 l 232.32 337.84 l 232.27 337.45 l 230.83 334.34 l 230.82 334.29 l 230.84 334.23 l 230.84 330.79 l 230.87 330.73 l 230.92 330.65 l 231.50 327.39 l 231.69 327.18 l 231.90 326.87 l 232.54 324.08 l 232.93 323.62 l 233.18 323.01 l 233.18 320.68 l 233.47 320.06 l 233.37 319.40 l 232.02 316.84 l 231.96 316.51 l 231.68 316.25 l 230.59 315.32 l 227.93 313.58 l 226.85 312.95 l 222.81 311.24 l 222.04 310.92 l 218.43 309.39 l 217.20 309.02 l 215.62 308.42 l 210.41 307.07 l 206.41 305.84 l 203.53 305.15 l 200.65 304.36 l 195.13 303.59 l 187.55 302.28 l 186.35 302.12 l 185.67 302.01 l 184.52 302.01 l 171.85 302.01 l 170.70 302.01 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 425.64 m 449.51 425.40 l 445.92 425.40 l 440.23 425.02 l 434.07 424.66 l 426.02 423.38 l 425.25 423.28 l 424.96 423.26 l 424.62 423.19 l 415.65 421.92 l 410.28 421.05 l 406.15 420.62 l 400.43 419.64 l 397.28 419.17 l 395.31 418.88 l 388.99 418.14 l 387.38 417.96 l 380.33 416.97 l 377.72 416.70 l 373.91 416.08 l 368.42 415.35 l 365.36 414.92 l 358.63 414.12 l 354.32 413.46 l 350.38 412.89 l 349.33 412.78 l 347.81 412.53 l 340.08 411.42 l 335.41 410.65 l 330.88 410.04 l 324.78 408.97 l 322.44 408.49 l 320.44 408.07 l 314.10 406.92 l 307.12 405.41 l 306.42 405.18 l 305.46 404.88 l 299.61 403.25 l 295.03 401.86 l 293.85 401.06 l 290.49 398.99 l 289.58 398.52 l 289.17 398.30 l 289.10 397.97 l 289.10 395.07 l 289.01 394.74 l 289.32 394.47 l 290.49 393.72 l 293.12 391.81 l 294.32 391.19 l 298.52 389.54 l 302.41 388.36 l 304.71 387.63 l 305.03 387.53 l 305.46 387.41 l 311.87 385.60 l 318.87 384.08 l 319.59 383.87 l 320.44 383.68 l 327.04 382.09 l 335.21 380.52 l 335.30 380.49 l 335.41 380.47 l 342.53 378.65 l 348.72 377.36 l 350.38 377.01 l 350.48 376.98 l 350.60 376.96 l 351.04 376.81 l 356.43 374.84 l 361.18 373.41 l 361.87 372.58 l 364.08 370.15 l 364.34 369.85 l 363.69 369.45 l 360.37 367.48 l 358.48 366.29 l 353.86 365.47 l 350.38 364.54 l 346.51 363.66 l 343.31 362.74 l 338.17 362.08 l 335.41 361.54 l 329.47 360.59 l 323.07 359.18 l 321.35 358.96 l 320.44 358.80 l 316.16 358.17 l 312.07 357.61 l 305.46 356.30 l 303.78 356.02 l 302.01 355.63 l 295.08 354.54 l 290.49 353.55 l 286.91 352.92 l 283.36 352.07 l 279.23 351.19 l 275.52 350.19 l 271.85 349.38 l 268.78 348.51 l 265.33 347.37 l 260.54 345.55 l 259.46 345.21 l 258.76 344.96 l 257.47 344.23 l 254.82 342.76 l 252.48 341.40 l 251.74 339.93 l 251.19 339.18 l 250.45 337.84 l 251.03 336.55 l 251.16 335.62 l 251.85 334.29 l 253.64 332.65 l 254.42 332.19 l 256.40 330.73 l 257.44 330.00 l 260.54 328.52 l 262.24 327.58 l 263.29 327.18 l 265.94 325.89 l 267.20 325.20 l 271.37 323.62 l 272.50 322.90 l 275.52 321.52 l 277.41 320.51 l 278.58 320.06 l 279.86 319.03 l 281.09 317.83 l 283.00 316.51 l 282.91 314.75 l 282.89 314.70 l 282.79 312.95 l 280.82 311.69 l 278.64 310.13 l 277.54 309.39 l 276.71 309.11 l 275.52 308.62 l 270.83 306.95 l 268.03 305.84 l 264.42 304.92 l 260.54 303.70 l 257.73 302.95 l 255.69 302.28 l 250.59 301.09 l 245.57 299.59 l 243.78 299.15 l 242.42 298.72 l 236.58 297.30 l 230.59 295.39 l 230.13 295.28 l 229.76 295.17 l 222.95 293.43 l 222.13 293.16 l 217.28 291.61 l 216.56 291.39 l 215.62 291.04 l 209.54 289.50 l 204.50 288.06 l 202.82 287.54 l 200.65 286.83 l 194.86 285.87 l 186.51 284.50 l 186.02 284.42 l 185.67 284.36 l 185.07 284.36 l 171.30 284.36 l 170.70 284.36 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 425.42 m 448.37 425.13 l 447.06 425.13 l 440.23 424.68 l 435.23 424.38 l 427.77 423.19 l 426.60 422.87 l 425.25 422.62 l 418.99 421.71 l 417.46 421.49 l 410.28 420.33 l 408.26 420.12 l 405.46 419.64 l 399.22 418.71 l 395.31 418.15 l 389.50 417.46 l 380.33 416.08 l 370.73 414.81 l 365.36 414.05 l 361.08 413.54 l 354.50 412.53 l 352.10 412.12 l 350.38 411.84 l 342.93 410.74 l 342.70 410.70 l 335.41 409.51 l 333.96 409.31 l 332.01 408.97 l 325.78 407.70 l 320.44 406.57 l 317.68 406.07 l 314.64 405.41 l 310.78 404.15 l 305.46 402.44 l 304.33 402.13 l 303.44 401.86 l 302.35 401.12 l 300.16 399.56 l 298.20 398.30 l 298.60 396.67 l 298.78 396.33 l 299.23 394.74 l 300.96 393.67 l 305.46 391.55 l 305.95 391.30 l 306.24 391.19 l 308.50 390.47 l 312.22 389.24 l 318.39 387.63 l 319.34 387.37 l 320.44 387.13 l 326.91 385.61 l 335.09 384.08 l 335.25 384.04 l 335.41 384.00 l 338.01 383.46 l 343.17 382.36 l 350.38 381.08 l 351.72 380.84 l 353.77 380.52 l 359.72 379.18 l 365.36 378.09 l 367.92 377.57 l 371.51 376.96 l 375.36 375.78 l 380.33 374.41 l 382.25 373.86 l 384.07 373.41 l 385.47 372.18 l 386.43 371.30 l 388.16 369.85 l 385.05 368.73 l 381.01 366.46 l 380.68 366.29 l 380.45 366.27 l 380.33 366.24 l 379.71 366.15 l 371.09 364.93 l 365.36 363.60 l 363.33 363.22 l 361.49 362.74 l 354.04 361.87 l 350.38 361.22 l 345.01 360.46 l 338.69 359.18 l 336.55 358.91 l 335.41 358.72 l 330.73 358.07 l 327.07 357.61 l 320.44 356.41 l 318.39 356.11 l 316.02 355.63 l 309.62 354.64 l 305.46 353.81 l 301.14 353.09 l 296.43 352.07 l 293.30 351.40 l 290.49 350.69 l 285.69 349.65 l 281.39 348.51 l 278.98 347.69 l 275.52 346.38 l 272.98 345.56 l 271.34 344.96 l 268.99 343.41 l 268.48 343.07 l 265.94 341.40 l 265.81 340.15 l 265.49 339.02 l 265.36 337.84 l 266.77 336.36 l 267.13 335.85 l 268.90 334.29 l 270.80 333.17 l 275.52 331.18 l 276.14 330.88 l 276.56 330.73 l 278.37 330.05 l 281.80 328.67 l 286.91 327.18 l 288.30 326.66 l 290.49 326.01 l 294.75 324.63 l 298.86 323.62 l 301.41 322.66 l 305.46 321.42 l 307.84 320.63 l 309.98 320.06 l 313.33 318.38 l 314.31 317.96 l 317.57 316.51 l 317.82 315.88 l 319.30 313.22 l 319.42 312.95 l 318.89 312.58 l 315.77 310.50 l 314.25 309.39 l 310.42 308.22 l 305.46 306.48 l 304.29 306.12 l 303.51 305.84 l 296.66 304.37 l 290.49 302.68 l 289.67 302.48 l 288.99 302.28 l 281.45 300.87 l 275.52 299.37 l 274.08 299.07 l 272.84 298.72 l 266.16 297.39 l 260.54 295.86 l 259.05 295.52 l 257.84 295.17 l 251.83 293.68 l 245.57 291.68 l 245.43 291.65 l 245.32 291.61 l 244.76 291.42 l 239.18 289.57 l 235.30 288.06 l 233.82 287.29 l 230.59 285.53 l 229.00 284.88 l 228.14 284.50 l 226.74 283.59 l 224.90 282.30 l 222.67 280.94 l 221.46 279.56 l 220.09 278.45 l 219.02 277.39 l 218.74 276.65 l 216.12 273.95 l 216.06 273.83 l 216.04 273.73 l 215.62 273.12 l 213.23 270.84 l 212.10 270.27 l 209.92 268.92 l 209.05 268.28 l 206.00 266.72 l 204.49 265.81 l 200.65 264.18 l 198.34 263.71 l 194.66 263.16 l 189.58 262.23 l 185.67 261.64 l 179.26 261.64 l 177.12 261.64 l 170.70 261.64 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 425.20 m 448.05 424.89 l 446.86 424.77 l 440.23 424.33 l 436.39 424.10 l 430.67 423.19 l 428.15 422.51 l 425.25 421.97 l 419.18 421.08 l 410.45 419.64 l 410.36 419.62 l 410.28 419.61 l 409.94 419.56 l 401.16 418.25 l 395.31 417.41 l 391.57 416.97 l 385.68 416.08 l 382.53 415.56 l 380.33 415.25 l 373.02 414.26 l 372.11 414.13 l 365.36 413.17 l 363.54 412.96 l 360.74 412.53 l 354.69 411.50 l 350.38 410.81 l 345.61 410.10 l 338.85 408.97 l 337.12 408.56 l 335.41 408.20 l 329.11 406.91 l 322.04 405.41 l 321.42 405.18 l 320.44 404.84 l 315.16 403.11 l 311.27 401.86 l 310.10 400.76 l 307.54 398.79 l 306.97 398.30 l 307.27 397.87 l 308.47 395.46 l 309.04 394.74 l 312.76 393.01 l 312.88 392.95 l 317.33 391.19 l 318.66 390.76 l 320.44 390.31 l 325.73 388.89 l 331.41 387.63 l 333.42 387.16 l 335.41 386.78 l 341.58 385.54 l 350.23 384.08 l 350.31 384.06 l 350.38 384.05 l 350.93 383.95 l 358.70 382.49 l 365.36 381.43 l 367.63 381.06 l 371.38 380.52 l 376.21 379.54 l 380.33 378.82 l 384.80 378.02 l 391.42 376.96 l 393.19 376.46 l 395.31 375.93 l 400.45 374.63 l 405.79 373.41 l 406.84 372.59 l 410.28 370.16 l 410.60 369.93 l 410.72 369.85 l 410.40 369.82 l 410.28 369.79 l 408.52 369.43 l 402.15 368.22 l 400.53 367.53 l 397.07 366.29 l 395.91 366.15 l 395.31 366.04 l 392.74 365.68 l 386.17 364.91 l 380.33 363.72 l 377.84 363.33 l 375.30 362.74 l 368.65 361.96 l 365.36 361.42 l 359.29 360.62 l 351.54 359.18 l 350.80 359.08 l 350.38 359.02 l 348.75 358.79 l 341.10 357.83 l 335.41 356.88 l 332.08 356.42 l 327.87 355.63 l 323.40 354.92 l 320.44 354.37 l 314.67 353.44 l 307.91 352.07 l 306.64 351.79 l 305.46 351.51 l 298.84 350.08 l 292.60 348.51 l 291.77 348.21 l 290.49 347.73 l 285.64 346.11 l 282.52 344.96 l 280.95 343.67 l 279.02 342.23 l 277.96 341.40 l 278.12 340.78 l 278.27 338.50 l 278.46 337.84 l 280.06 336.76 l 281.42 335.69 l 283.87 334.29 l 286.21 333.27 l 290.49 331.81 l 292.27 331.15 l 293.74 330.73 l 298.91 329.17 l 305.46 327.57 l 306.26 327.36 l 307.17 327.18 l 313.50 325.53 l 320.44 324.02 l 321.31 323.83 l 322.42 323.62 l 328.45 321.97 l 335.41 320.34 l 335.99 320.20 l 336.66 320.06 l 338.98 319.22 l 342.01 318.07 l 346.78 316.51 l 347.32 315.78 l 349.66 313.12 l 349.80 312.95 l 349.49 312.74 l 346.08 310.42 l 344.63 309.39 l 340.09 308.28 l 335.41 306.86 l 333.41 306.31 l 331.93 305.84 l 325.07 304.74 l 320.44 303.71 l 317.11 303.07 l 313.86 302.28 l 308.67 301.52 l 305.46 300.87 l 300.27 299.96 l 294.85 298.72 l 292.30 298.30 l 290.49 297.89 l 284.11 296.68 l 277.87 295.17 l 276.66 294.90 l 275.52 294.58 l 269.28 293.09 l 264.25 291.61 l 262.74 291.09 l 260.54 290.23 l 256.72 288.96 l 254.42 288.06 l 252.00 286.53 l 250.74 285.73 l 248.80 284.50 l 248.49 283.81 l 246.82 281.24 l 246.68 280.94 l 246.83 280.64 l 247.46 277.84 l 247.74 277.39 l 248.53 276.68 l 249.99 274.88 l 251.45 273.83 l 253.71 272.21 l 255.04 271.58 l 257.41 270.27 l 258.22 269.72 l 260.54 268.67 l 263.08 267.32 l 264.66 266.72 l 267.13 265.15 l 267.55 264.83 l 270.84 263.16 l 271.63 262.24 l 274.79 259.78 l 274.96 259.61 l 274.93 259.47 l 274.43 256.31 l 274.36 256.05 l 273.70 255.62 l 270.59 253.66 l 268.86 252.49 l 265.48 251.32 l 260.54 249.36 l 259.81 249.11 l 259.39 248.94 l 252.98 247.18 l 252.61 247.05 l 247.50 245.38 l 246.54 245.15 l 245.57 244.85 l 239.31 243.31 l 234.46 241.82 l 232.54 241.36 l 230.59 240.73 l 225.51 239.48 l 221.61 238.27 l 218.75 237.53 l 215.62 236.49 l 211.80 235.62 l 208.43 234.71 l 204.70 233.75 l 200.65 232.51 l 197.18 231.98 l 192.09 231.16 l 188.20 230.56 l 185.67 230.14 l 181.40 230.14 l 174.98 230.14 l 170.70 230.14 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 424.97 m 448.84 424.70 l 444.85 424.29 l 440.23 423.99 l 437.55 423.83 l 433.56 423.19 l 429.69 422.14 l 425.25 421.31 l 420.89 420.67 l 414.60 419.64 l 412.32 419.15 l 410.28 418.85 l 403.10 417.79 l 401.56 417.57 l 395.31 416.67 l 393.65 416.48 l 391.03 416.08 l 384.73 415.04 l 380.33 414.42 l 375.26 413.73 l 366.90 412.53 l 366.06 412.36 l 365.36 412.25 l 361.36 411.58 l 357.28 410.89 l 350.38 409.78 l 348.29 409.47 l 345.33 408.97 l 340.33 407.80 l 335.41 406.75 l 332.39 406.13 l 329.00 405.41 l 325.71 404.16 l 320.44 402.35 l 319.56 402.07 l 318.91 401.86 l 318.39 401.37 l 316.44 399.25 l 315.33 398.30 l 316.07 397.26 l 318.00 395.32 l 318.46 394.74 l 319.13 394.43 l 320.44 393.94 l 324.90 392.25 l 328.19 391.19 l 331.60 390.28 l 335.41 389.44 l 339.33 388.56 l 344.09 387.63 l 347.48 386.94 l 350.38 386.44 l 356.13 385.44 l 365.06 384.08 l 365.23 384.04 l 365.36 384.02 l 366.05 383.91 l 374.04 382.58 l 380.33 381.65 l 383.28 381.22 l 388.59 380.52 l 392.40 379.83 l 395.31 379.35 l 401.25 378.37 l 409.33 377.19 l 410.28 377.04 l 410.49 377.01 l 410.85 376.96 l 418.10 375.26 l 425.25 373.71 l 425.92 373.57 l 426.73 373.41 l 427.66 372.83 l 430.47 371.09 l 432.53 369.85 l 426.45 369.57 l 425.25 369.36 l 420.75 368.78 l 416.41 368.39 l 410.28 366.67 l 409.43 366.50 l 408.86 366.29 l 399.98 365.18 l 395.31 364.33 l 391.07 363.74 l 386.26 362.74 l 382.47 362.23 l 380.33 361.90 l 372.92 360.94 l 372.39 360.85 l 365.36 359.71 l 363.92 359.52 l 362.09 359.18 l 354.62 358.18 l 350.38 357.52 l 345.33 356.83 l 338.44 355.63 l 336.68 355.32 l 335.41 355.10 l 328.42 353.96 l 327.82 353.87 l 320.44 352.50 l 319.36 352.32 l 318.09 352.07 l 311.55 350.62 l 305.46 349.17 l 304.01 348.86 l 302.65 348.51 l 297.85 346.76 l 297.42 346.60 l 292.97 344.96 l 292.52 344.47 l 290.49 342.62 l 289.38 341.66 l 289.05 341.40 l 289.13 341.08 l 290.49 338.32 l 290.69 337.89 l 290.72 337.84 l 290.93 337.74 l 295.19 335.40 l 297.71 334.29 l 300.84 333.19 l 305.46 331.89 l 307.66 331.25 l 309.79 330.73 l 314.91 329.42 l 320.44 328.25 l 322.81 327.74 l 325.85 327.18 l 330.73 326.06 l 335.41 325.17 l 338.99 324.47 l 344.06 323.62 l 347.19 322.86 l 350.38 322.20 l 355.10 321.18 l 361.08 320.06 l 362.87 319.47 l 365.36 318.76 l 369.58 317.51 l 373.36 316.51 l 374.83 315.20 l 376.54 313.85 l 377.61 312.95 l 375.65 311.84 l 373.91 310.92 l 371.49 309.39 l 367.78 308.82 l 365.36 308.24 l 359.89 307.14 l 355.11 305.84 l 352.02 305.45 l 350.38 305.15 l 342.95 304.05 l 342.17 303.89 l 335.41 302.55 l 334.76 302.44 l 334.07 302.28 l 325.38 301.11 l 320.44 300.19 l 316.71 299.61 l 312.47 298.72 l 308.31 298.05 l 305.46 297.47 l 299.89 296.49 l 294.02 295.17 l 292.21 294.76 l 290.49 294.31 l 284.66 293.00 l 279.64 291.61 l 278.01 291.02 l 275.52 290.04 l 272.08 288.87 l 269.94 288.06 l 267.64 286.37 l 267.27 286.10 l 265.09 284.50 l 265.05 283.43 l 264.66 281.92 l 264.61 280.94 l 265.93 279.66 l 266.59 278.82 l 268.31 277.39 l 270.44 276.18 l 275.52 274.09 l 275.89 273.92 l 276.15 273.83 l 277.28 273.41 l 281.56 271.71 l 286.48 270.27 l 288.05 269.70 l 290.49 269.00 l 294.64 267.70 l 298.58 266.72 l 301.24 265.72 l 305.46 264.45 l 307.77 263.71 l 309.89 263.16 l 313.30 261.47 l 314.27 261.07 l 317.68 259.61 l 317.91 259.01 l 319.10 256.37 l 319.22 256.05 l 318.64 255.62 l 315.85 253.58 l 314.37 252.49 l 310.42 251.32 l 305.46 249.60 l 304.29 249.22 l 303.54 248.94 l 296.77 247.44 l 290.49 245.76 l 289.70 245.57 l 289.03 245.38 l 281.54 243.95 l 275.52 242.39 l 274.28 242.12 l 273.24 241.82 l 266.35 240.44 l 260.54 238.87 l 259.23 238.58 l 258.15 238.27 l 252.05 236.73 l 246.57 234.95 l 245.81 234.71 l 245.71 234.68 l 245.57 234.62 l 239.51 232.59 l 235.85 231.16 l 234.20 230.30 l 230.59 228.31 l 229.51 227.86 l 228.93 227.60 l 228.01 226.99 l 225.60 225.23 l 223.66 224.04 l 222.28 222.46 l 221.61 221.91 l 220.20 220.49 l 219.84 219.48 l 218.02 217.50 l 217.76 216.93 l 217.65 216.45 l 215.62 214.09 l 214.91 213.54 l 214.55 213.37 l 214.04 213.00 l 211.76 210.74 l 210.18 209.82 l 207.20 208.26 l 204.39 207.15 l 202.31 206.26 l 201.76 206.00 l 200.65 205.55 l 193.99 204.29 l 185.67 202.71 l 170.70 202.71 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 424.75 m 449.64 424.52 l 442.84 423.81 l 440.23 423.64 l 438.72 423.55 l 436.46 423.19 l 431.24 421.77 l 425.25 420.66 l 422.59 420.27 l 418.76 419.64 l 414.29 418.69 l 410.28 418.08 l 405.08 417.32 l 396.36 416.08 l 395.80 415.96 l 395.31 415.89 l 392.84 415.50 l 386.92 414.52 l 380.33 413.58 l 377.49 413.20 l 372.82 412.53 l 368.76 411.72 l 365.36 411.17 l 359.92 410.26 l 351.84 408.97 l 351.15 408.79 l 350.38 408.62 l 343.58 407.03 l 335.98 405.41 l 335.78 405.32 l 335.41 405.19 l 330.10 403.12 l 326.49 401.86 l 325.68 400.61 l 324.42 399.25 l 323.74 398.30 l 325.02 397.21 l 326.14 396.10 l 327.92 394.74 l 330.87 393.67 l 335.41 392.24 l 337.36 391.65 l 339.04 391.19 l 344.89 389.88 l 350.38 388.79 l 353.11 388.28 l 356.78 387.63 l 361.70 386.76 l 365.36 386.19 l 370.76 385.36 l 379.89 384.08 l 380.15 384.03 l 380.33 384.00 l 381.11 383.89 l 389.34 382.66 l 395.31 381.85 l 398.90 381.37 l 405.68 380.52 l 408.38 380.07 l 410.28 379.78 l 417.57 378.69 l 418.51 378.56 l 425.25 377.61 l 426.99 377.37 l 430.11 376.96 l 435.42 375.82 l 440.23 374.86 l 443.55 374.20 l 447.71 373.41 l 449.86 372.14 l 453.01 370.37 l 453.92 369.85 l 441.70 369.50 l 440.23 369.36 l 436.88 369.06 l 429.96 368.73 l 425.25 367.93 l 420.80 367.35 l 416.80 366.29 l 413.01 365.64 l 410.28 365.16 l 403.85 364.26 l 395.85 362.74 l 395.53 362.68 l 395.31 362.65 l 394.43 362.53 l 385.97 361.40 l 380.33 360.54 l 376.64 360.06 l 371.51 359.18 l 367.76 358.61 l 365.36 358.25 l 358.40 357.28 l 355.16 356.76 l 350.38 356.02 l 349.34 355.87 l 347.92 355.63 l 340.64 354.38 l 335.41 353.46 l 331.93 352.90 l 327.55 352.07 l 324.00 351.22 l 320.44 350.40 l 316.33 349.49 l 312.24 348.51 l 309.72 347.50 l 305.46 345.90 l 303.89 345.33 l 302.88 344.96 l 302.15 344.17 l 300.77 342.51 l 299.66 341.40 l 300.44 340.21 l 301.79 338.72 l 302.42 337.84 l 303.39 337.35 l 305.46 336.48 l 308.80 335.08 l 311.03 334.29 l 315.30 333.07 l 320.44 331.81 l 322.68 331.27 l 325.17 330.73 l 330.50 329.57 l 335.41 328.64 l 338.86 327.99 l 343.79 327.18 l 347.38 326.46 l 350.38 325.95 l 356.05 324.96 l 364.74 323.62 l 365.06 323.55 l 365.36 323.49 l 368.08 322.97 l 373.33 321.96 l 380.33 320.74 l 382.00 320.46 l 384.48 320.06 l 389.58 318.70 l 395.31 317.32 l 397.01 316.91 l 398.80 316.51 l 400.61 315.25 l 401.68 314.46 l 403.97 312.95 l 399.42 311.97 l 395.31 310.09 l 394.17 309.66 l 393.64 309.39 l 384.97 308.29 l 380.33 307.32 l 376.66 306.71 l 373.00 305.84 l 367.98 305.22 l 365.36 304.78 l 358.70 303.86 l 350.88 302.40 l 350.38 302.31 l 350.31 302.30 l 350.22 302.28 l 340.72 301.02 l 335.41 300.12 l 331.77 299.59 l 327.24 298.72 l 323.22 298.06 l 320.44 297.54 l 314.60 296.56 l 307.85 295.17 l 306.64 294.89 l 305.46 294.60 l 299.02 293.14 l 293.09 291.61 l 292.10 291.23 l 290.49 290.60 l 286.22 289.07 l 283.59 288.06 l 281.87 286.55 l 280.94 285.79 l 279.43 284.50 l 279.77 283.49 l 280.01 282.01 l 280.41 280.94 l 283.08 279.19 l 283.23 279.11 l 286.31 277.39 l 287.82 276.75 l 290.49 275.86 l 293.92 274.65 l 296.79 273.83 l 300.64 272.68 l 305.46 271.53 l 308.04 270.89 l 310.99 270.27 l 315.49 269.10 l 320.44 268.03 l 323.27 267.39 l 326.85 266.72 l 330.85 265.63 l 335.41 264.57 l 338.36 263.86 l 341.83 263.16 l 345.24 261.94 l 350.38 260.32 l 351.64 259.90 l 352.66 259.61 l 353.30 258.91 l 354.82 257.10 l 355.83 256.05 l 354.41 255.09 l 350.89 252.61 l 350.72 252.49 l 350.54 252.46 l 350.38 252.41 l 343.22 250.64 l 337.47 248.94 l 336.17 248.76 l 335.41 248.61 l 330.30 247.72 l 327.49 247.26 l 320.44 245.69 l 319.73 245.55 l 319.05 245.38 l 310.70 244.14 l 305.46 243.06 l 302.48 242.53 l 299.38 241.82 l 294.20 240.94 l 290.49 240.11 l 286.18 239.29 l 281.96 238.27 l 278.66 237.52 l 275.52 236.65 l 271.46 235.68 l 268.23 234.71 l 265.16 233.62 l 260.54 231.76 l 259.49 231.41 l 258.85 231.16 l 257.82 230.51 l 255.19 228.87 l 253.16 227.60 l 252.48 225.96 l 252.28 225.64 l 251.56 224.04 l 252.40 222.42 l 252.46 222.12 l 253.46 220.49 l 255.02 219.18 l 257.92 217.56 l 258.84 216.93 l 259.28 216.63 l 260.54 216.04 l 263.92 214.18 l 266.02 213.37 l 269.13 211.86 l 274.15 210.14 l 275.03 209.82 l 275.17 209.74 l 275.52 209.58 l 279.88 207.30 l 282.50 206.26 l 284.35 204.80 l 286.09 203.75 l 287.61 202.71 l 287.61 202.02 l 287.99 199.74 l 287.99 199.15 l 286.63 198.23 l 284.68 196.97 l 282.70 195.59 l 279.74 194.59 l 275.52 192.93 l 273.98 192.40 l 273.02 192.04 l 266.98 190.51 l 260.54 188.48 l 253.12 186.69 l 247.44 184.92 l 246.49 184.71 l 245.57 184.43 l 239.11 182.90 l 234.22 181.37 l 232.53 180.91 l 230.59 180.23 l 225.70 178.98 l 222.11 177.81 l 219.26 176.95 l 215.62 175.61 l 212.80 174.93 l 210.41 174.26 l 206.19 172.94 l 200.65 171.12 l 199.61 170.95 l 198.15 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 369.37 m 452.44 369.19 l 444.00 368.95 l 440.23 368.60 l 433.22 367.96 l 428.27 367.01 l 425.25 366.49 l 424.71 366.42 l 424.21 366.29 l 416.12 364.91 l 410.28 363.86 l 407.29 363.45 l 403.56 362.74 l 398.72 361.93 l 395.31 361.41 l 389.38 360.59 l 380.41 359.18 l 380.37 359.17 l 380.33 359.17 l 380.17 359.14 l 371.24 357.78 l 365.36 356.90 l 361.97 356.43 l 356.94 355.63 l 353.28 354.94 l 350.38 354.44 l 344.57 353.45 l 336.78 352.07 l 336.13 351.90 l 335.41 351.74 l 328.63 350.12 l 321.67 348.51 l 321.24 348.32 l 320.44 348.00 l 315.70 346.08 l 312.75 344.96 l 311.78 343.46 l 311.20 342.76 l 310.24 341.40 l 311.85 339.88 l 312.24 339.45 l 314.12 337.84 l 316.46 336.90 l 320.44 335.53 l 322.62 334.81 l 324.35 334.29 l 329.82 332.96 l 335.41 331.75 l 337.70 331.28 l 340.56 330.73 l 346.02 329.69 l 350.38 328.95 l 354.80 328.22 l 361.75 327.18 l 363.82 326.81 l 365.36 326.57 l 372.84 325.40 l 380.33 324.30 l 382.14 324.05 l 385.39 323.62 l 391.12 322.62 l 395.31 321.95 l 400.06 321.19 l 407.71 320.06 l 408.98 319.75 l 410.28 319.46 l 416.70 318.03 l 423.98 316.51 l 424.33 316.29 l 425.25 315.73 l 428.58 313.74 l 429.98 312.95 l 426.10 312.75 l 425.25 312.60 l 421.66 312.10 l 416.24 311.53 l 410.28 309.77 l 409.46 309.59 l 408.94 309.39 l 400.16 308.24 l 395.31 307.34 l 391.38 306.77 l 387.01 305.84 l 382.79 305.25 l 380.33 304.87 l 373.36 303.94 l 369.59 303.29 l 365.36 302.59 l 364.54 302.48 l 363.50 302.28 l 355.23 301.13 l 350.38 300.37 l 346.05 299.75 l 340.20 298.72 l 337.44 298.24 l 335.41 297.88 l 328.73 296.75 l 320.44 295.17 l 312.83 293.42 l 305.46 291.61 l 299.75 289.41 l 296.26 288.06 l 295.26 286.92 l 293.50 285.22 l 292.83 284.50 l 293.31 283.83 l 294.37 281.87 l 295.10 280.94 l 298.49 279.29 l 299.92 278.70 l 302.99 277.39 l 304.01 277.04 l 305.46 276.64 l 310.86 275.11 l 316.21 273.83 l 318.28 273.32 l 320.44 272.87 l 326.14 271.63 l 333.43 270.27 l 334.44 270.04 l 335.41 269.86 l 342.68 268.45 l 344.15 268.20 l 350.38 267.13 l 351.38 266.96 l 352.92 266.72 l 359.49 265.32 l 365.36 264.23 l 367.85 263.76 l 371.29 263.16 l 375.31 261.97 l 380.33 260.63 l 382.38 260.09 l 384.39 259.61 l 386.23 258.21 l 386.96 257.62 l 389.12 256.05 l 385.91 254.73 l 383.56 253.26 l 382.11 252.49 l 380.96 252.34 l 380.33 252.21 l 376.22 251.52 l 372.15 250.88 l 365.36 249.23 l 364.70 249.09 l 364.13 248.94 l 355.15 247.81 l 350.38 246.95 l 346.35 246.34 l 341.72 245.38 l 337.69 244.84 l 335.41 244.46 l 328.56 243.45 l 321.86 242.16 l 320.44 241.90 l 320.25 241.87 l 320.04 241.82 l 311.42 240.41 l 305.46 239.19 l 303.23 238.80 l 300.88 238.27 l 295.55 237.07 l 290.49 235.74 l 288.28 235.24 l 286.36 234.71 l 282.07 233.16 l 279.26 232.05 l 276.96 231.16 l 276.67 230.88 l 275.52 229.93 l 273.17 228.16 l 272.41 227.60 l 272.39 226.86 l 272.74 224.70 l 272.72 224.04 l 273.27 223.51 l 275.52 221.97 l 277.03 220.85 l 277.69 220.49 l 280.51 219.30 l 282.22 218.52 l 286.81 216.93 l 288.26 216.40 l 290.49 215.77 l 294.92 214.43 l 299.35 213.37 l 302.04 212.56 l 305.46 211.72 l 309.25 210.72 l 313.47 209.82 l 316.47 208.88 l 320.44 207.84 l 323.53 207.00 l 326.74 206.26 l 329.83 204.94 l 335.41 202.86 l 335.66 202.77 l 335.84 202.71 l 335.95 202.58 l 338.03 199.77 l 338.59 199.15 l 337.77 198.59 l 335.41 196.89 l 334.03 195.92 l 333.60 195.59 l 327.67 193.87 l 326.43 193.46 l 322.06 192.04 l 321.10 191.88 l 320.44 191.73 l 313.39 190.36 l 312.90 190.27 l 305.46 188.48 l 296.74 187.00 l 290.49 185.54 l 289.06 185.26 l 287.70 184.92 l 280.78 183.67 l 275.52 182.38 l 273.24 181.91 l 271.24 181.37 l 265.89 180.10 l 260.54 178.47 l 259.18 178.14 l 258.15 177.81 l 253.28 176.09 l 253.10 176.02 l 248.72 174.26 l 247.84 173.72 l 245.57 172.32 l 243.38 171.22 l 242.45 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 424.53 m 450.43 424.33 l 440.83 423.34 l 440.23 423.30 l 439.88 423.28 l 439.36 423.19 l 433.42 421.58 l 432.80 421.40 l 432.36 421.33 l 425.25 420.00 l 424.30 419.86 l 422.92 419.64 l 416.25 418.22 l 410.28 417.32 l 407.06 416.85 l 401.65 416.08 l 398.28 415.37 l 395.31 414.95 l 389.23 413.97 l 382.68 413.08 l 380.33 412.75 l 379.73 412.67 l 378.73 412.53 l 371.46 411.08 l 365.36 410.10 l 362.57 409.63 l 358.43 408.97 l 354.66 407.95 l 350.38 407.03 l 346.95 406.23 l 343.11 405.41 l 340.46 404.21 l 335.41 402.36 l 334.60 402.05 l 334.05 401.86 l 333.80 401.47 l 332.67 398.95 l 332.20 398.30 l 332.90 397.70 l 335.41 396.01 l 336.89 395.09 l 337.54 394.74 l 343.24 393.05 l 347.89 391.78 l 350.05 391.19 l 350.22 391.15 l 350.38 391.12 l 351.83 390.84 l 358.53 389.57 l 365.36 388.35 l 367.15 388.06 l 369.77 387.63 l 376.14 386.64 l 380.33 386.03 l 385.58 385.32 l 395.00 384.08 l 395.19 384.05 l 395.31 384.03 l 395.72 383.98 l 404.75 382.76 l 410.28 382.05 l 414.56 381.53 l 423.14 380.52 l 424.43 380.32 l 425.25 380.21 l 428.35 379.78 l 433.90 379.02 l 440.23 378.17 l 443.53 377.75 l 449.68 376.96 l 452.67 376.36 l 455.20 375.88 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 312.93 m 455.08 312.92 l 442.13 312.50 l 440.23 312.31 l 435.73 311.88 l 430.83 311.63 l 425.25 310.63 l 421.97 310.17 l 419.13 309.39 l 414.03 308.50 l 410.28 307.82 l 405.07 307.07 l 398.64 305.84 l 396.70 305.51 l 395.31 305.29 l 389.59 304.48 l 387.35 304.17 l 380.33 303.09 l 378.17 302.79 l 375.19 302.28 l 369.25 301.36 l 365.36 300.77 l 360.00 300.00 l 352.10 298.72 l 351.15 298.54 l 350.38 298.41 l 345.34 297.53 l 342.53 297.03 l 335.41 295.76 l 333.95 295.52 l 332.14 295.17 l 326.36 293.76 l 320.44 292.37 l 318.82 292.00 l 317.25 291.61 l 313.02 289.85 l 312.97 289.83 l 308.53 288.06 l 308.16 287.42 l 305.94 284.61 l 305.86 284.50 l 306.01 284.37 l 308.64 281.70 l 309.57 280.94 l 313.70 279.34 l 317.28 278.14 l 319.45 277.39 l 319.90 277.26 l 320.44 277.13 l 327.37 275.48 l 335.04 273.83 l 335.23 273.79 l 335.41 273.75 l 336.87 273.48 l 343.61 272.22 l 350.38 271.08 l 352.39 270.75 l 355.52 270.27 l 361.19 269.28 l 365.36 268.63 l 370.22 267.87 l 378.30 266.72 l 379.42 266.50 l 380.33 266.34 l 385.90 265.40 l 388.12 265.01 l 395.31 263.86 l 397.08 263.58 l 399.91 263.16 l 405.05 261.92 l 410.28 260.75 l 412.77 260.20 l 415.58 259.61 l 418.27 257.95 l 418.95 257.55 l 421.43 256.05 l 413.73 255.23 l 410.28 254.19 l 406.59 253.37 l 404.29 252.49 l 398.51 251.73 l 395.31 251.13 l 389.61 250.29 l 383.30 248.94 l 381.42 248.68 l 380.33 248.51 l 376.15 247.94 l 371.82 247.40 l 365.36 246.34 l 362.81 245.99 l 359.60 245.38 l 353.82 244.57 l 350.38 244.02 l 344.61 243.20 l 336.77 241.82 l 335.99 241.69 l 335.41 241.59 l 331.86 240.98 l 327.23 240.21 l 320.44 238.92 l 318.84 238.65 l 317.01 238.27 l 311.16 236.92 l 305.46 235.53 l 303.71 235.13 l 302.10 234.71 l 297.69 233.00 l 296.79 232.65 l 292.93 231.16 l 292.53 230.67 l 290.49 228.57 l 289.69 227.79 l 289.48 227.60 l 289.55 227.38 l 290.49 225.66 l 291.25 224.22 l 291.39 224.04 l 292.27 223.62 l 295.87 221.77 l 298.90 220.49 l 301.60 219.57 l 305.46 218.49 l 308.45 217.64 l 311.41 216.93 l 315.81 215.83 l 320.44 214.85 l 323.70 214.15 l 327.92 213.37 l 331.78 212.51 l 335.41 211.83 l 340.05 210.92 l 346.56 209.82 l 348.46 209.36 l 350.38 208.97 l 356.44 207.70 l 364.26 206.26 l 364.73 206.11 l 365.36 205.93 l 371.39 204.14 l 376.79 202.71 l 377.52 202.04 l 380.33 199.80 l 380.94 199.30 l 381.14 199.15 l 380.85 199.03 l 380.33 198.71 l 376.41 196.52 l 374.96 195.59 l 369.14 194.70 l 365.36 193.78 l 361.45 192.97 l 358.02 192.04 l 353.04 191.41 l 350.38 190.93 l 344.12 189.97 l 336.88 188.48 l 335.94 188.35 l 335.41 188.26 l 332.98 187.90 l 326.58 187.02 l 320.44 185.88 l 318.02 185.50 l 315.28 184.92 l 309.47 183.97 l 305.46 183.17 l 301.12 182.40 l 296.57 181.37 l 293.47 180.66 l 290.49 179.88 l 286.03 178.87 l 282.15 177.81 l 279.53 176.86 l 275.52 175.25 l 273.84 174.66 l 272.83 174.26 l 271.57 173.32 l 269.87 172.04 l 268.03 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 368.86 m 449.50 368.50 l 446.31 368.41 l 440.23 367.83 l 435.55 367.40 l 429.74 366.29 l 427.72 365.71 l 425.25 365.22 l 419.20 364.18 l 411.20 362.74 l 410.72 362.63 l 410.28 362.56 l 407.89 362.17 l 401.91 361.17 l 395.31 360.17 l 392.67 359.81 l 388.69 359.18 l 383.92 358.33 l 380.33 357.80 l 374.74 356.95 l 365.81 355.63 l 365.57 355.57 l 365.36 355.54 l 363.68 355.23 l 357.20 354.01 l 350.38 352.85 l 348.47 352.52 l 345.91 352.07 l 340.90 350.76 l 335.41 349.51 l 333.30 349.01 l 331.15 348.51 l 327.44 346.85 l 325.97 346.27 l 322.74 344.96 l 322.57 344.45 l 320.94 341.52 l 320.90 341.40 l 321.15 341.23 l 324.55 338.82 l 326.13 337.84 l 330.04 336.57 l 335.41 334.98 l 336.76 334.61 l 337.98 334.29 l 344.58 332.91 l 350.38 331.79 l 352.94 331.34 l 356.41 330.73 l 361.66 329.85 l 365.36 329.28 l 370.87 328.48 l 380.15 327.18 l 380.26 327.16 l 380.33 327.15 l 380.63 327.11 l 389.61 325.82 l 395.31 325.06 l 399.24 324.55 l 406.64 323.62 l 408.81 323.27 l 410.28 323.05 l 416.41 322.16 l 418.09 321.92 l 425.25 320.91 l 427.54 320.60 l 431.63 320.06 l 436.23 319.11 l 440.23 318.31 l 444.39 317.49 l 449.52 316.51 l 451.23 315.56 l 455.20 313.38 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 424.31 m 451.22 424.14 l 442.06 423.19 l 441.62 422.86 l 440.23 422.50 l 434.71 420.95 l 427.23 419.64 l 426.39 419.37 l 425.25 419.17 l 418.30 417.73 l 415.78 417.39 l 410.28 416.56 l 409.03 416.38 l 406.95 416.08 l 400.76 414.79 l 395.31 414.00 l 391.60 413.40 l 385.10 412.53 l 382.71 411.96 l 380.33 411.57 l 374.31 410.40 l 366.06 409.13 l 365.36 409.02 l 365.23 409.00 l 365.03 408.97 l 362.53 408.30 l 358.20 407.11 l 351.85 405.76 l 350.38 405.44 l 350.32 405.43 l 350.24 405.41 l 350.08 405.34 l 345.37 403.05 l 342.27 401.86 l 341.89 400.32 l 341.62 399.77 l 341.21 398.30 l 343.86 396.75 l 345.51 395.90 l 347.65 394.74 l 348.86 394.38 l 350.38 393.97 l 356.14 392.55 l 361.82 391.19 l 363.78 390.81 l 365.36 390.53 l 372.59 389.35 l 374.23 389.08 l 380.33 388.09 l 381.52 387.91 l 383.38 387.63 l 390.94 386.59 l 395.31 386.01 l 400.68 385.35 l 409.57 384.24 l 410.28 384.15 l 410.51 384.13 l 410.96 384.08 l 420.39 382.92 l 425.25 382.34 l 430.48 381.76 l 439.06 380.80 l 440.23 380.67 l 440.66 380.62 l 441.59 380.52 l 450.40 379.38 l 455.20 378.77 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 312.22 m 450.95 311.94 l 445.26 311.75 l 440.23 311.26 l 434.62 310.73 l 427.83 309.39 l 426.68 309.06 l 425.25 308.77 l 418.15 307.52 l 414.86 306.93 l 410.28 306.10 l 409.60 306.00 l 408.76 305.84 l 400.92 304.51 l 395.31 303.65 l 391.71 303.14 l 386.30 302.28 l 382.91 301.67 l 380.33 301.29 l 373.80 300.28 l 368.62 299.50 l 365.36 299.01 l 364.62 298.90 l 363.53 298.72 l 356.24 297.33 l 350.38 296.33 l 347.57 295.84 l 343.83 295.17 l 339.86 294.11 l 335.41 293.09 l 332.34 292.34 l 329.25 291.61 l 326.25 290.23 l 321.37 288.28 l 320.84 288.06 l 320.81 287.97 l 320.44 287.17 l 319.39 284.75 l 319.23 284.50 l 319.49 284.27 l 320.44 283.59 l 323.34 281.63 l 324.49 280.94 l 329.15 279.46 l 335.41 277.62 l 335.88 277.50 l 336.31 277.39 l 343.86 275.84 l 350.38 274.59 l 352.21 274.26 l 354.69 273.83 l 360.98 272.79 l 365.36 272.12 l 370.18 271.42 l 378.26 270.27 l 379.50 270.08 l 380.33 269.96 l 383.54 269.51 l 388.91 268.76 l 395.31 267.90 l 398.56 267.49 l 404.66 266.72 l 408.02 266.18 l 410.28 265.84 l 417.33 264.84 l 419.43 264.55 l 425.25 263.73 l 426.79 263.53 l 429.53 263.16 l 435.24 261.98 l 440.23 260.98 l 443.41 260.36 l 447.39 259.61 l 449.76 258.31 l 452.90 256.60 l 453.90 256.05 l 441.89 255.65 l 440.23 255.49 l 436.27 255.11 l 430.50 254.80 l 425.25 253.86 l 421.64 253.35 l 418.56 252.49 l 413.81 251.65 l 410.28 251.01 l 404.85 250.23 l 398.22 248.94 l 396.52 248.65 l 395.31 248.46 l 390.31 247.75 l 387.16 247.32 l 380.33 246.26 l 377.98 245.94 l 374.72 245.38 l 369.07 244.50 l 365.36 243.94 l 359.84 243.13 l 351.81 241.82 l 351.02 241.67 l 350.38 241.57 l 346.28 240.85 l 342.37 240.17 l 335.41 238.93 l 333.78 238.66 l 331.78 238.27 l 326.22 236.90 l 320.44 235.52 l 318.71 235.12 l 317.03 234.71 l 312.81 232.97 l 312.37 232.80 l 308.24 231.16 l 307.91 230.57 l 305.66 227.65 l 305.63 227.60 l 305.70 227.54 l 308.56 224.78 l 309.48 224.04 l 313.63 222.43 l 316.69 221.38 l 319.22 220.49 l 319.78 220.33 l 320.44 220.17 l 327.29 218.56 l 334.94 216.93 l 335.19 216.88 l 335.41 216.84 l 337.23 216.50 l 343.56 215.31 l 350.38 214.16 l 352.34 213.84 l 355.38 213.37 l 361.13 212.37 l 365.36 211.71 l 370.19 210.97 l 378.15 209.82 l 379.35 209.59 l 380.33 209.42 l 386.15 208.44 l 388.09 208.11 l 395.31 206.96 l 397.09 206.69 l 399.94 206.26 l 405.02 205.01 l 410.28 203.81 l 412.68 203.28 l 415.40 202.71 l 418.19 201.03 l 418.74 200.70 l 421.31 199.15 l 413.72 198.33 l 410.28 197.31 l 406.57 196.47 l 404.29 195.59 l 398.54 194.83 l 395.31 194.22 l 389.61 193.39 l 383.25 192.04 l 381.41 191.78 l 380.33 191.61 l 376.17 191.05 l 371.82 190.50 l 365.36 189.44 l 362.82 189.08 l 359.61 188.48 l 353.83 187.66 l 350.38 187.11 l 344.63 186.29 l 336.91 184.92 l 336.05 184.77 l 335.41 184.66 l 331.55 184.01 l 327.27 183.30 l 320.44 182.00 l 318.89 181.74 l 317.09 181.37 l 311.18 180.01 l 305.46 178.61 l 303.76 178.22 l 302.20 177.81 l 297.74 176.09 l 296.98 175.80 l 292.99 174.26 l 292.57 173.76 l 290.49 171.69 l 289.67 170.89 l 289.45 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 368.35 m 448.38 367.91 l 445.63 367.58 l 440.23 367.07 l 437.88 366.85 l 434.96 366.29 l 430.59 365.03 l 425.25 363.97 l 422.24 363.45 l 418.26 362.74 l 414.15 361.82 l 410.28 361.22 l 405.22 360.38 l 397.06 359.18 l 396.15 358.98 l 395.31 358.86 l 390.23 357.98 l 387.48 357.48 l 380.33 356.43 l 378.26 356.12 l 374.94 355.63 l 369.89 354.55 l 365.36 353.79 l 361.28 353.04 l 355.48 352.07 l 353.18 351.40 l 350.38 350.76 l 345.88 349.58 l 341.17 348.51 l 339.35 347.58 l 335.41 345.94 l 334.02 345.29 l 333.21 344.96 l 333.02 344.39 l 332.66 342.05 l 332.42 341.40 l 333.20 340.88 l 335.41 339.59 l 337.72 338.39 l 338.84 337.84 l 344.22 336.38 l 350.38 334.76 l 351.41 334.53 l 352.46 334.29 l 359.82 332.97 l 365.36 332.00 l 368.59 331.50 l 373.38 330.73 l 377.68 330.10 l 380.33 329.73 l 387.24 328.82 l 389.86 328.47 l 395.31 327.75 l 396.91 327.56 l 399.94 327.18 l 406.66 326.31 l 410.28 325.85 l 416.57 325.11 l 421.37 324.54 l 425.25 324.08 l 426.59 323.94 l 429.36 323.62 l 436.30 322.69 l 440.23 322.16 l 446.02 321.44 l 453.40 320.49 l 455.20 320.26 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 424.08 m 452.02 423.95 l 444.68 423.19 l 443.62 422.39 l 440.23 421.51 l 436.62 420.49 l 431.73 419.64 l 428.99 418.75 l 425.25 418.12 l 420.67 417.17 l 412.68 416.08 l 411.55 415.78 l 410.28 415.59 l 403.34 414.17 l 400.97 413.87 l 395.31 413.05 l 393.98 412.84 l 391.64 412.53 l 385.98 411.18 l 380.33 410.27 l 377.32 409.68 l 372.65 408.97 l 369.50 407.99 l 365.36 407.06 l 362.13 406.18 l 358.54 405.41 l 356.06 404.06 l 351.04 402.01 l 350.69 401.86 l 350.70 401.78 l 350.60 398.35 l 350.61 398.30 l 350.88 398.18 l 355.78 396.03 l 358.79 394.74 l 362.02 393.95 l 365.36 393.15 l 369.78 392.24 l 374.63 391.19 l 378.00 390.63 l 380.33 390.26 l 387.21 389.26 l 390.62 388.74 l 395.31 388.04 l 396.42 387.90 l 398.23 387.63 l 406.19 386.66 l 410.28 386.15 l 416.23 385.49 l 422.45 384.74 l 425.25 384.41 l 426.24 384.31 l 428.29 384.08 l 436.45 383.18 l 440.23 382.76 l 446.79 382.08 l 450.21 381.70 l 455.20 381.17 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 198.97 m 454.15 198.90 l 442.86 198.52 l 440.23 198.27 l 433.95 197.66 l 431.97 197.55 l 425.25 196.34 l 423.28 196.06 l 421.59 195.59 l 415.10 194.45 l 410.28 193.57 l 406.28 192.99 l 401.36 192.04 l 397.83 191.44 l 395.31 191.05 l 388.55 190.09 l 384.12 189.38 l 380.33 188.79 l 379.50 188.68 l 378.35 188.48 l 370.49 187.26 l 365.36 186.48 l 361.30 185.89 l 355.38 184.92 l 352.61 184.40 l 350.38 184.01 l 343.98 182.89 l 335.41 181.37 l 328.09 179.55 l 320.81 177.81 l 320.69 177.75 l 320.44 177.65 l 315.27 175.48 l 312.18 174.26 l 311.42 172.84 l 310.78 171.96 l 310.04 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 255.19 m 450.17 254.85 l 445.86 254.71 l 440.23 254.16 l 435.24 253.68 l 429.22 252.49 l 427.45 251.97 l 425.25 251.54 l 419.00 250.42 l 410.87 248.94 l 410.57 248.87 l 410.28 248.82 l 408.67 248.56 l 401.82 247.39 l 395.31 246.39 l 392.64 246.01 l 388.64 245.38 l 383.92 244.53 l 380.33 244.00 l 374.79 243.14 l 366.10 241.82 l 365.71 241.74 l 365.36 241.68 l 362.42 241.13 l 357.38 240.16 l 350.38 238.97 l 348.68 238.67 l 346.42 238.27 l 341.24 236.88 l 335.41 235.52 l 333.75 235.11 l 332.08 234.71 l 328.55 233.08 l 328.14 232.88 l 323.97 231.16 l 323.76 230.37 l 322.79 228.16 l 322.63 227.60 l 323.93 226.77 l 326.01 225.37 l 328.22 224.04 l 331.28 223.06 l 335.41 221.85 l 338.12 221.13 l 340.63 220.49 l 345.88 219.42 l 350.38 218.55 l 354.30 217.86 l 359.68 216.93 l 363.04 216.38 l 365.36 216.02 l 372.25 215.01 l 375.20 214.59 l 380.33 213.86 l 381.65 213.69 l 384.00 213.37 l 391.09 212.37 l 395.31 211.81 l 400.78 211.12 l 409.17 210.08 l 410.28 209.94 l 410.64 209.90 l 411.35 209.82 l 419.99 208.57 l 425.25 207.84 l 429.47 207.26 l 436.86 206.26 l 438.64 205.89 l 440.23 205.57 l 446.90 204.29 l 455.20 202.71 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 311.51 m 448.21 311.05 l 446.10 310.79 l 440.23 310.21 l 437.77 309.98 l 434.79 309.39 l 430.53 308.14 l 425.25 307.10 l 422.21 306.56 l 418.23 305.84 l 414.15 304.92 l 410.28 304.31 l 405.26 303.47 l 397.26 302.28 l 396.25 302.06 l 395.31 301.92 l 389.45 300.89 l 387.60 300.56 l 380.33 299.48 l 378.40 299.18 l 375.34 298.72 l 370.10 297.60 l 365.36 296.80 l 361.53 296.08 l 356.11 295.17 l 353.54 294.42 l 350.38 293.69 l 346.27 292.59 l 342.02 291.61 l 339.97 290.53 l 335.41 288.61 l 334.64 288.24 l 334.21 288.06 l 334.13 287.75 l 333.90 284.86 l 333.80 284.50 l 334.23 284.22 l 335.41 283.55 l 338.93 281.78 l 340.70 280.94 l 345.27 279.73 l 350.38 278.40 l 352.58 277.91 l 354.84 277.39 l 360.87 276.32 l 365.36 275.54 l 369.70 274.86 l 376.09 273.83 l 378.72 273.45 l 380.33 273.22 l 386.08 272.47 l 388.33 272.17 l 395.31 271.25 l 398.07 270.93 l 403.33 270.27 l 407.86 269.70 l 410.28 269.39 l 417.56 268.55 l 417.84 268.51 l 425.25 267.64 l 427.93 267.35 l 433.50 266.72 l 437.80 266.14 l 440.23 265.82 l 447.52 264.89 l 448.38 264.78 l 455.20 263.91 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 367.83 m 450.08 367.51 l 440.28 366.31 l 440.23 366.30 l 440.20 366.30 l 440.17 366.29 l 439.94 366.23 l 433.64 364.30 l 425.33 362.74 l 425.30 362.73 l 425.25 362.72 l 424.10 362.46 l 417.58 361.00 l 410.28 359.87 l 408.57 359.59 l 405.81 359.18 l 400.35 357.98 l 395.31 357.24 l 391.38 356.56 l 384.69 355.63 l 382.56 355.10 l 380.33 354.72 l 374.39 353.48 l 365.48 352.07 l 365.43 352.05 l 365.36 352.04 l 358.77 350.08 l 351.91 348.51 l 351.48 348.25 l 350.38 347.75 l 346.90 345.78 l 345.03 344.96 l 345.03 343.68 l 345.22 342.63 l 345.22 341.40 l 346.87 340.56 l 350.38 338.88 l 352.03 338.23 l 353.02 337.84 l 359.34 336.41 l 365.36 335.01 l 367.02 334.68 l 368.87 334.29 l 375.81 333.21 l 380.33 332.49 l 385.03 331.85 l 392.35 330.73 l 394.25 330.48 l 395.31 330.34 l 398.58 329.95 l 404.23 329.29 l 410.28 328.55 l 414.26 328.12 l 422.03 327.18 l 424.19 326.92 l 425.25 326.79 l 428.18 326.48 l 434.50 325.81 l 440.23 325.17 l 444.80 324.71 l 454.67 323.62 l 455.02 323.58 l 455.20 323.55 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 423.86 m 452.81 423.76 l 447.31 423.19 l 445.61 421.91 l 440.23 420.52 l 438.53 420.04 l 436.22 419.64 l 431.58 418.13 l 425.25 417.07 l 423.03 416.61 l 419.16 416.08 l 415.00 414.96 l 410.28 414.25 l 406.37 413.45 l 399.11 412.53 l 397.38 412.03 l 395.31 411.69 l 389.56 410.33 l 380.33 408.97 l 374.06 406.90 l 367.31 405.41 l 366.81 405.07 l 365.36 404.38 l 362.44 402.55 l 360.88 401.86 l 361.05 400.83 l 361.70 399.17 l 361.87 398.30 l 363.10 397.76 l 365.36 396.81 l 368.97 395.60 l 371.38 394.74 l 376.18 393.76 l 380.33 392.86 l 384.39 392.15 l 389.22 391.19 l 393.03 390.65 l 395.31 390.30 l 402.61 389.37 l 403.57 389.23 l 410.28 388.28 l 412.11 388.07 l 415.21 387.63 l 422.11 386.88 l 425.25 386.52 l 432.44 385.78 l 433.59 385.65 l 440.23 384.92 l 442.76 384.68 l 448.03 384.08 l 453.06 383.57 l 455.20 383.34 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 197.84 m 447.80 197.35 l 447.44 197.31 l 440.23 196.60 l 437.23 196.31 l 433.62 195.59 l 429.88 194.50 l 425.25 193.58 l 421.54 192.92 l 416.74 192.04 l 413.45 191.29 l 410.28 190.79 l 404.58 189.83 l 395.49 188.48 l 395.39 188.46 l 395.31 188.45 l 394.76 188.35 l 386.88 186.93 l 380.33 185.97 l 377.67 185.56 l 373.49 184.92 l 369.26 184.00 l 365.36 183.34 l 360.73 182.47 l 354.23 181.37 l 352.52 180.86 l 350.38 180.38 l 345.29 179.02 l 340.05 177.81 l 338.64 177.05 l 335.41 175.64 l 333.53 174.70 l 332.46 174.26 l 332.26 173.51 l 332.01 171.51 l 331.78 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 254.29 m 449.29 253.90 l 442.62 253.06 l 440.23 252.83 l 439.23 252.73 l 438.02 252.49 l 432.32 250.81 l 425.25 249.41 l 424.12 249.21 l 422.66 248.94 l 416.31 247.50 l 410.28 246.56 l 407.37 246.07 l 402.72 245.38 l 398.87 244.53 l 395.31 244.01 l 390.02 243.08 l 381.04 241.82 l 380.69 241.74 l 380.33 241.68 l 374.03 240.33 l 372.79 240.06 l 365.36 238.81 l 364.08 238.57 l 362.27 238.27 l 356.97 236.70 l 350.38 235.18 l 349.47 234.93 l 348.53 234.71 l 347.06 233.92 l 344.68 232.51 l 341.72 231.16 l 341.80 229.64 l 341.74 229.10 l 341.83 227.60 l 344.63 226.23 l 348.18 224.57 l 349.28 224.04 l 349.80 223.91 l 350.38 223.76 l 357.50 222.18 l 364.85 220.49 l 365.14 220.44 l 365.36 220.40 l 366.45 220.23 l 374.20 219.03 l 380.33 218.04 l 383.28 217.63 l 387.82 216.93 l 392.65 216.30 l 395.31 215.95 l 402.56 215.10 l 403.54 214.98 l 410.28 214.15 l 412.52 213.91 l 417.02 213.37 l 422.60 212.74 l 425.25 212.43 l 432.57 211.64 l 432.80 211.61 l 440.23 210.76 l 443.01 210.48 l 448.96 209.82 l 453.07 209.31 l 455.20 209.05 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 310.81 m 450.54 310.50 l 441.71 309.39 l 441.36 309.12 l 440.23 308.82 l 434.77 307.13 l 427.95 305.84 l 426.82 305.47 l 425.25 305.20 l 418.92 303.79 l 413.16 302.97 l 410.28 302.51 l 409.70 302.42 l 408.78 302.28 l 401.79 300.74 l 395.31 299.77 l 392.76 299.33 l 388.45 298.72 l 384.48 297.74 l 380.33 297.05 l 376.15 296.16 l 369.98 295.17 l 368.06 294.53 l 365.36 293.90 l 361.11 292.62 l 356.71 291.61 l 354.95 290.53 l 350.38 288.39 l 349.97 288.15 l 349.75 288.06 l 349.76 287.91 l 350.38 285.21 l 350.58 284.55 l 350.60 284.50 l 350.94 284.37 l 356.24 282.34 l 359.74 280.94 l 362.63 280.29 l 365.36 279.66 l 370.68 278.65 l 376.59 277.39 l 378.86 277.04 l 380.33 276.80 l 386.17 276.00 l 388.28 275.72 l 395.31 274.67 l 397.63 274.38 l 401.47 273.83 l 407.43 273.15 l 410.28 272.81 l 417.62 272.02 l 418.22 271.94 l 425.25 271.13 l 427.78 270.88 l 432.91 270.27 l 437.99 269.74 l 440.23 269.49 l 446.01 268.90 l 448.42 268.67 l 455.20 267.93 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 367.32 m 451.78 367.11 l 445.17 366.29 l 444.01 365.39 l 440.23 364.38 l 437.20 363.46 l 433.38 362.74 l 429.99 361.61 l 425.25 360.81 l 421.71 360.02 l 415.75 359.18 l 413.23 358.48 l 410.28 358.03 l 404.97 356.89 l 395.31 355.63 l 388.02 353.80 l 386.88 353.62 l 380.33 352.53 l 379.30 352.31 l 377.75 352.07 l 372.53 350.37 l 365.36 348.71 l 364.99 348.60 l 364.60 348.51 l 364.12 348.22 l 361.05 345.98 l 359.03 344.96 l 359.54 343.57 l 360.03 342.67 l 360.53 341.40 l 362.35 340.69 l 365.36 339.49 l 368.39 338.56 l 370.49 337.84 l 375.92 336.80 l 380.33 335.86 l 384.20 335.21 l 388.82 334.29 l 392.96 333.73 l 395.31 333.38 l 402.64 332.47 l 403.42 332.36 l 410.28 331.40 l 412.19 331.19 l 415.45 330.73 l 422.29 330.03 l 425.25 329.68 l 432.70 328.94 l 432.87 328.92 l 440.23 328.11 l 443.05 327.84 l 448.74 327.18 l 453.31 326.73 l 455.20 326.52 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 423.64 m 453.60 423.57 l 449.93 423.19 l 447.61 421.44 l 445.29 420.84 l 441.00 419.64 l 440.80 419.50 l 440.23 419.38 l 434.88 417.35 l 425.87 416.08 l 425.63 415.99 l 425.25 415.93 l 418.72 414.08 l 414.73 413.58 l 410.28 412.91 l 409.40 412.73 l 407.77 412.53 l 402.09 410.91 l 395.31 409.79 l 393.58 409.38 l 390.80 408.97 l 386.65 407.47 l 380.33 406.01 l 379.29 405.66 l 378.16 405.41 l 377.02 404.63 l 375.26 403.06 l 373.05 401.86 l 374.01 400.35 l 374.55 399.67 l 375.49 398.30 l 377.48 397.62 l 380.33 396.60 l 384.02 395.62 l 386.83 394.74 l 391.74 393.90 l 395.31 393.20 l 400.47 392.41 l 407.02 391.19 l 409.16 390.92 l 410.28 390.76 l 413.77 390.36 l 419.26 389.77 l 425.25 388.97 l 429.14 388.55 l 435.92 387.63 l 438.98 387.34 l 440.23 387.20 l 443.29 386.90 l 449.74 386.33 l 455.20 385.75 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 196.72 m 451.50 196.47 l 444.50 195.59 l 443.50 194.82 l 440.23 193.94 l 436.75 192.86 l 432.40 192.04 l 429.43 191.05 l 425.25 190.32 l 421.29 189.42 l 414.72 188.48 l 412.67 187.91 l 410.28 187.54 l 404.51 186.30 l 396.82 185.29 l 395.31 185.06 l 394.98 185.00 l 394.41 184.92 l 387.51 183.22 l 380.33 182.02 l 378.91 181.71 l 376.78 181.37 l 372.00 179.79 l 365.36 178.23 l 364.59 178.00 l 363.78 177.81 l 362.83 177.21 l 360.40 175.43 l 358.18 174.26 l 358.86 172.71 l 359.21 172.16 l 359.91 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 253.39 m 452.24 253.20 l 446.64 252.49 l 445.14 251.33 l 440.23 250.00 l 438.29 249.40 l 435.87 248.94 l 431.43 247.47 l 425.25 246.42 l 423.01 245.91 l 419.26 245.38 l 415.14 244.23 l 410.28 243.48 l 406.62 242.69 l 399.97 241.82 l 397.88 241.21 l 395.31 240.77 l 390.22 239.48 l 382.35 238.27 l 381.57 237.97 l 380.33 237.68 l 375.34 235.90 l 370.25 234.71 l 369.10 233.82 l 365.36 231.83 l 364.67 231.32 l 364.36 231.16 l 364.45 230.94 l 365.36 229.38 l 366.57 227.89 l 366.82 227.60 l 372.01 226.02 l 372.75 225.80 l 378.00 224.04 l 379.30 223.80 l 380.33 223.58 l 386.88 222.49 l 388.00 222.31 l 395.31 220.87 l 396.32 220.73 l 397.57 220.49 l 406.09 219.49 l 410.28 218.91 l 415.98 218.28 l 424.63 217.08 l 425.25 217.00 l 425.45 216.98 l 425.79 216.93 l 436.22 215.98 l 440.23 215.54 l 446.74 214.92 l 450.59 214.47 l 455.20 213.97 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 310.10 m 452.87 309.95 l 448.46 309.39 l 446.53 307.90 l 440.23 306.20 l 439.56 306.00 l 438.72 305.84 l 434.85 304.56 l 433.25 303.94 l 430.63 303.56 l 425.25 302.64 l 424.47 302.47 l 423.18 302.28 l 417.23 300.63 l 410.28 299.57 l 408.42 299.17 l 405.10 298.72 l 400.72 297.44 l 395.31 296.51 l 392.55 295.82 l 388.27 295.17 l 385.23 294.01 l 380.33 292.82 l 378.31 292.09 l 376.25 291.61 l 374.41 290.21 l 373.81 289.60 l 371.29 288.06 l 372.84 286.28 l 374.46 284.50 l 377.02 283.71 l 380.33 282.58 l 383.70 281.74 l 386.39 280.94 l 391.71 280.09 l 395.31 279.38 l 400.49 278.62 l 406.99 277.39 l 409.20 277.13 l 410.28 276.98 l 413.49 276.63 l 419.49 276.02 l 425.25 275.26 l 429.46 274.83 l 436.80 273.83 l 439.28 273.61 l 440.23 273.50 l 442.55 273.28 l 450.14 272.63 l 455.20 272.08 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 366.81 m 453.48 366.70 l 450.16 366.29 l 447.95 364.57 l 447.95 364.46 l 442.18 362.74 l 441.67 362.39 l 440.23 362.08 l 435.62 360.28 l 428.03 359.18 l 426.95 358.78 l 425.25 358.50 l 419.88 356.90 l 410.84 355.76 l 410.28 355.67 l 410.17 355.65 l 409.99 355.63 l 408.66 355.24 l 403.59 353.66 l 399.23 353.00 l 395.31 352.33 l 394.77 352.20 l 393.93 352.07 l 391.56 351.18 l 388.91 350.03 l 382.51 348.51 l 382.11 348.09 l 380.33 346.93 l 378.76 345.33 l 378.16 344.96 l 378.52 344.53 l 380.33 342.59 l 381.58 341.70 l 381.96 341.40 l 388.37 339.75 l 391.71 338.70 l 394.49 337.84 l 394.97 337.76 l 395.31 337.70 l 396.88 337.47 l 404.40 336.45 l 410.28 335.37 l 413.21 334.98 l 417.02 334.29 l 422.79 333.70 l 425.25 333.38 l 432.04 332.67 l 433.05 332.58 l 440.23 331.68 l 443.06 331.40 l 447.92 330.73 l 453.27 330.27 l 455.20 330.06 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 423.42 m 454.40 423.38 l 452.55 423.19 l 451.34 422.28 l 451.34 420.55 l 448.07 419.64 l 446.03 418.26 l 440.23 417.01 l 438.73 416.44 l 436.20 416.08 l 431.91 414.50 l 425.25 413.41 l 423.56 412.93 l 420.31 412.53 l 416.23 411.11 l 410.28 410.07 l 408.23 409.46 l 404.90 408.97 l 401.49 407.50 l 395.31 405.99 l 394.41 405.62 l 393.50 405.41 l 392.88 404.84 l 391.48 402.76 l 390.24 401.86 l 391.36 400.92 l 394.13 398.58 l 394.46 398.30 l 394.86 398.19 l 395.31 398.05 l 402.52 396.46 l 408.53 394.74 l 409.62 394.59 l 410.28 394.47 l 412.93 394.11 l 419.36 393.35 l 425.25 392.32 l 428.38 391.93 l 432.41 391.19 l 437.99 390.66 l 440.23 390.37 l 446.22 389.77 l 448.40 389.57 l 455.20 388.72 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 195.59 m 455.20 192.04 l 455.20 188.48 l 455.20 184.92 l 455.20 181.37 l 455.20 177.81 l 455.20 174.26 l 455.20 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 252.49 m 455.20 248.94 l 455.20 245.38 l 455.20 241.82 l 455.20 238.27 l 455.20 234.71 l 455.20 231.16 l 455.20 227.60 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 309.39 m 455.20 305.84 l 455.20 302.28 l 455.20 298.72 l 455.20 295.17 l 455.20 291.61 l 455.20 288.06 l 455.20 284.50 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 366.30 m 455.18 366.30 l 455.15 366.29 l 455.13 366.28 l 455.20 362.74 l 455.20 359.18 l 455.20 355.63 l 455.20 352.07 l 455.20 348.51 l 455.20 344.96 l 455.20 341.40 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 423.20 m 455.19 423.20 l 455.17 423.19 l 455.16 423.18 l 455.16 419.65 l 455.13 419.64 l 455.09 419.61 l 455.20 416.08 l 455.20 412.53 l 455.20 408.97 l 455.20 405.41 l 455.20 401.86 l 455.20 398.30 l S % END GriPath stroke/fill %gri: set graylevel 0.0 %gri:end if %gri:draw axes % gr_show_at() BEGIN 0 g 0 G 167.4 149.9 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 304.6 149.9 m (0.5) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 451.9 149.9 m (1) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 170.70 165.01 l 170.70 170.70 l 199.15 170.70 l 199.15 167.86 l 199.15 170.70 l 227.60 170.70 l 227.60 167.86 l 227.60 170.70 l 256.05 170.70 l 256.05 167.86 l 256.05 170.70 l 284.50 170.70 l 284.50 167.86 l 284.50 170.70 l 312.95 170.70 l 312.95 165.01 l 312.95 170.70 l 341.40 170.70 l 341.40 167.86 l 341.40 170.70 l 369.85 170.70 l 369.85 167.86 l 369.85 170.70 l 398.30 170.70 l 398.30 167.86 l 398.30 170.70 l 426.75 170.70 l 426.75 167.86 l 426.75 170.70 l 455.20 170.70 l 455.20 165.01 l 455.20 170.70 l 455.34 170.70 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 259.8 134.7 m (distance along cove) sh % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 455.20 m 170.70 455.20 l 170.70 460.89 l 170.70 455.20 l 199.15 455.20 l 199.15 458.05 l 199.15 455.20 l 227.60 455.20 l 227.60 458.05 l 227.60 455.20 l 256.05 455.20 l 256.05 458.05 l 256.05 455.20 l 284.50 455.20 l 284.50 458.05 l 284.50 455.20 l 312.95 455.20 l 312.95 460.89 l 312.95 455.20 l 341.40 455.20 l 341.40 458.05 l 341.40 455.20 l 369.85 455.20 l 369.85 458.05 l 369.85 455.20 l 398.30 455.20 l 398.30 458.05 l 398.30 455.20 l 426.75 455.20 l 426.75 458.05 l 426.75 455.20 l 455.20 455.20 l 455.20 460.89 l 455.20 455.20 l 455.34 455.20 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf % gr_show_at() BEGIN 0 g 0 G 152.5 166.4 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 450.9 m (81) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 165.01 170.70 l 170.70 170.70 l 170.70 455.20 l 165.01 455.20 l 170.70 455.20 l 170.70 455.20 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 139.9 301.6 m 90.00 rotate (time) sh -90.00 rotate % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 455.20 170.70 m 455.20 170.70 l 460.89 170.70 l 455.20 170.70 l 455.20 455.20 l 460.89 455.20 l 455.20 455.20 l 455.20 455.20 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:draw image palette left -1 right 21 increment 5 %^ scale 1 170.7 0 284.5 1 170.7 0 3.51235 q n % turn clipping on for image palette 170.700000 512.100000 moveto 455.200000 512.100000 lineto 455.200000 540.550000 lineto 170.700000 540.550000 lineto 170.700000 512.100000 lineto closepath W % Push map onto stack, then image stuff. [ 1.0000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.8000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.4000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.0000 ] 170.421624 512.100000 455.478376 540.550000 1 512 im 000000000000000000000000000000000000000000000000000102020303040405050606070808 09090A0A0B0B0C0D0D0E0E0F0F1010111112131314141515161617171819191A1A1B1B1C1C1D1E 1E1F1F2020212122222324242525262627272828292A2A2B2B2C2C2D2D2E2F2F30303131323233 33343535363637373838393A3A3B3B3C3C3D3D3E3E3F4040414142424343444445464647474848 49494A4B4B4C4C4D4D4E4E4F4F5051515252535354545556565757585859595A5A5B5C5C5D5D5E 5E5F5F6060616262636364646565666767686869696A6A6B6B6C6D6D6E6E6F6F70707172727373 74747575767677787879797A7A7B7B7C7C7D7E7E7F7F8080818182838384848585868687878889 898A8A8B8B8C8C8D8D8E8F8F9090919192929394949595969697979898999A9A9B9B9C9C9D9D9E 9F9FA0A0A1A1A2A2A3A3A4A5A5A6A6A7A7A8A8A9A9AAABABACACADADAEAEAFB0B0B1B1B2B2B3B3 B4B4B5B6B6B7B7B8B8B9B9BABBBBBCBCBDBDBEBEBFBFC0C1C1C2C2C3C3C4C4C5C5C6C7C7C8C8C9 C9CACACBCCCCCDCDCECECFCFD0D0D1D2D2D3D3D4D4D5D5D6D7D7D8D8D9D9DADADBDBDCDDDDDEDE DFDFE0E0E1E1E2E3E3E4E4E5E5E6E6E7E8E8E9E9EAEAEBEBECECEDEEEEEFEFF0F0F1F1F2F2F3F4 F4F5F5F6F6F7F7F8F9F9FAFAFBFBFCFCFDFDFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFF S Q % turn clipping off for image palette % gr_show_at() BEGIN 0 g 0 G 180.3 491.3 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 244.9 491.3 m (5) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 306.3 491.3 m (10) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 370.9 491.3 m (15) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 435.6 491.3 m (20) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 512.10 m 183.63 512.10 l 183.63 506.41 l 183.63 512.10 l 248.29 512.10 l 248.29 506.41 l 248.29 512.10 l 312.95 512.10 l 312.95 506.41 l 312.95 512.10 l 377.61 512.10 l 377.61 506.41 l 377.61 512.10 l 442.27 512.10 l 442.27 506.41 l 442.27 512.10 l 455.26 512.10 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 512.10 m 170.70 540.55 l 455.20 540.55 l 455.20 512.10 l S % END GriPath stroke/fill %gri:draw title "Example 10 -- file=\file header=`\header'" %^ scale 1 170.7 0 284.5 1 170.7 0 3.51235 % gr_show_at() BEGIN 0 g 0 G 123.0 569.0 m (Example 10 -- file=example10.dat header=`0.300000 variable_area = 0') sh % gr_show_at() END %gri:quit showpage %%Trailer %%BoundingBox: 113 130 515 590 %%DocumentFonts: Courier Helvetica Palatino-Roman Palatino-Italic Symbol Times-Roman %%Pages: 1 gri/doc/examples/example1.ps0000644000175000017500000004212013147557614014462 0ustar psgpsg%!PS-Adobe-2.0 EPSF-1.2 %%Creator: %%Title: example1.ps %%CreationDate: Tue Dec 7 13:18:36 2010 %%Pages: (atend) %%BoundingBox: (atend) % trial bounding box 0.000000 0.000000 0.000000 0.000000 %%TemplateBox: 0 0 612 792 %%DocumentFonts: (atend) %%Orientation: (atend) %%Endcomments % NOTE: The Gri postscript dictionary is being converted to the Adobe % Illustrator 3.0 dialect of PostScript, as described in the Adobe % documents stored at URL % http://www.adobe.com/Support/TechNotes.html % (as of Jan 1996, this doc is number 5007). When the conversion % is complete, the Adobe Illustrator drawing program -- and any % program compatible with AI -- will be able to edit Gri output. % % The IslandDraw (TM) program is able to read Gri output % at this time; remarkably, it can read/edit arbitrary PostScript. % % The definitions below are presented in the same order as the Adobe % manual. The stack configuration before and after is shown in curly % brackets. All the operators are listed, but only some are defined % here. Most things are faithful, except that no distinction is made % between colors for stroking and filling paths. The string 'WRONGLY' % appears with commands that are approximations. % % PDF-style abbreviations: /rg {setrgbcolor} def % {red green blue} {-} set RGB color /RG {setrgbcolor} def % {red green blue} {-} set RGB color /q {gsave} def /Q {grestore} def /W {clip} def /W* {eoclip} def % % Gri-specific abbreviations: /hsb {sethsbcolor} def % {hue saturation brightness} {-} set HSB color % % Following all try to mimic Adobe Illustrator % % Mimicking section 5.1 of Adobe manual: %A % {flag A} {-} Determine whether % following object can % be selected. Flag=1 % prevents selection; % flag=0 allows it. % Mimicking section 5.2 of Adobe manual: %u % {u} {-} start group %U % end group %q % as 'u' but first item is a clip path %Q % as 'U' but first item is a clip path % Mimicking section 5.3 of Adobe manual: /g {setgray} def % {gray g} {-} Set gray for fill % path, WRONGLY used % for stroking also. /G {setgray} def % As 'g', but for filling path. %k % Set cmyk color for filling path. %K % As 'k', but for stroking path. %x % Set cmyk custom color for filling path. %X % As 'x' but for stroking path. %p % Define pattern for filling path. %P % As 'p' but for stroking path. %O % Specify whether overprinting for fill paths %R % As 'O' but for stroking path. % Mimicking section 5.4 of Adobe manual: /d {setdash} def % {[array] phase d} {-} Set dash. /i {setflat} def % {flatness i} {-} Set flatness. /j {setlinejoin} def % {linejoin j} {-} Set line join. /J {setlinecap} def % {linecap J} {-} Set line cap. /M {setmiterlimit} def % {miterlimit M} {-} Set miter limit. /w {setlinewidth} def % {linewidth w} {-} Set line width. % Mimicking section 5.5 of Adobe manual: /m {moveto} def % {x y m} {-} Move to locn /l {lineto} def % {x y l} {-} Draw line to locn % not a smooth point. % WRONGLY, no % distinction is made % between smooth and % corner. %L % {x y L} {-} As 'l' but a corner %c % Bezier curve to smooth point. %C % As 'c' but to corner point. %v % Something else to do with Bezier. %V % %y % %Y % % Mimicking section 5.6 of Adobe manual: %N % {N} {-} As 'n' for nondrawn stuff /n {newpath} def % {n} {-} WRONGLY interpreted % as path constructor /F {fill} def % {F} {-} Fill current path. %f % {f} {-} 'F' but close first /S {stroke} def % {S} {-} Stroke current path. %s % {s} {-} 'S' but close first %B % {B} {-} As 's' but don't empty path. %b % {b} {-} As 'f' but don't empty path. %H % no-op (weird huh?) /h {closepath} def % {h} {-} Close current path %W % Used to create masks. % Mimicking section 5.7 of Adobe manual: %a % Begin text block ... %e % Similar to 'a' but ... %I % Similar to 'a' but ... %o % Similar to 'a' but ... %r % Similar to 'a' but ... %t % {len (string) t} {-} Render string. %T % End block of text % That's the end of the Illustrator stuff. Following are some Gri % definitions which provide a temporary way of handling fonts. /sf {setfont} def % {fontname sf} {-} Set font name. /sh {show} def % {(text) sh} {-} Show text. /sc {scalefont} def % {size sc} {-} Scale font. % Gri items which should be translated to Illustrator format: /rl {rlineto} def /rm {rmoveto} def % Procedures /cimdict 7 dict def /cim { cimdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def q xll yll translate xur xll sub yur yll sub scale /do cl 3 mul string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop} false 3 colorimage Q end } def /imdict 14 dict def /im { imdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def /imagemap exch def q % Until version 2.6.0 used a 'settransfer' here, but that % triggers a bug in ps2pdf xll yll translate xur xll sub yur yll sub scale /do cl string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop dup length 1 sub 0 1 3 -1 roll { 1 index exch 2 copy get imagemap exch get 255 mul cvi put } for }image Q end } bind def /frdict 5 dict def /fr { frdict begin /yt exch def /xr exch def /yb exch def /xl exch def n xl yb m xl yt l xr yt l xr yb l h F n end } def /plusdict 3 dict def /_plus { plusdict begin dup 0.5 mul /t0 exch def /t1 exch def 0 t0 rm 0 t1 neg rl t0 neg t0 rm t1 0 rl t0 neg 0 rm end } def /timesdict 3 dict def /_times { timesdict begin dup 0.353553 mul /t0 exch def 0.707106 mul /t1 exch def t0 neg t0 rm t1 dup neg rl t1 neg 0 rm t1 dup rl t0 neg dup rm end } def /boxdict 3 dict def /_box { boxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm end } def /filledboxdict 3 dict def /_filledbox { filledboxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm F end } def /diamonddict 2 dict def /_diamond { diamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm end } def /filleddiamonddict 2 dict def /_filleddiamond { filleddiamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm F end } def /triangleupdict 5 dict def /_triangleup { triangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm end } def /filledtriangleupdict 5 dict def /_filledtriangleup { filledtriangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm F end } def /trianglerightdict 5 dict def /_triangleright { trianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm end } def /filledtrianglerightdict 5 dict def /_filledtriangleright { filledtrianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm F end } def /triangledowndict 5 dict def /_triangledown { triangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm end } def /filledtriangledowndict 5 dict def /_filledtriangledown { filledtriangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm F end } def /triangleleftdict 5 dict def /_triangleleft { triangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm end } def /filledtriangleleftdict 5 dict def /_filledtriangleleft { filledtriangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm F end } def /circdict 5 dict def /_circ { circdict begin 0.5 mul /t0 exch def currentpoint /t2 exch def /t1 exch def S n t1 t2 t0 0 360 arc t1 t2 m end } def /bulldict 3 dict def /_bull { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 360 arc h F S end } def /filledhalfmoonupdict 3 dict def /_filledhalfmoonup { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 180 arc h F S end } def /filledhalfmoondowndict 3 dict def /_filledhalfmoondown { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 180 360 arc h F S end } def 1 1 scale 10.0 M 1 j /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-ISOLatin1 exch definefont pop /Courier-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Oblique-ISOLatin1 exch definefont pop /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Bold-ISOLatin1 exch definefont pop /Courier-BoldOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-BoldOblique-ISOLatin1 exch definefont pop /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-ISOLatin1 exch definefont pop /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Bold-ISOLatin1 exch definefont pop /Helvetica-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Oblique-ISOLatin1 exch definefont pop /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Roman-ISOLatin1 exch definefont pop /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Italic-ISOLatin1 exch definefont pop /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Bold-ISOLatin1 exch definefont pop /Palatino-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-BoldItalic-ISOLatin1 exch definefont pop /Symbol findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Symbol-ISOLatin1 exch definefont pop /Century findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Century-ISOLatin1 exch definefont pop /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Roman-ISOLatin1 exch definefont pop /Times-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Italic-ISOLatin1 exch definefont pop /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Bold-ISOLatin1 exch definefont pop /Times-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-BoldItalic-ISOLatin1 exch definefont pop %%EndProlog %%Page: 1 1 gsave /Helvetica-ISOLatin1 findfont 12.00 sc sf %^ scale 1 170.7 0 284.5 1 170.7 12 40.6429 0.709 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 184.92 191.02 m 241.82 455.20 l 312.95 292.63 l 384.07 292.63 l 440.97 211.34 l S % END GriPath stroke/fill 0 g 0 G 167.4 149.9 m (0) sh 0 g 0 G 190.8 149.9 m (0.1) sh 0 g 0 G 219.2 149.9 m (0.2) sh 0 g 0 G 247.7 149.9 m (0.3) sh 0 g 0 G 276.1 149.9 m (0.4) sh 0 g 0 G 304.6 149.9 m (0.5) sh 0 g 0 G 333.0 149.9 m (0.6) sh 0 g 0 G 361.5 149.9 m (0.7) sh 0 g 0 G 389.9 149.9 m (0.8) sh 0 g 0 G 418.4 149.9 m (0.9) sh 0 g 0 G 451.9 149.9 m (1) sh 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 170.70 165.01 l 170.70 170.70 l 199.15 170.70 l 199.15 165.01 l 199.15 170.70 l 227.60 170.70 l 227.60 165.01 l 227.60 170.70 l 256.05 170.70 l 256.05 165.01 l 256.05 170.70 l 284.50 170.70 l 284.50 165.01 l 284.50 170.70 l 312.95 170.70 l 312.95 165.01 l 312.95 170.70 l 341.40 170.70 l 341.40 165.01 l 341.40 170.70 l 369.85 170.70 l 369.85 165.01 l 369.85 170.70 l 398.30 170.70 l 398.30 165.01 l 398.30 170.70 l 426.75 170.70 l 426.75 165.01 l 426.75 170.70 l 455.20 170.70 l 455.20 165.01 l 455.20 170.70 l 455.23 170.70 l S % END GriPath stroke/fill 0 g 0 G 310.0 134.7 m (x) sh /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 455.20 m 170.70 455.20 l 170.70 460.89 l 170.70 455.20 l 199.15 455.20 l 199.15 460.89 l 199.15 455.20 l 227.60 455.20 l 227.60 460.89 l 227.60 455.20 l 256.05 455.20 l 256.05 460.89 l 256.05 455.20 l 284.50 455.20 l 284.50 460.89 l 284.50 455.20 l 312.95 455.20 l 312.95 460.89 l 312.95 455.20 l 341.40 455.20 l 341.40 460.89 l 341.40 455.20 l 369.85 455.20 l 369.85 460.89 l 369.85 455.20 l 398.30 455.20 l 398.30 460.89 l 398.30 455.20 l 426.75 455.20 l 426.75 460.89 l 426.75 455.20 l 455.20 455.20 l 455.20 460.89 l 455.20 455.20 l 455.23 455.20 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf 0 g 0 G 145.8 166.4 m (12) sh 0 g 0 G 145.8 207.0 m (13) sh 0 g 0 G 145.8 247.7 m (14) sh 0 g 0 G 145.8 288.3 m (15) sh 0 g 0 G 145.8 328.9 m (16) sh 0 g 0 G 145.8 369.6 m (17) sh 0 g 0 G 145.8 410.2 m (18) sh 0 g 0 G 145.8 450.9 m (19) sh 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 165.01 170.70 l 170.70 170.70 l 170.70 211.34 l 165.01 211.34 l 170.70 211.34 l 170.70 251.99 l 165.01 251.99 l 170.70 251.99 l 170.70 292.63 l 165.01 292.63 l 170.70 292.63 l 170.70 333.27 l 165.01 333.27 l 170.70 333.27 l 170.70 373.91 l 165.01 373.91 l 170.70 373.91 l 170.70 414.56 l 165.01 414.56 l 170.70 414.56 l 170.70 455.20 l 165.01 455.20 l 170.70 455.20 l 170.70 455.20 l S % END GriPath stroke/fill 0 g 0 G 139.9 309.9 m 90.00 rotate (y) sh -90.00 rotate /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 455.20 170.70 m 455.20 170.70 l 460.89 170.70 l 455.20 170.70 l 455.20 211.34 l 460.89 211.34 l 455.20 211.34 l 455.20 251.99 l 460.89 251.99 l 455.20 251.99 l 455.20 292.63 l 460.89 292.63 l 455.20 292.63 l 455.20 333.27 l 460.89 333.27 l 455.20 333.27 l 455.20 373.91 l 460.89 373.91 l 455.20 373.91 l 455.20 414.56 l 460.89 414.56 l 455.20 414.56 l 455.20 455.20 l 460.89 455.20 l 455.20 455.20 l 455.20 455.20 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf 0 g 0 G 284.5 483.6 m (Example 1) sh showpage %%Trailer %%BoundingBox: 129 130 463 494 %%DocumentFonts: Courier Helvetica Palatino-Roman Palatino-Italic Symbol Times-Roman %%Pages: 1 %%Orientation: Portrait gri/doc/examples/example1.txt0000644000175000017500000000001513147557614014654 0ustar psgpsgexample1.gri gri/doc/examples/logo.gri0000644000175000017500000000105513147557614014047 0ustar psgpsgset x size 5 set y size 5 set x axis 0 1 0.25 set y axis 0 20 10 set font size 0 \background_color = "hsb 0.60 0.24 1" \line_color = "red" \word_color = "black" read columns x y 0.0 12.5 0.25 19 0.5 12 0.75 15 1 13 set color \background_color set line width axis rapidograph 6 draw curve filled to ..ybottom.. y set color black draw axes set color \line_color set line width rapidograph 7 draw curve set symbol size 0.4 draw symbol bullet set color \word_color set font size 80 set font to TimesRoman draw label "Gri" at 0.1 2 gri/doc/examples/example7g.dat0000644000175000017500000000136413147557614014772 0ustar psgpsg 0.184 -0.735 0.211 -0.676 0.216 -0.666 0.303 -0.519 0.400 -0.398 0.104 -0.983 0.309 -0.510 0.313 -0.504 0.296 -0.529 0.198 -0.703 0.063 -1.201 0.264 -0.578 0.619 -0.208 0.236 -0.627 0.282 -0.550 0.425 -0.372 0.196 -0.708 0.182 -0.740 0.295 -0.530 0.129 -0.889 0.231 -0.636 0.211 -0.676 0.066 -1.180 0.367 -0.435 0.283 -0.548 0.318 -0.498 0.694 -0.159 0.128 -0.893 0.172 -0.764 0.402 -0.396 0.758 -0.120 0.272 -0.565 0.588 -0.231 0.147 -0.833 0.098 -1.009 0.120 -0.921 gri/doc/examples/example7.ps0000644000175000017500000006763513147557614014512 0ustar psgpsg%!PS-Adobe-2.0 EPSF-1.2 %%Creator: Gri2.2.4 (released 1999-Oct-20). User=kelley, commandfile=example7.gri %%Title: example7.ps %%CreationDate: Thu Oct 21 11:30:28 1999 %%Pages: (atend) %%BoundingBox: (atend) %%TemplateBox: 0 0 612 792 %%DocumentFonts: (atend) %%Endcomments % NOTE: The Gri postscript dictionary is being converted to the Adobe % Illustrator 3.0 dialect of PostScript, as described in the Adobe % documents stored at URL % http://www.adobe.com/Support/TechNotes.html % (as of Jan 1996, this doc is number 5007). When the conversion % is complete, the Adobe Illustrator drawing program -- and any % program compatible with AI -- will be able to edit Gri output. % % The IslandDraw (TM) program is able to read Gri output % at this time; remarkably, it can read/edit arbitrary PostScript. % % The definitions below are presented in the same order as the Adobe % manual. The stack configuration before and after is shown in curly % brackets. All the operators are listed, but only some are defined % here. Most things are faithful, except that no distinction is made % between colors for stroking and filling paths. The string 'WRONGLY' % appears with commands that are approximations. % % PDF-style abbreviations: /rg {setrgbcolor} def % {red green blue} {-} set RGB color /RG {setrgbcolor} def % {red green blue} {-} set RGB color /q {gsave} def /Q {grestore} def /W {clip} def /W* {eoclip} def % % Gri-specific abbreviations: /hsb {sethsbcolor} def % {hue saturation brightness} {-} set HSB color % % Following all try to mimic Adobe Illustrator % % Mimicking section 5.1 of Adobe manual: %A % {flag A} {-} Determine whether % following object can % be selected. Flag=1 % prevents selection; % flag=0 allows it. % Mimicking section 5.2 of Adobe manual: %u % {u} {-} start group %U % end group %q % as 'u' but first item is a clip path %Q % as 'U' but first item is a clip path % Mimicking section 5.3 of Adobe manual: /g {setgray} def % {gray g} {-} Set gray for fill % path, WRONGLY used % for stroking also. /G {setgray} def % As 'g', but for filling path. %k % Set cmyk color for filling path. %K % As 'k', but for stroking path. %x % Set cmyk custom color for filling path. %X % As 'x' but for stroking path. %p % Define pattern for filling path. %P % As 'p' but for stroking path. %O % Specify whether overprinting for fill paths %R % As 'O' but for stroking path. % Mimicking section 5.4 of Adobe manual: /d {setdash} def % {[array] phase d} {-} Set dash. /i {setflat} def % {flatness i} {-} Set flatness. /j {setlinejoin} def % {linejoin j} {-} Set line join. /J {setlinecap} def % {linecap J} {-} Set line cap. /M {setmiterlimit} def % {miterlimit M} {-} Set miter limit. /w {setlinewidth} def % {linewidth w} {-} Set line width. % Mimicking section 5.5 of Adobe manual: /m {moveto} def % {x y m} {-} Move to locn /l {lineto} def % {x y l} {-} Draw line to locn % not a smooth point. % WRONGLY, no % distinction is made % between smooth and % corner. %L % {x y L} {-} As 'l' but a corner %c % Bezier curve to smooth point. %C % As 'c' but to corner point. %v % Something else to do with Bezier. %V % %y % %Y % % Mimicking section 5.6 of Adobe manual: %N % {N} {-} As 'n' for nondrawn stuff /n {newpath} def % {n} {-} WRONGLY interpreted % as path constructor /F {fill} def % {F} {-} Fill current path. %f % {f} {-} 'F' but close first /S {stroke} def % {S} {-} Stroke current path. %s % {s} {-} 'S' but close first %B % {B} {-} As 's' but don't empty path. %b % {b} {-} As 'f' but don't empty path. %H % no-op (weird huh?) /h {closepath} def % {h} {-} Close current path %W % Used to create masks. % Mimicking section 5.7 of Adobe manual: %a % Begin text block ... %e % Similar to 'a' but ... %I % Similar to 'a' but ... %o % Similar to 'a' but ... %r % Similar to 'a' but ... %t % {len (string) t} {-} Render string. %T % End block of text % That's the end of the Illustrator stuff. Following are some Gri % definitions which provide a temporary way of handling fonts. /sf {setfont} def % {fontname sf} {-} Set font name. /sh {show} def % {(text) sh} {-} Show text. /sc {scalefont} def % {size sc} {-} Scale font. % Gri items which should be translated to Illustrator format: /rl {rlineto} def /rm {rmoveto} def % Procedures /cimdict 7 dict def /cim { cimdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def q xll yll translate xur xll sub yur yll sub scale /do cl 3 mul string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop} false 3 colorimage Q end } def /imdict 14 dict def /im { imdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def /imagemap exch def q % Add the mapping to the transfer function (ref: white book, p 743. [{255 mul cvi imagemap exch get} /exec load currenttransfer /exec load] cvx settransfer xll yll translate xur xll sub yur yll sub scale /do cl string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop}image Q end } def /frdict 5 dict def /fr { frdict begin /yt exch def /xr exch def /yb exch def /xl exch def n xl yb m xl yt l xr yt l xr yb l h F n end } def /plusdict 3 dict def /_plus { plusdict begin dup 0.5 mul /t0 exch def /t1 exch def 0 t0 rm 0 t1 neg rl t0 neg t0 rm t1 0 rl t0 neg 0 rm end } def /timesdict 3 dict def /_times { timesdict begin dup 0.353553 mul /t0 exch def 0.707106 mul /t1 exch def t0 neg t0 rm t1 dup neg rl t1 neg 0 rm t1 dup rl t0 neg dup rm end } def /boxdict 3 dict def /_box { boxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm end } def /filledboxdict 3 dict def /_filledbox { filledboxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm F end } def /diamonddict 2 dict def /_diamond { diamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm end } def /filleddiamonddict 2 dict def /_filleddiamond { filleddiamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm F end } def /triangleupdict 5 dict def /_triangleup { triangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm end } def /filledtriangleupdict 5 dict def /_filledtriangleup { filledtriangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm F end } def /trianglerightdict 5 dict def /_triangleright { trianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm end } def /filledtrianglerightdict 5 dict def /_filledtriangleright { filledtrianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm F end } def /triangledowndict 5 dict def /_triangledown { triangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm end } def /filledtriangledowndict 5 dict def /_filledtriangledown { filledtriangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm F end } def /triangleleftdict 5 dict def /_triangleleft { triangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm end } def /filledtriangleleftdict 5 dict def /_filledtriangleleft { filledtriangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm F end } def /circdict 5 dict def /_circ { circdict begin 0.5 mul /t0 exch def currentpoint /t2 exch def /t1 exch def S n t1 t2 t0 0 360 arc t1 t2 m end } def /bulldict 3 dict def /_bull { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 360 arc h F S end } def /filledhalfmoonupdict 3 dict def /_filledhalfmoonup { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 180 arc h F S end } def /filledhalfmoondowndict 3 dict def /_filledhalfmoondown { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 180 360 arc h F S end } def 1 1 scale 10.0 M 1 j /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-ISOLatin1 exch definefont pop /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Bold-ISOLatin1 exch definefont pop /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-ISOLatin1 exch definefont pop /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Bold-ISOLatin1 exch definefont pop /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Roman-ISOLatin1 exch definefont pop /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Bold-ISOLatin1 exch definefont pop /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Italic-ISOLatin1 exch definefont pop /Symbol findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Symbol-ISOLatin1 exch definefont pop /Times findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-ISOLatin1 exch definefont pop /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Bold-ISOLatin1 exch definefont pop /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Roman-ISOLatin1 exch definefont pop %%EndProlog %%Page: 1 1 /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:# Example 7 -- Box plots of mixing efficiency vs density ratio (meddy) %gri:# $Id: example7.ps,v 1.2 2000/05/29 19:45:11 psg Exp $ %gri: %gri:`Draw y boxplot from \file at .x.' %gri:/* %gri:Draw a y boxplot for data in given file, at given %gri:value of x. %gri:*/ %gri:{ %gri: open \.word4. %gri: read columns * y %gri: close %gri: draw y box plot at \.word6. %gri:} %gri:if !..publication.. %gri:end if %gri:set x axis 1 3 1 0.1 %gri:set x name "Density Ratio, $R_\rho$" %gri:set x margin 4 %gri:set y axis -2 1 1 %gri:# %gri:# Must fool gri into not drawing the axes, because the y data %gri:# are already in logspace. %gri:draw axes none %gri:Draw y boxplot from example7a.dat at 1.3 %^ scale 1 113.8 1 142.25 1 170.7 -2 94.8333 0.369 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 163.59 295.31 m 149.36 295.31 l 149.36 328.60 l 163.59 328.60 l 163.59 295.31 l 163.59 308.78 m 149.36 308.78 l S % END GriPath stroke/fill 0.369 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 163.59 295.31 m 149.36 295.31 l 149.36 328.60 l 163.59 328.60 l 163.59 295.31 l 163.59 308.78 m 149.36 308.78 l 156.47 328.60 m 156.47 357.62 l S % END GriPath stroke/fill n 156.5 357.6 m 4.3 _times S 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 163.59 295.31 m 149.36 295.31 l 149.36 328.60 l 163.59 328.60 l 163.59 295.31 l 163.59 308.78 m 149.36 308.78 l 156.47 328.60 m 156.47 357.62 l 156.47 295.31 m 156.47 258.80 l S % END GriPath stroke/fill n 156.5 258.8 m 4.3 _times S n 156.5 379.9 m 4.3 _circ S %gri:Draw y boxplot from example7b.dat at 1.4 %^ scale 1 113.8 1 142.25 1 170.7 -2 94.8333 0.369 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 177.81 298.91 m 163.59 298.91 l 163.59 324.76 l 177.81 324.76 l 177.81 298.91 l 177.81 309.54 m 163.59 309.54 l S % END GriPath stroke/fill 0.369 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 177.81 298.91 m 163.59 298.91 l 163.59 324.76 l 177.81 324.76 l 177.81 298.91 l 177.81 309.54 m 163.59 309.54 l 170.70 324.76 m 170.70 361.03 l S % END GriPath stroke/fill n 170.7 361.0 m 4.3 _times S 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 177.81 298.91 m 163.59 298.91 l 163.59 324.76 l 177.81 324.76 l 177.81 298.91 l 177.81 309.54 m 163.59 309.54 l 170.70 324.76 m 170.70 361.03 l 170.70 298.91 m 170.70 263.45 l S % END GriPath stroke/fill n 170.7 263.4 m 4.3 _times S n 170.7 382.3 m 4.3 _circ S n 170.7 430.4 m 4.3 _bull S n 170.7 422.4 m 4.3 _bull S n 170.7 364.4 m 4.3 _circ S n 170.7 393.1 m 4.3 _circ S n 170.7 372.6 m 4.3 _circ S n 170.7 250.8 m 4.3 _circ S %gri:Draw y boxplot from example7c.dat at 1.5 %^ scale 1 113.8 1 142.25 1 170.7 -2 94.8333 0.369 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 192.04 289.22 m 177.81 289.22 l 177.81 320.61 l 192.04 320.61 l 192.04 289.22 l 192.04 305.84 m 177.81 305.84 l S % END GriPath stroke/fill 0.369 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 192.04 289.22 m 177.81 289.22 l 177.81 320.61 l 192.04 320.61 l 192.04 289.22 l 192.04 305.84 m 177.81 305.84 l 184.93 320.61 m 184.93 367.48 l S % END GriPath stroke/fill n 184.9 367.5 m 4.3 _times S 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 192.04 289.22 m 177.81 289.22 l 177.81 320.61 l 192.04 320.61 l 192.04 289.22 l 192.04 305.84 m 177.81 305.84 l 184.93 320.61 m 184.93 367.48 l 184.93 289.22 m 184.93 246.47 l S % END GriPath stroke/fill n 184.9 246.5 m 4.3 _times S n 184.9 379.9 m 4.3 _circ S n 184.9 372.8 m 4.3 _circ S n 184.9 373.4 m 4.3 _circ S n 184.9 368.2 m 4.3 _circ S n 184.9 383.8 m 4.3 _circ S n 184.9 213.1 m 4.3 _circ S n 184.9 228.8 m 4.3 _circ S %gri:Draw y boxplot from example7d.dat at 1.6 %^ scale 1 113.8 1 142.25 1 170.7 -2 94.8333 0.369 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 206.26 285.92 m 192.04 285.92 l 192.04 316.74 l 206.26 316.74 l 206.26 285.92 l 206.26 300.15 m 192.04 300.15 l S % END GriPath stroke/fill 0.369 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 206.26 285.92 m 192.04 285.92 l 192.04 316.74 l 206.26 316.74 l 206.26 285.92 l 206.26 300.15 m 192.04 300.15 l 199.15 316.74 m 199.15 362.17 l S % END GriPath stroke/fill n 199.2 362.2 m 4.3 _times S 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 206.26 285.92 m 192.04 285.92 l 192.04 316.74 l 206.26 316.74 l 206.26 285.92 l 206.26 300.15 m 192.04 300.15 l 199.15 316.74 m 199.15 362.17 l 199.15 285.92 m 199.15 247.80 l S % END GriPath stroke/fill n 199.2 247.8 m 4.3 _times S n 199.2 384.5 m 4.3 _circ S n 199.2 406.6 m 4.3 _circ S n 199.2 369.8 m 4.3 _circ S n 199.2 373.5 m 4.3 _circ S n 199.2 223.4 m 4.3 _circ S n 199.2 239.4 m 4.3 _circ S %gri:Draw y boxplot from example7e.dat at 1.7 %^ scale 1 113.8 1 142.25 1 170.7 -2 94.8333 0.369 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 220.49 286.11 m 206.26 286.11 l 206.26 317.22 l 220.49 317.22 l 220.49 286.11 l 220.49 300.91 m 206.26 300.91 l S % END GriPath stroke/fill 0.369 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 220.49 286.11 m 206.26 286.11 l 206.26 317.22 l 220.49 317.22 l 220.49 286.11 l 220.49 300.91 m 206.26 300.91 l 213.38 317.22 m 213.38 356.57 l S % END GriPath stroke/fill n 213.4 356.6 m 4.3 _times S 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 220.49 286.11 m 206.26 286.11 l 206.26 317.22 l 220.49 317.22 l 220.49 286.11 l 220.49 300.91 m 206.26 300.91 l 213.38 317.22 m 213.38 356.57 l 213.38 286.11 m 213.38 243.82 l S % END GriPath stroke/fill n 213.4 243.8 m 4.3 _times S n 213.4 388.0 m 4.3 _circ S n 213.4 383.4 m 4.3 _circ S n 213.4 385.1 m 4.3 _circ S n 213.4 365.8 m 4.3 _circ S n 213.4 368.1 m 4.3 _circ S n 213.4 234.4 m 4.3 _circ S %gri:Draw y boxplot from example7f.dat at 1.8 %^ scale 1 113.8 1 142.25 1 170.7 -2 94.8333 0.369 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 234.71 281.23 m 220.49 281.23 l 220.49 322.91 l 234.71 322.91 l 234.71 281.23 l 234.71 296.54 m 220.49 296.54 l S % END GriPath stroke/fill 0.369 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 234.71 281.23 m 220.49 281.23 l 220.49 322.91 l 234.71 322.91 l 234.71 281.23 l 234.71 296.54 m 220.49 296.54 l 227.60 322.91 m 227.60 369.57 l S % END GriPath stroke/fill n 227.6 369.6 m 4.3 _times S 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 234.71 281.23 m 220.49 281.23 l 220.49 322.91 l 234.71 322.91 l 234.71 281.23 l 234.71 296.54 m 220.49 296.54 l 227.60 322.91 m 227.60 369.57 l 227.60 281.23 m 227.60 234.43 l S % END GriPath stroke/fill n 227.6 234.4 m 4.3 _times S n 227.6 215.9 m 4.3 _circ S %gri:Draw y boxplot from example7g.dat at 1.9 %^ scale 1 113.8 1 142.25 1 170.7 -2 94.8333 0.369 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 248.94 289.62 m 234.71 289.62 l 234.71 312.71 l 248.94 312.71 l 248.94 289.62 l 248.94 303.23 m 234.71 303.23 l S % END GriPath stroke/fill 0.369 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 248.94 289.62 m 234.71 289.62 l 234.71 312.71 l 248.94 312.71 l 248.94 289.62 l 248.94 303.23 m 234.71 303.23 l 241.82 312.71 m 241.82 345.29 l S % END GriPath stroke/fill n 241.8 345.3 m 4.3 _times S 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 248.94 289.62 m 234.71 289.62 l 234.71 312.71 l 248.94 312.71 l 248.94 289.62 l 248.94 303.23 m 234.71 303.23 l 241.82 312.71 m 241.82 345.29 l 241.82 289.62 m 241.82 264.68 l S % END GriPath stroke/fill n 241.8 264.7 m 4.3 _times S n 241.8 349.0 m 4.3 _circ S n 241.8 246.5 m 4.3 _circ S n 241.8 248.5 m 4.3 _circ S %gri:delete y scale %gri:set y name "Efficiency, $\Gamma$" %gri:set y type log %gri:set y axis 0.01 10 1 %gri:draw axes % gr_show_at() BEGIN 0 g 0 G 110.5 149.9 m (1) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 252.7 149.9 m (2) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 395.0 149.9 m (3) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 113.80 170.70 m 113.80 170.70 l 113.80 165.01 l 113.80 170.70 l 128.03 170.70 l 128.03 167.86 l 128.03 170.70 l 142.25 170.70 l 142.25 167.86 l 142.25 170.70 l 156.47 170.70 l 156.47 167.86 l 156.47 170.70 l 170.70 170.70 l 170.70 167.86 l 170.70 170.70 l 184.93 170.70 l 184.93 167.86 l 184.93 170.70 l 199.15 170.70 l 199.15 167.86 l 199.15 170.70 l 213.38 170.70 l 213.38 167.86 l 213.38 170.70 l 227.60 170.70 l 227.60 167.86 l 227.60 170.70 l 241.82 170.70 l 241.82 167.86 l 241.82 170.70 l 256.05 170.70 l 256.05 165.01 l 256.05 170.70 l 270.28 170.70 l 270.28 167.86 l 270.28 170.70 l 284.50 170.70 l 284.50 167.86 l 284.50 170.70 l 298.73 170.70 l 298.73 167.86 l 298.73 170.70 l 312.95 170.70 l 312.95 167.86 l 312.95 170.70 l 327.18 170.70 l 327.18 167.86 l 327.18 170.70 l 341.40 170.70 l 341.40 167.86 l 341.40 170.70 l 355.63 170.70 l 355.63 167.86 l 355.63 170.70 l 369.85 170.70 l 369.85 167.86 l 369.85 170.70 l 384.08 170.70 l 384.08 167.86 l 384.08 170.70 l 398.30 170.70 l 398.30 165.01 l 398.30 170.70 l 398.44 170.70 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 209.3 134.7 m (Density Ratio, ) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf (R) sh 0.0 -3.2 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Symbol findfont 9.00 sc sf (\162) sh /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 3.2 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 113.80 455.20 m 113.80 455.20 l 113.80 460.89 l 113.80 455.20 l 128.03 455.20 l 128.03 458.05 l 128.03 455.20 l 142.25 455.20 l 142.25 458.05 l 142.25 455.20 l 156.47 455.20 l 156.47 458.05 l 156.47 455.20 l 170.70 455.20 l 170.70 458.05 l 170.70 455.20 l 184.93 455.20 l 184.93 458.05 l 184.93 455.20 l 199.15 455.20 l 199.15 458.05 l 199.15 455.20 l 213.38 455.20 l 213.38 458.05 l 213.38 455.20 l 227.60 455.20 l 227.60 458.05 l 227.60 455.20 l 241.82 455.20 l 241.82 458.05 l 241.82 455.20 l 256.05 455.20 l 256.05 460.89 l 256.05 455.20 l 270.28 455.20 l 270.28 458.05 l 270.28 455.20 l 284.50 455.20 l 284.50 458.05 l 284.50 455.20 l 298.73 455.20 l 298.73 458.05 l 298.73 455.20 l 312.95 455.20 l 312.95 458.05 l 312.95 455.20 l 327.18 455.20 l 327.18 458.05 l 327.18 455.20 l 341.40 455.20 l 341.40 458.05 l 341.40 455.20 l 355.63 455.20 l 355.63 458.05 l 355.63 455.20 l 369.85 455.20 l 369.85 458.05 l 369.85 455.20 l 384.08 455.20 l 384.08 458.05 l 384.08 455.20 l 398.30 455.20 l 398.30 460.89 l 398.30 455.20 l 398.44 455.20 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf % gr_show_at() BEGIN 0 g 0 G 78.2 166.4 m () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (1) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (0) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh 0.0 5.4 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh (\261) sh () sh /Helvetica-ISOLatin1 findfont 9.00 sc sf (2) sh /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 -5.4 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 78.2 261.2 m () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (1) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (0) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh 0.0 5.4 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh (\261) sh () sh /Helvetica-ISOLatin1 findfont 9.00 sc sf (1) sh /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 -5.4 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 95.6 356.0 m (1) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 82.2 450.9 m () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (1) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (0) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh 0.0 5.4 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-ISOLatin1 findfont 9.00 sc sf (1) sh /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 -5.4 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 113.80 170.56 m 113.80 170.70 l 108.11 170.70 l 113.80 170.70 l 113.80 199.25 l 110.95 199.25 l 113.80 199.25 l 113.80 215.95 l 110.95 215.95 l 113.80 215.95 l 113.80 227.80 l 110.95 227.80 l 113.80 227.80 l 113.80 236.99 l 110.95 236.99 l 113.80 236.99 l 113.80 244.49 l 110.95 244.49 l 113.80 244.49 l 113.80 250.84 l 110.95 250.84 l 113.80 250.84 l 113.80 256.34 l 110.95 256.34 l 113.80 256.34 l 113.80 261.19 l 110.95 261.19 l 113.80 261.19 l 113.80 265.53 l 108.11 265.53 l 113.80 265.53 l 113.80 294.08 l 110.95 294.08 l 113.80 294.08 l 113.80 310.78 l 110.95 310.78 l 113.80 310.78 l 113.80 322.63 l 110.95 322.63 l 113.80 322.63 l 113.80 331.82 l 110.95 331.82 l 113.80 331.82 l 113.80 339.33 l 110.95 339.33 l 113.80 339.33 l 113.80 345.68 l 110.95 345.68 l 113.80 345.68 l 113.80 351.18 l 110.95 351.18 l 113.80 351.18 l 113.80 356.03 l 110.95 356.03 l 113.80 356.03 l 113.80 360.37 l 108.11 360.37 l 113.80 360.37 l 113.80 388.91 l 110.95 388.91 l 113.80 388.91 l 113.80 405.61 l 110.95 405.61 l 113.80 405.61 l 113.80 417.46 l 110.95 417.46 l 113.80 417.46 l 113.80 426.65 l 110.95 426.65 l 113.80 426.65 l 113.80 434.16 l 110.95 434.16 l 113.80 434.16 l 113.80 440.51 l 110.95 440.51 l 113.80 440.51 l 113.80 446.01 l 110.95 446.01 l 113.80 446.01 l 113.80 450.86 l 110.95 450.86 l 113.80 450.86 l 113.80 455.20 l 108.11 455.20 l 113.80 455.20 l 113.80 455.20 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 72.3 280.2 m 90.00 rotate (Efficiency, ) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Symbol findfont 12.00 sc sf (\107) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh -90.00 rotate % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 398.30 170.56 m 398.30 170.70 l 403.99 170.70 l 398.30 170.70 l 398.30 199.25 l 401.15 199.25 l 398.30 199.25 l 398.30 215.95 l 401.15 215.95 l 398.30 215.95 l 398.30 227.80 l 401.15 227.80 l 398.30 227.80 l 398.30 236.99 l 401.15 236.99 l 398.30 236.99 l 398.30 244.49 l 401.15 244.49 l 398.30 244.49 l 398.30 250.84 l 401.15 250.84 l 398.30 250.84 l 398.30 256.34 l 401.15 256.34 l 398.30 256.34 l 398.30 261.19 l 401.15 261.19 l 398.30 261.19 l 398.30 265.53 l 403.99 265.53 l 398.30 265.53 l 398.30 294.08 l 401.15 294.08 l 398.30 294.08 l 398.30 310.78 l 401.15 310.78 l 398.30 310.78 l 398.30 322.63 l 401.15 322.63 l 398.30 322.63 l 398.30 331.82 l 401.15 331.82 l 398.30 331.82 l 398.30 339.33 l 401.15 339.33 l 398.30 339.33 l 398.30 345.68 l 401.15 345.68 l 398.30 345.68 l 398.30 351.18 l 401.15 351.18 l 398.30 351.18 l 398.30 356.03 l 401.15 356.03 l 398.30 356.03 l 398.30 360.37 l 403.99 360.37 l 398.30 360.37 l 398.30 388.91 l 401.15 388.91 l 398.30 388.91 l 398.30 405.61 l 401.15 405.61 l 398.30 405.61 l 398.30 417.46 l 401.15 417.46 l 398.30 417.46 l 398.30 426.65 l 401.15 426.65 l 398.30 426.65 l 398.30 434.16 l 401.15 434.16 l 398.30 434.16 l 398.30 440.51 l 401.15 440.51 l 398.30 440.51 l 398.30 446.01 l 401.15 446.01 l 398.30 446.01 l 398.30 450.86 l 401.15 450.86 l 398.30 450.86 l 398.30 455.20 l 403.99 455.20 l 398.30 455.20 l 398.30 455.20 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:draw title "Example 7 -- Box plot" %^ scale 1 113.8 1 142.25 0 170.7 0.01 94.8333 % gr_show_at() BEGIN 0 g 0 G 198.5 483.6 m (Example 7 -- Box plot) sh % gr_show_at() END %gri:quit showpage %%Trailer %%BoundingBox: 41 130 424 503 %%DocumentFonts: Courier Helvetica Palatino-Roman Palatino-Italic Symbol Times-Roman %%Pages: 1 gri/doc/examples/example3.gri0000644000175000017500000000427413147557614014633 0ustar psgpsg# Example 3 -- Controlling scales, etc # # Example of how to control axis scales, etc. This example makes # two panels, plotting the same data in different ways. # # # ----- PANEL 2 ------------------------------------------------ # # Set up the x axis. # # Make the x axis run from 0 to 1, with labelled tics each 0.25. set x axis 0 1 .25 # Make the plot 5 cm wide. set x size 5 # 2 cm of space between the left edge of the plot # and the left edge of the paper. set x margin 2 # Give the x-axis the name "t" with subscript 0. set x name "$t_0$" # # Set up the y axis. # # Make the y axis run from 10 to 20, with labelled tics at intervals # of 5 and smaller, unlabelled, tics, at intervals of 1. Other # commands are similar to those for the x-axis. set y axis 10 20 5 1 set y size 10 set y margin 2 set y name "F" # # Now, read our simple data set. open example1.dat read columns x y close # # Draw a curve connecting these (x,y) data. Note that the axes, as # defined above, will be drawn automatically along with the curve. draw curve # # ----- PANEL 2 ----------------------------------------- # # OK, now for a more complicated version. We'll keep the # same data, but redraw it in a new panel, to the right of # the first graph. So, the first step is to increase the # x margin. The rpn command creates a number which is # the sum of the old x margin (stored in the variable # ..xmargin..) and the old plot width (stored in # the variable ..xsize..), plus an extra 1 cm set x margin {rpn ..xsize.. ..xmargin.. + 1 +} # # Set the line thickness for the curve to 1 point (0.3 mm) and the # axis line thickness to 0.2 points (0.1 mm). set line width 1.0 # points set line width axis 0.2 # points # Set the tics to be 1.5 mm. set tic size 0.15 # centimetres # Draw axes and frame, with axes offset from frame. Some # people find this more attractive. set axes style offset draw axes 1 # Now draw the actual curve. draw curve # Superimpose dots (radius 1.5 mm) at the data. set symbol size 0.15 draw symbol bullet # # All done. # Draw a title above the plot. set font size 20 \label = "Example 3 -- scales, axes, etc" draw label "\label" centered at \ {rpn 2 5 + .5 + } \ {rpn ..ytop.. yusertocm 2 +} cm gri/doc/examples/example7f.dat0000644000175000017500000000361413147557614014771 0ustar psgpsg 0.285 -0.545 0.030 -1.523 0.514 -0.289 0.255 -0.593 0.181 -0.742 0.060 -1.222 0.138 -0.860 0.126 -0.900 0.408 -0.389 0.242 -0.616 0.192 -0.717 0.096 -1.018 0.442 -0.355 0.095 -1.022 0.237 -0.625 0.301 -0.521 0.159 -0.799 0.150 -0.824 0.178 -0.750 0.205 -0.688 0.074 -1.131 0.119 -0.924 0.057 -1.244 0.142 -0.848 0.184 -0.735 0.278 -0.556 0.799 -0.097 0.231 -0.636 0.149 -0.827 1.251 0.097 0.177 -0.752 0.253 -0.597 0.123 -0.910 0.110 -0.959 0.168 -0.775 0.216 -0.666 0.155 -0.810 0.120 -0.921 0.168 -0.775 0.074 -1.131 0.263 -0.580 0.399 -0.399 0.096 -1.018 0.179 -0.747 0.537 -0.270 0.964 -0.016 0.115 -0.939 0.452 -0.345 0.148 -0.830 0.209 -0.680 0.424 -0.373 0.115 -0.939 0.508 -0.294 0.206 -0.686 0.439 -0.358 0.191 -0.719 0.201 -0.697 0.711 -0.148 0.077 -1.114 0.444 -0.353 0.284 -0.547 0.563 -0.249 0.201 -0.697 0.272 -0.565 0.513 -0.290 0.357 -0.447 0.312 -0.506 0.251 -0.600 0.401 -0.397 0.190 -0.721 0.170 -0.770 0.555 -0.256 0.696 -0.157 0.294 -0.532 0.226 -0.646 0.185 -0.733 0.701 -0.154 0.492 -0.308 0.262 -0.582 0.275 -0.561 0.052 -1.284 0.623 -0.206 0.319 -0.496 0.109 -0.963 0.754 -0.123 0.527 -0.278 0.191 -0.719 0.047 -1.328 0.090 -1.046 0.269 -0.570 0.091 -1.041 0.417 -0.380 gri/doc/examples/example11.txt0000644000175000017500000000001613147557614014736 0ustar psgpsgexample11.gri gri/doc/examples/example7a.dat0000644000175000017500000000163413147557614014764 0ustar psgpsg 0.172 -0.764 0.288 -0.541 0.146 -0.836 0.164 -0.785 0.190 -0.721 0.191 -0.719 0.399 -0.399 0.118 -0.928 0.236 -0.627 0.246 -0.609 0.257 -0.590 0.148 -0.830 0.205 -0.688 0.935 -0.029 0.503 -0.298 0.308 -0.511 0.581 -0.236 0.409 -0.388 0.245 -0.611 0.550 -0.260 0.639 -0.194 0.269 -0.570 0.307 -0.513 0.206 -0.686 0.472 -0.326 0.284 -0.547 0.627 -0.203 0.445 -0.352 0.212 -0.674 0.337 -0.472 0.459 -0.338 0.089 -1.051 0.206 -0.686 0.294 -0.532 0.740 -0.131 1.606 0.206 0.213 -0.672 0.085 -1.071 0.890 -0.051 0.371 -0.431 0.321 -0.493 0.241 -0.618 0.263 -0.580 0.513 -0.290 gri/doc/examples/FEM.txt0000644000175000017500000000001013147557614013542 0ustar psgpsgFEM.gri gri/doc/examples/example2.txt0000644000175000017500000000001513147557614014655 0ustar psgpsgexample2.gri gri/doc/examples/example10.dat0000644000175000017500000002421613147557614014676 0ustar psgpsg0.300000 variable_area = 0 0.010000 20 81 0.000 400.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 0.393 400.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 0.785 400.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 1.178 400.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 1.571 400.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 1.963 400.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 2.356 400.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 2.749 400.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 3.142 400.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 3.534 365.64 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 19.99 19.96 19.82 19.34 17.97 14.87 9.70 3.99 3.927 345.25 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 20.00 19.99 19.96 19.88 19.66 19.13 18.02 16.02 13.04 9.44 6.11 3.99 4.320 320.80 20.00 20.00 20.00 20.00 20.00 20.00 19.99 19.98 19.93 19.82 19.55 18.99 17.98 16.33 14.00 11.20 8.37 6.06 4.61 4.00 4.712 295.45 20.00 20.00 20.00 20.00 19.99 19.97 19.91 19.79 19.51 18.99 18.07 16.64 14.66 12.26 9.73 7.44 5.71 4.65 4.15 4.00 5.105 272.92 20.00 20.00 19.99 19.97 19.92 19.82 19.59 19.16 18.41 17.24 15.60 13.53 11.22 8.95 7.00 5.57 4.68 4.23 4.05 4.00 5.498 255.72 19.97 19.97 19.95 19.88 19.73 19.44 18.92 18.09 16.86 15.22 13.23 11.08 8.98 7.18 5.80 4.89 4.38 4.13 4.03 4.00 5.890 245.06 19.91 19.91 19.84 19.69 19.40 18.90 18.13 17.01 15.54 13.76 11.80 9.82 8.03 6.56 5.47 4.76 4.35 4.14 4.04 4.00 6.283 241.31 19.79 19.79 19.68 19.45 19.05 18.43 17.54 16.35 14.87 13.18 11.39 9.62 8.02 6.69 5.67 4.96 4.50 4.24 4.09 4.00 6.676 244.50 19.62 19.62 19.50 19.23 18.80 18.16 17.30 16.19 14.87 13.38 11.79 10.21 8.73 7.43 6.36 5.53 4.93 4.53 4.26 4.07 7.069 254.34 19.45 19.45 19.33 19.07 18.67 18.10 17.35 16.42 15.32 14.07 12.72 11.33 9.97 8.70 7.57 6.61 5.83 5.22 4.76 4.41 7.461 269.39 19.29 19.29 19.19 18.97 18.63 18.17 17.56 16.82 15.95 14.95 13.85 12.69 11.50 10.33 9.21 8.18 7.26 6.47 5.81 5.26 7.854 286.61 19.16 19.16 19.08 18.90 18.64 18.27 17.80 17.23 16.55 15.77 14.91 13.98 12.99 11.98 10.97 9.98 9.04 8.16 7.37 6.66 8.247 302.27 19.06 19.06 18.99 18.85 18.64 18.36 17.99 17.54 17.02 16.41 15.73 14.99 14.19 13.35 12.48 11.61 10.73 9.88 9.07 8.30 8.639 313.78 18.98 18.98 18.92 18.81 18.63 18.40 18.10 17.74 17.31 16.82 16.27 15.67 15.01 14.30 13.57 12.80 12.03 11.25 10.48 9.72 9.032 320.22 18.90 18.90 18.86 18.76 18.60 18.40 18.14 17.82 17.45 17.03 16.55 16.02 15.44 14.83 14.17 13.49 12.79 12.07 11.36 10.64 9.425 321.63 18.84 18.84 18.79 18.69 18.55 18.35 18.10 17.80 17.45 17.05 16.59 16.09 15.55 14.96 14.34 13.69 13.02 12.34 11.64 10.94 9.817 303.68 18.77 18.77 18.72 18.61 18.46 18.25 17.99 17.67 17.31 16.89 16.41 15.90 15.33 14.72 14.02 13.15 11.88 9.86 6.99 3.99 10.210 288.43 18.69 18.69 18.63 18.51 18.33 18.09 17.79 17.43 17.01 16.53 15.99 15.38 14.66 13.77 12.61 11.07 9.13 7.01 5.15 4.00 10.603 269.37 18.59 18.59 18.51 18.36 18.14 17.85 17.48 17.04 16.51 15.90 15.16 14.25 13.11 11.69 10.01 8.20 6.49 5.15 4.34 4.00 10.996 249.44 18.46 18.46 18.37 18.18 17.89 17.51 17.03 16.43 15.70 14.79 13.67 12.32 10.74 9.05 7.41 6.00 4.98 4.37 4.09 4.00 11.388 231.67 18.30 18.30 18.18 17.93 17.55 17.05 16.38 15.55 14.50 13.24 11.77 10.15 8.51 7.01 5.79 4.92 4.39 4.13 4.03 4.00 11.781 218.05 18.09 18.09 17.93 17.62 17.13 16.47 15.60 14.51 13.21 11.72 10.13 8.55 7.12 5.94 5.08 4.53 4.22 4.07 4.02 4.00 12.174 209.53 17.84 17.84 17.65 17.27 16.69 15.89 14.88 13.66 12.25 10.74 9.22 7.79 6.56 5.59 4.90 4.46 4.21 4.08 4.02 4.00 12.566 206.43 17.56 17.56 17.35 16.94 16.32 15.48 14.44 13.22 11.87 10.45 9.04 7.74 6.61 5.71 5.05 4.59 4.31 4.14 4.05 4.00 12.959 208.79 17.27 17.27 17.08 16.68 16.09 15.31 14.36 13.24 12.02 10.74 9.46 8.25 7.16 6.25 5.52 4.97 4.59 4.33 4.16 4.04 13.352 216.42 17.02 17.02 16.85 16.51 16.01 15.34 14.53 13.58 12.54 11.42 10.29 9.18 8.13 7.19 6.38 5.71 5.18 4.78 4.48 4.26 13.744 228.31 16.81 16.81 16.68 16.41 16.01 15.47 14.82 14.06 13.20 12.28 11.31 10.33 9.37 8.45 7.61 6.85 6.19 5.64 5.19 4.82 14.137 242.26 16.65 16.65 16.55 16.34 16.03 15.62 15.11 14.51 13.84 13.09 12.30 11.47 10.63 9.80 8.99 8.22 7.51 6.86 6.29 5.78 14.530 255.32 16.53 16.53 16.45 16.29 16.05 15.73 15.34 14.87 14.33 13.74 13.09 12.41 11.70 10.97 10.24 9.53 8.83 8.17 7.55 6.98 14.923 265.22 16.43 16.43 16.37 16.24 16.05 15.79 15.47 15.09 14.65 14.16 13.63 13.05 12.45 11.82 11.18 10.53 9.89 9.26 8.65 8.06 15.315 270.90 16.35 16.35 16.30 16.19 16.02 15.80 15.52 15.19 14.81 14.38 13.91 13.41 12.87 12.31 11.73 11.14 10.54 9.95 9.36 8.78 15.708 272.19 16.28 16.28 16.22 16.12 15.96 15.75 15.49 15.17 14.82 14.41 13.97 13.49 12.98 12.45 11.90 11.33 10.76 10.18 9.61 9.03 16.101 258.71 16.20 16.20 16.14 16.03 15.87 15.65 15.38 15.05 14.68 14.27 13.81 13.32 12.80 12.25 11.64 10.92 9.91 8.37 6.22 4.00 16.493 246.60 16.11 16.11 16.05 15.92 15.73 15.49 15.18 14.82 14.40 13.94 13.43 12.87 12.24 11.48 10.54 9.33 7.85 6.25 4.86 4.00 16.886 231.37 16.01 16.01 15.93 15.78 15.55 15.25 14.88 14.45 13.95 13.37 12.71 11.93 10.99 9.86 8.55 7.17 5.87 4.86 4.25 4.00 17.279 215.43 15.88 15.88 15.78 15.59 15.30 14.92 14.46 13.90 13.23 12.44 11.50 10.40 9.15 7.84 6.58 5.51 4.73 4.27 4.06 4.00 17.671 201.21 15.71 15.71 15.59 15.34 14.98 14.50 13.89 13.14 12.25 11.19 10.00 8.72 7.44 6.29 5.35 4.69 4.29 4.10 4.02 4.00 18.064 190.30 15.51 15.51 15.36 15.05 14.60 13.99 13.23 12.30 11.21 10.00 8.73 7.49 6.38 5.48 4.82 4.40 4.17 4.06 4.01 4.00 18.457 183.47 15.27 15.27 15.09 14.74 14.22 13.52 12.64 11.62 10.47 9.25 8.03 6.91 5.96 5.21 4.68 4.35 4.16 4.06 4.02 4.00 18.850 180.96 15.01 15.01 14.83 14.46 13.91 13.19 12.31 11.29 10.18 9.03 7.91 6.89 6.01 5.31 4.80 4.45 4.23 4.11 4.04 4.00 19.242 182.82 14.76 14.76 14.58 14.24 13.73 13.06 12.25 11.33 10.32 9.28 8.26 7.30 6.45 5.73 5.17 4.75 4.45 4.25 4.12 4.03 19.635 188.90 14.54 14.54 14.39 14.10 13.66 13.10 12.41 11.62 10.76 9.85 8.94 8.05 7.22 6.48 5.84 5.32 4.91 4.60 4.37 4.20 20.028 198.41 14.36 14.36 14.24 14.01 13.67 13.22 12.66 12.03 11.32 10.56 9.78 8.98 8.21 7.48 6.81 6.21 5.70 5.27 4.92 4.63 20.420 209.61 14.22 14.22 14.13 13.96 13.69 13.34 12.91 12.41 11.85 11.24 10.59 9.91 9.23 8.56 7.91 7.30 6.74 6.23 5.78 5.38 20.813 220.15 14.12 14.12 14.05 13.91 13.71 13.44 13.11 12.71 12.27 11.77 11.24 10.68 10.10 9.51 8.92 8.35 7.79 7.27 6.78 6.32 21.206 228.18 14.03 14.03 13.98 13.87 13.71 13.49 13.22 12.90 12.54 12.13 11.69 11.21 10.72 10.21 9.68 9.16 8.64 8.14 7.65 7.18 21.598 232.81 13.96 13.96 13.92 13.82 13.68 13.50 13.26 12.99 12.67 12.31 11.93 11.51 11.07 10.61 10.13 9.65 9.17 8.69 8.22 7.76 21.991 233.87 13.90 13.90 13.86 13.77 13.63 13.46 13.24 12.98 12.68 12.34 11.97 11.58 11.16 10.72 10.27 9.81 9.35 8.88 8.42 7.96 22.384 223.19 13.84 13.84 13.79 13.70 13.56 13.37 13.15 12.88 12.57 12.22 11.85 11.44 11.01 10.56 10.07 9.48 8.68 7.45 5.75 4.00 22.777 213.51 13.76 13.76 13.71 13.60 13.45 13.24 12.98 12.68 12.34 11.95 11.53 11.07 10.56 9.95 9.19 8.23 7.05 5.78 4.68 4.00 23.169 201.30 13.68 13.68 13.61 13.48 13.29 13.04 12.73 12.37 11.96 11.49 10.95 10.32 9.56 8.65 7.61 6.51 5.48 4.68 4.20 4.00 23.562 188.53 13.57 13.57 13.48 13.32 13.08 12.77 12.39 11.93 11.38 10.74 9.98 9.09 8.10 7.05 6.04 5.19 4.58 4.22 4.05 4.00 23.955 177.13 13.43 13.43 13.33 13.12 12.82 12.42 11.92 11.31 10.59 9.74 8.78 7.75 6.73 5.81 5.07 4.55 4.23 4.08 4.02 4.00 24.347 168.39 13.26 13.26 13.13 12.88 12.51 12.01 11.39 10.63 9.76 8.78 7.77 6.78 5.89 5.17 4.65 4.32 4.13 4.04 4.01 4.00 24.740 162.90 13.06 13.06 12.92 12.63 12.20 11.63 10.92 10.09 9.16 8.18 7.21 6.32 5.56 4.96 4.54 4.28 4.12 4.05 4.01 4.00 25.133 160.89 12.85 12.85 12.70 12.40 11.95 11.36 10.65 9.83 8.94 8.01 7.12 6.30 5.60 5.04 4.63 4.36 4.19 4.09 4.03 4.00 25.525 162.38 12.64 12.64 12.50 12.22 11.81 11.26 10.61 9.86 9.05 8.22 7.40 6.63 5.95 5.38 4.93 4.59 4.36 4.20 4.10 4.02 25.918 167.25 12.46 12.46 12.34 12.11 11.75 11.29 10.74 10.10 9.41 8.68 7.94 7.23 6.57 5.98 5.47 5.05 4.72 4.48 4.29 4.16 26.311 174.87 12.32 12.32 12.22 12.04 11.76 11.39 10.95 10.43 9.86 9.25 8.62 7.98 7.36 6.78 6.24 5.76 5.35 5.01 4.73 4.50 26.704 183.85 12.21 12.21 12.13 11.99 11.78 11.50 11.15 10.74 10.29 9.80 9.27 8.73 8.18 7.64 7.12 6.63 6.18 5.78 5.42 5.10 27.096 192.32 12.12 12.12 12.07 11.96 11.79 11.57 11.30 10.99 10.63 10.23 9.80 9.35 8.88 8.41 7.93 7.47 7.03 6.61 6.21 5.85 27.489 198.77 12.05 12.05 12.01 11.92 11.79 11.61 11.40 11.14 10.84 10.52 10.16 9.78 9.38 8.97 8.55 8.13 7.71 7.31 6.91 6.54 27.882 202.49 12.00 12.00 11.96 11.88 11.77 11.62 11.43 11.21 10.95 10.66 10.35 10.01 9.66 9.29 8.91 8.52 8.13 7.75 7.37 7.00 28.274 203.34 11.95 11.95 11.91 11.84 11.73 11.59 11.41 11.20 10.96 10.69 10.39 10.07 9.74 9.38 9.02 8.65 8.28 7.90 7.53 7.16 28.667 194.80 11.89 11.89 11.86 11.78 11.67 11.52 11.34 11.12 10.87 10.59 10.29 9.96 9.62 9.25 8.86 8.39 7.74 6.76 5.40 4.00 29.060 187.04 11.84 11.84 11.79 11.71 11.58 11.41 11.20 10.96 10.68 10.38 10.04 9.67 9.25 8.76 8.15 7.38 6.44 5.42 4.54 4.00 29.452 177.25 11.77 11.77 11.71 11.61 11.45 11.25 11.00 10.71 10.38 10.00 9.57 9.06 8.45 7.72 6.89 6.01 5.19 4.55 4.16 4.00 29.845 167.01 11.68 11.68 11.61 11.48 11.29 11.04 10.72 10.35 9.92 9.40 8.79 8.08 7.28 6.44 5.63 4.96 4.47 4.17 4.04 4.00 30.238 157.87 11.57 11.57 11.48 11.32 11.08 10.75 10.35 9.86 9.28 8.59 7.83 7.00 6.19 5.45 4.86 4.44 4.19 4.06 4.01 4.00 30.631 150.86 11.43 11.43 11.33 11.13 10.83 10.42 9.92 9.31 8.61 7.83 7.02 6.22 5.51 4.94 4.52 4.25 4.11 4.04 4.01 4.00 31.023 146.47 11.27 11.27 11.15 10.92 10.57 10.12 9.55 8.88 8.13 7.35 6.57 5.86 5.25 4.77 4.43 4.22 4.10 4.04 4.01 4.00 31.416 144.85 11.10 11.10 10.98 10.74 10.38 9.90 9.33 8.67 7.95 7.22 6.50 5.84 5.28 4.84 4.51 4.29 4.15 4.07 4.03 4.00 gri/doc/examples/example9.txt0000644000175000017500000000001513147557614014664 0ustar psgpsgexample9.gri gri/doc/examples/example11.ps0000644000175000017500000011273113147557614014551 0ustar psgpsg%!PS-Adobe-2.0 EPSF-1.2 %%Creator: Gri2.2.4 (released 1999-Oct-20). User=kelley, commandfile=example11.gri %%Title: example11.ps %%CreationDate: Thu Oct 21 11:30:30 1999 %%Pages: (atend) %%BoundingBox: (atend) %%TemplateBox: 0 0 612 792 %%DocumentFonts: (atend) %%Endcomments % NOTE: The Gri postscript dictionary is being converted to the Adobe % Illustrator 3.0 dialect of PostScript, as described in the Adobe % documents stored at URL % http://www.adobe.com/Support/TechNotes.html % (as of Jan 1996, this doc is number 5007). When the conversion % is complete, the Adobe Illustrator drawing program -- and any % program compatible with AI -- will be able to edit Gri output. % % The IslandDraw (TM) program is able to read Gri output % at this time; remarkably, it can read/edit arbitrary PostScript. % % The definitions below are presented in the same order as the Adobe % manual. The stack configuration before and after is shown in curly % brackets. All the operators are listed, but only some are defined % here. Most things are faithful, except that no distinction is made % between colors for stroking and filling paths. The string 'WRONGLY' % appears with commands that are approximations. % % PDF-style abbreviations: /rg {setrgbcolor} def % {red green blue} {-} set RGB color /RG {setrgbcolor} def % {red green blue} {-} set RGB color /q {gsave} def /Q {grestore} def /W {clip} def /W* {eoclip} def % % Gri-specific abbreviations: /hsb {sethsbcolor} def % {hue saturation brightness} {-} set HSB color % % Following all try to mimic Adobe Illustrator % % Mimicking section 5.1 of Adobe manual: %A % {flag A} {-} Determine whether % following object can % be selected. Flag=1 % prevents selection; % flag=0 allows it. % Mimicking section 5.2 of Adobe manual: %u % {u} {-} start group %U % end group %q % as 'u' but first item is a clip path %Q % as 'U' but first item is a clip path % Mimicking section 5.3 of Adobe manual: /g {setgray} def % {gray g} {-} Set gray for fill % path, WRONGLY used % for stroking also. /G {setgray} def % As 'g', but for filling path. %k % Set cmyk color for filling path. %K % As 'k', but for stroking path. %x % Set cmyk custom color for filling path. %X % As 'x' but for stroking path. %p % Define pattern for filling path. %P % As 'p' but for stroking path. %O % Specify whether overprinting for fill paths %R % As 'O' but for stroking path. % Mimicking section 5.4 of Adobe manual: /d {setdash} def % {[array] phase d} {-} Set dash. /i {setflat} def % {flatness i} {-} Set flatness. /j {setlinejoin} def % {linejoin j} {-} Set line join. /J {setlinecap} def % {linecap J} {-} Set line cap. /M {setmiterlimit} def % {miterlimit M} {-} Set miter limit. /w {setlinewidth} def % {linewidth w} {-} Set line width. % Mimicking section 5.5 of Adobe manual: /m {moveto} def % {x y m} {-} Move to locn /l {lineto} def % {x y l} {-} Draw line to locn % not a smooth point. % WRONGLY, no % distinction is made % between smooth and % corner. %L % {x y L} {-} As 'l' but a corner %c % Bezier curve to smooth point. %C % As 'c' but to corner point. %v % Something else to do with Bezier. %V % %y % %Y % % Mimicking section 5.6 of Adobe manual: %N % {N} {-} As 'n' for nondrawn stuff /n {newpath} def % {n} {-} WRONGLY interpreted % as path constructor /F {fill} def % {F} {-} Fill current path. %f % {f} {-} 'F' but close first /S {stroke} def % {S} {-} Stroke current path. %s % {s} {-} 'S' but close first %B % {B} {-} As 's' but don't empty path. %b % {b} {-} As 'f' but don't empty path. %H % no-op (weird huh?) /h {closepath} def % {h} {-} Close current path %W % Used to create masks. % Mimicking section 5.7 of Adobe manual: %a % Begin text block ... %e % Similar to 'a' but ... %I % Similar to 'a' but ... %o % Similar to 'a' but ... %r % Similar to 'a' but ... %t % {len (string) t} {-} Render string. %T % End block of text % That's the end of the Illustrator stuff. Following are some Gri % definitions which provide a temporary way of handling fonts. /sf {setfont} def % {fontname sf} {-} Set font name. /sh {show} def % {(text) sh} {-} Show text. /sc {scalefont} def % {size sc} {-} Scale font. % Gri items which should be translated to Illustrator format: /rl {rlineto} def /rm {rmoveto} def % Procedures /cimdict 7 dict def /cim { cimdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def q xll yll translate xur xll sub yur yll sub scale /do cl 3 mul string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop} false 3 colorimage Q end } def /imdict 14 dict def /im { imdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def /imagemap exch def q % Add the mapping to the transfer function (ref: white book, p 743. [{255 mul cvi imagemap exch get} /exec load currenttransfer /exec load] cvx settransfer xll yll translate xur xll sub yur yll sub scale /do cl string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop}image Q end } def /frdict 5 dict def /fr { frdict begin /yt exch def /xr exch def /yb exch def /xl exch def n xl yb m xl yt l xr yt l xr yb l h F n end } def /plusdict 3 dict def /_plus { plusdict begin dup 0.5 mul /t0 exch def /t1 exch def 0 t0 rm 0 t1 neg rl t0 neg t0 rm t1 0 rl t0 neg 0 rm end } def /timesdict 3 dict def /_times { timesdict begin dup 0.353553 mul /t0 exch def 0.707106 mul /t1 exch def t0 neg t0 rm t1 dup neg rl t1 neg 0 rm t1 dup rl t0 neg dup rm end } def /boxdict 3 dict def /_box { boxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm end } def /filledboxdict 3 dict def /_filledbox { filledboxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm F end } def /diamonddict 2 dict def /_diamond { diamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm end } def /filleddiamonddict 2 dict def /_filleddiamond { filleddiamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm F end } def /triangleupdict 5 dict def /_triangleup { triangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm end } def /filledtriangleupdict 5 dict def /_filledtriangleup { filledtriangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm F end } def /trianglerightdict 5 dict def /_triangleright { trianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm end } def /filledtrianglerightdict 5 dict def /_filledtriangleright { filledtrianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm F end } def /triangledowndict 5 dict def /_triangledown { triangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm end } def /filledtriangledowndict 5 dict def /_filledtriangledown { filledtriangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm F end } def /triangleleftdict 5 dict def /_triangleleft { triangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm end } def /filledtriangleleftdict 5 dict def /_filledtriangleleft { filledtriangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm F end } def /circdict 5 dict def /_circ { circdict begin 0.5 mul /t0 exch def currentpoint /t2 exch def /t1 exch def S n t1 t2 t0 0 360 arc t1 t2 m end } def /bulldict 3 dict def /_bull { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 360 arc h F S end } def /filledhalfmoonupdict 3 dict def /_filledhalfmoonup { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 180 arc h F S end } def /filledhalfmoondowndict 3 dict def /_filledhalfmoondown { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 180 360 arc h F S end } def 1 1 scale 10.0 M 1 j /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-ISOLatin1 exch definefont pop /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Bold-ISOLatin1 exch definefont pop /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-ISOLatin1 exch definefont pop /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Bold-ISOLatin1 exch definefont pop /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Roman-ISOLatin1 exch definefont pop /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Bold-ISOLatin1 exch definefont pop /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Italic-ISOLatin1 exch definefont pop /Symbol findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Symbol-ISOLatin1 exch definefont pop /Times findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-ISOLatin1 exch definefont pop /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Bold-ISOLatin1 exch definefont pop /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Roman-ISOLatin1 exch definefont pop %%EndProlog %%Page: 1 1 /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:# Example 11 -- Fancy plot %gri:# $Id: example11.ps,v 1.2 2000/05/29 19:45:11 psg Exp $ %gri: %gri:.thin. = 0.5 # for whole data set %gri:.thick. = 2 # for bravo time period %gri:.gray_for_guiding_lines. = 0.75 # for guiding lines %gri:.tmin. = 1964 # time axis %gri:.tmax. = 1974 %gri:.tinc. = 5 %gri:.tincinc. = 1 %gri:.missing_value. = -9 %gri:\file = "./example11.dat" %gri:# %gri:# Guiding lines to draw on both panels. %gri:# %gri:.1xl. = 1962 %gri:.1yb. = -3 %gri:.1xr. = 1968 %gri:.1yt. = 3 %gri:.1slope. = {rpn .1yt. .1yb. - .1xr. .1xl. - /} %gri:.1intercept. = {rpn .1yb. .1slope. .1xl. * -} %gri:.2xl. = 1966.4 %gri:.2yb. = 3 %gri:.2xr. = 1980 %gri:.2yt. = -1 %gri:.2slope. = {rpn .2yt. .2yb. - .2xr. .2xl. - /} %gri:.2intercept. = {rpn .2yb. .2slope. .2xl. * -} %gri:# %gri:# PANEL 1: Bravo time period. %gri:# %gri:set x margin 3 %gri:set x size 15 %gri:set y margin 3 %gri:set y size 5 %gri:# Draw border big enough for this and next panel. %gri:draw border box {rpn ..xmargin.. 2 -} {rpn ..ymargin.. 2 -} {rpn ..xmargin.. ..xsize.. + 2 +} {rpn ..ymargin.. ..ysize.. 2 * 3 + + 2 +} 0.2 0.75 %^ scale 1 85.35 0 42.675 1 85.35 0 14.225 0.75 g 0.75 G 5.690 w 0.75 g 0.75 G 1.0 i 0 J 1 j 5.690 w 10.0 M [] 0 d 28.45 31.30 m 569.00 31.30 l S % END GriPath stroke/fill %^ scale 1 85.35 0 42.675 1 85.35 0 14.225 0.75 g 0.75 G 5.690 w 0.75 g 0.75 G 1.0 i 0 J 1 j 5.690 w 10.0 M [] 0 d 31.30 28.45 m 31.30 512.10 l S % END GriPath stroke/fill %^ scale 1 85.35 0 42.675 1 85.35 0 14.225 0.75 g 0.75 G 5.690 w 0.75 g 0.75 G 1.0 i 0 J 1 j 5.690 w 10.0 M [] 0 d 28.45 509.25 m 569.00 509.25 l S % END GriPath stroke/fill %^ scale 1 85.35 0 42.675 1 85.35 0 14.225 0.75 g 0.75 G 5.690 w 0.75 g 0.75 G 1.0 i 0 J 1 j 5.690 w 10.0 M [] 0 d 566.15 28.45 m 566.15 512.10 l S % END GriPath stroke/fill %^ scale 1 85.35 0 42.675 1 85.35 0 14.225 0 g 0 G 1.0 i 0 J 1 j 0.250 w 10.0 M [] 0 d 28.45 28.45 m 569.00 28.45 l 569.00 512.10 l 28.45 512.10 l 28.45 28.45 l S % END GriPath stroke/fill %gri:set missing value .missing_value. %gri:set ignore error eof %gri:set x name "Year" %gri:set x axis .tmin. .tmax. .tinc. .tincinc. %gri:set y name "Area / 10$^5$km$^2$" %gri:set y axis -3 3 1 %gri:draw axes % gr_show_at() BEGIN 0 g 0 G 114.6 64.5 m (1965) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 328.0 64.5 m (1970) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 85.35 85.35 m 85.35 85.35 l 85.35 82.50 l 85.35 85.35 l 128.03 85.35 l 128.03 79.66 l 128.03 85.35 l 170.70 85.35 l 170.70 82.50 l 170.70 85.35 l 213.38 85.35 l 213.38 82.50 l 213.38 85.35 l 256.05 85.35 l 256.05 82.50 l 256.05 85.35 l 298.73 85.35 l 298.73 82.50 l 298.73 85.35 l 341.40 85.35 l 341.40 79.66 l 341.40 85.35 l 384.07 85.35 l 384.07 82.50 l 384.07 85.35 l 426.75 85.35 l 426.75 82.50 l 426.75 85.35 l 469.43 85.35 l 469.43 82.50 l 469.43 85.35 l 512.10 85.35 l 512.10 82.50 l 512.10 85.35 l 512.31 85.35 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 286.1 49.4 m (Year) sh % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 85.35 227.60 m 85.35 227.60 l 85.35 230.44 l 85.35 227.60 l 128.03 227.60 l 128.03 233.29 l 128.03 227.60 l 170.70 227.60 l 170.70 230.44 l 170.70 227.60 l 213.38 227.60 l 213.38 230.44 l 213.38 227.60 l 256.05 227.60 l 256.05 230.44 l 256.05 227.60 l 298.73 227.60 l 298.73 230.44 l 298.73 227.60 l 341.40 227.60 l 341.40 233.29 l 341.40 227.60 l 384.07 227.60 l 384.07 230.44 l 384.07 227.60 l 426.75 227.60 l 426.75 230.44 l 426.75 227.60 l 469.43 227.60 l 469.43 230.44 l 469.43 227.60 l 512.10 227.60 l 512.10 230.44 l 512.10 227.60 l 512.31 227.60 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf % gr_show_at() BEGIN 0 g 0 G 63.1 81.0 m (-3) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 63.1 104.7 m (-2) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 63.1 128.4 m (-1) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 67.1 152.2 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 67.1 175.9 m (1) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 67.1 199.6 m (2) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 67.1 223.3 m (3) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 85.35 85.35 m 85.35 85.35 l 79.66 85.35 l 85.35 85.35 l 85.35 109.06 l 79.66 109.06 l 85.35 109.06 l 85.35 132.77 l 79.66 132.77 l 85.35 132.77 l 85.35 156.47 l 79.66 156.47 l 85.35 156.47 l 85.35 180.18 l 79.66 180.18 l 85.35 180.18 l 85.35 203.89 l 79.66 203.89 l 85.35 203.89 l 85.35 227.60 l 79.66 227.60 l 85.35 227.60 l 85.35 227.60 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 57.3 117.3 m 90.00 rotate (Area / 10) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh 0.0 5.4 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-ISOLatin1 findfont 9.00 sc sf (5) sh /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 -5.4 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (km) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh 0.0 5.4 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-ISOLatin1 findfont 9.00 sc sf (2) sh /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 -5.4 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh -90.00 rotate % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 512.10 85.35 m 512.10 85.35 l 517.79 85.35 l 512.10 85.35 l 512.10 109.06 l 517.79 109.06 l 512.10 109.06 l 512.10 132.77 l 517.79 132.77 l 512.10 132.77 l 512.10 156.47 l 517.79 156.47 l 512.10 156.47 l 512.10 180.18 l 517.79 180.18 l 512.10 180.18 l 512.10 203.89 l 517.79 203.89 l 512.10 203.89 l 512.10 227.60 l 517.79 227.60 l 512.10 227.60 l 512.10 227.60 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:# %gri:# Draw index lines 1 and 2. %gri:# %gri:# Upward sloped line. %gri:set line width .thin. %gri:set graylevel .gray_for_guiding_lines. %gri:if {rpn .1intercept. ..xright.. .1slope. * + ..ytop.. <} %gri: draw line from ..xleft.. {rpn .1intercept. ..xleft.. .1slope. * +} to {rpn ..ytop.. .1intercept. - .1slope. /} ..ytop.. %^ scale 1 85.35 1964 42.675 1 85.35 -3 23.7083 0.75 g 0.75 G 0.500 w 0.75 g 0.75 G 1.0 i 0 J 1 j 0.500 w 10.0 M [] 0 d 85.35 132.77 m 256.05 227.60 l S % END GriPath stroke/fill %gri:else %gri: draw line from ..xleft.. {rpn .1intercept. ..xleft.. .1slope. * +} to ..xright.. {rpn .1intercept. ..xright.. .1slope. * +} %gri:end if %gri:set graylevel 0 %gri:# %gri:# Downward sloped line. %gri:set line width .thin. %gri:set graylevel .gray_for_guiding_lines. %gri:if {rpn .2intercept. ..xleft.. .2slope. * + ..ytop.. <} %gri: draw line from {rpn ..ytop.. .2intercept. - .2slope. /} ..ytop.. to ..xright.. {rpn .2intercept. ..xright.. .2slope. * +} %^ scale 1 85.35 1964 42.675 1 85.35 -3 23.7083 0.75 g 0.75 G 0.500 w 0.75 g 0.75 G 1.0 i 0 J 1 j 0.500 w 10.0 M [] 0 d 187.77 227.60 m 512.10 174.60 l S % END GriPath stroke/fill %gri:else %gri: draw line from ..xleft.. {rpn .2intercept. ..xleft.. .2slope. * +} to ..xright.. {rpn .2intercept. ..xright.. .2slope. * +} %gri:end if %gri:set graylevel 0 %gri:# %gri:# Finally, draw the data curve on top, after first %gri:# whiting out a background. %gri:set input data window x .tmin. .tmax. %gri:open \file %gri:read columns x y %gri:close %gri:y /= 1e5 %gri:set line width ..linewidthaxis.. %gri:draw zero line %^ scale 1 85.35 1964 42.675 1 85.35 -3 23.7083 0.369 w 0 g 0 G 1.0 i 0 J 1 j 0.369 w 10.0 M [] 0 d 85.35 156.47 m 512.10 156.47 l S % END GriPath stroke/fill %gri:set line width {rpn .thick. 3 *} %gri:set graylevel 1 %gri:draw curve %^ scale 1 85.35 1964 42.675 1 85.35 -3 23.7083 6.000 w 1 g 1 G 1.0 i 0 J 1 j 6.000 w 10.0 M [] 0 d 85.36 134.42 m 95.81 132.22 l 103.47 135.60 l 106.03 142.61 l 114.15 150.88 l 118.56 163.63 l 121.58 165.42 l 127.38 166.26 l 136.44 177.06 l 141.55 179.39 l 149.68 181.07 l 153.86 179.76 l 159.89 182.89 l 166.16 190.42 l 166.86 194.30 l 174.75 196.22 l 181.25 195.41 l 187.99 193.12 l 191.70 191.29 l 192.86 190.79 l 198.90 192.58 l 200.76 190.42 l 204.01 188.70 l 208.88 191.63 l 212.83 195.38 l 217.01 199.86 l 217.47 198.31 l 222.81 201.35 l 228.38 205.09 l 234.89 196.05 l 240.23 186.23 l 244.87 189.20 l 251.14 193.25 l 253.23 190.59 l 256.02 194.67 l 263.45 201.11 l 269.71 211.57 l 269.94 206.37 l 275.52 216.93 l 282.95 220.21 l 284.80 215.75 l 292.70 211.84 l 295.49 208.33 l 299.66 205.30 l 306.63 194.80 l 307.79 204.76 l 312.90 192.85 l 320.56 198.01 l 324.97 207.83 l 333.10 214.30 l 335.66 214.71 l 341.69 211.57 l 344.48 210.42 l 351.68 210.69 l 357.01 209.44 l 361.19 198.75 l 369.78 178.71 l 370.25 172.94 l 385.34 180.57 l 395.09 193.52 l 405.08 208.94 l 405.31 210.25 l 412.97 209.55 l 414.60 202.90 l 419.24 199.53 l 422.72 198.55 l 428.53 200.61 l 434.10 200.67 l 439.90 203.64 l 443.38 204.38 l 445.01 201.18 l 448.49 197.03 l 448.73 194.77 l 453.84 200.88 l 459.40 202.23 l 464.51 201.75 l 470.55 194.57 l 472.87 181.51 l 481.00 167.48 l 490.05 156.78 l 493.54 153.58 l 502.36 154.05 l 503.99 149.33 l 511.65 149.02 l S % END GriPath stroke/fill %gri:set graylevel 0 %gri:set line width .thick. %gri:draw curve %^ scale 1 85.35 1964 42.675 1 85.35 -3 23.7083 2.000 w 0 g 0 G 1.0 i 0 J 1 j 2.000 w 10.0 M [] 0 d 85.36 134.42 m 95.81 132.22 l 103.47 135.60 l 106.03 142.61 l 114.15 150.88 l 118.56 163.63 l 121.58 165.42 l 127.38 166.26 l 136.44 177.06 l 141.55 179.39 l 149.68 181.07 l 153.86 179.76 l 159.89 182.89 l 166.16 190.42 l 166.86 194.30 l 174.75 196.22 l 181.25 195.41 l 187.99 193.12 l 191.70 191.29 l 192.86 190.79 l 198.90 192.58 l 200.76 190.42 l 204.01 188.70 l 208.88 191.63 l 212.83 195.38 l 217.01 199.86 l 217.47 198.31 l 222.81 201.35 l 228.38 205.09 l 234.89 196.05 l 240.23 186.23 l 244.87 189.20 l 251.14 193.25 l 253.23 190.59 l 256.02 194.67 l 263.45 201.11 l 269.71 211.57 l 269.94 206.37 l 275.52 216.93 l 282.95 220.21 l 284.80 215.75 l 292.70 211.84 l 295.49 208.33 l 299.66 205.30 l 306.63 194.80 l 307.79 204.76 l 312.90 192.85 l 320.56 198.01 l 324.97 207.83 l 333.10 214.30 l 335.66 214.71 l 341.69 211.57 l 344.48 210.42 l 351.68 210.69 l 357.01 209.44 l 361.19 198.75 l 369.78 178.71 l 370.25 172.94 l 385.34 180.57 l 395.09 193.52 l 405.08 208.94 l 405.31 210.25 l 412.97 209.55 l 414.60 202.90 l 419.24 199.53 l 422.72 198.55 l 428.53 200.61 l 434.10 200.67 l 439.90 203.64 l 443.38 204.38 l 445.01 201.18 l 448.49 197.03 l 448.73 194.77 l 453.84 200.88 l 459.40 202.23 l 464.51 201.75 l 470.55 194.57 l 472.87 181.51 l 481.00 167.48 l 490.05 156.78 l 493.54 153.58 l 502.36 154.05 l 503.99 149.33 l 511.65 149.02 l S % END GriPath stroke/fill %gri: %gri:# %gri:# PANEL 2: Longer timescale. %gri:# %gri:delete x scale %gri:set x margin bigger 5 %gri:set x size 10 %gri:set x name "" %gri:set y name "" %gri:set y margin bigger {rpn ..ysize.. 3 +} %gri:# %gri:# Draw long data set in thin pen. %gri:set input data window x off %gri:open \file %gri:read columns x y %gri:close %gri:y /= 1e5 %gri:# %gri:# Draw guiding lines, axes, etc. %gri:set x axis 1952 1980 5 1 %gri:draw axes frame 0 g 0 G 1.0 i 0 J 1 j 0.369 w 10.0 M [] 0 d 227.60 455.20 m 512.10 455.20 l 512.10 312.95 l 227.60 312.95 l 227.60 455.20 l S % END GriPath stroke/fill %gri:set line width .thin. %gri:set graylevel .gray_for_guiding_lines. %gri:draw line from .1xl. .1yb. to .1xr. .1yt. %^ scale 1 227.6 1952 10.1607 1 312.95 -3 23.7083 0.75 g 0.75 G 0.500 w 0.75 g 0.75 G 1.0 i 0 J 1 j 0.500 w 10.0 M [] 0 d 329.21 312.95 m 390.17 455.20 l S % END GriPath stroke/fill %gri:draw line from .2xl. .2yb. to .2xr. .2yt. %^ scale 1 227.6 1952 10.1607 1 312.95 -3 23.7083 0.75 g 0.75 G 0.500 w 0.75 g 0.75 G 1.0 i 0 J 1 j 0.500 w 10.0 M [] 0 d 373.91 455.20 m 512.10 360.37 l S % END GriPath stroke/fill %gri:set graylevel 0 %gri:set line width ..linewidthaxis.. %gri:draw zero line %^ scale 1 227.6 1952 10.1607 1 312.95 -3 23.7083 0.369 w 0 g 0 G 1.0 i 0 J 1 j 0.369 w 10.0 M [] 0 d 227.60 384.07 m 512.10 384.07 l S % END GriPath stroke/fill %gri: %gri: %gri:draw x axis at bottom % gr_show_at() BEGIN 0 g 0 G 244.7 292.1 m (1955) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 295.5 292.1 m (1960) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 346.3 292.1 m (1965) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 397.1 292.1 m (1970) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 447.9 292.1 m (1975) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 498.7 292.1 m (1980) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 227.60 312.95 m 227.60 312.95 l 227.60 310.11 l 227.60 312.95 l 237.76 312.95 l 237.76 310.11 l 237.76 312.95 l 247.92 312.95 l 247.92 310.11 l 247.92 312.95 l 258.08 312.95 l 258.08 307.26 l 258.08 312.95 l 268.24 312.95 l 268.24 310.11 l 268.24 312.95 l 278.40 312.95 l 278.40 310.11 l 278.40 312.95 l 288.56 312.95 l 288.56 310.11 l 288.56 312.95 l 298.73 312.95 l 298.73 310.11 l 298.73 312.95 l 308.89 312.95 l 308.89 307.26 l 308.89 312.95 l 319.05 312.95 l 319.05 310.11 l 319.05 312.95 l 329.21 312.95 l 329.21 310.11 l 329.21 312.95 l 339.37 312.95 l 339.37 310.11 l 339.37 312.95 l 349.53 312.95 l 349.53 310.11 l 349.53 312.95 l 359.69 312.95 l 359.69 307.26 l 359.69 312.95 l 369.85 312.95 l 369.85 310.11 l 369.85 312.95 l 380.01 312.95 l 380.01 310.11 l 380.01 312.95 l 390.17 312.95 l 390.17 310.11 l 390.17 312.95 l 400.33 312.95 l 400.33 310.11 l 400.33 312.95 l 410.49 312.95 l 410.49 307.26 l 410.49 312.95 l 420.65 312.95 l 420.65 310.11 l 420.65 312.95 l 430.81 312.95 l 430.81 310.11 l 430.81 312.95 l 440.98 312.95 l 440.98 310.11 l 440.98 312.95 l 451.14 312.95 l 451.14 310.11 l 451.14 312.95 l 461.30 312.95 l 461.30 307.26 l 461.30 312.95 l 471.46 312.95 l 471.46 310.11 l 471.46 312.95 l 481.62 312.95 l 481.62 310.11 l 481.62 312.95 l 491.78 312.95 l 491.78 310.11 l 491.78 312.95 l 501.94 312.95 l 501.94 310.11 l 501.94 312.95 l 512.10 312.95 l 512.10 307.26 l 512.10 312.95 l 512.15 312.95 l S % END GriPath stroke/fill %gri:.old. = ..fontsize.. %gri:set font size 0 /Helvetica-ISOLatin1 findfont 0.00 sc sf %gri:draw y axis at left 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 227.60 312.95 m 227.60 312.95 l 221.91 312.95 l 227.60 312.95 l 227.60 336.66 l 221.91 336.66 l 227.60 336.66 l 227.60 360.37 l 221.91 360.37 l 227.60 360.37 l 227.60 384.07 l 221.91 384.07 l 227.60 384.07 l 227.60 407.78 l 221.91 407.78 l 227.60 407.78 l 227.60 431.49 l 221.91 431.49 l 227.60 431.49 l 227.60 455.20 l 221.91 455.20 l 227.60 455.20 l 227.60 455.20 l S % END GriPath stroke/fill %gri:set font size .old. /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:delete .old. %gri:# %gri:# Draw full curve (first whiting out region around it). %gri:set line width {rpn .thin. 4 *} %gri:set graylevel 1 %gri:draw curve %^ scale 1 227.6 1952 10.1607 1 312.95 -3 23.7083 2.000 w 1 g 1 G 1.0 i 0 J 1 j 2.000 w 10.0 M [] 0 d 237.81 385.43 m 238.80 384.79 l 240.79 386.54 l 243.00 385.80 l 245.66 373.01 l 246.38 368.05 l 248.53 364.21 l 251.57 368.43 l 252.73 363.06 l 254.89 362.76 l 256.49 365.22 l 260.03 366.20 l 261.30 367.82 l 262.74 368.90 l 263.85 377.70 l 265.61 379.12 l 266.33 388.90 l 267.66 392.85 l 268.82 394.27 l 270.37 393.96 l 270.98 391.80 l 271.36 388.53 l 271.42 385.80 l 272.25 383.30 l 273.68 382.36 l 274.29 379.32 l 274.35 380.74 l 275.29 384.05 l 276.50 388.43 l 278.61 391.33 l 279.55 392.82 l 279.93 387.89 l 280.60 383.98 l 282.86 373.76 l 283.53 367.89 l 284.47 363.90 l 285.07 361.85 l 286.07 362.86 l 287.12 361.61 l 288.17 362.52 l 288.50 364.68 l 289.72 364.82 l 292.04 367.35 l 292.59 369.84 l 293.92 373.01 l 295.08 374.13 l 296.57 371.16 l 297.51 368.39 l 298.23 366.00 l 299.22 363.33 l 299.22 361.07 l 299.61 358.54 l 299.67 357.16 l 301.66 360.23 l 303.87 362.18 l 304.31 362.66 l 304.64 361.51 l 304.70 359.42 l 305.42 357.76 l 306.14 355.88 l 306.14 351.19 l 307.19 343.26 l 309.67 333.71 l 311.66 323.86 l 313.71 315.73 l 315.09 312.83 l 316.75 312.79 l 318.08 302.84 l 319.35 302.44 l 320.78 300.18 l 322.33 302.50 l 324.16 303.15 l 325.04 308.81 l 327.09 315.26 l 328.41 317.62 l 329.63 318.39 l 330.07 319.78 l 330.79 319.64 l 333.11 328.92 l 334.55 329.33 l 335.55 333.91 l 337.04 334.89 l 341.07 346.73 l 342.34 344.14 l 346.32 362.62 l 348.04 361.61 l 349.53 362.02 l 352.02 359.82 l 353.84 363.20 l 354.45 370.21 l 356.39 378.48 l 357.44 391.23 l 358.16 393.02 l 359.54 393.86 l 361.69 404.66 l 362.91 406.99 l 364.84 408.67 l 365.84 407.36 l 367.28 410.49 l 368.77 418.02 l 368.94 421.90 l 370.81 423.82 l 372.36 423.01 l 373.97 420.72 l 374.85 418.89 l 375.13 418.39 l 376.56 420.18 l 377.01 418.02 l 377.78 416.30 l 378.94 419.23 l 379.88 422.98 l 380.88 427.46 l 380.99 425.91 l 382.26 428.95 l 383.58 432.69 l 385.13 423.65 l 386.40 413.83 l 387.51 416.80 l 389.00 420.85 l 389.50 418.19 l 390.16 422.27 l 391.93 428.71 l 393.42 439.17 l 393.48 433.97 l 394.81 444.53 l 396.58 447.81 l 397.02 443.35 l 398.90 439.44 l 399.56 435.93 l 400.56 432.90 l 402.21 422.40 l 402.49 432.36 l 403.71 420.45 l 405.53 425.61 l 406.58 435.43 l 408.52 441.90 l 409.13 442.31 l 410.56 439.17 l 411.23 438.02 l 412.94 438.29 l 414.21 437.04 l 415.21 426.35 l 417.25 406.31 l 417.36 400.54 l 420.96 408.17 l 423.28 421.12 l 425.65 436.54 l 425.71 437.85 l 427.53 437.15 l 427.92 430.50 l 429.03 427.13 l 429.86 426.15 l 431.24 428.21 l 432.56 428.27 l 433.95 431.24 l 434.77 431.98 l 435.16 428.78 l 435.99 424.63 l 436.05 422.37 l 437.26 428.48 l 438.59 429.83 l 439.81 429.35 l 441.24 422.17 l 441.80 409.11 l 443.73 395.08 l 445.89 384.38 l 446.72 381.18 l 448.82 381.65 l 449.20 376.93 l 451.03 376.62 l 455.34 367.41 l 457.94 369.84 l 459.76 369.61 l 462.14 374.84 l 463.85 381.62 l 465.95 383.37 l 467.72 381.89 l 469.93 385.90 l 471.43 392.28 l 472.86 391.33 l 475.08 402.50 l 476.13 405.64 l 477.78 406.95 l 478.95 397.81 l 478.95 400.95 l 480.38 392.78 l 480.66 395.08 l 483.64 388.50 l 484.20 384.28 l 484.64 382.49 l 486.30 383.17 l 487.46 386.44 l 489.06 385.83 l 489.45 389.00 l 489.95 368.05 l 490.00 376.42 l 490.06 382.73 l 491.83 364.68 l S % END GriPath stroke/fill %gri:set graylevel 0 %gri:set line width .thin. %gri:draw curve %^ scale 1 227.6 1952 10.1607 1 312.95 -3 23.7083 0.500 w 0 g 0 G 1.0 i 0 J 1 j 0.500 w 10.0 M [] 0 d 237.81 385.43 m 238.80 384.79 l 240.79 386.54 l 243.00 385.80 l 245.66 373.01 l 246.38 368.05 l 248.53 364.21 l 251.57 368.43 l 252.73 363.06 l 254.89 362.76 l 256.49 365.22 l 260.03 366.20 l 261.30 367.82 l 262.74 368.90 l 263.85 377.70 l 265.61 379.12 l 266.33 388.90 l 267.66 392.85 l 268.82 394.27 l 270.37 393.96 l 270.98 391.80 l 271.36 388.53 l 271.42 385.80 l 272.25 383.30 l 273.68 382.36 l 274.29 379.32 l 274.35 380.74 l 275.29 384.05 l 276.50 388.43 l 278.61 391.33 l 279.55 392.82 l 279.93 387.89 l 280.60 383.98 l 282.86 373.76 l 283.53 367.89 l 284.47 363.90 l 285.07 361.85 l 286.07 362.86 l 287.12 361.61 l 288.17 362.52 l 288.50 364.68 l 289.72 364.82 l 292.04 367.35 l 292.59 369.84 l 293.92 373.01 l 295.08 374.13 l 296.57 371.16 l 297.51 368.39 l 298.23 366.00 l 299.22 363.33 l 299.22 361.07 l 299.61 358.54 l 299.67 357.16 l 301.66 360.23 l 303.87 362.18 l 304.31 362.66 l 304.64 361.51 l 304.70 359.42 l 305.42 357.76 l 306.14 355.88 l 306.14 351.19 l 307.19 343.26 l 309.67 333.71 l 311.66 323.86 l 313.71 315.73 l 315.09 312.83 l 316.75 312.79 l 318.08 302.84 l 319.35 302.44 l 320.78 300.18 l 322.33 302.50 l 324.16 303.15 l 325.04 308.81 l 327.09 315.26 l 328.41 317.62 l 329.63 318.39 l 330.07 319.78 l 330.79 319.64 l 333.11 328.92 l 334.55 329.33 l 335.55 333.91 l 337.04 334.89 l 341.07 346.73 l 342.34 344.14 l 346.32 362.62 l 348.04 361.61 l 349.53 362.02 l 352.02 359.82 l 353.84 363.20 l 354.45 370.21 l 356.39 378.48 l 357.44 391.23 l 358.16 393.02 l 359.54 393.86 l 361.69 404.66 l 362.91 406.99 l 364.84 408.67 l 365.84 407.36 l 367.28 410.49 l 368.77 418.02 l 368.94 421.90 l 370.81 423.82 l 372.36 423.01 l 373.97 420.72 l 374.85 418.89 l 375.13 418.39 l 376.56 420.18 l 377.01 418.02 l 377.78 416.30 l 378.94 419.23 l 379.88 422.98 l 380.88 427.46 l 380.99 425.91 l 382.26 428.95 l 383.58 432.69 l 385.13 423.65 l 386.40 413.83 l 387.51 416.80 l 389.00 420.85 l 389.50 418.19 l 390.16 422.27 l 391.93 428.71 l 393.42 439.17 l 393.48 433.97 l 394.81 444.53 l 396.58 447.81 l 397.02 443.35 l 398.90 439.44 l 399.56 435.93 l 400.56 432.90 l 402.21 422.40 l 402.49 432.36 l 403.71 420.45 l 405.53 425.61 l 406.58 435.43 l 408.52 441.90 l 409.13 442.31 l 410.56 439.17 l 411.23 438.02 l 412.94 438.29 l 414.21 437.04 l 415.21 426.35 l 417.25 406.31 l 417.36 400.54 l 420.96 408.17 l 423.28 421.12 l 425.65 436.54 l 425.71 437.85 l 427.53 437.15 l 427.92 430.50 l 429.03 427.13 l 429.86 426.15 l 431.24 428.21 l 432.56 428.27 l 433.95 431.24 l 434.77 431.98 l 435.16 428.78 l 435.99 424.63 l 436.05 422.37 l 437.26 428.48 l 438.59 429.83 l 439.81 429.35 l 441.24 422.17 l 441.80 409.11 l 443.73 395.08 l 445.89 384.38 l 446.72 381.18 l 448.82 381.65 l 449.20 376.93 l 451.03 376.62 l 455.34 367.41 l 457.94 369.84 l 459.76 369.61 l 462.14 374.84 l 463.85 381.62 l 465.95 383.37 l 467.72 381.89 l 469.93 385.90 l 471.43 392.28 l 472.86 391.33 l 475.08 402.50 l 476.13 405.64 l 477.78 406.95 l 478.95 397.81 l 478.95 400.95 l 480.38 392.78 l 480.66 395.08 l 483.64 388.50 l 484.20 384.28 l 484.64 382.49 l 486.30 383.17 l 487.46 386.44 l 489.06 385.83 l 489.45 389.00 l 489.95 368.05 l 490.00 376.42 l 490.06 382.73 l 491.83 364.68 l S % END GriPath stroke/fill %gri:# %gri:# Draw bravo time period (first whiting out region around it). %gri:set input data window x .tmin. .tmax. %gri:open \file %gri:read columns x y %gri:close %gri:y /= 1e5 %gri:set line width {rpn .thick. 3 *} %gri:set graylevel 1 %gri:draw curve %^ scale 1 227.6 1952 10.1607 1 312.95 -3 23.7083 6.000 w 1 g 1 G 1.0 i 0 J 1 j 6.000 w 10.0 M [] 0 d 349.53 362.02 m 352.02 359.82 l 353.84 363.20 l 354.45 370.21 l 356.39 378.48 l 357.44 391.23 l 358.16 393.02 l 359.54 393.86 l 361.69 404.66 l 362.91 406.99 l 364.84 408.67 l 365.84 407.36 l 367.28 410.49 l 368.77 418.02 l 368.94 421.90 l 370.81 423.82 l 372.36 423.01 l 373.97 420.72 l 374.85 418.89 l 375.13 418.39 l 376.56 420.18 l 377.01 418.02 l 377.78 416.30 l 378.94 419.23 l 379.88 422.98 l 380.88 427.46 l 380.99 425.91 l 382.26 428.95 l 383.58 432.69 l 385.13 423.65 l 386.40 413.83 l 387.51 416.80 l 389.00 420.85 l 389.50 418.19 l 390.16 422.27 l 391.93 428.71 l 393.42 439.17 l 393.48 433.97 l 394.81 444.53 l 396.58 447.81 l 397.02 443.35 l 398.90 439.44 l 399.56 435.93 l 400.56 432.90 l 402.21 422.40 l 402.49 432.36 l 403.71 420.45 l 405.53 425.61 l 406.58 435.43 l 408.52 441.90 l 409.13 442.31 l 410.56 439.17 l 411.23 438.02 l 412.94 438.29 l 414.21 437.04 l 415.21 426.35 l 417.25 406.31 l 417.36 400.54 l 420.96 408.17 l 423.28 421.12 l 425.65 436.54 l 425.71 437.85 l 427.53 437.15 l 427.92 430.50 l 429.03 427.13 l 429.86 426.15 l 431.24 428.21 l 432.56 428.27 l 433.95 431.24 l 434.77 431.98 l 435.16 428.78 l 435.99 424.63 l 436.05 422.37 l 437.26 428.48 l 438.59 429.83 l 439.81 429.35 l 441.24 422.17 l 441.80 409.11 l 443.73 395.08 l 445.89 384.38 l 446.72 381.18 l 448.82 381.65 l 449.20 376.93 l 451.03 376.62 l S % END GriPath stroke/fill %gri:set graylevel 0 %gri:set line width .thick. %gri:draw curve %^ scale 1 227.6 1952 10.1607 1 312.95 -3 23.7083 2.000 w 0 g 0 G 1.0 i 0 J 1 j 2.000 w 10.0 M [] 0 d 349.53 362.02 m 352.02 359.82 l 353.84 363.20 l 354.45 370.21 l 356.39 378.48 l 357.44 391.23 l 358.16 393.02 l 359.54 393.86 l 361.69 404.66 l 362.91 406.99 l 364.84 408.67 l 365.84 407.36 l 367.28 410.49 l 368.77 418.02 l 368.94 421.90 l 370.81 423.82 l 372.36 423.01 l 373.97 420.72 l 374.85 418.89 l 375.13 418.39 l 376.56 420.18 l 377.01 418.02 l 377.78 416.30 l 378.94 419.23 l 379.88 422.98 l 380.88 427.46 l 380.99 425.91 l 382.26 428.95 l 383.58 432.69 l 385.13 423.65 l 386.40 413.83 l 387.51 416.80 l 389.00 420.85 l 389.50 418.19 l 390.16 422.27 l 391.93 428.71 l 393.42 439.17 l 393.48 433.97 l 394.81 444.53 l 396.58 447.81 l 397.02 443.35 l 398.90 439.44 l 399.56 435.93 l 400.56 432.90 l 402.21 422.40 l 402.49 432.36 l 403.71 420.45 l 405.53 425.61 l 406.58 435.43 l 408.52 441.90 l 409.13 442.31 l 410.56 439.17 l 411.23 438.02 l 412.94 438.29 l 414.21 437.04 l 415.21 426.35 l 417.25 406.31 l 417.36 400.54 l 420.96 408.17 l 423.28 421.12 l 425.65 436.54 l 425.71 437.85 l 427.53 437.15 l 427.92 430.50 l 429.03 427.13 l 429.86 426.15 l 431.24 428.21 l 432.56 428.27 l 433.95 431.24 l 434.77 431.98 l 435.16 428.78 l 435.99 424.63 l 436.05 422.37 l 437.26 428.48 l 438.59 429.83 l 439.81 429.35 l 441.24 422.17 l 441.80 409.11 l 443.73 395.08 l 445.89 384.38 l 446.72 381.18 l 448.82 381.65 l 449.20 376.93 l 451.03 376.62 l S % END GriPath stroke/fill %gri:# %gri:# Done %gri:set font size 20 /Helvetica-ISOLatin1 findfont 20.00 sc sf %gri:\label = "Example 11 (Arctic ice anomaly)" %gri:draw label "\label" at {rpn 8.5 2.54 * "\label" width - 2 /} {rpn ..ytop.. yusertocm 0.7 +} cm %^ scale 1 227.6 1952 10.1607 1 312.95 -3 23.7083 % gr_show_at() BEGIN 0 g 0 G S n 163.2 475.1 m (Example 11 \(Arctic ice anomaly\)) sh % gr_show_at() END %gri:quit showpage %%Trailer %%BoundingBox: 26 26 571 515 %%DocumentFonts: Courier Helvetica Palatino-Roman Palatino-Italic Symbol Times-Roman %%Pages: 1 gri/doc/examples/Makefile.in0000644000175000017500000003666613147560320014455 0ustar psgpsg# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/examples ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) VPATH = @srcdir@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS_TEMPLATE = @EXTRA_CFLAGS_TEMPLATE@ GREP = @GREP@ HAVE_CONVERT = @HAVE_CONVERT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PROGS = @PROGS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ # gri/doc/examples/ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ txt_files = example1.txt example2.txt example3.txt example4.txt example5.txt\ example6histogram.txt example6.txt\ example7.txt example8.txt example9.txt\ example10color.txt example10.txt\ example11.txt example12.txt example13.txt\ FEM.txt html_files = example1.html example2.html example3.html example4.html \ example5.html example6.html example6histogram.html \ example7.html example8.html example9.html example10.html \ example10color.html example11.html example12.html example13.html \ FEM.html logo.html eps_files = example1.eps example2.eps example3.eps example4.eps example5.eps\ example6.eps example6histogram.eps\ example7.eps example8.eps example9.eps example10.eps\ example10color.eps example11.eps example12.eps example13.eps\ FEM.eps logo.eps svg_files = example1.svg example2.svg example3.svg example4.svg example5.svg\ example6.svg example6histogram.svg\ example7.svg example8.svg example9.svg example10.svg\ example10color.svg example11.svg example12.svg example13.svg\ FEM.svg logo.svg png_files = FEM.png example1.png example2.png example3.png example4.png \ example5.png example6.png example6histogram.png \ example7.png example8.png example9.png example10.png \ example10color.png example11.png example12.png example13.png \ FEM-tiny.png example1-tiny.png example2-tiny.png example3-tiny.png \ example4-tiny.png example5-tiny.png example6-tiny.png \ example6histogram-tiny.png example7-tiny.png \ example8-tiny.png example9-tiny.png example10-tiny.png \ example10color-tiny.png example11-tiny.png example12-tiny.png \ example13-tiny.png logo.png EXTRA_DIST = \ example1.txt example2.txt example3.txt example4.txt example5.txt\ example6histogram.txt example6.txt\ example7.txt example8.txt example9.txt\ example10color.txt example10.txt\ example11.txt example12.txt example13.txt FEM.txt\ example1.gri example2.gri example3.gri example4.gri example5.gri\ example6.gri example6histogram.gri example7.gri example8.gri\ example9.gri example10.gri example10color.gri example11.gri\ example12.gri example13.gri\ FEM.gri logo.gri\ example1.dat example5.dat example6image.dat example6mask.dat\ example7a.dat example7b.dat example7c.dat example7d.dat example7e.dat\ example7f.dat example7g.dat \ example8a.dat example8b.dat \ example9a.dat example9b.dat\ example10.dat example11.dat\ example12.dat example13.dat\ FEM.pl \ model.elements model.nodes\ example1.ps example2.ps example3.ps example4.ps example5.ps \ example6.ps example6histogram.ps example7.ps example8.ps \ example9.ps example10.ps example10color.ps example11.ps \ example12.ps example13.ps \ logo.ps FEM.ps DISTCLEANFILES = $(png_files) $(eps_files) $(html_files) $(txt_files) $(svg_files) # Everything below this line is old, or is provide # for the developer's use only. GRITEST = ../../gri -directory ../.. -y GRI = gri -y -p all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/examples/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/examples/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf-am: ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am .PRECIOUS: Makefile %.svg : %.gri gri -output $@ $< %.txt : %.gri echo "$<" | cat >$@ chmod +w $@ %.eps : %.ps cp $< $@ chmod +w $@ %.png : %.ps -convert -strip -background white $< $@ %-tiny.png : %.png -convert -strip -background white -geometry 90x999 $< $@ %.pdf : %.ps convert $< $@ # ps2pdf $< $@ %.html : %.gri perl $(srcdir)/../gri2html $< $@ all: html png eps txt html: $(html_files) eps: $(eps_files) png: $(png_files) txt: $(txt_files) #%.ps : %.gri # $(GRI) $< old_all_target: ${MAKE} eps ${MAKE} html ${MAKE} png pdf: FEM.pdf example1.pdf example2.pdf example3.pdf example4.pdf \ example5.pdf example6.pdf example6histogram.pdf \ example7.pdf example8.pdf example9.pdf example10.pdf \ example10color.pdf example11.pdf example12.pdf example13.pdf logo.pdf ps: FEM.ps example1.ps example2.ps example3.ps example4.ps \ example5.ps example6.ps example6histogram.ps \ example7.ps example8.ps example9.ps example10.ps \ example10color.ps example11.ps example12.ps example13.ps logo.ps testps: $(GRITEST) FEM.gri $(GRITEST) example1.gri $(GRITEST) example2.gri $(GRITEST) example3.gri $(GRITEST) example4.gri $(GRITEST) example5.gri $(GRITEST) example6.gri $(GRITEST) example6histogram.gri $(GRITEST) example7.gri $(GRITEST) example8.gri $(GRITEST) example9.gri $(GRITEST) example10.gri $(GRITEST) example10color.gri $(GRITEST) example11.gri $(GRITEST) example12.gri $(GRITEST) example13.gri svg: $(svg_files) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gri/doc/examples/example5.dat0000644000175000017500000000066213147557614014621 0ustar psgpsg 3.05 0.55 11 5.25 0.30 14 9.33 0.65 12 3.85 1.20 17 5.65 1.25 17 7.25 1.05 16 0.10 1.90 34 2.30 2.25 27 3.85 2.45 24 4.52 2.40 25 6.55 2.45 24 7.85 2.52 21 8.90 2.52 16 10.55 2.70 17 2.15 3.17 27 3.40 3.67 25 0.00 4.20 9 2.55 4.30 28 4.97 4.35 27 7.70 4.02 19 6.80 5.45 23 10.80 5.05 29 3.47 5.95 28 7.75 6.45 18 9.50 6.55 22 0.95 7.00 7 2.70 6.90 16 5.88 6.80 22 3.10 8.10 17 5.62 8.30 18 9.05 7.85 19 gri/doc/examples/example4.gri0000644000175000017500000000117313147557614014627 0ustar psgpsg# Example 4 -- Simple contour graph # # Read x-grid; blank-line means stop reading. read grid x 0 .2 1 # Note that the x-grid was irregular. The y-grid # in this example is regular, so we can just set # it to range from 10 to 20, incrementing by 2.5. set y grid 10 20 2.5 # Thus we now have a grid 3 wide and 5 high. Let's # read the actual data now. read grid data 1 2 3 2 3 4 3 4 5 4 5 6 5 6 7 # Now draw contours (automatically set; we could # have done `draw contour 2' to draw contour fro # value 2 or `draw contour 1 10 2' to draw contours # ranging from 1 to 10 with an increment of 2.) draw contour draw title "Example 4" gri/doc/examples/example4.txt0000644000175000017500000000001513147557614014657 0ustar psgpsgexample4.gri gri/doc/examples/example10color.txt0000644000175000017500000000002313147557614015772 0ustar psgpsgexample10color.gri gri/doc/examples/example9.ps0000644000175000017500000035003713147557614014503 0ustar psgpsg%!PS-Adobe-2.0 EPSF-1.2 %%Creator: Gri2.12.2 (released 2002-nov-23). User=kelley, commandfile=example9 %%Title: example9.ps %%CreationDate: Thu Dec 5 19:21:17 2002 %%Pages: (atend) %%BoundingBox: (atend) %%TemplateBox: 0 0 612 792 %%DocumentFonts: (atend) %%Endcomments % NOTE: The Gri postscript dictionary is being converted to the Adobe % Illustrator 3.0 dialect of PostScript, as described in the Adobe % documents stored at URL % http://www.adobe.com/Support/TechNotes.html % (as of Jan 1996, this doc is number 5007). When the conversion % is complete, the Adobe Illustrator drawing program -- and any % program compatible with AI -- will be able to edit Gri output. % % The IslandDraw (TM) program is able to read Gri output % at this time; remarkably, it can read/edit arbitrary PostScript. % % The definitions below are presented in the same order as the Adobe % manual. The stack configuration before and after is shown in curly % brackets. All the operators are listed, but only some are defined % here. Most things are faithful, except that no distinction is made % between colors for stroking and filling paths. The string 'WRONGLY' % appears with commands that are approximations. % % PDF-style abbreviations: /rg {setrgbcolor} def % {red green blue} {-} set RGB color /RG {setrgbcolor} def % {red green blue} {-} set RGB color /q {gsave} def /Q {grestore} def /W {clip} def /W* {eoclip} def % % Gri-specific abbreviations: /hsb {sethsbcolor} def % {hue saturation brightness} {-} set HSB color % % Following all try to mimic Adobe Illustrator % % Mimicking section 5.1 of Adobe manual: %A % {flag A} {-} Determine whether % following object can % be selected. Flag=1 % prevents selection; % flag=0 allows it. % Mimicking section 5.2 of Adobe manual: %u % {u} {-} start group %U % end group %q % as 'u' but first item is a clip path %Q % as 'U' but first item is a clip path % Mimicking section 5.3 of Adobe manual: /g {setgray} def % {gray g} {-} Set gray for fill % path, WRONGLY used % for stroking also. /G {setgray} def % As 'g', but for filling path. %k % Set cmyk color for filling path. %K % As 'k', but for stroking path. %x % Set cmyk custom color for filling path. %X % As 'x' but for stroking path. %p % Define pattern for filling path. %P % As 'p' but for stroking path. %O % Specify whether overprinting for fill paths %R % As 'O' but for stroking path. % Mimicking section 5.4 of Adobe manual: /d {setdash} def % {[array] phase d} {-} Set dash. /i {setflat} def % {flatness i} {-} Set flatness. /j {setlinejoin} def % {linejoin j} {-} Set line join. /J {setlinecap} def % {linecap J} {-} Set line cap. /M {setmiterlimit} def % {miterlimit M} {-} Set miter limit. /w {setlinewidth} def % {linewidth w} {-} Set line width. % Mimicking section 5.5 of Adobe manual: /m {moveto} def % {x y m} {-} Move to locn /l {lineto} def % {x y l} {-} Draw line to locn % not a smooth point. % WRONGLY, no % distinction is made % between smooth and % corner. %L % {x y L} {-} As 'l' but a corner %c % Bezier curve to smooth point. %C % As 'c' but to corner point. %v % Something else to do with Bezier. %V % %y % %Y % % Mimicking section 5.6 of Adobe manual: %N % {N} {-} As 'n' for nondrawn stuff /n {newpath} def % {n} {-} WRONGLY interpreted % as path constructor /F {fill} def % {F} {-} Fill current path. %f % {f} {-} 'F' but close first /S {stroke} def % {S} {-} Stroke current path. %s % {s} {-} 'S' but close first %B % {B} {-} As 's' but don't empty path. %b % {b} {-} As 'f' but don't empty path. %H % no-op (weird huh?) /h {closepath} def % {h} {-} Close current path %W % Used to create masks. % Mimicking section 5.7 of Adobe manual: %a % Begin text block ... %e % Similar to 'a' but ... %I % Similar to 'a' but ... %o % Similar to 'a' but ... %r % Similar to 'a' but ... %t % {len (string) t} {-} Render string. %T % End block of text % That's the end of the Illustrator stuff. Following are some Gri % definitions which provide a temporary way of handling fonts. /sf {setfont} def % {fontname sf} {-} Set font name. /sh {show} def % {(text) sh} {-} Show text. /sc {scalefont} def % {size sc} {-} Scale font. % Gri items which should be translated to Illustrator format: /rl {rlineto} def /rm {rmoveto} def % Procedures /cimdict 7 dict def /cim { cimdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def q xll yll translate xur xll sub yur yll sub scale /do cl 3 mul string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop} false 3 colorimage Q end } def /imdict 14 dict def /im { imdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def /imagemap exch def q % Until version 2.6.0 used a 'settransfer' here, but that % triggers a bug in ps2pdf xll yll translate xur xll sub yur yll sub scale /do cl string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop dup length 1 sub 0 1 3 -1 roll { 1 index exch 2 copy get imagemap exch get 255 mul cvi put } for }image Q end } bind def /frdict 5 dict def /fr { frdict begin /yt exch def /xr exch def /yb exch def /xl exch def n xl yb m xl yt l xr yt l xr yb l h F n end } def /plusdict 3 dict def /_plus { plusdict begin dup 0.5 mul /t0 exch def /t1 exch def 0 t0 rm 0 t1 neg rl t0 neg t0 rm t1 0 rl t0 neg 0 rm end } def /timesdict 3 dict def /_times { timesdict begin dup 0.353553 mul /t0 exch def 0.707106 mul /t1 exch def t0 neg t0 rm t1 dup neg rl t1 neg 0 rm t1 dup rl t0 neg dup rm end } def /boxdict 3 dict def /_box { boxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm end } def /filledboxdict 3 dict def /_filledbox { filledboxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm F end } def /diamonddict 2 dict def /_diamond { diamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm end } def /filleddiamonddict 2 dict def /_filleddiamond { filleddiamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm F end } def /triangleupdict 5 dict def /_triangleup { triangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm end } def /filledtriangleupdict 5 dict def /_filledtriangleup { filledtriangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm F end } def /trianglerightdict 5 dict def /_triangleright { trianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm end } def /filledtrianglerightdict 5 dict def /_filledtriangleright { filledtrianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm F end } def /triangledowndict 5 dict def /_triangledown { triangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm end } def /filledtriangledowndict 5 dict def /_filledtriangledown { filledtriangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm F end } def /triangleleftdict 5 dict def /_triangleleft { triangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm end } def /filledtriangleleftdict 5 dict def /_filledtriangleleft { filledtriangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm F end } def /circdict 5 dict def /_circ { circdict begin 0.5 mul /t0 exch def currentpoint /t2 exch def /t1 exch def S n t1 t2 t0 0 360 arc t1 t2 m end } def /bulldict 3 dict def /_bull { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 360 arc h F S end } def /filledhalfmoonupdict 3 dict def /_filledhalfmoonup { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 180 arc h F S end } def /filledhalfmoondowndict 3 dict def /_filledhalfmoondown { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 180 360 arc h F S end } def 1 1 scale 10.0 M 1 j /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-ISOLatin1 exch definefont pop /Courier-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Oblique-ISOLatin1 exch definefont pop /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Bold-ISOLatin1 exch definefont pop /Courier-BoldOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-BoldOblique-ISOLatin1 exch definefont pop /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-ISOLatin1 exch definefont pop /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Bold-ISOLatin1 exch definefont pop /Helvetica-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Oblique-ISOLatin1 exch definefont pop /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Roman-ISOLatin1 exch definefont pop /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Italic-ISOLatin1 exch definefont pop /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Bold-ISOLatin1 exch definefont pop /Palatino-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-BoldItalic-ISOLatin1 exch definefont pop /Symbol findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Symbol-ISOLatin1 exch definefont pop /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Roman-ISOLatin1 exch definefont pop /Times-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Italic-ISOLatin1 exch definefont pop /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Bold-ISOLatin1 exch definefont pop /Times-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-BoldItalic-ISOLatin1 exch definefont pop %%EndProlog %%Page: 1 1 /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:# Gri was invoked by user named %gri:# kelley %gri:# on host named %gri:# kelley-home %gri:# using the command %gri:# gri example9 %gri:# at local time Thu Dec 5 19:21:17 2002. %gri:# Example 9 -- Plot dTdrho-rho section %gri: %gri:`Initialize Parameters' %gri:{ %gri: \FILE_DATA = "example9a.dat" # T vs rho %gri: \FILE_LOCN = "example9b.dat" # section distances %gri: # %gri: # Following values from ~/eubex/processing/to_rho_bins/do_rho_inter %gri: \RHO_MIN = "28.1" %gri: \RHO_MAX = "27.5" %gri: \RHO_INC = "-0.002" %gri: \NY = "301" %gri: set missing value -99.0 %gri: \xmin = "350" %gri: \xmax = "0" %gri: \xinc = "-100" %gri: \ymin = "28.1" %gri: \ymax = "27.8" %gri: \yinc = "-0.1" %gri: \zmin = "-10" # black %gri: \zmax = "0" # white %gri:} %gri:`Initialize Axes' %gri:Set up axes. %gri:{ %gri: set x name "km" %gri: set x size 10 %gri: set x axis \xmin \xmax \xinc %gri: set y size 5 %gri: set y name "$\sigma_T$" %gri: set y axis name horizontal %gri: set y axis \ymin \ymax \yinc %gri: set y format %.1lf %gri: draw axes none %gri:} %gri:`Initialize Files' %gri:{ %gri: query \data "Data file? " ("\FILE_DATA") %gri: query \locn "Station locn?" ("\FILE_LOCN") %gri:} %gri:`Read Data' %gri:{ %gri: # Read x-locations %gri: system awk '{print $2}' < \locn > TMP %gri: system wc TMP | awk '{print $1}' > NUM %gri: open NUM %gri: read .gridx_number. %gri: close %gri: system rm NUM %gri: open TMP %gri: read grid x .gridx_number. %gri: close %gri: system rm TMP %gri: # Create y-locations %gri: set y grid \RHO_MIN \RHO_MAX \RHO_INC %gri: # %gri: # Read data %gri: open \data %gri: read grid data \NY .gridx_number. %gri: close %gri:} %gri:Initialize Parameters %gri:Initialize Axes %gri:Initialize Files %gri:Read Data %gri:set image range \zmin \zmax %gri:set image colorscale hsb 0 1 1 \zmin hsb .6 1 1 \zmax %gri:convert grid to image box \xmin \ymin \xmax \ymax %gri:# %gri:# Draw the image, then draw the axes. Note that the image has %gri:# extends beyond the axes frame, so we will turn clipping %gri:# on before drawing it, to make a clean picture. %gri:set clip postscript on %^ scale 1 170.7 350 -0.812857 1 170.7 28.1 -474.167 q n 170.700000 170.700000 moveto 455.200000 170.700000 lineto 455.200000 312.950000 lineto 170.700000 312.950000 lineto h W n % turn clipping on %gri:draw image %^ scale 1 170.7 350 -0.812857 1 170.7 28.1 -474.167 %BEGIN_IMAGE 169.579921 170.139961 456.320079 313.510039 128 128 cim FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0098FF00CAFF00F9FF00FFD100FFA300FFBF00FFDC00FFF5 00EBFF00CEFF00B5FF0098FF007BFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0086FF00BCFF00D5FF00A6FF0077FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0070FF007BFF0082FF008DFF0094FF009FFF00AAFF00B1FF00BCFF00C3FF00CEFF00D9FF 00E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0070FF008AFF00A3FF00BCFF00D5FF00EEFF00FFF200FFD9FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF007BFF00B5FF00EEFF00FFD900FFEE00F6FF00E0FF00C7FF00B1FF0098FF 0082FF006DFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0069FF00A6FF00E0FF00FFE400FFAA00FF70FFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF009FFF00E0FF00FFDC 00FF9C00FF5B00FF1A26FF0060FF0038FF0010FF0000FF1A00FF4100FF6D00FF9400FFBC00FFE7 00EEFF00C7FF009CFF0074FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0091FF00D9FF00FFE000FF9CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF00B8FF00FFC7 00FF4538FF00AFFF008EFF0072FF0051FF0034FF0014FF0000FF0800FF2800FF4500FF6500FF82 00FFA300FFBF00FFE000FFFD00E0FF00C3FF00A3FF0086FF0069FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0069FF 0091FF00BCFF00E4FF00FFF200FFC700FF9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0070FF 00D5FF00FFC700FF6500FF0460FF00C1FF00FFDB00FF7A00FF1500FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF5D00E8FF0031FF0000FF8200C3FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFF007FFF0074FF006DFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFF00FF8600FF9C00FFAD00FFBF00FFD500FFE700FFFD00EEFF00D9FF00C7FF00B1FF009FFF 008AFF0077FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0086FF00A6FF00AAFF00ADFF00B1FF00B5FF00B8FF 00BCFF00C3FF00C7FF00CAFF00CEFF00D1FF00D5FF00D9FF00DCFF00E0FF00E4FF00E7FF00EBFF 00EEFF00F2FF00F9FF00FDFF00FFFD00FFF900FFF500FFF200FFEE00FFEB00FFF500D9FF00AAFF 007FFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0077FF0091FF00ADFF00CAFF 00E4FF00FFFD00FFE000FFC700FFAA00FF9400FFEB00BCFF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF008AFF00B5FF00DCFF00FFF500FFCE00FFA300FF77 00FF5000FF2502FF002AFF0002FF0000FF2500FF4900FF7000FF9400FFBC00FFE000F6FF00D1FF 00AAFF0086FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0094FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 006DFF00A3FF00D9FF00FFF200FFBC00FF8600FF5400FF1D10FF0000FF0F00FF3300FF5700FF7B 00FF9C00FFBF00FFE400F6FF00D5FF00B1FF008DFF0069FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0082FF009FFF00BCFF00DCFF00F9FF00FFE400FFC700FFD90098FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF009CFF00FFD900FF54 31FF00B6FF00FFBE00FF3900FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF2E00 FF8800FFE600BDFF0060FF0006FF0000FF5700FFB100EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0069FF0077FF0082FF0091FF009CFF00A6FF00B5FF00C0FF00CEFF00D9FF00E7FF 00F2FF00FDFF00FFF200FFE700FFE000FFD900FFCE00FFC700FFBF00FFB800FFB100FFA600FF9F 00FF9800FF9100FF8900FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0069FF0098FF00C7FF00F6FF00FFD500FFA600FF7700FF4900FF1614FF0022FF00 31FF003FFF004EFF0058FF0067FF0075FF0084FF0092FF009DFF00ABFF00BAFF00C8FF00D6FF00 E5FF00F0FF00FEFF00FFF100FFE200FFD400FFC500FFBB00FFAC00FF9E00FF8F00FF8100FF7300 FF6800FFA90055FF0000FFAA0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0094FF00C7FF00F6FF00FFD500FFA3 00FF7000FF3E00FF0C26FF0055FF0087FF00BAFF00E8FF00F3FF00FAFF00FFF800FFED00FFE600 FFDB00FFD400FFC900FFC200FFB700FFAC00FFA500FF9A00FF9300FF8800FF7E00FF7600FF6B00 FF6400FF5900FF5200FF4700FF3D00FF3500FF2B00FF2300FF1900FF1100FF3200FFC200ABFF00 1BFF0000FF7400F6FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF007FFF00BCFF00FDFF00FFC300FF8600FF49 00FF0C31FF0072FF00AFFF00ECFF00FFD400FF9700FF5900FF1C00FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF3900FFD70087FF0000FF16 00FFB500AAFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF9C00FFA300FFA600FFAD00FFB1 00FFB500FFBC00FFBF00FFC700FFCA00FFCE00FFD500FFD900FFE000FFE400FFEB00FFEE00FFF2 00FFF900FFFD00F9FF00F6FF00F2FF00EBFF00E7FF00E0FF00DCFF00D5FF00D1FF00CEFF00C7FF 00C3FF00BCFF00B8FF00B5FF00ADFF00AAFF00A3FF009FFF009CFF0094FF0091FF008AFF0086FF 007FFF007BFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF008AFF00D5FF 00FFD900FF8D00FF3E10FF005CFF00ABFF00BAFF002AFF0000FF6200FFEE0082FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF007BFF0094FF00ADFF00B8FF009CFF007BFF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0086FF00AAFF00CAFF00EBFF00FFEE00FFCE00FFAD 00FFAD00FFAD00FFAA00FFAA00FFAA00FFAA00FFA600FFA600FFA600FFA600FFA600FFA300FFA3 00FFA300FFA300FF9F00FF9F00FF9F00FF9F00FF9C00FF9C00FF9C00FF9C00FF9800FF9800FF98 00FF9800FF9400FFAD00FDFF00AAFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF009CFF00D1FF00FFF500FFBF00FF8900FF5000FF1A1BFF0051FF0087FF00C1FF00 E5FF00E8FF00E8FF00E8FF00E8FF00E8FF00E8FF00ECFF00ECFF00ECFF00ECFF00ECFF00F0FF00 F0FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 51FF0055FF005CFF0060FF0067FF006AFF0072FF0075FF0079FF0080FF0084FF008BFF008EFF00 96FF0099FF00A0FF00A4FF00ABFF00AFFF00B6FF00BAFF00C1FF00C4FF00CCFF00CFFF00D3FF00 DAFF00DEFF00E5FF00E8FF00F0FF00F3FF00FAFF00FEFF00FFF800FFF400FFED00FFE900FFE200 FFDF00FFDB00FFD400FFD000FFC900FFC500FFBE00FFC200FFCD00FFD700FFE200FFED00FFF800 FAFF00F0FF00E5FF00DAFF00CFFF00C4FF00BAFF00AFFF00A4FF0099FF008EFF0084FF0079FF00 6EFF0063FF0058FF004EFF0043FF0038FF002DFF0022FF001BFF003FFF0067FF008BFF00AFFF00 D6FF00FAFF00FFDF00FFB700FF9300FF6F00FF4700FF2300FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF5600FFC200CFFF0063FF0000FF0400FF7000FFDC00B8FFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0700FF1500FF2700FF3500FF4700FF5600FF6400 FF7600FF8500FF9300FFA500FFB300FFA900FF8800FF6B00FF4F00FF2E00FF1100FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF3900FF9700FFF400ABFF0051FF0000FF0C00FF6900FFC700DCFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8800FF9300FF9E00FFA900 FFB000FFBB00FFC500FFD000FFDB00FFE600FFED00FFF800FAFF00F0FF00E5FF00DAFF00D3FF00 C8FF00BDFF00B2FF00A8FF009DFF0096FF008BFF0080FF0075FF006AFF0063FF0058FF004EFF00 43FF0038FF002DFF0026FF001BFF0010FF0006FF0000FF0400FF0F00FF1600FF2100FF2C00FF37 00FF4100FF4C00FF5400FF5700FF5000FF4C00FF4500FF4100FF3A00FF3700FF2F00FF2C00FF25 00FF2100FF1A00FF1600FF0F00FF0C00FF0400FF0106FF0009FF0010FF0014FF001BFF001FFF00 26FF002AFF0031FF0034FF0038FF0009FF0000FF2800FF5700FF8900FFB800FFEB00E4FF00B1FF 0082FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF007FFF00D5FF00FFD5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0300FF4B00FF9300FFD700DEFF0099FF0051FF0009FF0000FF3A00FF8200FFC7 00EEFF00A6FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FF0300FF2300FF4700FF6800FF8C00FFAC00 FFD000FFF100ECFF00C8FF00A8FF0084FF0063FF003FFF001FFF0000FF0100FF2500FF4500FF69 00FF8900FFAD00FFCE00FFEE00EBFF00CAFF00A6FF0086FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0070FF008DFF00AAFF00C7FF00E7FF00FFF900FFDC00FFBF 00FFA600FFB800FFC700FFD900FFE700FFF900F6FF00E4FF00D5FF00C3FF00B5FF00A3FF0094FF 0082FF0070FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF008AFF00B5FF00DCFF00FFF5 00FFCE00FFA300FF7700FF50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF00FFF500FF4C5CFF00FFF800FF4F00 FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0070FF009FFF00D1FF00FFFD00FFCE00FF9F00FF70 00FF4100FF131BFF004EFF007CFF00ABFF00DAFF00FFF400FFC500FF9A00FFA900FFB300FFC200 FFD000FFDF00FFED00FFFC00F3FF00E5FF00D6FF00C8FF00BAFF00ABFF009DFF008EFF0080FF00 75FF0067FF0058FF004AFF003BFF002DFF001FFF0010FF0002FF0000FF0C00FF1A00FF2800FF08 8BFF00FFDF00FF4F00FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0082FF00A6FF00CAFF00EEFF00FFEE00FFCA 00FFA600FF8200FF6200FF3E00FF1A09FF002AFF004AFF003FFF0031FF0026FF0018FF000DFF00 00FF0100FF0F00FF1A00FF2800FF3300FF4100FF4C00FF5B00FF6500FF7400FF7F00FF8D00FF9C 00FFA600FFB500FFBF00FFCE00FFD900FFE700FFF200FDFF00EEFF00E4FF00E7FF00FFEB00FFBC 00FF9100FF6500FF3A00FF0C1FFF004AFF0079FF00A4FF00CFFF00FAFF00FFD400FFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0069FF007BFF008AFF009CFF00ADFF 00C0FF00CEFF00E0FF00F2FF00FFF900FFE700FFD900FFC700FFB500FFA300FF9400FF8200FF70 00FF5E00FF4C00FF3E00FF2C00FF1A00FF0810FF002DFF0046FF0063FF007CFF0099FF00B2FF00 CFFF00E8FF00FFF800FFDF00FFC200FFA900FF8C00FF7300FF5600FF3D00FF2000FF0700FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF1100FF2700FFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0070FF007FFF008DFF009CFF00AAFF00B8FF00C3FF00D1FF 00E0FF00EEFF00FFF900FFE000FFC700FFAA00FF9100FF7700FF5E00FF4500FF2800FF0F09FF00 22FF003FFF0058FF0072FF008BFF00A4FF00C1FF00DAFF00F3FF00FFF100FFD400FFBB00FFA100 FF8800FF6F00FF5200FF3900FF2E00FF2000FF1500FF0700FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF2B00FF5900FF8800FFBB00FFE900E5FF00B6FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0070FF007BFF008AFF0098FF00A3FF 00ADFF00B1FF00B8FF00BCFF00C3FF00C7FF00CEFF00D1FF00D9FF00E0FF00E4FF00EBFF00EEFF 00F6FF00F9FF00FFFD00FFF900FFF200FFEB00FFE700FFE000FFDC00FFD500FFD100FFCA00FFC3 00FFBF00FFB500FF5E00FF084EFF00A4FF00FAFF00FFAC00FF5900FF0300FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF3900FFCD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF008DFF00B5FF00DCFF00FFF9 00FFD100FFAA00FF8200FF5B00FF3300FF0C1BFF003FFF0067FF008EFF00B6FF00DEFF00FFF800 FFD000FFA900FF8100FF5900FF3200FF0A00FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF1500FF2E00FF4700FF6100FF7A00FF9300FFAC00 FFC900FFE200FFFC00E8FF00CFFF00B6FF009DFF0084FF006AFF004EFF0034FF001BFF0006FF00 14FF0022FF0031FF003FFF004EFF005CFF006AFF0079FF0087FF0092FF00A0FF00AFFF00BDFF00 CCFF00DAFF00E8FF00F7FF00FFF800FFE900FFDB00FFCD00FFBE00FFB000FFA100FF9300FF8500 FF7600FF6800FF5900FF4700FF3900FF2700FF1900FF0700FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF007BFF0077FF0074FF0070FF006DFF0069FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0082FF00AAFF00D1FF00F9FF00FFDC00FFB500FF9100FF6900FF4100FF1A0DFF0034FF005CFF00 80FF00A8FF00CFFF00F7FF00FFDF00FFB700FF9300FF6B00FF4400FF1C00FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 6AFF0058FF0046FF0031FF001FFF000DFF0000FF0400FF1600FF2800FF3A00FF4C00FF6200FF74 00FF8600FF9800FFAA00FFBC00FFCE00FFE000FFF500F6FF00E4FF00D1FF00C0FF00ADFF009CFF 0086FF0074FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0069FF007FFF0091FF 00A6FF00B8FF00CEFF00E0FF00F6FF00FFF500FFE000FFCE00FFB800FF8900FF5E00FF2F00FF01 2AFF0058FF0087FF00B2FF00E1FF00FFF100FFC200FF9300FF6800FF3900FF0E00FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0A00FF4700FF8500FFBE00FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1FFF0014FF00 09FF0000FF0100FF0C00FF1A00FF2500FF2F00FF3A00FF4900FF5400FF5E00FF6900FF7700FF82 00FF8D00FF9800FFA600FFB100FFBC00FFC700FFD100FFE000FFEB00FFF500FDFF00EEFF00E4FF 00D9FF00CEFF00C0FF00B5FF00AAFF009FFF0091FF0086FF007BFF0070FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF006DFF0074FF007FFF0086FF008DFF0094FF009CFF00A3FF00AAFF 00B1FF00BCFF00C3FF00CAFF00D1FF00D9FF00E4FF00FFF900FFD500FFB100FF8D00FF6900FF49 00FF2500FF0122FF0043FF0067FF008BFF00AFFF00D3FF00F3FF00FFE600FFC200FF9E00FF7E00 FF5900FF3500FF1100FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0069FF0077FF 008AFF0098FF00AAFF00B8FF00C3FF00D1FF00DCFF00EBFF00F6FF00FFF900FFEE00FFE000FFD5 00FFC700FFBC00FFAD00FFA300FF9400FF8900FF7B00FF7000FF6200FF5700FF4900FF3E00FF2F 00FF2500FF1600FF0C02FF000DFF001BFF002DFF003BFF004AFF0058FF0067FF0075FF0084FF00 92FF00A0FF00AFFF00BDFF00CCFF00DEFF00ECFF00FAFF00FFF400FFE600FFD700FFC900FFBB00 FFAC00FF9E00FF8F00FF8100FF7300FF6100FF5200FF4000FF2300FF0700FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0082FF009CFF 00B5FF00D1FF00EBFF00FFF900FFE000FFC300FFAA00FF9100FF7400FF5B00FF4100FF2800FF0C 0DFF0026FF003FFF005CFF0075FF008EFF00ABFF00C4FF00DEFF00F7FF00FFE900FFD000FFB700 FF9A00FF9700FFA100FFA900FFB300FFBE00FFC500FFD000FFD700FFE200FFED00FFF400FEFF00 F7FF00ECFF00E5FF00DAFF00CFFF00C8FF00BDFF00B6FF00ABFF00A0FF0099FF008EFF0087FF00 7CFF0072FF0072FF00F3FF00FF8C00FF0E00FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF006DFF 0094FF00B8FF00E0FF00FFF900FFD100FFAD00FF8900FF6200FF3E00FF160DFF0034FF0058FF00 7CFF00A4FF00C8FF00F0FF00FFE900FFC200FF9E00FF7A00FF5200FF2E00FF0700FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0E00FF2300FF3D00FF5200 FF6800FF5900FF4F00FF4000FF3500FF2B00FF1C00FF1100FF0300FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFDB00FFBB00FF9E00FF7E00FF5D00FF4000FF2000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0E00FF2000FF3200FF4400FF5600FF6800FF7A00FF8C00FF9E00 FFB000FFB000FF7E00FF4F00FF2000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0A00FF2300FF3D00FF5600FF6F00FF8800FFA500FFBE00FFD700FFF100F3FF00D6FF00C8FF00 CCFF00D3FF00D6FF00DEFF00E1FF00E8FF00ECFF00F3FF00F7FF00FEFF00FFFC00FFF400FFED00 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0E00FF4400 FF7A00FFB000FFE600E1FF00ABFF0075FF003FFF0009FF0000FF2C00FF6200FF9800FFCE00F9FF 00C3FF008DFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0074FF00B8FF00FDFF00FFBC00FF74 00FF2F14FF0058FF009DFF00E1FF00FFD700FF9300FF4F00FF0A00FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0700FF1900FF2B00FF3D00 FF5200FF6400FF7600FF8C00FFBB00C8FF004EFF0000FF2C00FFA300E0FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0069FF0091FF00B8FF00E0FF00FFF500FFCE00FFA600FF7F00FF5700FF2F00FF0422FF00 4AFF0072FF0099FF00C1FF00E8FF00FFED00FFC500FF9E00FF7600FF4F00FF2700FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0300FF2300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF007BFF0094FF00B1FF00CAFF00DCFF00EBFF00F6FF00FFFD 00FFEE00FFE400FFD900FFCA00FFBF00FFB500FFA600FF9C00FF9100FF8200FF7700FF6D00FF62 00FF5400FF4900FF3E00FF2F00FF2500FF1A00FF0C00FF0109FF0018FF0022FF0034FF0046FF00 58FF0067FF0079FF008BFF009DFF00AFFF00BDFF00CFFF00E1FF00F3FF00FFF800FFE900FFD700 FFC500FFB300FFA100FF8F00FF8100FF6F00FF5D00FF4B00FF3900FF2B00FF1900FF0700FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF007BFF0091FF00A6FF00BCFF00D5FF 00EBFF00FFFD00FFE700FFD100FFB800FFA300FF8D00FF8900FF9100FF9800FF9F00FFA600FFB1 00FFB800FFBF00FFC700FFCE00FFD500FFDC00FFE700FFEE00FFF500FFFD00F9FF00F2FF00EBFF 00E0FF00D9FF00D1FF00CAFF00C3FF00BCFF00B5FF00AAFF00A6FF00C3FF00DCFF00F9FF00FFE7 00FFCE00FFB100FF9400FF7B00FF5E00FF4100FF2800FF0C10FF002DFF0046FF0063FF0080FF00 99FF00B6FF00D3FF00ECFF00FFF400FFD700FFBE00FFA100FF8500FF6800FF4F00FF2000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0082FF00A3FF00C7FF00E7FF00FFF200FFD100FFAD00FF8D 00FF6900FF4900FF2500FF011FFF002DFF002DFF002DFF002DFF002DFF002DFF002DFF002DFF00 2DFF002DFF002DFF002DFF002DFF002DFF002DFF002DFF002DFF002DFF002DFF002DFF0031FF00 31FF0031FF0031FF0031FF0031FF0031FF0031FF0034FF003BFF0043FF0046FF004EFF0051FF00 58FF0060FF0063FF006AFF006EFF0075FF0079FF0080FF0087FF008BFF0092FF0096FF009DFF00 A4FF00A8FF00AFFF00B2FF00BAFF00BDFF00C4FF00CCFF00CFFF00E5FF00FFE200FFA900FF6F00 FF3500FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF4900FF4900FF4900FF49 00FF4900FF4900FF4900FF4900FF4900FF4900FF4900FF4900FF4900FF4900FF4900FF4900FF49 00FF4900FF4C00FF4C00FF4C00FF4C00FF4C00FF4C00FF4C00FF4C00FF4C00FF4C00FF4C00FF4C 00FF4C00FF4C00FF4C00FF4C00FF4C00FF4C00FF4C00FF4C00FF4C00FF4C00FF4C00FF4C00FF4C 00FF4C00FF4C00FF4C00FF5000FF5400FF5B00FF5E00FF6200FF6900FF6D00FF7000FF7700FF7B 00FF7F00FF8200FF8900FF8D00FF9100FF9800FF9C00FF9F00FFA600FFAA00FFAD00FFB100FFB8 00FFBC00FFBF00FFC700FFCA00FFCE00FFCE00FFCE00FFCE00FFCE00FFCE00FFCE00FFCE00FFCE 00FFCE00FFCE00FFCE00FFCE00FFCE00FFCE00FFCE00FFD100FFD100FFD100FFD100FFD100FFD1 00FFD100FFD100FFD100FFD100FFD100FFD100FFD100FFB500FF540DFF0072FF00D3FF00FFC900 FF6800FF0700FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00D5FF00D9FF00DCFF00DCFF00E0FF00E0FF 00E4FF00E4FF00E7FF00E7FF00EBFF00EBFF00EEFF00EEFF00F2FF00F2FF00F6FF00F6FF00F9FF 00F9FF00FDFF00FDFF00FFFD00FFFD00FFF900FFF900FFF500FFF500FFF200FFF200FFEE00FFEE 00FFEB00FFEB00FFE700FFE700FFE400FFE400FFE000FFE000FFDC00FFDC00FFD900FFD900FFD5 00FFD500FFCE00FFC700FFBC00FFB500FFAD00FFA600FF9C00FF9400FF8D00FF8200FF7B00FF74 00FF6D00FF6200FF5B00FF5400FF4900FF4100FF3A00FF3300FF2800FF2100FF1A00FF0F00FF08 00FF0106FF0010FF0022FF0031FF0043FF0055FF0067FF0079FF008BFF0099FF00ABFF00BDFF00 CFFF00E1FF00F0FF00FFFC00FFE900FFD700FFC500FFB700FFA500FF9300FF8100FF6F00FF6100 FF4F00FF3D00FF2B00FF1900FF0A00FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF008AFF00AAFF 00CEFF00F2FF00FFE700FFC300FF9F00FF7B00FF5700FF3300FF1310FF0034FF0058FF007CFF00 A0FF00C4FF00E8FF00FFF100FFD000FFAC00FF8800FF6400FF4000FF1C00FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF1900FF1100FF0A00FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0E00FF6B00FFC200FFA900FF8F00FF7600FF5D00FF4400FF2700FF0E00 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0069FF0077FF0082FF008DFF009CFF00A6FF00B1FF00C0FF00CAFF00D9FF 00FFEB00FF9400FF3E18FF006EFF00C4FF00FFE200FF8C00FF3500FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF3200FF6F00FF7E00FF1C00FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0077FF00A6FF00D9FF00FFF200FFBF00FF9100FF5E00FF2C06FF0038FF0067FF00 75FF0084FF0092FF00A0FF00AFFF00BDFF00CCFF00DAFF00E8FF00F7FF00FFF800FFE900FFDB00 FFCD00FFBE00FFB000FFA100FF9300FF8500FF7600FF6800FF5900FF4B00FF3D00FF2E00FF2000 FF0E00FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF007FFF00A6FF00CEFF00F6FF 00FFE000FFB800FF9400FF6D00FF4500FF1D09FF002DFF0055FF007CFF00A0FF00A0FF00A4FF00 A4FF00A4FF00A4FF00A4FF00A8FF00A8FF00A8FF00A8FF00A8FF00ABFF00ABFF00ABFF00ABFF00 ABFF00AFFF00AFFF00AFFF00AFFF00B2FF00B2FF00B2FF00B2FF00B2FF00B6FF00B6FF00B6FF00 C4FF00F0FF00FFDF00FFB300FF8500FF5900FF2B00FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0082FF00AAFF00CEFF 00F2FF00FFE700FFC300FF9F00FF7700FF5400FF2F00FF0C18FF003BFF0060FF0087FF00ABFF00 CFFF00F3FF00FFE600FFC200FF9E00FF7600FF5200FF2E00FF0A00FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0086FF00ADFF00D9FF00FFF9 00FFCE00FFA300FF7700FF5000FF2506FF0031FF005CFF0087FF00AFFF00DAFF00FFF800FFCD00 FFA100FF7600FF4F00FF2300FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0300FF0A00FF1100FF1900FF1C00 FF2300FF2B00FF3200FF3500FF3D00FF4400FF4B00FF4F00FF5600FF5600FF4000FF2E00FF1900 FF0700FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0069FF006DFF0074FF0077FF007FFF0082FF008AFF008DFF 0094FF0098FF009CFF00A3FF00A6FF00ADFF00B1FF00B8FF00BCFF00C3FF00C7FF00CEFF00D1FF 00D5FF00DCFF00E0FF00E7FF00EBFF00F2FF00F6FF00FDFF00FFFD00FFF500FFF200FFEE00FFE7 00FFE400FFDC00FFD900FFE700FDFF00E0FF00C3FF00AAFF008DFF0074FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0070FF00A3FF00D1FF00FFFD00FFCE00FF9F00FF7000FF4100FF131BFF00 4AFF0079FF00A8FF00D6FF00FFF800FFC900FF9A00FF6400FF2300FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF2300FF5200FF8100FFB000FFDF00F0FF00C1FF0092FF0063FF0034FF00 06FF0000FF2500FF5400FF8200FFB100FFE000EEFF00C0FF0091FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0082FF 009FFF00C0FF00DCFF00FDFF00FFE400FFC300FFA600FF8600FF6900FF4900FF2C00FF0C10FF00 31FF004EFF006EFF008BFF00ABFF00CCFF00F3FF00FFE200FFBB00FF9300FF6B00FF4700FF2000 FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF2300FF6100FF9E00FFD700E8FF00 AFFF00A4FF009DFF0092FF0087FF0080FF0075FF006AFF0063FF0058FF004EFF0043FF003BFF00 31FF0026FF001FFF0014FF0009FF0002FF0000FF0800FF1300FF1A00FF2500FF2F00FF3700FF41 00FF4C00FF5700FF5E00FF5B00FF3300FF0C1BFF0043FF006AFF0092FF00BAFF00E1FF00FFF400 FFCD00FFA500FF7E00FF5600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF5200FFC200ECFF00 FEFF00FFF100FFE200FFD400FFC200FFB300FFA500FF9700FF8500FF7600FF6800FF5600FF4700 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2300FF1C00FF1500FF0E00FF0700 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0300FF1C00FF3900 FF5600FF6F00FF8C00FFA500FFC200FFDF00FFF800E8FF00CFFF00CFFF00FFE200FF9700FF4B00 FF0300FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0700FF1C00FF2E00FF4400FF5600FF6800FF7E00FF8F00FFA500FFB700FFC900FFD400 FFBE00FFAC00FF9A00FF8800FF7600FF6400FF4F00FF3D00FF2B00FF1900FF0700FF0000FF0000 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0A00FF2B00FF1500FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0300FF1C00 FF3500FF5200FF6B00FF8500FF9E00FFB700FFD400FFED00F7FF00DEFF00C1FF00D3FF00F7FF00 FFDF00FFB700FF8F00FF6800FF4000FF1900FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFF00FF4500FF3E00FF3700FF2F00FF2800FF2100FF1A00FF0F00FF0800FF0106FF00 0DFF0014FF001BFF0022FF002AFF0031FF0038FF0043FF004AFF0051FF0058FF0060FF0067FF00 6EFF0075FF007CFF0084FF008BFF0096FF009DFF00A4FF00ABFF00B2FF00BAFF00C1FF00C8FF00 CFFF00D6FF00DEFF00E8FF00F0FF00F7FF00FEFF00FFF800FFF100FFD400FFA900FF7E00FF5200 FF2700FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0077FF008DFF00A3FF00B8FF00CEFF00E4FF00F9FF00FFEE00FFD9 00FFC300FFAD00FF9800FF8200FF6D00FF5700FF4100FF2C00FF1600FF0114FF002AFF003FFF00 55FF006AFF0080FF0096FF00ABFF00C1FF00D6FF00ECFF00FFFC00FFE600FFD000FFBB00FFA500 FF8F00FF7A00FF6400FF5200FF4000FF3200FF2000FF1100FF0300FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22FF0060FF00 A0FF00DEFF00FFE200FFA500FF6800FF2B00FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFF %END_IMAGE %gri:set clip postscript off S Q % turn clipping off %gri:draw axes % gr_show_at() BEGIN 0 g 0 G 201.3 149.9 m (300) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 282.6 149.9 m (200) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 363.9 149.9 m (100) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 451.9 149.9 m (0) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 211.34 170.70 l 211.34 165.01 l 211.34 170.70 l 292.63 170.70 l 292.63 165.01 l 292.63 170.70 l 373.91 170.70 l 373.91 165.01 l 373.91 170.70 l 455.20 170.70 l 455.20 165.01 l 455.20 170.70 l 455.28 170.70 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 305.0 134.7 m (km) sh % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 312.95 m 211.34 312.95 l 211.34 318.64 l 211.34 312.95 l 292.63 312.95 l 292.63 318.64 l 292.63 312.95 l 373.91 312.95 l 373.91 318.64 l 373.91 312.95 l 455.20 312.95 l 455.20 318.64 l 455.20 312.95 l 455.28 312.95 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf % gr_show_at() BEGIN 0 g 0 G 135.7 166.4 m (28.1) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 135.7 213.8 m (28.0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 135.7 261.2 m (27.9) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 135.7 308.6 m (27.8) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 165.01 170.70 l 170.70 170.70 l 170.70 218.12 l 165.01 218.12 l 170.70 218.12 l 170.70 265.53 l 165.01 265.53 l 170.70 265.53 l 170.70 312.95 l 165.01 312.95 l 170.70 312.95 l 170.70 312.95 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 115.3 237.5 m () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Symbol findfont 12.00 sc sf (\163) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh 0.0 -3.2 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf (T) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 3.2 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 455.20 170.70 m 455.20 170.70 l 460.89 170.70 l 455.20 170.70 l 455.20 218.12 l 460.89 218.12 l 455.20 218.12 l 455.20 265.53 l 460.89 265.53 l 455.20 265.53 l 455.20 312.95 l 460.89 312.95 l 455.20 312.95 l 455.20 312.95 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri: %gri:# %gri:# All done. %gri:draw title "Example 9" % gr_show_at() BEGIN 0 g 0 G 284.5 341.4 m (Example 9) sh % gr_show_at() END %gri:if {"\dohisto" == "yes"} %gri: draw title "Histogram enhanced grayscales" %gri:end if showpage %%Trailer %%BoundingBox: 113 130 463 352 %%DocumentFonts: Courier Helvetica Palatino-Roman Palatino-Italic Symbol Times-Roman %%Pages: 1 gri/doc/examples/example7e.dat0000644000175000017500000000525213147557614014770 0ustar psgpsg 0.198 -0.703 0.283 -0.548 0.047 -1.328 0.260 -0.585 0.278 -0.556 0.284 -0.547 0.129 -0.889 0.410 -0.387 0.173 -0.762 0.215 -0.668 0.097 -1.013 0.911 -0.040 0.376 -0.425 0.530 -0.276 0.093 -1.032 0.178 -0.750 1.956 0.291 0.247 -0.607 0.174 -0.759 0.365 -0.438 0.186 -0.730 0.174 -0.759 0.438 -0.359 0.137 -0.863 0.473 -0.325 0.132 -0.879 0.209 -0.680 0.333 -0.478 0.127 -0.896 0.101 -0.996 1.748 0.243 0.312 -0.506 0.107 -0.971 0.205 -0.688 0.499 -0.302 0.497 -0.304 0.215 -0.668 0.468 -0.330 1.822 0.261 1.140 0.057 0.292 -0.535 0.067 -1.174 0.326 -0.487 0.125 -0.903 0.106 -0.975 0.427 -0.370 0.059 -1.229 0.173 -0.762 0.229 -0.640 0.307 -0.513 0.229 -0.640 0.186 -0.730 0.122 -0.914 0.143 -0.845 0.224 -0.650 0.192 -0.717 0.260 -0.585 0.277 -0.558 0.172 -0.764 0.180 -0.745 0.165 -0.783 0.207 -0.684 0.107 -0.971 0.150 -0.824 0.309 -0.510 0.285 -0.545 0.105 -0.979 0.061 -1.215 0.186 -0.730 0.154 -0.812 0.154 -0.812 0.365 -0.438 0.205 -0.688 0.297 -0.527 0.225 -0.648 0.352 -0.453 0.252 -0.599 0.340 -0.469 0.415 -0.382 0.346 -0.461 0.273 -0.564 0.166 -0.780 0.246 -0.609 0.098 -1.009 0.365 -0.438 0.422 -0.375 0.345 -0.462 0.369 -0.433 0.396 -0.402 0.433 -0.364 0.486 -0.313 0.275 -0.561 0.370 -0.432 0.150 -0.824 0.261 -0.583 0.243 -0.614 0.378 -0.423 0.262 -0.582 0.093 -1.032 0.193 -0.714 0.268 -0.572 0.296 -0.529 0.596 -0.225 0.291 -0.536 0.414 -0.383 0.165 -0.783 0.123 -0.910 0.270 -0.569 0.106 -0.975 0.134 -0.873 0.425 -0.372 1.209 0.082 0.534 -0.272 0.292 -0.535 0.310 -0.509 0.088 -1.056 0.194 -0.712 0.226 -0.646 0.206 -0.686 0.491 -0.309 0.228 -0.642 0.610 -0.215 0.201 -0.697 0.096 -1.018 0.146 -0.836 0.144 -0.842 0.186 -0.730 0.147 -0.833 0.222 -0.654 0.273 -0.564 gri/doc/examples/example10color.gri0000644000175000017500000000343313147557614015744 0ustar psgpsg# Example 10 -- Draw color image plot # Test various colorscales. # INSTRUCTIONS: Uncomment one of the following '\scale = ' statements # CASE 1: From black at high values to white at low values #\scale = "rgb 0 0 0 20.0 rgb 1 1 1 0.0 increment 5" # CASE 2: From skyblue at 20 to tan for 0; traverse RGB space # See also case 5, which names the colors. #\scale = "rgb 0.529 0.808 0.922 20.0 rgb 0.824 0.706 0.549 0.0 increment 5" # CASE 3: From skyblue at 20 to tan for 0; traverse HSB space # Is it just me, or is this uglier than case 2? #\scale = "hsb 0.548 0.426 0.922 20.0 hsb 0.095 0.334 0.824 0.0 increment 5" # CASE 4: Use a spectrum; traverse HSB space #\scale = "hsb 0 1 1 20.0 hsb 0.6666 1 1 0.0 increment 5" # CASE 5: From skyblue to tan, traversing RGB space (by default) # (Compare case 2, which uses similar endpoints, with # colors specified with RGB values, and larger increment.) #\scale = "skyblue 20.0 tan 0.0 increment 2" # CASE 6: From skyblue to tan, traversing RGB space (by default) # Compare 2 and 5; note this has continuous increment #\scale = "skyblue 20.0 tan 0.0" # CASE 7: From blue to brown \scale = "blue 20.0 brown 0.0 increment 2.5" open example10.dat read line \header read \D read .nx. read .ny. set x name "distance along cove" set y name "time" set x grid 0 1 /.nx. set x axis 0 1 0.5 0.1 set y grid 0 .ny. / .ny. set y axis 0 .ny. read grid data * * .ny. .nx. set image range 0 20 convert grid to image set image colorscale \scale draw image # Draw contours in white ink set graylevel 1.0 draw contour 0 20 1 unlabelled set graylevel 0.0 draw axes # redraw in case whited out draw image palette left -1 right 21 increment 5 set font size 9 # Title tells what method used draw title "Used `draw image colorscale \scale'" gri/doc/examples/example1.png0000644000175000017500000001602213147557614014626 0ustar psgpsg‰PNG  IHDRNlY®DœbKGDÿÿ«1Í pHYsHHFÉk> vpAgNlN}“=èIDATxÚíÝ?’òÊÕÇñÓoÝÄ™5]å*ë ßÒ,A³Æ;€Ì),Ad.g87,A$Ιò¬É\v4”WÐop®ÌÀFB-uKú~ª¸Ïð炘ߴÔÝGÆZ4ð¾7ÓcŒµ_/yî{›|¿/ŽŸ|o¦ÉZc|oƒ ÆD‘HQXûôä{[ÐzœÀŒ‰cc²Läx‰"ßÛƒ~œŠ1Ç£1ó¹þ<Ÿ—»ðÆ$‰1E¡»õZåÿ£»úçûv;ý×Ú¯Ûl·v;í1~~ý(ÒÛ¿¾Î¥ÓIäpY,|¿gðÀZ.\ú½Tßšez_‹…È|®ÿF‘Þ>Ÿ‹¤©þœ$"Ö^>_ùÿë}"³Yõã6í!F‘þ¼Ù”÷é¿›Íù¹¢H$ÏE–ËïÚãû=åÒï…Câè1ÖÞ;Æ©=ÎÍFäõÕÚýþ|{’h˜¥©†™>Çõó}¾~ý³ÈÓ“µ§“^"‘k)§9Î[Ç"ooÖ¾¾>ÚŒƒCP‹¼¿ë¿Ê˜ÍFo{{³vµ2f¹ìîõ__Ëp*ùîòr™ÞEäö®­î^—.E!’$åÿsþy¹üü×Ïwë>ýïõ®ún÷ùq"»ÝåcŽG‘ùüÑöpç…Á!xQ5Sww;‘ÅB{|«•†˜ˆþ¬@®ooÆEóW>4?>4¯w ½ýãCw8X»Ýú~¿Žqb28 Wèq@C'&d½ö½vÕ !zœÐÁ œÐÁ œÐÁ œÐÁ œÐÁ œÐÁ œÐÁ œÐÁ œÐÁ œÐÐ ‚Ó˜<ï÷õÒÔ˜,£Coc–“¦´‘66{½ï7œçÁiLQ\^"cv;c¬ÕËfcLùn8<ÊYpjw:ÏEâøòžÝNäýÝZcDžŸEÒTd¹ôÝpx”Ãçá ²^½=M­]­DD¬}{ÙïEf3ß €Gk?¡±V{—åõ<9¬]¯‰cí•~~Ìåÿ_uPöùÛßú{[¢H{Îooý½æl¦TšúÃDþó‘ÿþw¼m|T’ˆ¼¿‹œN´‘6Ö÷»ß‰üþ÷"ÿûõ=e'°‡àLÝ5ŸÍ´áÛ­Èry;8«FÏþò‘?ý©Ÿ7mhÖk‘ÿ[äÏö½%À8üü³^þú×ë{¬=DD~êzt÷üõµ¼®Az{jA¹aŸó¯UÝc~ÿ{‘_ÿZäíÍÚ>{À8i—î7¿¹—9OGÒõÍFŽc‘ÍF{hK{燃î61àô¥‡yœëµHc­Èñ¨Ç; N7Êc?ëµÈ|î{k€©p¾«~}ìRwÕ_^|7tœâXd¿·öt2f¿7f>çÐ=V ZšžGÅéu}!8JW_N倵:]£ïuËÀœƒ•$_ç`n·ô:õy7]Y»ß‹$‰Î^Ђs°ªzœ"ëºGpV’茅kZ € T@wÎÒ]ñê5æ:X´ßÓëºCpÒ×ã›—$ºDpÒýªF:5ép0†ò}@ÎAú®Ç)Âî:Ђs¢H{•·ie—(ÒjT\"8FWÕ->̱N  ×ã„keE¤ïY»ÝSÆDµ:wèqN’h κ¨Õ ¸FpN’4«†ÏJ"À5‚s@ÊŠHMþŸrB¼1„'à Á9(M†>£× ¸DpÊ­Â÷Q«p‹à”Ç‚S15 p…à”8®®ˆô=ju+€êÍß¼c€ ç`´ÙM/Q«pàŒû‘ê V'àÁ9iÚlÅÐ- mœƒáf½9µ:öÎhV©v×6ÎApœÔêÚ!8¡ýÀÐWëE=ÎAhZé{ÔêG3pºÒ§«`£V'ð‚3xM 7ÁJ"àgð\,µ¬F­Nà1΃Ә¢¸¼ž$z,ÍZý—‘Üf\,µ¼‡^'Д³à4&ËŒÉsþ,ÏE kY,ô:êK’G+"ÕA­N 9‡=ÎÃA{/pE{ç]ö6KLMšp6©œ.cÌõ=//"y~®Ès?\µ×zmª»÷ý§µû½î1ıö@©›Íª+Zûò""b¬uûrÆX«»ååõ,ÓŸÊÀÔé/Ö®VõŸ3ÏË žc6‘ýÞõÎêךϵPrýÏ#=l•¦÷~zÎËë·n»ÿœS ÎãQäå¥ êºGp<ŠjubêÎ „<ñýz˜.‚3áOEºF­NLÁ陎NŸNáUDªƒ©I˜&‚Ó»aLCªB­NLÁéÝðvÓ/q¬ÓCpz7ܧ¢V'¦‡àô.IB­ˆTµ:1E§GèˆTƒD˜çÁiLQ\^·öë%Ï}7< C?¾©¨Õ‰©qœÆd™âåëudêDïõÚwÃÃ0–§»ë˜‡=ÎïјåRäíMë:b,=NjubZ~rõDeS}¿Ï›ÍD^^î=OõJ”±ŽØFÑp*"ÕQë\,|o ÐNUeQ™s΂ó{Ë¥Èvûý ™i§~(ãèm–¬Ýn) c¢h˜+¡€RWgQÁ©süf3k¿ï‰X»Z}ýÿǸû7¬ŠHõ•µ:¿~ŽÀp¼½UeQ©§éHó¹þBá,I†W©Vaüz Ρ¯ŽéB’ŒqŒZ˜ç»ê:åèú¶×Wß IYÉ÷vtg½Ùít°Vy1¾¡Ï¨Õ‰±#8½˜Â¡ –ab¼N/ÆœÔêĘœ^Äñ+"ÕÇ;Ɖàì™ÎIãüÍ*ÔêÄ8œ½ÿnz‰Z+‚³wcªˆTƒD‚³wi:ÎCÕ¨Õ‰1"8{7Åì®c\α"RÔêÄØœ½šfp*Žub<Î^Mm`èÌÚíV$M™š„1 8{5ΊHõ•µ:a#8{¢K§6(t•D‚³7c-\\µ:1go¦´Ôòz>‚³7ÓYjyµ:1go’d‘ê`j†àìNü&4KÔêÄМ½ 8¿âX'†‹àì#ê_Q«ÃEpö‚ç5jubÈÎ^L±"R a˜ÎŽé´vÓ«P«CEpv.M™ø~»ë‚³sÓ­ˆTµ:1DgçÒtÚ‘êàX'†å'ß0f:Á›Þæw¬Ýn) cDÃ0ÐãìÓê£V'†ƒàì‘êc%†ƒàì+†ê¢V'†„àìT’è\EÔC¯Ãà<8)Н·e™1ÆXkL–ùnt¨ˆÔµ:1΂SÃ1ÏuÞâåízÛ"OOZØa ½Š)Ÿ ¸ ¦&!|{œ‡ƒîj]KS‘õÚÚÓI/?~è©bÇ.Ž9¾Ùµ:1ÆZÇOh¬µÖ˜Ï×ÏÇ®¢H§¬×·ª¡k¯õZ’XûôäûÍjö>"//ÌKlN÷HâØÚÕÊ÷¶`zôPÑfS5#ÆÚ——_~p{±öúºnDéõ,ÉófÏÙìñ¾/úâxô½C½èûWåw† —~¿i*’e÷Óèúû»È~_ö¼´1öƒÿ µA­N„®‡à¼¬ô­ƒEc?öGE¤ö$B¸zÎrÀH§#é Éë«ï†w‹¡¶¨Õ‰9ÎÏCzýt²v±°VgqZûú:þ“4åTÀ.°»Ž0±rÈ1*"¹C­N„Šàtމïnq¬á¡§sô8]¢V'BDÓ9¦"¹G­N„…àtŽŠHîQ5 a!8âTÀÝ V'BCp:EÅ÷îÐëD8N§˜øÞju"$§SLEêS“‚Ó]‹¯5G}oËXQ«¡ 8aR?8Ö ÿNgØMïÇeµ-À‡ÊàÔó±>¸zœ} V'Bp§Ç¹Ûs<³\rL©Ž$¡"R_$‚_•Áiíjeíz<)ŽEŠÂ˜ÝΘùœ]¤¯¨ˆÔ/ju·oŽqêÜ9ý7MEf3 QþÚ_âøfÿØ]‡?7Žq.—z–Æ<×g­VÖ>=éÞžŸõäk8£ÇÙ7ju§=Î8ÖSø>=iõöýþ|ßé$òË)2ñ zœ~p¬~TÖã´v±¸õ?è¨&Ë /E‘úG­NøÂ<Ζtí4½M¨Õ‰þœ­QÉ/V¡gkI¡ ¨Õ ÎÖ’DGxá½Nô‹àl¡¬ˆä{;¦ŽZèÁÙ Cá`júCp¶BaPP«}"8[!8ñNôƒàl%Ž©ˆju¢çƒt4ó7CB­Nô…à|»éabÝ#8FE¤Q«} 8–¦¬ »ëè–óà4¦(.¯§©1Ö^^²ÌwÃÛ£"O¨¨Õ‰®9 N=Á[žë.ìgq,²ß_Fçjå»áíÚÊÄ÷ðq¬ÝqØã<tÝ5 R­›h­1›Íð§‹œ¡³v»IÓá×¢ŸÚ?…* ]s}O’èzîçg½žez©.–¬½ÖªçIkaÛnõl­¾·#DZgAO‡ƒ¯f³ªC=åûe¬uûrÆXkíí¯ªö>>î=æëÿ“ç!}ÀÆ…ž.cv;‘·7k«ö§KÅ¥é½CŠžFÕ‡;¨¢k¡‡»ýÀÙb!2Ÿ3ˆÖ\çÁ©Ç6u]{›Y6ìÝ\ ctVÈjÅYk›ë¡ÇùúªUk¬) í­ y×€¥–­*u8ŒcŠ`œ •®]jŒpŽO¶—$:Á‹õZäx4æpàlõ°r¨±$¡"ÆDwÙ__EÆ0U°gzÐÄøhg`¿×1|‡àl„àÄxéô›$¡@Ê÷ÎFQÇØ½¾Šd»ì÷œÐãĸiY>]qå{[BFp6BE$ŒŸ®$:ŒY.}oK¨Κt»é˜ VÝCpÖ–¦L|ÇT°ªè>‚³6N•iaUÑmgmiʪ LÏz­%ÖÒÔ÷–„„à¬A+"ÑÛÄô°ª¨ÁY Ó0]¬*úŠà¬…ŠH˜6V]"8kaÅÀª¢3‚³–$ÑÀt±ªèŒàü‘€3V)‚ó[œ ¸Äª"‚ó[qÌñMàŒUEg ìªצ¾ªˆà¼£=¤"Peº«Šλèm·LyUÁy‘€{¦ºªˆà¼‹!à;S\UDpÞ•¦œ ¨cZ«ŠÎ¨ˆÔ7µUEçML|š˜Òª"‚ó&zœ@sÓXUDpÞÄT$ ©©¬*"8o¢"ðˆ)¬*"8+p*` ­q¯*"8+Qñhc쫊œ§1EQ}{óñá»Áõ0ñhkÌ«Šœ§1YfLžkèTY.E†ò—‡©H€ c]Uä°Çy8èq¯t^×~ï»±uènÅéDE$À•ñ­*úÉÕY«»¶Æ\Þ®ó¹’ÄÚõúú¾*Õ“û|Ù†¸díû»1媢—ßÛSOUeQ™s΂ó¶,ÓI±uùNvÓ×´ã”$Æ,—ºÂ(tq\E¿Œ}Xëö"bíùç4­~Tž7{Îfo·ýy®=ä~^ —©\´T¡ÿ~ineÙ½ÇtÚãÔníyÝk­­³ÃîS’P pÏÚÓɘrUÑó³ïíiƒyœŸP èÖXV9Î{=Êð{›ßº7üUEô8/Ðãº6†UEçzœ@†¾ªˆà¼ETDú1äUEç/ôx ½M _Ã\UDpþ‘€¾ õ\Eçÿ$ ‘€þ ñ\Eçÿ$I¹@߆u®"‚SΑ|o0UC;WÁ)"LCüÒª"‚SD(%„b«ŠN!80 eUÁ)""qLE$ CXU4ùàÔQ<æo! }UÑ䃓Ýt Tá®*"8©ˆ)äUE§¤)+†€0…ºªˆà”(âTÀ@ÈÂ[U4éà¤"¾WM:8Y1 Ch«Š&œ ÃΪ¢‰'‘€¡iUÑdƒSOÌ 0$¡¬*šlpR¸¦VM<8Yj “ßUEN†€!ò½ªhÒÁIE$`¸|®*šdpê B>?«Š&œì¦ãàkUÑ„ƒ“u` |¬*šppÒãÆ£ßUE N*"cÒ÷ª¢É§þEb7›>W9NcŠâòzšSÆX«ÿú>‡Hš2ñ§¾V9 Nc²Ì˜<׊CŸm6"‹…µÆèÔß5õ¨ˆŒ[÷«Šö8=@{m±8W :D|Ÿx)M©ˆŒW«Š~r·±FÆÜº=Ïu7¹*\Ïôq×ÜLnÕŠHô6±³v½6&Žyt…àlV5©ÞÚ—c­Û 6ÆZÝ-¿uÿr©£Ú«UýçÌórƒÛmÛl¦K-ë¿6€iÑä4½—ª_OJÕõ¥¾ÎXGE$íõ0i6ûžú³¯cŒ¬Ð^Áùú*’¦:ÉZÕ^,ü47IôÀ1<ÎÙàPéúø¦˜}~öÝP*"peB+‡807&œqÌñM.L(8ÙUàÆ$‚³\zEE$.L"8émpi"ÁIE$îL$8àÎD‚3M90WFœTDàÚ胓‰ï\›@pÒãàÖ‚“©HÜšDpR €K£NN   £N*¾è‚ózœ!ÑÓt€[#ïq€{'4Dp@C'4Dp@C'4Dp@C'4Dp@C'4Dp@C'4Dp@C'4Dp@C'4ä<8)ŠËëqlÌngŒµzÉsc’ÄwÃàQ΂Ә,3&Ïõt¼Ÿe™þûôd­1zÆÉÍÆwÃàQOq8è%M/oÙn­=DD¬]­Œ±ÖwÃàQÎ#Ìkµgyë~íZ»ZUߟç_oýùg‘ü£¿·%ŠôÒç‰Þú>ÿûÚÇ"§“^h#m¬ë·¿ùÕ¯DþùÏë{¬}yùå·k«oŸÏEŽG‘,kþœyîz;ï¿^š>²í^“6º½,ISÚH]ÿnt~–KcâXd·ÓÝø——r—†ª‡Óo6"û=§ê0=ÌãÔnïy:’^|7å¼Çy=0to †ˆ¾4Ä’Khˆà€†Nhˆà€†Nhˆà€†‚N-W÷ñ¡—²DŸç¾®5Úüõ¢Hë‘–uI£¨úqó¹1E¡;ÛÔ/­ÓFc’D_§\ ðøkÖmãåk·›W¯iz½ãÑïSýÏ1ŠŒÙlôqEÑýçxÝ>ݾnÛ˜$çïjmŒ¢Ëú¾›Íw߱Ƕåx¼wÐÁ©o^‹üø¡—8vžMžûv­Ñ¦–K‘··s]Òå²úqY&²Xèã]ëßew;]«_E‘õúÑ׬ßFý%¸w¿Û6Æñç6ꥺB—»6.—ZêéIdµêús¼ŽLýî<ºÔ¹nóüü]],ôzwmÔ÷ðý]_ïùYW&¶û]nÇ|®¿ëßüè³ÊIó*%Ç£H’œ¯'‰ÈñØ÷s뇓¦"Õ•Ÿê¿fQˆÄ±þÇ"Eñõ1q,2Ÿ_ÞöØëÖmãuåmëÇGWmÊïO»ïMÝÏñò»¢ŸëíïXóíH’:¿ëÞÃñ~#¾n|ÛðjóÜíƒóúCÿþùô`³é£ú%´Viû…¯ÛF}-ýÑæ}­ÛFí ívç:¤›«÷õv­íâ=ýþsŒc ¢Çþ04ÿËk]·Q?ÇåòÜNýCØGö\Üïú»ÞxWoÒ#ÏÝöµë~õ¾$Ñ/I›žÑcïŸË°®Þ†Ùìóó·y_oc=úºõCåsol¹|´gÔ´ú¹ÜkéæsÌ2½”Œ²¬ë?òú{±Ûéµ2¸ûÈž‹û]¿ Û¿ü+­oš›nù#ÏÝöª¿ûS}nW¼µnõõt»Ú¶µÞáˆ<¯þ¿›·÷Ñïˆþ¢w{8Bd·s÷žÖkc›v5ÿÝulÿݾkÒŽ ‡Dö{‘åRGÒÊ„ý¾ëçÖÛ®ÏäÂá !%¢ÿׯwÞ–—kõþnÚ˜¦çÑÈ$ÑÒz]Ê?úÚß·ÑÚ——ËA ýù‘׬×FñÕÁ½-ËD¶Û®Ú¨ÞßÏŸk›÷´îçXn‹ß‘:m<tàT·«6ꈺžìQ‹¤o6Ž-tÑSt—ú屨ò–Çw[›<÷­ƒÃí{œQtîmåyÕë•?__Ü·ñÜÃÓÇ•»?Ö–ƒ6]µÑåûZ¿å¡kÏ»x©×Ưkóž~ßF½¾ÛµÝM¯ÿ]-Ïîðù{s¹çÒÇçØMöÜÿNRV |WÂCp@C'4Dp@C'4Dp@C'4Dp@C'FǘÙL‹1—KÇn–ÐbªX9„QÒuÓåîÓéñ¢ÅÀW'FI‹Bh5rkŸŸ}oÆ…]uŒXYQÇý9i0mô81JÆèy”´šNY»XøÞ&Œ=NŒŽ1zò.k÷{=¶™$ÆÌf¾· ãA¢Ç œÐÁ œÐÐÿ?ŸOŸ0½%tEXtdate:create2010-12-09T09:09:54-04:00(Ź%tEXtdate:modify2010-12-09T09:09:54-04:00Y˜«#tEXtps:HiResBoundingBox334x364+129+130:,TtEXtps:LevelAdobe-2.0 EPSF-1.2 ÞÙÈoIEND®B`‚gri/doc/examples/example13.dat0000644000175000017500000000301413147557614014672 0ustar psgpsg34.476 8.70 34.490 8.64 34.662 4.08 34.908 4.40 34.921 4.33 34.925 4.31 34.913 4.06 34.892 3.92 34.882 3.74 34.876 3.66 34.882 3.66 34.882 3.58 34.881 3.56 34.904 3.58 34.511 8.70 34.503 8.71 34.658 5.77 34.858 3.99 34.861 3.90 34.862 3.81 34.863 3.74 34.868 3.71 34.870 3.65 34.870 3.61 34.870 3.60 34.877 3.56 34.875 3.52 34.888 3.57 34.585 8.63 34.590 8.63 34.729 5.31 34.828 3.82 34.841 3.77 34.846 3.76 34.836 3.68 34.841 3.66 34.842 3.66 34.863 3.65 34.864 3.64 34.877 3.63 34.882 3.60 34.892 3.55 34.585 8.51 34.590 8.26 34.604 7.91 34.832 3.99 34.835 3.75 34.876 3.82 34.869 3.72 34.871 3.74 34.881 3.69 34.893 3.63 34.880 3.56 34.893 3.60 34.897 3.53 34.914 3.56 34.589 8.49 34.586 8.46 34.710 5.61 34.797 3.84 34.802 3.78 34.829 3.73 34.829 3.64 34.857 3.66 34.869 3.64 34.869 3.63 34.869 3.60 34.875 3.59 34.892 3.54 34.568 7.30 34.564 7.32 34.738 4.46 34.826 4.15 34.836 3.96 34.837 3.79 34.858 3.72 34.847 3.66 34.586 7.84 34.620 7.61 34.782 4.10 34.835 3.80 34.841 3.74 34.845 3.72 34.856 3.65 34.860 3.65 34.866 3.61 34.892 3.62 34.899 3.60 34.589 7.87 34.588 7.80 34.748 4.96 34.814 4.00 34.803 3.83 34.851 3.83 34.860 3.81 34.877 3.81 34.882 3.71 34.865 3.67 34.875 3.66 34.893 3.69 34.893 3.61 34.582 7.06 34.582 7.08 34.586 7.09 34.778 4.06 34.770 3.79 34.821 3.83 34.848 3.72 34.848 3.68 34.852 3.64 34.860 3.66 34.864 3.65 34.872 3.60 34.888 3.60 34.896 3.52 34.616 6.99 34.616 6.98 34.620 6.98 34.805 4.22 34.829 3.85 34.847 3.77 34.848 3.69 34.856 3.73 34.864 3.67 34.872 3.68 34.884 3.69 34.884 3.66 34.896 3.59 34.915 3.57 gri/doc/examples/example2.ps0000644000175000017500000004214613147557614014473 0ustar psgpsg%!PS-Adobe-2.0 EPSF-1.2 %%Creator: %%Title: example2.ps %%CreationDate: Sun Dec 13 11:49:05 2009 %%Pages: (atend) %%BoundingBox: (atend) %%TemplateBox: 0 0 612 792 %%DocumentFonts: (atend) %%Orientation: (atend) %%Endcomments % NOTE: The Gri postscript dictionary is being converted to the Adobe % Illustrator 3.0 dialect of PostScript, as described in the Adobe % documents stored at URL % http://www.adobe.com/Support/TechNotes.html % (as of Jan 1996, this doc is number 5007). When the conversion % is complete, the Adobe Illustrator drawing program -- and any % program compatible with AI -- will be able to edit Gri output. % % The IslandDraw (TM) program is able to read Gri output % at this time; remarkably, it can read/edit arbitrary PostScript. % % The definitions below are presented in the same order as the Adobe % manual. The stack configuration before and after is shown in curly % brackets. All the operators are listed, but only some are defined % here. Most things are faithful, except that no distinction is made % between colors for stroking and filling paths. The string 'WRONGLY' % appears with commands that are approximations. % % PDF-style abbreviations: /rg {setrgbcolor} def % {red green blue} {-} set RGB color /RG {setrgbcolor} def % {red green blue} {-} set RGB color /q {gsave} def /Q {grestore} def /W {clip} def /W* {eoclip} def % % Gri-specific abbreviations: /hsb {sethsbcolor} def % {hue saturation brightness} {-} set HSB color % % Following all try to mimic Adobe Illustrator % % Mimicking section 5.1 of Adobe manual: %A % {flag A} {-} Determine whether % following object can % be selected. Flag=1 % prevents selection; % flag=0 allows it. % Mimicking section 5.2 of Adobe manual: %u % {u} {-} start group %U % end group %q % as 'u' but first item is a clip path %Q % as 'U' but first item is a clip path % Mimicking section 5.3 of Adobe manual: /g {setgray} def % {gray g} {-} Set gray for fill % path, WRONGLY used % for stroking also. /G {setgray} def % As 'g', but for filling path. %k % Set cmyk color for filling path. %K % As 'k', but for stroking path. %x % Set cmyk custom color for filling path. %X % As 'x' but for stroking path. %p % Define pattern for filling path. %P % As 'p' but for stroking path. %O % Specify whether overprinting for fill paths %R % As 'O' but for stroking path. % Mimicking section 5.4 of Adobe manual: /d {setdash} def % {[array] phase d} {-} Set dash. /i {setflat} def % {flatness i} {-} Set flatness. /j {setlinejoin} def % {linejoin j} {-} Set line join. /J {setlinecap} def % {linecap J} {-} Set line cap. /M {setmiterlimit} def % {miterlimit M} {-} Set miter limit. /w {setlinewidth} def % {linewidth w} {-} Set line width. % Mimicking section 5.5 of Adobe manual: /m {moveto} def % {x y m} {-} Move to locn /l {lineto} def % {x y l} {-} Draw line to locn % not a smooth point. % WRONGLY, no % distinction is made % between smooth and % corner. %L % {x y L} {-} As 'l' but a corner %c % Bezier curve to smooth point. %C % As 'c' but to corner point. %v % Something else to do with Bezier. %V % %y % %Y % % Mimicking section 5.6 of Adobe manual: %N % {N} {-} As 'n' for nondrawn stuff /n {newpath} def % {n} {-} WRONGLY interpreted % as path constructor /F {fill} def % {F} {-} Fill current path. %f % {f} {-} 'F' but close first /S {stroke} def % {S} {-} Stroke current path. %s % {s} {-} 'S' but close first %B % {B} {-} As 's' but don't empty path. %b % {b} {-} As 'f' but don't empty path. %H % no-op (weird huh?) /h {closepath} def % {h} {-} Close current path %W % Used to create masks. % Mimicking section 5.7 of Adobe manual: %a % Begin text block ... %e % Similar to 'a' but ... %I % Similar to 'a' but ... %o % Similar to 'a' but ... %r % Similar to 'a' but ... %t % {len (string) t} {-} Render string. %T % End block of text % That's the end of the Illustrator stuff. Following are some Gri % definitions which provide a temporary way of handling fonts. /sf {setfont} def % {fontname sf} {-} Set font name. /sh {show} def % {(text) sh} {-} Show text. /sc {scalefont} def % {size sc} {-} Scale font. % Gri items which should be translated to Illustrator format: /rl {rlineto} def /rm {rmoveto} def % Procedures /cimdict 7 dict def /cim { cimdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def q xll yll translate xur xll sub yur yll sub scale /do cl 3 mul string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop} false 3 colorimage Q end } def /imdict 14 dict def /im { imdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def /imagemap exch def q % Until version 2.6.0 used a 'settransfer' here, but that % triggers a bug in ps2pdf xll yll translate xur xll sub yur yll sub scale /do cl string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop dup length 1 sub 0 1 3 -1 roll { 1 index exch 2 copy get imagemap exch get 255 mul cvi put } for }image Q end } bind def /frdict 5 dict def /fr { frdict begin /yt exch def /xr exch def /yb exch def /xl exch def n xl yb m xl yt l xr yt l xr yb l h F n end } def /plusdict 3 dict def /_plus { plusdict begin dup 0.5 mul /t0 exch def /t1 exch def 0 t0 rm 0 t1 neg rl t0 neg t0 rm t1 0 rl t0 neg 0 rm end } def /timesdict 3 dict def /_times { timesdict begin dup 0.353553 mul /t0 exch def 0.707106 mul /t1 exch def t0 neg t0 rm t1 dup neg rl t1 neg 0 rm t1 dup rl t0 neg dup rm end } def /boxdict 3 dict def /_box { boxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm end } def /filledboxdict 3 dict def /_filledbox { filledboxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm F end } def /diamonddict 2 dict def /_diamond { diamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm end } def /filleddiamonddict 2 dict def /_filleddiamond { filleddiamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm F end } def /triangleupdict 5 dict def /_triangleup { triangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm end } def /filledtriangleupdict 5 dict def /_filledtriangleup { filledtriangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm F end } def /trianglerightdict 5 dict def /_triangleright { trianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm end } def /filledtrianglerightdict 5 dict def /_filledtriangleright { filledtrianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm F end } def /triangledowndict 5 dict def /_triangledown { triangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm end } def /filledtriangledowndict 5 dict def /_filledtriangledown { filledtriangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm F end } def /triangleleftdict 5 dict def /_triangleleft { triangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm end } def /filledtriangleleftdict 5 dict def /_filledtriangleleft { filledtriangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm F end } def /circdict 5 dict def /_circ { circdict begin 0.5 mul /t0 exch def currentpoint /t2 exch def /t1 exch def S n t1 t2 t0 0 360 arc t1 t2 m end } def /bulldict 3 dict def /_bull { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 360 arc h F S end } def /filledhalfmoonupdict 3 dict def /_filledhalfmoonup { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 180 arc h F S end } def /filledhalfmoondowndict 3 dict def /_filledhalfmoondown { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 180 360 arc h F S end } def 1 1 scale 10.0 M 1 j /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-ISOLatin1 exch definefont pop /Courier-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Oblique-ISOLatin1 exch definefont pop /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Bold-ISOLatin1 exch definefont pop /Courier-BoldOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-BoldOblique-ISOLatin1 exch definefont pop /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-ISOLatin1 exch definefont pop /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Bold-ISOLatin1 exch definefont pop /Helvetica-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Oblique-ISOLatin1 exch definefont pop /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Roman-ISOLatin1 exch definefont pop /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Italic-ISOLatin1 exch definefont pop /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Bold-ISOLatin1 exch definefont pop /Palatino-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-BoldItalic-ISOLatin1 exch definefont pop /Symbol findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Symbol-ISOLatin1 exch definefont pop /Century findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Century-ISOLatin1 exch definefont pop /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Roman-ISOLatin1 exch definefont pop /Times-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Italic-ISOLatin1 exch definefont pop /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Bold-ISOLatin1 exch definefont pop /Times-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-BoldItalic-ISOLatin1 exch definefont pop %%EndProlog %%Page: 1 1 gsave /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:0.05 12.5 %gri:0.25 19 %gri:0.5 15 %gri:0.75 15 %gri:0.95 13 %gri: %^ scale 1 170.7 0 284.5 1 170.7 12 40.6429 0.709 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 184.92 191.02 m 241.82 455.20 l 312.95 292.63 l 384.07 292.63 l 440.97 211.34 l S % END GriPath stroke/fill 0 g 0 G 167.4 149.9 m (0) sh 0 g 0 G 190.8 149.9 m (0.1) sh 0 g 0 G 219.2 149.9 m (0.2) sh 0 g 0 G 247.7 149.9 m (0.3) sh 0 g 0 G 276.1 149.9 m (0.4) sh 0 g 0 G 304.6 149.9 m (0.5) sh 0 g 0 G 333.0 149.9 m (0.6) sh 0 g 0 G 361.5 149.9 m (0.7) sh 0 g 0 G 389.9 149.9 m (0.8) sh 0 g 0 G 418.4 149.9 m (0.9) sh 0 g 0 G 451.9 149.9 m (1) sh 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 170.70 165.01 l 170.70 170.70 l 199.15 170.70 l 199.15 165.01 l 199.15 170.70 l 227.60 170.70 l 227.60 165.01 l 227.60 170.70 l 256.05 170.70 l 256.05 165.01 l 256.05 170.70 l 284.50 170.70 l 284.50 165.01 l 284.50 170.70 l 312.95 170.70 l 312.95 165.01 l 312.95 170.70 l 341.40 170.70 l 341.40 165.01 l 341.40 170.70 l 369.85 170.70 l 369.85 165.01 l 369.85 170.70 l 398.30 170.70 l 398.30 165.01 l 398.30 170.70 l 426.75 170.70 l 426.75 165.01 l 426.75 170.70 l 455.20 170.70 l 455.20 165.01 l 455.20 170.70 l 455.23 170.70 l S % END GriPath stroke/fill 0 g 0 G 310.0 134.7 m (x) sh /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 455.20 m 170.70 455.20 l 170.70 460.89 l 170.70 455.20 l 199.15 455.20 l 199.15 460.89 l 199.15 455.20 l 227.60 455.20 l 227.60 460.89 l 227.60 455.20 l 256.05 455.20 l 256.05 460.89 l 256.05 455.20 l 284.50 455.20 l 284.50 460.89 l 284.50 455.20 l 312.95 455.20 l 312.95 460.89 l 312.95 455.20 l 341.40 455.20 l 341.40 460.89 l 341.40 455.20 l 369.85 455.20 l 369.85 460.89 l 369.85 455.20 l 398.30 455.20 l 398.30 460.89 l 398.30 455.20 l 426.75 455.20 l 426.75 460.89 l 426.75 455.20 l 455.20 455.20 l 455.20 460.89 l 455.20 455.20 l 455.23 455.20 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf 0 g 0 G 145.8 166.4 m (12) sh 0 g 0 G 145.8 207.0 m (13) sh 0 g 0 G 145.8 247.7 m (14) sh 0 g 0 G 145.8 288.3 m (15) sh 0 g 0 G 145.8 328.9 m (16) sh 0 g 0 G 145.8 369.6 m (17) sh 0 g 0 G 145.8 410.2 m (18) sh 0 g 0 G 145.8 450.9 m (19) sh 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 165.01 170.70 l 170.70 170.70 l 170.70 211.34 l 165.01 211.34 l 170.70 211.34 l 170.70 251.99 l 165.01 251.99 l 170.70 251.99 l 170.70 292.63 l 165.01 292.63 l 170.70 292.63 l 170.70 333.27 l 165.01 333.27 l 170.70 333.27 l 170.70 373.91 l 165.01 373.91 l 170.70 373.91 l 170.70 414.56 l 165.01 414.56 l 170.70 414.56 l 170.70 455.20 l 165.01 455.20 l 170.70 455.20 l 170.70 455.20 l S % END GriPath stroke/fill 0 g 0 G 139.9 309.9 m 90.00 rotate (y) sh -90.00 rotate /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 455.20 170.70 m 455.20 170.70 l 460.89 170.70 l 455.20 170.70 l 455.20 211.34 l 460.89 211.34 l 455.20 211.34 l 455.20 251.99 l 460.89 251.99 l 455.20 251.99 l 455.20 292.63 l 460.89 292.63 l 455.20 292.63 l 455.20 333.27 l 460.89 333.27 l 455.20 333.27 l 455.20 373.91 l 460.89 373.91 l 455.20 373.91 l 455.20 414.56 l 460.89 414.56 l 455.20 414.56 l 455.20 455.20 l 460.89 455.20 l 455.20 455.20 l 455.20 455.20 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf 0 g 0 G 284.5 483.6 m (Example 2) sh showpage %%Trailer %%BoundingBox: 129 130 463 494 %%DocumentFonts: Courier Helvetica Palatino-Roman Palatino-Italic Symbol Times-Roman %%Pages: 1 %%Orientation: Portrait gri/doc/examples/example6color.gri0000644000175000017500000000204613147557614015670 0ustar psgpsg# Example 6color -- Plot IR image of Gulf of Maine # define characteristics of norda images \0val = "5" # 0 in image \255val = "30.5" # 255 in image .rows. = 128 .cols. = 128 .pixel_width. = 2 .km. = {rpn .cols. .pixel_width. *} # get filenames query \filename "Name image file" ("example6image.dat") query \maskname "Name mask file" ("example6mask.dat") # get data open \filename binary uchar set image range \0val \255val read image .rows. .cols. box 0 0 .km. .km. close open \maskname binary uchar read image mask .rows. .cols. close # find out what grayscale method to use query \minT "T/deg for white on page? " ("11") query \maxT "T/deg for black on page? " ("14") \incT = "1" # set up scales. set x size 12.8 set y size 12.8 set x name "km" set y name "km" set x axis 0 .km. 32 set y axis 0 .km. 32 # plot image, grayscale, and histogram set image colorscale hsb 0 1 1 \maxT hsb .6666666 1 1 \minT draw image draw image palette left \minT right \maxT increment \incT draw image histogram draw title "Example 6: colorscale" gri/doc/examples/example8a.dat0000644000175000017500000002325613147557614014771 0ustar psgpsg-99.000 -99.000 -1.600 -1.800 -1.760 -99.000 -99.000 -1.593 -1.801 -1.743 -99.000 -99.000 -1.585 -1.801 -1.733 -99.000 -99.000 -1.578 -1.800 -1.735 -99.000 -99.000 -1.570 -1.800 -1.737 -99.000 -1.870 -1.562 -1.799 -1.739 -99.000 -1.871 -1.556 -1.799 -1.741 -99.000 -1.871 -1.551 -1.798 -1.745 -99.000 -1.872 -1.546 -1.798 -1.750 -99.000 -1.873 -1.541 -1.796 -1.755 -99.000 -1.873 -1.536 -1.794 -1.759 -99.000 -1.873 -1.532 -1.792 -1.762 -99.000 -1.874 -1.527 -1.790 -1.760 -99.000 -1.874 -1.521 -1.788 -1.765 -99.000 -1.873 -1.515 -1.785 -1.770 -99.000 -1.873 -1.509 -1.780 -1.770 -99.000 -1.873 -1.503 -1.775 -1.768 -99.000 -1.873 -1.497 -1.778 -1.767 -99.000 -1.873 -1.491 -1.781 -1.751 -99.000 -1.873 -1.485 -1.784 -1.754 -99.000 -1.872 -1.479 -1.788 -1.756 -99.000 -1.871 -1.473 -1.788 -1.756 -99.000 -1.871 -1.467 -1.788 -1.756 -99.000 -1.870 -1.462 -1.787 -1.757 -99.000 -1.870 -1.456 -1.787 -1.758 -1.869 -1.870 -1.450 -1.789 -1.757 -1.865 -1.869 -1.444 -1.791 -1.756 -1.861 -1.869 -1.442 -1.794 -1.757 -1.858 -1.869 -1.439 -1.796 -1.750 -1.854 -1.869 -1.436 -1.799 -1.746 -1.851 -1.869 -1.433 -1.801 -1.742 -1.848 -1.869 -1.430 -1.803 -1.743 -1.846 -1.866 -1.429 -1.806 -1.743 -1.844 -1.866 -1.428 -1.809 -1.740 -1.841 -1.867 -1.428 -1.811 -1.734 -1.839 -1.868 -1.427 -1.811 -1.739 -1.837 -1.867 -1.426 -1.812 -1.744 -1.835 -1.854 -1.426 -1.813 -1.745 -1.833 -1.852 -1.425 -1.812 -1.737 -1.832 -1.850 -1.425 -1.814 -1.732 -1.830 -1.849 -1.424 -1.817 -1.729 -1.829 -1.849 -1.425 -1.821 -1.726 -1.828 -1.848 -1.427 -1.823 -1.720 -1.827 -1.843 -1.429 -1.824 -1.711 -1.826 -1.839 -1.430 -1.824 -1.708 -1.825 -1.836 -1.432 -1.824 -1.706 -1.824 -1.835 -1.434 -1.826 -1.700 -1.823 -1.834 -1.435 -1.825 -1.694 -1.821 -1.830 -1.438 -1.822 -1.689 -1.819 -1.823 -1.453 -1.822 -1.683 -1.816 -1.818 -1.469 -1.824 -1.676 -1.812 -1.814 -1.484 -1.824 -1.674 -1.807 -1.813 -1.500 -1.819 -1.671 -1.803 -1.810 -1.515 -1.816 -1.660 -1.800 -1.807 -1.530 -1.812 -1.655 -1.797 -1.808 -1.546 -1.804 -1.639 -1.791 -1.799 -1.565 -1.803 -1.633 -1.784 -1.791 -1.586 -1.785 -1.613 -1.777 -1.780 -1.606 -1.781 -1.602 -1.771 -1.765 -1.627 -1.782 -1.588 -1.768 -1.770 -1.648 -1.783 -1.581 -1.763 -1.769 -1.669 -1.782 -1.558 -1.757 -1.772 -1.690 -1.781 -1.545 -1.751 -1.718 -1.589 -1.772 -1.503 -1.742 -1.713 -1.608 -1.764 -1.479 -1.736 -1.670 -1.629 -1.735 -1.465 -1.704 -1.658 -1.651 -1.719 -1.436 -1.688 -1.654 -1.675 -1.601 -1.358 -1.650 -1.609 -1.712 -1.574 -1.334 -1.646 -1.578 -1.750 -1.400 -1.314 -1.597 -1.566 -1.764 -1.348 -1.270 -1.554 -1.554 -1.705 -1.261 -1.217 -1.508 -1.543 -1.730 -1.193 -1.200 -1.479 -1.526 -1.199 -1.140 -1.177 -1.473 -1.471 -1.177 -1.099 -1.100 -1.467 -1.338 -1.159 -1.090 -1.097 -1.457 -1.307 -1.119 -1.081 -1.090 -1.439 -1.279 -1.005 -1.072 -1.079 -1.422 -1.249 -0.988 -1.055 -1.066 -1.396 -1.198 -0.970 -1.035 -1.042 -1.364 -0.973 -0.953 -1.016 -1.014 -1.329 -0.957 -0.935 -1.006 -0.987 -1.285 -0.941 -0.784 -0.996 -0.957 -1.248 -0.925 -0.759 -0.978 -0.880 -1.215 -0.911 -0.737 -0.915 -0.848 -1.203 -0.899 -0.719 -0.804 -0.820 -1.190 -0.886 -0.702 -0.757 -0.798 -1.177 -0.866 -0.696 -0.723 -0.755 -1.160 -0.845 -0.689 -0.703 -0.721 -1.142 -0.800 -0.683 -0.688 -0.705 -1.128 -0.755 -0.669 -0.672 -0.687 -1.115 -0.733 -0.617 -0.653 -0.662 -1.084 -0.723 -0.563 -0.633 -0.639 -1.079 -0.708 -0.522 -0.618 -0.618 -1.072 -0.690 -0.407 -0.598 -0.592 -1.026 -0.672 -0.349 -0.568 -0.551 -0.866 -0.622 -0.306 -0.540 -0.510 -0.848 -0.601 -0.292 -0.513 -0.478 -0.828 -0.535 -0.278 -0.485 -0.452 -0.809 -0.436 -0.264 -0.438 -0.429 -0.793 -0.428 -0.247 -0.433 -0.404 -0.779 -0.420 -0.214 -0.429 -0.366 -0.759 -0.412 0.067 -0.424 -0.344 -0.752 -0.407 0.080 -0.418 -0.332 -0.750 -0.402 0.093 -0.385 -0.305 -0.749 -0.398 0.106 -0.350 -0.271 -0.747 -0.394 0.132 -0.278 -0.244 -0.640 -0.393 0.164 -0.243 -0.221 -0.629 -0.391 0.172 -0.215 -0.203 -0.618 -0.391 0.180 -0.157 -0.186 -0.600 -0.388 0.188 -0.131 -0.172 -0.573 -0.382 0.195 -0.115 -0.160 -0.546 -0.271 0.280 -0.098 -0.129 -0.480 -0.214 0.320 -0.066 -0.100 -0.449 -0.203 0.354 -0.035 -0.073 -0.421 -0.183 0.379 -0.020 -0.054 -0.286 -0.160 0.404 -0.004 -0.039 -0.241 -0.143 0.432 0.013 -0.016 -0.207 -0.129 0.456 0.035 0.008 -0.196 -0.113 0.474 0.058 0.036 -0.184 -0.069 0.492 0.086 0.064 -0.173 0.144 0.513 0.113 0.092 -0.165 0.183 0.534 0.132 0.113 -0.163 0.222 0.593 0.159 0.130 -0.161 0.250 0.624 0.208 0.149 -0.159 0.277 0.639 0.238 0.168 -0.152 0.281 0.648 0.256 0.192 -0.144 0.285 0.654 0.275 0.218 -0.132 0.372 0.674 0.360 0.238 -0.107 0.511 0.758 0.374 0.255 0.052 0.625 0.787 0.388 0.275 0.075 0.704 0.816 0.397 0.327 0.071 0.723 0.834 0.404 0.338 0.064 0.742 0.850 0.413 0.346 0.055 0.751 0.868 0.423 0.366 0.182 0.755 0.924 0.435 0.382 0.205 0.758 0.950 0.448 0.394 0.262 0.798 0.968 0.470 0.415 0.263 1.119 1.014 0.488 0.435 0.280 1.166 1.038 0.523 0.447 0.317 1.225 1.063 0.558 0.459 0.359 1.308 1.099 0.583 0.471 0.388 1.321 1.117 0.608 0.487 0.434 1.334 1.125 0.637 0.505 0.457 1.346 1.151 0.678 0.517 0.466 1.359 1.177 0.717 0.532 0.474 1.372 1.254 0.752 0.553 0.478 1.395 1.268 0.765 0.564 0.563 1.421 1.282 0.778 0.591 0.604 1.430 1.297 0.794 0.621 0.643 1.434 1.308 0.819 0.635 0.677 1.439 1.323 0.845 0.653 0.708 1.453 1.341 0.849 0.682 0.734 1.470 1.381 0.857 0.701 0.751 1.514 1.411 0.901 0.724 0.792 1.523 1.421 0.920 0.733 1.009 1.525 1.422 0.957 0.745 1.024 1.538 1.416 0.980 0.775 1.035 1.534 1.447 0.998 0.817 1.052 1.545 1.482 1.014 0.831 1.090 1.555 1.506 1.060 0.856 1.118 1.753 1.536 1.099 0.882 1.186 1.769 1.582 1.115 0.902 1.323 1.772 1.615 1.143 0.916 1.319 1.772 1.633 1.157 0.928 1.315 1.775 1.638 1.167 0.927 1.307 1.780 1.637 1.195 0.945 1.300 1.800 1.627 1.230 0.962 1.293 1.810 1.615 1.252 0.974 1.287 1.815 1.602 1.332 0.999 1.281 1.908 1.570 1.355 1.022 1.547 1.947 1.662 1.363 1.022 1.552 1.973 1.694 1.371 1.014 1.548 1.963 1.697 1.400 1.013 1.577 1.967 1.690 1.409 1.021 1.616 2.042 1.685 1.421 1.046 1.806 2.041 1.674 1.437 1.094 1.834 2.047 1.730 1.448 1.120 1.851 2.052 1.739 1.467 1.153 1.842 2.063 1.756 1.484 1.183 1.853 2.082 1.753 1.498 1.189 1.910 2.089 1.738 1.528 1.190 1.941 2.079 1.764 1.550 1.238 1.936 2.047 1.822 1.568 1.240 1.932 2.107 1.843 1.576 1.262 1.927 2.109 1.850 1.602 1.284 1.917 2.088 1.845 1.610 1.303 2.073 2.074 1.830 1.644 1.328 2.071 2.090 1.855 1.656 1.353 2.103 2.061 1.831 1.673 1.375 2.116 2.130 1.798 1.677 1.382 2.154 2.114 1.835 1.672 1.379 2.141 2.112 1.858 1.696 1.360 2.188 2.110 1.855 1.723 1.433 2.183 2.101 1.848 1.727 1.446 2.165 2.085 1.880 1.727 1.446 2.168 2.050 1.865 1.709 1.434 2.168 2.018 1.830 1.693 1.401 2.159 2.027 1.812 1.678 1.389 2.162 2.082 1.826 1.696 1.356 2.160 2.090 1.828 1.713 1.276 2.148 2.093 1.818 1.722 1.292 2.114 2.122 1.842 1.725 1.298 2.060 2.113 1.824 1.737 1.368 2.044 2.113 1.813 1.749 1.406 2.026 2.096 1.805 1.751 1.434 2.006 2.053 1.795 1.752 1.452 2.002 2.042 1.768 1.745 1.456 1.986 1.962 1.773 1.746 1.471 1.962 1.953 1.762 1.718 1.486 1.941 1.903 1.741 1.721 1.486 1.926 1.869 1.735 1.729 1.476 1.913 1.838 1.734 1.733 1.460 1.852 1.822 1.729 1.732 1.459 1.847 1.802 1.717 1.730 1.484 1.696 1.691 1.706 1.709 1.489 1.647 1.669 1.688 1.677 1.495 1.613 1.652 1.660 1.630 1.479 1.601 1.643 1.638 1.590 1.471 1.580 1.621 1.593 1.546 1.421 1.555 1.588 1.549 1.500 1.361 1.512 1.562 1.520 1.465 1.294 1.483 1.540 1.491 1.437 1.223 1.506 1.524 1.462 1.450 1.179 1.490 1.494 1.440 1.454 1.188 1.463 1.469 1.423 1.454 1.218 1.408 1.455 1.424 1.448 1.235 1.370 1.433 1.421 1.442 1.251 1.341 1.422 1.409 1.431 1.278 1.306 1.418 1.405 1.424 1.269 1.251 1.399 1.401 1.422 1.262 1.226 1.372 1.358 1.403 1.289 1.191 1.338 1.334 1.377 1.276 1.150 1.244 1.312 1.352 1.238 1.117 1.204 1.284 1.288 1.175 1.092 1.182 1.266 1.227 1.121 1.049 1.150 1.252 1.154 1.069 1.025 1.121 1.195 1.103 1.028 0.996 1.120 1.118 1.094 1.044 0.923 1.080 1.097 1.101 1.044 0.877 1.074 1.093 1.128 1.053 0.856 1.059 1.078 1.134 1.051 0.831 1.022 1.058 1.136 1.061 0.810 1.004 1.031 1.140 1.074 0.764 0.986 1.044 1.141 1.083 0.746 0.970 1.054 1.125 1.066 0.713 0.960 1.056 1.097 1.032 0.701 0.955 1.036 1.038 0.978 0.670 0.873 0.995 0.977 0.890 0.654 0.860 0.908 0.947 0.850 0.551 0.816 0.877 0.891 0.815 0.522 0.795 0.857 0.848 0.781 0.495 0.764 0.812 0.824 0.755 0.482 0.730 0.762 0.795 0.741 0.426 0.689 0.740 0.750 0.697 0.392 0.658 0.718 0.709 0.643 0.373 0.593 0.684 0.661 0.614 0.351 0.527 0.636 0.633 0.570 0.309 0.515 0.616 0.569 0.543 0.279 0.501 0.575 0.543 0.487 0.244 0.472 0.556 0.508 0.452 0.219 0.452 0.508 0.473 0.426 0.200 0.427 0.452 0.416 0.399 0.152 0.387 0.410 0.357 0.372 0.134 0.364 0.381 0.335 0.329 0.108 0.361 0.356 0.297 0.302 0.072 0.308 0.319 0.240 0.254 0.053 0.283 0.306 0.206 0.204 0.023 0.239 0.221 0.180 0.145 -0.006 0.203 0.168 0.103 0.087 -0.043 0.195 0.135 0.086 0.037 -0.065 0.092 0.090 0.083 0.025 -0.104 0.071 0.054 0.055 0.023 -0.160 0.017 0.033 -0.058 -0.023 -0.199 -0.018 -0.018 -0.082 -0.102 -0.232 -0.055 -0.045 -0.100 -0.098 -0.261 -0.092 -0.110 -0.118 -0.117 -99.000 -0.128 -0.165 -99.000 -0.153 -99.000 -0.155 -0.169 -99.000 -99.000 -99.000 -0.220 -0.183 -99.000 -99.000 -99.000 -0.261 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 -99.000 gri/doc/examples/example8.txt0000644000175000017500000000001513147557614014663 0ustar psgpsgexample8.gri gri/doc/examples/example5.txt0000644000175000017500000000001513147557614014660 0ustar psgpsgexample5.gri gri/doc/examples/example6color.ps0000644000175000017500000040364713147557614015545 0ustar psgpsg%!PS-Adobe-2.0 EPSF-1.2 %%Creator: Gri2.6.0 (released 2000-Jul-26). User=kelley, commandfile=example6color.gri %%Title: example6color.ps %%CreationDate: Mon Mar 5 18:23:07 2001 %%Pages: (atend) %%BoundingBox: (atend) %%TemplateBox: 0 0 612 792 %%DocumentFonts: (atend) %%Endcomments % NOTE: The Gri postscript dictionary is being converted to the Adobe % Illustrator 3.0 dialect of PostScript, as described in the Adobe % documents stored at URL % http://www.adobe.com/Support/TechNotes.html % (as of Jan 1996, this doc is number 5007). When the conversion % is complete, the Adobe Illustrator drawing program -- and any % program compatible with AI -- will be able to edit Gri output. % % The IslandDraw (TM) program is able to read Gri output % at this time; remarkably, it can read/edit arbitrary PostScript. % % The definitions below are presented in the same order as the Adobe % manual. The stack configuration before and after is shown in curly % brackets. All the operators are listed, but only some are defined % here. Most things are faithful, except that no distinction is made % between colors for stroking and filling paths. The string 'WRONGLY' % appears with commands that are approximations. % % PDF-style abbreviations: /rg {setrgbcolor} def % {red green blue} {-} set RGB color /RG {setrgbcolor} def % {red green blue} {-} set RGB color /q {gsave} def /Q {grestore} def /W {clip} def /W* {eoclip} def % % Gri-specific abbreviations: /hsb {sethsbcolor} def % {hue saturation brightness} {-} set HSB color % % Following all try to mimic Adobe Illustrator % % Mimicking section 5.1 of Adobe manual: %A % {flag A} {-} Determine whether % following object can % be selected. Flag=1 % prevents selection; % flag=0 allows it. % Mimicking section 5.2 of Adobe manual: %u % {u} {-} start group %U % end group %q % as 'u' but first item is a clip path %Q % as 'U' but first item is a clip path % Mimicking section 5.3 of Adobe manual: /g {setgray} def % {gray g} {-} Set gray for fill % path, WRONGLY used % for stroking also. /G {setgray} def % As 'g', but for filling path. %k % Set cmyk color for filling path. %K % As 'k', but for stroking path. %x % Set cmyk custom color for filling path. %X % As 'x' but for stroking path. %p % Define pattern for filling path. %P % As 'p' but for stroking path. %O % Specify whether overprinting for fill paths %R % As 'O' but for stroking path. % Mimicking section 5.4 of Adobe manual: /d {setdash} def % {[array] phase d} {-} Set dash. /i {setflat} def % {flatness i} {-} Set flatness. /j {setlinejoin} def % {linejoin j} {-} Set line join. /J {setlinecap} def % {linecap J} {-} Set line cap. /M {setmiterlimit} def % {miterlimit M} {-} Set miter limit. /w {setlinewidth} def % {linewidth w} {-} Set line width. % Mimicking section 5.5 of Adobe manual: /m {moveto} def % {x y m} {-} Move to locn /l {lineto} def % {x y l} {-} Draw line to locn % not a smooth point. % WRONGLY, no % distinction is made % between smooth and % corner. %L % {x y L} {-} As 'l' but a corner %c % Bezier curve to smooth point. %C % As 'c' but to corner point. %v % Something else to do with Bezier. %V % %y % %Y % % Mimicking section 5.6 of Adobe manual: %N % {N} {-} As 'n' for nondrawn stuff /n {newpath} def % {n} {-} WRONGLY interpreted % as path constructor /F {fill} def % {F} {-} Fill current path. %f % {f} {-} 'F' but close first /S {stroke} def % {S} {-} Stroke current path. %s % {s} {-} 'S' but close first %B % {B} {-} As 's' but don't empty path. %b % {b} {-} As 'f' but don't empty path. %H % no-op (weird huh?) /h {closepath} def % {h} {-} Close current path %W % Used to create masks. % Mimicking section 5.7 of Adobe manual: %a % Begin text block ... %e % Similar to 'a' but ... %I % Similar to 'a' but ... %o % Similar to 'a' but ... %r % Similar to 'a' but ... %t % {len (string) t} {-} Render string. %T % End block of text % That's the end of the Illustrator stuff. Following are some Gri % definitions which provide a temporary way of handling fonts. /sf {setfont} def % {fontname sf} {-} Set font name. /sh {show} def % {(text) sh} {-} Show text. /sc {scalefont} def % {size sc} {-} Scale font. % Gri items which should be translated to Illustrator format: /rl {rlineto} def /rm {rmoveto} def % Procedures /cimdict 7 dict def /cim { cimdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def q xll yll translate xur xll sub yur yll sub scale /do cl 3 mul string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop} false 3 colorimage Q end } def /imdict 14 dict def /im { imdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def /imagemap exch def q % Until version 2.6.0 used a 'settransfer' here, but that % triggers a bug in ps2pdf xll yll translate xur xll sub yur yll sub scale /do cl string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop dup length 1 sub 0 1 3 -1 roll { 1 index exch 2 copy get imagemap exch get 255 mul cvi put } for }image Q end } bind def /frdict 5 dict def /fr { frdict begin /yt exch def /xr exch def /yb exch def /xl exch def n xl yb m xl yt l xr yt l xr yb l h F n end } def /plusdict 3 dict def /_plus { plusdict begin dup 0.5 mul /t0 exch def /t1 exch def 0 t0 rm 0 t1 neg rl t0 neg t0 rm t1 0 rl t0 neg 0 rm end } def /timesdict 3 dict def /_times { timesdict begin dup 0.353553 mul /t0 exch def 0.707106 mul /t1 exch def t0 neg t0 rm t1 dup neg rl t1 neg 0 rm t1 dup rl t0 neg dup rm end } def /boxdict 3 dict def /_box { boxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm end } def /filledboxdict 3 dict def /_filledbox { filledboxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm F end } def /diamonddict 2 dict def /_diamond { diamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm end } def /filleddiamonddict 2 dict def /_filleddiamond { filleddiamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm F end } def /triangleupdict 5 dict def /_triangleup { triangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm end } def /filledtriangleupdict 5 dict def /_filledtriangleup { filledtriangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm F end } def /trianglerightdict 5 dict def /_triangleright { trianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm end } def /filledtrianglerightdict 5 dict def /_filledtriangleright { filledtrianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm F end } def /triangledowndict 5 dict def /_triangledown { triangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm end } def /filledtriangledowndict 5 dict def /_filledtriangledown { filledtriangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm F end } def /triangleleftdict 5 dict def /_triangleleft { triangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm end } def /filledtriangleleftdict 5 dict def /_filledtriangleleft { filledtriangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm F end } def /circdict 5 dict def /_circ { circdict begin 0.5 mul /t0 exch def currentpoint /t2 exch def /t1 exch def S n t1 t2 t0 0 360 arc t1 t2 m end } def /bulldict 3 dict def /_bull { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 360 arc h F S end } def /filledhalfmoonupdict 3 dict def /_filledhalfmoonup { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 180 arc h F S end } def /filledhalfmoondowndict 3 dict def /_filledhalfmoondown { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 180 360 arc h F S end } def 1 1 scale 10.0 M 1 j /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-ISOLatin1 exch definefont pop /Courier-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Oblique-ISOLatin1 exch definefont pop /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Bold-ISOLatin1 exch definefont pop /Courier-BoldOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-BoldOblique-ISOLatin1 exch definefont pop /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-ISOLatin1 exch definefont pop /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Bold-ISOLatin1 exch definefont pop /Helvetica-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Oblique-ISOLatin1 exch definefont pop /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Roman-ISOLatin1 exch definefont pop /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Italic-ISOLatin1 exch definefont pop /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Bold-ISOLatin1 exch definefont pop /Palatino-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-BoldItalic-ISOLatin1 exch definefont pop /Symbol findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Symbol-ISOLatin1 exch definefont pop /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Roman-ISOLatin1 exch definefont pop /Times-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Italic-ISOLatin1 exch definefont pop /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Bold-ISOLatin1 exch definefont pop /Times-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-BoldItalic-ISOLatin1 exch definefont pop %%EndProlog %%Page: 1 1 /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:# Gri was invoked by user named %gri:# kelley %gri:# on host named %gri:# Intrusion.phys.ocean.dal.ca %gri:# using the command %gri:# gri -y -p example6color.gri %gri:# at time Mon Mar 5 18:23:07 2001. %gri:# %gri:# The user's ~/.grirc file ... %gri:# ... end of users ~/.grirc file. %gri: %gri:# Example 6color -- Plot IR image of Gulf of Maine %gri: %gri:# define characteristics of norda images %gri:\0val = "5" # 0 in image %gri:\255val = "30.5" # 255 in image %gri:.rows. = 128 %gri:.cols. = 128 %gri:.pixel_width. = 2 %gri:.km. = {rpn .cols. .pixel_width. *} %gri: %gri:# get filenames %gri:query \filename "Name image file" ("example6image.dat") %gri:query \maskname "Name mask file" ("example6mask.dat") %gri: %gri:# get data %gri:open \filename binary uchar %gri:set image range \0val \255val %gri:read image .rows. .cols. box 0 0 .km. .km. %gri:close %gri:open \maskname binary uchar %gri:read image mask .rows. .cols. %gri:close %gri: %gri:# find out what grayscale method to use %gri:query \minT "T/deg for white on page? " ("11") %gri:query \maxT "T/deg for black on page? " ("14") %gri:\incT = "1" %gri: %gri:# set up scales. %gri:set x size 12.8 %gri:set y size 12.8 %gri:set x name "km" %gri:set y name "km" %gri:set x axis 0 .km. 32 %gri:set y axis 0 .km. 32 %gri: %gri:# plot image, grayscale, and histogram %gri:set image colorscale hsb 0 1 1 \maxT hsb .6666666 1 1 \minT %gri:draw image %^ scale 1 170.7 0 1.4225 1 170.7 0 1.4225 %BEGIN_IMAGE 169.266299 169.266299 536.293701 536.293701 128 128 cim 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF88FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0044FF0000FF0000FFEEFF00FFCB00FFA900 AAFF000000FFFFA9000000FF0000FFFF00000000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0044FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0022FF0000FF00AAFF00FFA900FFA900FFA900EEFF00EEFF00CCFF0000FF00CCFF00EEFF 00CCFF0088FF0088FF0088FF0022FF0088FF0044FF0044FF0022FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFA900FFED00FFED00EEFF000088FF FF210000FF210000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF00FF870088FF00FFCB0022FF0000FF0066FF0000FF 0000FF0000FF0022FF0000FF0000FF0000FF0000FF0000FF0000FF0066FF0000FF0000FF00AAFF 0000FF00FFA900FF8700FF8700FFA900EEFF00EEFF00CCFF00CCFF00EEFF00CCFF0088FF0088FF 0088FF0088FF0088FF0066FF0022FF0022FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FFFF6500FF6500FFCB0000FF65CCFF0066FF00 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF88FF0000FFCBCCFF000000FF0044FF0000FF0000FF0000FF0000FF00FFA9 0000FF0000FF0000FF0000FF0000FF0000FF00CCFF00EEFF0000FF0088FF0088FF00CCFF00FFA9 00FFA900FF8700FFA900EEFF00AAFF0088FF0088FF00CCFF00AAFF00AAFF0088FF00AAFF00AAFF 0088FF0066FF0022FF0022FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0022FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FFFF0000FF000000FFA90000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00EEFF00EEFF 00FF00CCFF0000AAFF0000FF0000FF0000FF00EEFF0000FF0000FF0000FF0000FF00CCFF0000FF 0000FF0000FF0000FF0000FF0088FF00CCFF00AAFF00AAFF00CCFF00FFED00FFA900FFA900FFA9 00FFCB00FFED00AAFF0088FF0066FF0088FF0088FF0088FF0088FF0088FF0088FF0088FF0066FF 0044FF0044FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FFFF00000000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FFFF4300AAFF000000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FF0044FF0000FF00 0000FF0000FF00EEFF0000FF0000FF0044FF0000FF0000FF0000FF00FF650000FF0000FF0000FF 0000FF0000FF00CCFF0088FF00FFED00FFCB00FFA900FFCB00FFA900FFA900FFCB00FFED00CCFF 00CCFF0088FF0066FF0088FF00AAFF0088FF0088FF0088FF0088FF0088FF0066FF0044FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0088FFFF00000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FFFF00000000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF00FF21FF00000000FF0000FF0000FF0000FF0000FF0088FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FF8744FF0044FF000000FF0000FF 0000FF0022FF0022FF0088FF0000FF0000FF0000FF00FFCB0000FF0000FF0000FF0000FF0088FF 00EEFF0088FF00EEFF00FFA900FFCB00FFA900FFA900FFCB00FFCB00EEFF00CCFF00AAFF0088FF 0044FF00CCFF00AAFF00AAFF0088FF0088FF0066FF0044FF0000FF0000FF0000FF0044FF0022FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF FF6500FF000088FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0022FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF00AAFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0022FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF00CCFF0000FF00CCFF00FF8700FFED0066FF0000FF0000FF0088FF00CCFF 00EEFF00AAFF0000FF0000FF0000FF0088FF0000FF0088FF0022FF0066FF00EEFF00EEFF0088FF 00FFCB00FFCB00FFA900FFA900FFCB00FFCB00FFED00EEFF00EEFF00CCFF0000FF0000FF00AAFF 0066FF0044FF0088FF0044FF0066FF0022FF0000FF0000FF0022FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0088FFFF0000FF0000 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FF650000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 00FF8700FFED00CCFF0000FF00FF650000FF0000FF0000FF0000FF00EEFF00FFED00FFED00AAFF 0088FF0000FF0000FF0022FF00AAFF00CCFF0088FF00EEFF00FFCB00FF8700FF8700FF6500FF65 00FF8700FF8700FFED00FFED00EEFF00EEFF00EEFF00CCFF00AAFF00AAFF0088FF0088FF0066FF 0044FF0066FF0044FF0022FF0044FF0000FF0022FF0022FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0088FF0000FF0000FF22FF000000FF0000FF 0066FF0000FF0066FF0000FF0000FF0000FF0000FF0000FF0000FF00FF870000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FFA90000FF 0000FF0000FF0000FF0000FF0000FF0088FF00FFA900FF8700FFED00EEFF00CCFF00AAFF0000FF 00FFA900FFA900FFCB00CCFF00CCFF00CCFF00FFCB00FFA900FF8700FF6500FF4300FF8700FF87 00FFCB00EEFF00EEFF00FFED00CCFF00AAFF0088FF0088FF0044FF0088FF0066FF0000FF0066FF 0044FF0000FF0022FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0022FF 0000FF0000FF00CCFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FFA900FF430000FF0000FF0000FF 0000FF00FFCB00FF8700FF8700FF8700FF8700FFED0000FF0088FF0088FF00AAFF00FFCB00FFED 0088FF00FFCB00EEFF00FFCB00FFA900FF6500FF6500FF4300FF4300FF8700FFED00EEFF00EEFF 00FFED00EEFF00AAFF0088FF0088FF0088FF0066FF0088FF0066FF0022FF0044FF0044FF0066FF 0044FF0044FF0088FF0044FF0066FF0066FF0000FF0066FF0022FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF66FF0000EEFF0000FF0000FF FF000066FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0088FFFF00000000FF0022FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF00FF6500FFA90000FF0088FF0000FF0088FF00FFA9 00FF2100FF2100FF4300FF6500FFED0000FF00FFCB00FFCB00CCFF00FFED00CCFF00FFCB00FFCB 00FFED00FFA900FF8700FF4300FF2100FF4300FF6500FFA900FFCB00FFED00EEFF00EEFF00AAFF 00AAFF0088FF0088FF0066FF0044FF0044FF0088FF0066FF0044FF0066FF0066FF0088FF0088FF 0088FF0088FF0088FF0066FF0066FF0088FF0000FF0000FF0066FF0000FF0000FF0044FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FFFF43000000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0044FF0022FF0000FF0000FF0000FF88FF0000FFED0000FF00AAFF00FFA9 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF00FFED00CCFF00FF650000FF0066FF0000FF0066FF0088FF00FF65 0066FF00FFED00EEFF00FFED00FF4300FFCB00EEFF00CCFF00EEFF00FFED00FFA900FFCB00FF87 00FF4300FF2100FF4300FF4300FF8700FFCB00FFCB00EEFF00CCFF00AAFF00CCFF0088FF0088FF 0066FF0088FF0088FF0088FF0088FF0088FF0088FF0088FF00AAFF0088FF00AAFF0088FF00AAFF 00AAFF0088FF0088FF0088FF0088FF0000FF0022FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FFFF65000000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF00FFED0000FF0000FF88FF0000FF2100FF210000FFFF6500FFCB000000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0088FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF00FF4300FFCB00FF6500FFCB00FFA90000FF0000FF0000FF0000FF0000FF0088FF 00FFCB00FFCB00FF4300FFCB00EEFF00EEFF00FFA900FF6500FF8700FFA900FF6500FF2100FF21 00FF4300FF8700FFA900FFCB00EEFF00CCFF00AAFF0088FF0088FF0088FF0088FF0088FF0088FF 00AAFF00CCFF00AAFF00CCFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF 0088FF0088FF0088FF0044FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF00FFCB0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FFFFA90000FF0022FF0000EEFF88FF0044FF0066FF0000FF0000AAFF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0044FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 00FF8700FF4300FFCB0000FF0022FF00CCFF00FF2100FF6500FF2100FFED00FF4300FF0000FF00 00FF8700FFCB00FFCB00FF6500FF4300FF4300FF6500FF6500FF4300FF4300FF4300FF6500FF65 00FFCB00EEFF00EEFF00AAFF0088FF0088FF0088FF0088FF00AAFF00AAFF00CCFF00CCFF00EEFF 00FFCB00FFCB00CCFF00CCFF00CCFF00AAFF0088FF0066FF0044FF0066FF0066FF0088FF0066FF 0066FF0044FF0066FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FFFF650000FFCB88FF00EEFF00FFED00FF210088FF0000FF210000FF0000FF0000FF0088FF 0000FF0000FF0000FF0000FF0000FF00CCFF00FF0000FF000000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0088FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FFA900FF43 0000FF0000FF0000FF0000FF00FF0000FF0000FF0000FF4300EEFF00FF4300FFCB00FFCB00FFCB 0000FF00FF6500FF2100FF4300FF6500FF6500FF4300FF8700FF8700FF8700FF8700FFCB00FFED 00EEFF00EEFF00AAFF00AAFF00AAFF0088FF00AAFF00CCFF00EEFF00EEFF00EEFF00FFED00FFCB 00FFED00CCFF00AAFF00AAFF0088FF0000FF0044FF0044FF0022FF0000FF0000FF0022FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0022FF0000FF 88FF00FF4300FFED00FF2100FF000000FF65FF87000000FF0000FF00FFCBFF0000FF00000000FF 0000FF0000FF0000FF0000FF0044FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0088FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FFA90000FF0000FF 00AAFF88FF0044FF0022FF0000FF000000FF0088FF00CCFF00FFED00FFA900FF4300FF2100FF87 00FF0000FF4300FF4300FF8700FFA900FF8700FF6500FFA900FFA900FFA900FFCB00EEFF00FFED 00CCFF00AAFF00AAFF00CCFF00CCFF00CCFF00FFCB00EEFF00EEFF00FFED00FFCB00FFA900CCFF 00CCFF0088FF0088FF0066FF0044FF0044FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFA9000000FF0000FF0000FF AAFF00FF2100FF0000FF0000FF0000FF2100EEFF000000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FFFF0000FF000000FF650044FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FF2188FF0088FF00AAFF0088FF00 66FF000066FF0000FF0000FF00AAFF00FF8700FF2100FF4300FF2100FF2100FF0000FF2100FF21 00FFA900FFA900FF6500FF4300FF6500FF8700FF8700FF8700FFCB00FFED00AAFF00CCFF00AAFF 00CCFF00EEFF00EEFF00FFA900FF4300FFCB00FFED00FFED00FFA900FFA900CCFF00AAFF0088FF 0088FF0066FF0088FF0066FF0044FF0022FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF00FF870000FF0000FF0000FF0000FF0000FF0000FF0088FF FF0000FF2100FF0000FF0000FF000000FF870088FF0000FF0000FF88FF000000FF0000FF0000FF 0000FFAAFF00EEFF000000FFFF000022FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF00FF00AAFF00CCFF00AAFF0088FF0044FF0000AAFF 0000FF0066FF00FFA900FF0000FF2100FF4300FF2100FF2100FF6500FF870000FF0000FF0000FF 00FF8700FF8700FF8700FF8700FFA900FFA900FFED00EEFF00AAFF00CCFF00CCFF00EEFF00EEFF 00FFED00FFCB00FF2100FF8700FFCB00EEFF00FFCB00FFCB00AAFF00CCFF00FFCB00FFED00AAFF 00CCFF00AAFF0066FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF00FF000000FF0022FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF FF0000FF00000000FF0000FF0000FF0000FF0000FF0044FF0000FF0000FF0000FF00CCFF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00CCFF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0022FF00AAFF 00FF8700FF650000FF00FF2188FF0088FF00AAFF0088FF0066FF0000FF210000FF0000FF00FF00 00FF0022FF0000FF0000FF2100FF2100FF0000FF8700FF8700FF4300FF8700FF8700FF8700FFA9 00FF8700FFA900FFCB00FFED00FFCB00FFA900FFA900FF8700FFA900FF8700FFA900FF6500FF43 00FF0000FF4300FFA900FFCB00FF8700FFCB00CCFF00EEFF00FFCB00FFED00FFCB00FFED00AAFF 0022FF0022FF0000FF0000FF0000FF0022FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FFFF00000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFF87000000FF 0000FF0000FF0000FF0000FF0000FF0000FF0088FF00EEFF0000FF0000FF0000FF0000FF0000FF 0000FF00AAFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FF4344FF0000EEFF00FF0000FF21 00EEFF00FF8788FF00AAFF00AAFF0088FF0088FF0000FF8700FF0022FF0000FF0000FF0000FF00 00FF4300CCFF00FF4300FF0000FF0000FF2100FF4300FF6500FFA900FF8700FFA900FFCB00FFCB 00FFED00FFCB00FFCB00FFCB00FF8700FF6500FF4300FF2100FF2100FF2100FF2100FF2100FF00 00FF6500FFA900FF8700FF6500FFED00EEFF00FFCB00FFA900FFA900FFCB00FFED0022FF0022FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0022FF0000FF0044FF0088FF0000FF0000FF0000FF 0000FF0000FF0000FF0066FF00AAFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF88FF0044FF0000FF2122FF0000FF0044FF00AAFF00 AAFF00AAFF00AAFF0088FF0088FF0066FF0022FF0000FF0000FF0000FF0000FF650066FF00FF87 00FF2100FF0000FF2100FF4300FF6500FF8700FFCB00FFCB00FFCB00FFCB00FFED00FFED00FFED 00FFED00FFA900FF4300FF2100FF0022FF0000FF0000FF2100FF4300FF2100FF0000FF4300FFA9 00FFA900FF4300FF6500FF6500FFA900FF8700FF8700FFA900CCFF0000FF0000FF0000FF0000FF 0022FF0088FF0088FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFEEFF000000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0044FF0000FF0000FF00EEFF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF00CCFF0000FF0000FFAAFF0066FF0022FF0022FF0022FF00AAFF00AAFF00AAFF00AAFF00 AAFF00AAFF0088FF0044FF0044FF0000FF0000FF2100FF0000FF2100FF2100FF2100FF2100FF00 00FF2100FF6500FF8700FF8700FFCB00FFED00FFED00FFED00FFCB00FFED00FF8700FF4300FF00 00FF0022FF0022FF0000FF0000FF0000FF0000FF0000FF2100FF0000FF2100FF4300FF2100FF21 00FF4300FF4300FF6500FF4300FF8700FF870044FF0000FF0022FF0066FF0044FF0044FF0000FF 0044FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF00FF430000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0044FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0044FF00CCFFCCFF0088FF0066FF0044FF0044FF00CCFF00AAFF00AAFF00AAFF00AAFF00AAFF00 66FF0044FF0022FF0022FF0000FF0022FF0000FF2100FF2100FF4300FF4300FF4300FF6500FF87 00FFCB00FFCB00FFCB00FFCB00FFED00FFCB00FFCB00FF6500FF2122FF0066FF0066FF0044FF00 00FF0000FF2100FF2100FF2100FF4300FF4300FF6500FF4300FF2100FF2100FF0000FF4300FF43 00FF4300FF4300FF6500FF8700FFCB0088FF0066FF0066FF0066FF0066FF0066FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FFA90000FF 0000FF0000FF00FF650000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF AAFF0000FF00AAFF0088FF00AAFF00CCFF00AAFF00CCFF00AAFF00AAFF0088FF0066FF0022FF00 00FF0000FF2100FF0000FF0000FF2100FF4300FF6500FF6500FF8700FFA900FFA900FF8700FFCB 00FFCB00FF8700FF8700FF6500FF4300FF2122FF0088FF00AAFF0088FF0088FF0022FF0000FF65 00FF0000FF0000FF4300FF2100FF0000FF0000FF0000FF0000FF2100FF2100FF4300FF4300FF43 00FF4300FF8700FFCB0088FF0088FF0044FF0044FF0022FF0044FF0044FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0022FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FF0000FF00 88FF00AAFF00CCFF00AAFF00AAFF00AAFF0088FF00AAFF0088FF0044FF0000FF0000FF0000FF00 00FF0000FF0000FF2100FFA900FFCB00FFCB00FFCB00FFA900FF6500FF4300FF4300FF4300FF65 00FF0000FF2122FF0044FF0088FF0088FF0088FF0088FF0088FF0000FF0000FF8700FF4300FF21 00FF2100FF2100FF0000FF0000FF2100FF2100FF4300FF4300FF4300FF2100FF2100FF6500FF87 00FFCB0088FF0066FF0044FF0044FF0044FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0022FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF22FF0044FF0088FF00AAFF00 CCFF00AAFF0088FF00AAFF0088FF00AAFF0044FF0000FF0000FF2100FF2100FF0000FF2100FF21 00FF6500FF8700FFCB00FFCB00FFA900FF8700FF6500FF6500FF2100FF2122FF0022FF0044FF00 66FF0088FF00AAFF00AAFF00AAFF0066FF0088FF0000FF0000FF8700FF6500FF4300FF4300FF21 22FF0000FF0000FF4300FF6500FF8700FF4300FF6500FF2100FF4300FF6500FFA900FFED0088FF 0088FF0000FF0000FF0022FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0066FF0044FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF00FF8722FF0044FF0066FF0088FF00AAFF00AAFF00AAFF00 88FF0088FF0088FF00AAFF0022FF0000FF0000FF0000FF2100FF0000FF2100FF4300FF6500FFA9 00FFCB00FFCB00FF8700FF4300FF2100FF2122FF0022FF0066FF0088FF0088FF0088FF00AAFF00 AAFF0088FF0044FF0022FF0044FF0022FF0000FF6500FF8700FF4300FF4300FF2100FF2100FF65 00FF6500FF8700FFA900FFA900FF8700FF6500FF4300FF8700FFA900FFCB0066FF0066FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00CCFF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00AAFF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0088FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FFAAFF0088FF0066FF0088FF0088FF00AAFF0088FF0066FF0066FF0088FF00 88FF00AAFF0000FF0022FF0000FF0000FF2100FF2100FF2100FF2100FF6500FF8700FFA900FFA9 00FF8700FF8700FF2100FF0044FF0066FF0066FF0088FF00AAFF00AAFF0066FF0044FF0044FF00 00FF2100FF0000FF0022FF0000FF0000FF4300FF4300FF6500FF8700FF4300FF6500FF8700FF87 00FF8700FF6500FFA900FF6500FF4300FF4300FFA900EEFF0044FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00EEFF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF00FF210000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 00FFEDAAFF00AAFF0088FF0066FF0066FF0044FF0066FF0066FF0066FF0066FF0088FF0044FF00 00FF0022FF0000FF0000FF4300FF2100FF0000FF2100FF4300FF8700FFA900FFCB00FF8700FF87 00FFA900FF0066FF0088FF0088FF00AAFF00AAFF0066FF0000FF0000FF0000FF2100FF4300FF00 00FF0000FF2100FF4300FF4300FF6500FF8700FFA900FF8700FF8700FF8700FF8700FF8700FF87 00FF6500FF6500FF6500FF8700FFCB0044FF0000FF0000FF0000FF0044FF0022FF0022FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FF650000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0088FF 0044FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FF6500EEFF22FF00AAFF00AAFF00 AAFF0066FF0066FF0044FF0000FF0044FF0044FF0066FF0066FF0066FF0066FF0044FF0044FF00 00FF0000FF4300FF2100FF0000FF2100FF6500FFA900FFCB00FFCB00FFA922FF0044FF0000FF00 AAFF00AAFF00AAFF0088FF0066FF0000FF0000FF0000FF2100FF4300FF2100FF2100FF4300FF43 00FF6500FF4300FF6500FF8700FF8700FF8700FF8700FF8700FF6500FF6500FF6500FF8700FF65 00FF8700FFCB00FFED00AAFF0066FF0088FF0044FF0044FF0022FF0000FF0022FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF00FFCB0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FF650000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF00FF0000FF8744FF0066FF00AAFF00AAFF00AAFF0066FF00 66FF0022FF0000FF0000FF0066FF0066FF0066FF0044FF0066FF0044FF0022FF0000FF0000FF65 00FF4300FF2100FF4300FF6500FFA900EEFF00FFED00FFA900FF2100FF2166FF00AAFF00CCFF00 AAFF0044FF0022FF0022FF0000FF2100FF0000FF4300FF4300FF4300FF4300FF6500FF6500FF65 00FF6500FF8700FF6500FF6500FF6500FF6500FF6500FF8700FF8700FF8700FFA900FFCB00FFED 00CCFF0066FF0066FF0088FF0022FF0044FF0022FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF00CCFF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF00CCFF44FF0088FF00AAFF00AAFF00AAFF00AAFF0088FF0066FF0066FF0044FF00 00FF0000FF0044FF0066FF0066FF0044FF0066FF0044FF0000FF0000FF4300FF6500FF6500FF65 00FFA900FFED00FFCB00EEFF00FFED00FF8700FF6500FF4388FF00AAFF00AAFF0044FF0022FF00 22FF0000FF0000FF0000FF2100FF4300FF6500FF4300FF6500FF8700FF6500FF6500FF6500FF65 00FF6500FF6500FF6500FF8700FF6500FF8700FFA900FFA900FFCB00EEFF00EEFF0088FF0066FF 0088FF0088FF0066FF0000FF0000FF0000FF0000FF0022FF0022FF0022FF0022FF0044FF0088FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 44FF0066FF00AAFF00CCFF00CCFF00AAFF0088FF0044FF0044FF0044FF0022FF0022FF0000FF00 44FF0066FF0066FF0044FF0044FF0022FF0000FF4300FF6500FF6500FF8700FF8700FFA900FFA9 00FFCB00EEFF00FFA900FF6500FF4300FF0066FF00AAFF00AAFF0044FF0044FF0044FF0022FF00 22FF0000FF0000FF6500FF8700FF8700FF8700FF8700FF6500FF6500FF6500FF6500FF6500FF65 00FF4300FF6500FF8700FF8700FFCB00FFCB00EEFF00CCFF00CCFF0088FF0044FF0044FF0044FF 0066FF0022FF0000FF0000FF0000FF0000FF0044FF0066FF0066FF0066FF0088FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF88FF00AAFF00 CCFF00CCFF00AAFF00AAFF0088FF0066FF0066FF0044FF0044FF0022FF0000FF0066FF0088FF00 66FF0066FF0044FF0022FF0000FF8700FFA900FFA900FF8700FF8700FFA900FFCB00FFCB00FFED 00FF8700FF8700FF4344FF0088FF00AAFF00AAFF0044FF0066FF0044FF0022FF0044FF0000FF21 00FF6500FF8700FF6500FF8700FF8700FF6500FF6500FF4300FF4300FF6500FF6500FF6500FF87 00FF8700FFA900FFCB00EEFF00AAFF00EEFF00EEFF0066FF0066FF0066FF0066FF0066FF0022FF 0022FF0022FF0022FF0000FF0066FF0088FF0088FF0044FF0088FF0000FF0022FF00EEFF0088FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFA90044FF000000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF22FF00AAFF00CCFF00EEFF00EEFF00 CCFF00AAFF0088FF0066FF0066FF0044FF0044FF0000FF2122FF0044FF0088FF0044FF0044FF00 44FF0044FF0000FF6500FFA900FF8700FF8700FF6500FF8700FFA900FFCB00FFCB00FFA900FF65 00FF2122FF00AAFF00AAFF0088FF0044FF0066FF0044FF0022FF0044FF0000FF0000FF4300FF21 00FF2100FF6500FF8700FF6500FF6500FF2100FF4300FF4300FF4300FF6500FF8700FFCB00FFED 00FFED00FFED00CCFF00AAFF00CCFF00CCFF0088FF0044FF0066FF0022FF0000FF0022FF0066FF 0066FF0000FF0044FF0088FF00AAFF00CCFF00CCFF0000FF0000FF0088FF0088FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF44FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0088FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF00EEFFCCFF00CCFF00FFED00EEFF00CCFF00AAFF00 88FF0066FF0044FF0044FF0000FF0000FF2144FF0066FF0066FF0044FF0000FF0044FF0000FF00 00FF4300FF8700FF8700FF8700FF4300FF6500FF6500FF6500FF8700FF6500FF6500FF2144FF00 88FF00AAFF0088FF0066FF0066FF0066FF0044FF0044FF0022FF0000FF2100FF2100FF4300FF43 00FF4300FF4300FF2100FF2100FF2100FF4300FF4300FF6500FF8700FFA900FFED00FFCB00FFA9 00EEFF00CCFF00CCFF00AAFF0088FF0066FF0044FF0022FF0044FF0044FF0088FF0066FF0066FF 0088FF0088FF0044FF00EEFF00CCFF00AAFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF00AAFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0088FFEEFF00EEFF00FFED00EEFF00AAFF0088FF0066FF0066FF00 44FF0000FF0000FF2100FF0044FF0044FF0044FF0000FF0000FF4300FF4300FF6500FF8700FFA9 00FF8700FF6500FF4300FF4300FF2100FF4300FF6500FF4300FF0000FF0066FF0088FF00AAFF00 88FF0066FF0066FF0044FF0022FF0000FF0000FF0022FF0000FF0000FF2100FF2100FF4300FF43 00FF4300FF4300FF2100FF2100FF6500FF8700FFED00FFED00FFA900FF6500FF8700FFCB00AAFF 00CCFF00CCFF0088FF0066FF0044FF0022FF0022FF0088FF0088FF00AAFF00AAFF0088FF00CCFF 00EEFF00EEFF00CCFF00FFED0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FFFF87000000FF0000FF0000FF0000FF0000FF0088FF0022FF0022FF00FF870000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0088FF0000FF 0000FF0000FF88FF00EEFF00EEFF00FFED00CCFF00AAFF0066FF0044FF0066FF0044FF0000FF00 00FF0000FF0044FF0022FF0000FF2100FF2100FF8700FF8700FF6500FFA900FFA900FF8700FF43 00FF4300FF0022FF0000FF0022FF0000FF0022FF0044FF0066FF00AAFF00AAFF0088FF0044FF00 66FF0044FF0044FF0022FF0022FF0044FF0022FF0000FF0000FF0000FF2100FF2100FF2100FF00 00FF4300FF2100FF2100FF6500FFA900FFCB00FFA900FFA900FF4300FF4300EEFF00CCFF00CCFF 00AAFF0066FF0088FF0088FF0088FF0088FF0088FF0088FF00AAFF00CCFF00CCFF00EEFF00FFA9 00FFA900FF870000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00AAFF00FF43 0000FF0000FF0066FF00FFA90000FF00AAFF0044FF0066FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0066FF0022FF0000FF0044FF AAFF00EEFF00EEFF00FFCB00EEFF00AAFF0044FF0000FF4322FF0044FF0022FF0000FF0044FF00 00FF0000FF0000FF2100FF4300FF8700FF8700FF4300FF8700FFA900FF4300FF2100FF0044FF00 44FF0044FF0044FF0044FF0088FF00AAFF00AAFF00AAFF0088FF0088FF0066FF0088FF0044FF00 44FF0000FF0044FF0044FF0044FF0000FF0000FF0000FF0000FF2100FF0000FF2100FF2100FF00 00FF0000FF4300FF6500FF8700FF6500FF8700FF4300FF2100FF4300EEFF00AAFF0088FF0088FF 0088FF00AAFF00EEFF00CCFF00CCFF00CCFF00AAFF00CCFF00EEFF00FFED00FFA900FF6500FF43 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0022FF0088FF0000FF0000FF 0022FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFAAFF00EEFF00EEFF00 EEFF00FFED00EEFF00AAFF0066FF0000FF2100FF2144FF0000FF0000FF0022FF0000FF0000FF00 00FF2100FF4300FF6500FF8700FF6500FF8700FFA900FF4300FF4322FF0044FF0044FF0000FF00 22FF0066FF00AAFF00AAFF00AAFF00AAFF00AAFF0088FF00AAFF0066FF0044FF0022FF0022FF00 44FF0044FF0044FF0044FF0000FF0000FF0000FF2100FF0000FF0044FF0044FF0022FF0000FF21 00FF4300FF4300FF2100FF4300FF2100FF2100FF2100FFCB00AAFF00CCFF0000FF00FFED00FFED 00FFCB00FFED00FFCB00EEFF00FFED00FFA900FFCB00FFA900FF6500FF4300FF430000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF88FF00EEFF00FFED00FFED00FFED00 EEFF0088FF0066FF0000FF2100FF0044FF0000FF0000FF4300FF0000FF0000FF4300FF2100FF21 00FF6500FF8700FF4300FF6500FF8700FF6500FF4322FF0044FF0022FF0022FF0066FF0088FF00 AAFF00AAFF00AAFF00AAFF00AAFF0066FF0088FF0044FF0000FF0000FF0022FF0044FF0044FF00 44FF0044FF0022FF0044FF0022FF0044FF0044FF0044FF0066FF0066FF0044FF0000FF0000FF00 00FF2100FF2100FF4300FF2100FF0000FF4300FF8700CCFF00EEFF00FFCB00FF8700FF6500FFA9 00FF8700FFA900FF8700FF8700FF8700FF6500FF4300FF2100FF000000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FF870000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFF2100CCFF0000FF430000FF 0000FF0000FF0000FF0000FF0000FF00FF65EEFF00FFED00FFED00FFED00FFED00AAFF0066FF00 44FF0000FF2122FF0044FF0022FF0000FF2100FF2100FF4300FF2100FF2100FF2100FF6500FFA9 00FF6500FF4300FF4300FF6522FF0044FF0022FF0000FF0022FF0088FF00AAFF00AAFF00AAFF00 CCFF00AAFF0066FF0044FF0022FF0000FF0000FF0000FF2100FF0044FF0044FF0044FF0022FF00 44FF0044FF0044FF0066FF0044FF0044FF0066FF0088FF0066FF0044FF0022FF0000FF2100FF21 00FF2100FF2100FF2100FF0000FF4300FFA900FFED00EEFF00FFA900FF4300FF4300FF6500FF65 00FF4300FF4300FF2100FF4300FF2122FF0000FF000000FF0000FF0044FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FF2166FF0088FF000000FF0000FF0044FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FFFF00000000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF88FF00FFED00EEFF00EEFF00FFED00EEFF00AAFF0066FF0022FF0000FF00 00FF0022FF0022FF0000FF0000FF4300FF2100FF0000FF2100FF2100FF6500FF8700FF8700FF43 00FF0022FF0044FF0022FF0000FF0000FF0088FF00AAFF00AAFF00AAFF00AAFF00EEFF00AAFF00 88FF0066FF0044FF0022FF0000FF0000FF0000FF0022FF0022FF0022FF0000FF0022FF0044FF00 44FF0066FF0066FF0044FF0066FF0066FF0088FF0066FF0022FF0000FF0000FF2100FF2100FF00 00FF2100FF2100FF2100FF6500FFCB00FFA900FFA900FF6500FF2100FF2100FF4300FF2100FF00 00FF0000FF0000FF0000FF0000FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF22FF00AAFF000000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF66FF00FF21000000FF0000FF0000FF00EEFF0000FF00AAFF0000FF 0000FFFFED00FFED00EEFF00FFED00FFED00AAFF00AAFF0044FF0022FF0000FF0000FF0000FF00 00FF2100FF4300FF2100FF0000FF0000FF2100FF0000FF8700FFA900FFCB00FF0000FF0022FF00 00FF0000FF0000FF2122FF00AAFF00AAFF00CCFF00AAFF00AAFF00AAFF00AAFF0066FF0044FF00 66FF0000FF0000FF0000FF0022FF0022FF0022FF0000FF0000FF0022FF0044FF0044FF0044FF00 44FF0044FF0044FF0044FF0044FF0000FF0022FF0000FF0000FF0000FF2100FF0022FF0000FF00 00FF2100FF2100FF8700FFA900FFA900FF8700FF4300FF2100FF2100FF2100FF0000FF2100FF00 00FF0000FF0000FF000000FF0000FF0000FF0000FF0000FF0088FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FFFF0000FF0000FF00000000FF0000FF0022FF88FF0000AAFF0044FFAAFF00FFCB00 FFCB00FFED00FFED00EEFF00AAFF0066FF0022FF0022FF0000FF0000FF0000FF2100FF4300FF43 00FF0022FF0022FF0000FF0000FF0000FF2100FF8700FF8700FF2100FF2100FF2100FF2100FF00 00FF0088FF00AAFF00AAFF00AAFF00CCFF00AAFF00AAFF0066FF0044FF0044FF0044FF0000FF21 00FF0022FF0022FF0022FF0044FF0022FF0022FF0022FF0022FF0022FF0044FF0044FF0044FF00 00FF0000FF0000FF2100FF0000FF0000FF0000FF0000FF0022FF0022FF0000FF0000FF2100FF00 00FF4300FF4300FF6500FF8700FF4300FF4300FF4300FF0000FF0000FF0000FF0000FF0000FF21 00FF210000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF00FF870000FF0000FF0000FF0000FF88FF00AAFF00EEFF00EEFF00FFCB00FFCB00 FFED00CCFF00AAFF0044FF0044FF0022FF0000FF0000FF0000FF2100FF2100FF4300FF0022FF00 44FF0000FF0000FF0000FF2100FF2100FF2100FF2100FF4300FF4300FF2122FF0044FF00AAFF00 AAFF00AAFF00AAFF00AAFF00AAFF00AAFF0088FF0044FF0044FF0044FF0000FF0000FF0000FF00 00FF0000FF0044FF0044FF0044FF0066FF0044FF0044FF0066FF0044FF0022FF0000FF0000FF21 00FF0000FF0000FF0000FF0022FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF21 00FF4300FF4300FF2100FF2100FF4300FF2100FF0000FF2100FF0000FF4300FF4300FF430000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0022FF0000FF0000FF0000FF0000FF0000FF0066FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FFCCFF00AAFF00FFED00FFED00FFED00FFCB00EEFF00CCFF00 88FF0066FF0022FF0000FF0000FF0000FF0022FF0000FF0022FF0066FF0066FF0044FF0000FF00 00FF0000FF2100FF4300FF4300FF0000FF0000FF0022FF0044FF0088FF00AAFF0088FF00AAFF00 AAFF00AAFF00AAFF00AAFF0066FF0044FF0044FF0022FF0044FF0000FF2100FF2100FF0000FF00 22FF0022FF0022FF0044FF0044FF0044FF0044FF0022FF0022FF0000FF2100FF2100FF2100FF00 00FF0000FF0022FF0022FF0000FF2100FF0000FF0000FF4300FF2100FF2100FF0000FF4300FF21 00FF2100FF2100FF4300FF2100FF2100FF4300FF4300FF6500FF6500FF650000FF0000FF0000FF 0088FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0088FFCCFF00EEFF00FFED00FFED00FFED00FFED00EEFF00AAFF0088FF0022FF00 00FF2100FF2100FF2122FF0022FF0044FF0044FF0044FF0044FF0044FF0022FF0000FF0000FF00 00FF4300FF4300FF2144FF0000FF0044FF0066FF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF00 88FF0066FF0066FF0044FF0022FF0022FF0066FF0000FF2100FF2100FF0022FF0022FF0022FF00 22FF0022FF0044FF0044FF0022FF0000FF0000FF0000FF4300FF2100FF2100FF0000FF2100FF21 00FF0000FF0000FF0000FF2100FF2100FF2100FF0000FF2100FF2100FF2100FF4300FF2100FF21 00FF4300FF2100FF4300FF6500FF4300FF4300FF4300FF6500AAFF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0088FF0000FF0000FF 66FF0044FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF CCFF00EEFF00FFED00FFCB00FFED00EEFF00FFCB00FFED00CCFF0088FF0000FF4300FF4300FF43 00FF4300FF0022FF0000FF0022FF0000FF0000FF2122FF0022FF0000FF0000FF4300FF2100FF43 00FF4300FF0000FF0000FF0088FF00AAFF00AAFF0066FF00AAFF0088FF0088FF0088FF0044FF00 66FF0022FF0022FF0022FF0022FF0000FF2100FF0022FF0022FF0044FF0044FF0044FF0044FF00 44FF0044FF0022FF0000FF0000FF2100FF4300FF4300FF6500FF6500FF2100FF2100FF0000FF00 00FF0000FF2100FF4300FF2100FF4300FF4300FF6500FF2100FF2100FF2100FF2100FF2100FF21 00FF6500FF6500FF0000FF2100FF2100FF430000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF00FFCB00EEFF0000FF0000FF0066FF0000FF0000FFFF00000000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFAAFF00CCFF00FFED00 FFED00FFED00EEFF00AAFF00FFCB00FFED00CCFF0066FF0022FF0000FF6500FF4300FF2100FF00 22FF0000FF0000FF2100FF4300FF2100FF0000FF0000FF2100FF4300FF4300FF2100FF0000FF00 00FF0000FF0044FF00AAFF0088FF0088FF00AAFF0088FF0088FF0088FF0066FF0066FF0044FF00 22FF0000FF0044FF0000FF0000FF0022FF0000FF0022FF0044FF0044FF0022FF0000FF0022FF00 00FF2100FF0000FF0000FF6500FF4300FF4300FF6500FF8700FF2100FF4300FF4300FF2100FF43 00FF2100FF2100FF4300FF4300FF4300FF4300FF4300FF2100FF4300FF4300FF4300FF6500FF87 00FF0000FF2100FF2100FF650000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0044FF 0000FF0000FF0088FF0022FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF44FF00EEFF00FFED00EEFF00EEFF00 FFED00EEFF00FFCB00EEFF00AAFF0044FF0000FF0000FF6500FF2100FF2100FF0000FF0000FF00 00FF2100FF4300FF0022FF0022FF0022FF0000FF2100FF6500FF6500FF0000FF0000FF0044FF00 44FF0066FF0066FF0088FF00AAFF0066FF0066FF0088FF0088FF0066FF0044FF0044FF0044FF00 44FF0022FF0000FF0022FF0022FF0022FF0044FF0044FF0000FF0000FF0000FF0000FF0000FF00 00FF2100FF4300FF6500FF8700FF6500FFA900FF4300FF8700FFA900FF6500FF2100FF2100FF21 00FF4300FF4300FF4300FF4300FF2100FF4300FF4300FF4300FF4300FF6500FF6500FF2100FF00 00FF2100FF430000FF0000FF0022FF0000FF0000FF0000FF0000FF0000FF0088FF0000FF0000FF 0022FF0088FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF00EEFF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF00FF00EEFF00EEFF00FFED00EEFF00CCFF00EEFF00EEFF00 FFED00EEFF0088FF0044FF0000FF4300FF6500FF6500FF0000FF2100FF2100FF4300FF6500FF43 00FF2122FF0044FF0044FF0000FF2100FF8700FF8700FF6500FF4300FF0044FF0066FF0066FF00 AAFF00AAFF00AAFF0044FF0066FF0088FF0088FF0066FF0022FF0044FF0066FF0044FF0044FF00 44FF0044FF0022FF0022FF0044FF0044FF0022FF0000FF0000FF0022FF0000FF0000FF4300FF87 00FF8700FF8700FF8700FF8700FFA900FFCB00FFA900FF4300FF2100FF2100FF4300FF4300FF87 00FF4300FF6500FF4300FF4300FF4300FF4300FF6500FF6500FF6500FF4300FF2100FF2100FF43 0000FF0000FF0000FF0088FF0000FF0000FF0044FF0000FF00EEFF0066FF00EEFF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 00FF000000FF0000FF0000FF0088FFFF65000000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FFAAFF00EEFF00EEFF00CCFF00CCFF00CCFF00CCFF00EEFF00EEFF00AAFF00 88FF0000FF0000FF2100FF6500FF8700FF4300FF2100FF4300FF4300FF0000FF2100FF0044FF00 44FF0044FF0000FF0000FF6500FFA900FF8700FF4344FF0088FF0066FF0088FF00AAFF0088FF00 00FF0044FF0044FF0066FF0066FF0066FF0044FF0044FF0044FF0044FF0044FF0044FF0022FF00 22FF0022FF0044FF0044FF0044FF0000FF0000FF0000FF0000FF2100FF4300FF8700FF8700FF87 00FF8700FF8700FFA900FFCB00FFCB00FF4300FF2100FF4300FF4300FFA900FFA900FFA900FF87 00FF6500FF6500FF8700FF8700FF6500FF6500FF4300FF4300FF6500FF4300FF210000FF0000FF 0066FF0000FF0022FF0000FF0000FF0000FF00FFCB00FFA90022FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0044FF00FFED 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 00FF65EEFF00EEFF00CCFF00CCFF00CCFF00CCFF00CCFF00EEFF00EEFF00AAFF0066FF0000FF00 00FF4300FF6500FF8700FF6500FF4300FF4322FF0022FF0022FF0022FF0022FF0066FF0066FF00 44FF0000FF4300FF8700FFA900FF0066FF0044FF0066FF0088FF0088FF0066FF0044FF0066FF00 44FF0088FF0066FF0044FF0044FF0044FF0044FF0066FF0044FF0022FF0000FF0000FF0022FF00 44FF0066FF0044FF0022FF0000FF0000FF2100FF0000FF4300FF2100FF4300FF4300FF8700FFA9 00FFCB00FFCB00FF6500FF4300FF4300FF6500FF8700AAFF00CCFF00FFCB00FF8700FF6500FF65 00FF6500FF6500FF4300FF4300FF4300FF4300FF6500FF2100FF000066FF0000FF0088FF0044FF 0000FF0000FF0066FF0000FF0000FF0044FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0066FF00CCFF0066FF00CCFF0000FF0000FF 0000FFFF00000000FF0000FF0000FF0000FF0000FF0000FF0000FF0088FF0066FF00FF87EEFF00 CCFF00CCFF00CCFF00EEFF00CCFF00CCFF00CCFF00CCFF00AAFF0044FF0000FF0000FF2100FF65 00FF8700FF6500FF4300FF2100FF2100FF0044FF0044FF0044FF0066FF0088FF0044FF0000FF21 00FFA900FF2100FF0022FF0044FF0088FF0066FF0066FF0066FF0066FF0066FF0066FF0088FF00 66FF0022FF0066FF0066FF0066FF0022FF0022FF0022FF0000FF0000FF0022FF0044FF0066FF00 66FF0044FF0000FF0000FF0000FF0000FF0000FF0000FF2100FF4300FF4300FFA900FFCB00FFA9 00FF8700FF6500FF4300FF8700FFCB00AAFF00CCFF00EEFF00FFA900FF6500FF4300FF8700FF21 00FF4300FF4300FF4300FF4300FF4300FF4300FF210000FF00CCFF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FFFFA9000000FF0000FF0000FF0044FF0000FF0000FF 0000FF0000FF00FFCB0000FF0000FF0000FF0000FF0044FF0000FF44FF00EEFF00CCFF00EEFF00 EEFF00EEFF00CCFF00CCFF00CCFF00AAFF0088FF0044FF0000FF0000FF2100FF8700FF4300FF65 00FF4300FF6500FF0044FF0044FF0044FF0066FF0066FF0066FF0000FF0000FF4300FF6500FF00 00FF0044FF0044FF0044FF0044FF0088FF0066FF0066FF0066FF0066FF0088FF0066FF0066FF00 66FF0044FF0044FF0022FF0022FF0044FF0044FF0044FF0022FF0044FF0044FF0066FF0044FF00 22FF0022FF0022FF0022FF0000FF6500FF2100FF2100FF4300FF4300FF8700FF8700FF8700FF87 00FF6500FF8700FFED0088FF00CCFF00FFED00FFCB00FF6500FF6500FF2100FF2100FF2100FF43 00FF6500FF4300FF6500FF4300FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0044FF0000FF0000FF0000FF0000FF FFA9000000FF0000FF0000FF0088FF0000FF0000FF0000FFCCFF00CCFF00AAFF00EEFF00CCFF00 CCFF00AAFF00AAFF00AAFF0066FF0044FF0000FF0000FF4300FF6500FF4300FF6500FF6500FF21 44FF0044FF0044FF0066FF0066FF0044FF0066FF0022FF0000FF4300FF4300FF2122FF0022FF00 44FF0044FF0066FF0066FF0066FF0066FF0044FF0066FF0088FF0066FF0066FF0066FF0044FF00 44FF0066FF0044FF0044FF0066FF0044FF0044FF0044FF0066FF0088FF0044FF0044FF0022FF00 00FF0000FF0022FF0000FF0000FF4300FF4300FFA90066FF00FFA900FF8700FFA900FF8700FFA9 00FFED00CCFF00FFCB00FFCB00FFCB00FF6500FF4300FF0000FF0000FF2100FF6500FF6500FF43 00FF2100FF2100FF000000FF0000FF0000FF0000FF0000FF0044FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0088FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 00FF65AAFF0066FF000000FF0000FF00CCFFCCFF00AAFF00AAFF00CCFF00CCFF00AAFF00AAFF00 AAFF0088FF0066FF0000FF0000FF2100FF6500FFA900FF8700FF2100FF0066FF0066FF0044FF00 66FF0044FF0044FF0044FF0044FF0044FF0000FF0000FF2100FF0022FF0022FF0044FF0044FF00 66FF0066FF0066FF0066FF0066FF0088FF0066FF0088FF0088FF0066FF0066FF0066FF0044FF00 44FF0022FF0022FF0022FF0066FF0066FF0066FF00AAFF0066FF0066FF0044FF0044FF0000FF00 00AAFF00FF2100FF0000FF2100FFED00FF8700FFED00FF6500FF8700FF8700FFCB00FFED00FFED 00FFCB00FFA900FFCB00FF6500FF2100FF0000FF0000FF4300FF4300FF4300FF4300FF0000FF00 00FF000000FF0066FF0000FF0000FF0000FF0044FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0044FF0000FF 0000FFAAFF00FF000044FF00EEFF00CCFF00CCFF00AAFF00AAFF00CCFF00AAFF00AAFF0088FF00 66FF0022FF0000FF4300FF8700FFA900FF8700FF0088FF0066FF0044FF0066FF0044FF0022FF00 44FF0044FF0044FF0022FF0000FF0000FF2144FF0044FF0044FF0044FF0066FF0088FF0066FF00 88FF0088FF0088FF0088FF0088FF00AAFF00AAFF0088FF0088FF0066FF0088FF0066FF0044FF00 00FF0000FF0022FF0022FF0022FF0088FF0088FF0066FF0066FF0044FF0022FF0000FF0000FF21 00FF4300FF4300FF6500FFA900FF6500FF6500FFA900FFCB00FFED00FFCB00FFA900FFA900FFCB 00FFA900FF8700FF2100FF0000FF0000FF2100FF4300FF4300FF0022FF0022FF0022FF000088FF 0000FF0000FF0000FF0000FF00EEFF0000FF0000FF0000FF0022FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0044FF0000FF0000FF0000FF00FFA900FF000066FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0044FF00CCFF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FFEEFF00EEFF00EEFF00CCFF00AAFF00CCFF00AAFF00AAFF0088FF0044FF0000FF00 00FF2100FF6500FF4366FF0088FF0088FF0066FF0044FF0000FF0000FF2100FF2100FF0044FF00 44FF0022FF0000FF0000FF4344FF0066FF0066FF0066FF0088FF0088FF0066FF0088FF0088FF00 88FF0088FF00AAFF00AAFF0088FF00AAFF0088FF0066FF0066FF0066FF0066FF0044FF0022FF00 22FF0000FF0022FF0022FF0044FF0066FF0044FF0022FF0000FF0000FF4300FF2100FF6500FF21 00FF4300FF6500FF6500FF6500FFA900FFED00FFED00FFED00FFED00FFA900FF8700FF6500FF43 00FF2100FF0000FF0000FF0000FF0000FF0022FF0022FF0022FF0022FF000000FF0000FF0000FF 0066FF0000FF0000FF0000FF0000FF00AAFF00CCFF0066FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF00AAFF0000FF0000FF0000FF00EEFF0000FF0000FF0000FF0000FF0000FF0000FF FFED00FFED00EEFF00EEFF00AAFF00AAFF00AAFF0088FF0066FF0066FF0022FF0000FF0000FF43 00FF4366FF0066FF0044FF0000FF2100FF0000FF0000FF2100FF4300FF4366FF0066FF0044FF00 00FF0000FF4344FF0066FF0066FF0066FF00AAFF0088FF0088FF0088FF00AAFF0088FF00AAFF00 AAFF00AAFF00AAFF00AAFF0088FF0088FF0088FF0088FF0066FF0044FF0022FF0000FF0022FF00 22FF0000FF0000FF0000FF2100FF4300FF0000FF4300FF8700FF4300FF8700FF4300FF6500FF21 00FF4300FF6500FFA900FFED00EEFF00EEFF00EEFF00FFA900FF6500FF4300FF2100FF0022FF00 00FF2100FF0000FF0022FF0044FF0022FF0000FF0000FF000000FF0000FF0000FF0066FF0000FF 0000FF0000FF0000FF00FFCB00FF6500FFA90000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF00AAFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFAAFF0000FF43FFED00 FFED00CCFF00AAFF00AAFF00AAFF00AAFF0088FF0066FF0044FF0022FF0000FF0000FF4344FF00 44FF0000FF2100FF2100FF0000FF0000FF0000FF2100FF2100FF2144FF0044FF0044FF0000FF00 44FF0044FF0088FF0088FF00AAFF0066FF0088FF00AAFF00AAFF0088FF00AAFF00AAFF00AAFF00 AAFF00AAFF00AAFF00AAFF00AAFF0088FF0066FF0066FF0022FF0022FF0022FF0000FF0000FF21 00FF2100FF4300FF6500FF4300FF6500FF8700FF6500FFA900FFA900FF6500FF4300FF4300FF43 00FFA900FFED00EEFF00CCFF00EEFF00FFA900FF6500FF4300FF0000FF0000FF0000FF0022FF00 22FF0022FF0044FF0044FF0000FF0000FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF00CCFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0088FF0000FF0000FF0000FF0000FF0000FF0000FF0044FF0000FF0000FF 0000FF0088FF0000FF0000FF0000FF0000FF0000FF0000FFCCFF0066FF00FFCB00FFED00FFED00 CCFF00AAFF00AAFF00CCFF00AAFF0088FF0066FF0066FF0044FF0000FF0066FF0044FF0000FF00 00FF0000FF0022FF0022FF0000FF2100FF2100FF4300FF4344FF0044FF0000FF0044FF0066FF00 88FF0088FF0088FF0066FF0088FF00AAFF00AAFF00AAFF0088FF00AAFF00AAFF00AAFF00AAFF00 AAFF00AAFF00AAFF0088FF0088FF0044FF0000FF0000FF0000FF2100FF2100FF2100FF6500FF65 00FF8700FFA900FF8700FFA900FF8700FFCB00FFCB00FF6500FF4300FF6500FF6500FFA900FFCB 00FFED00EEFF00EEFF00FFCB00FF6500FF4300FF2100FF0000FF0000FF0022FF0022FF0022FF00 44FF0000FF0000FF0000FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0088FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0088FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FFFF87000088FFFFCB00FFED00FFCB00FFCB00FFED00 FFED00EEFF00EEFF00EEFF0088FF0088FF0066FF0066FF0066FF0066FF0000FF0000FF0000FF00 00FF0000FF0000FF2100FF4300FF6500FF4300FF2166FF0044FF0044FF0066FF0044FF0044FF00 88FF0066FF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF0088FF00 AAFF0088FF0066FF0044FF0000FF2100FF2100FF2100FF0000FF2100FF6500FF4300FF6500FF87 00FFA900FFA900FFCB00FFED00FFCB00FF4300FF6500FF8700FFA900FFCB00FFCB00FFED00FFED 00FFA900FF8700FF8700FF4300FF2100FF2100FF0000FF0000FF0044FF0044FF0044FF0022FF00 00FF2100FF000000FF0000FF0000FF0000FF0000FF0066FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00EEFF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF00FF870088FF0000FFFF87000000FF0000FF0022FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0022FF66FF00FFA900FFA900FF6500FFA900FFA900FF0000FF2100 FF4300FFA900FFED00AAFF0088FF0066FF0088FF0066FF0022FF0022FF0000FF2100FF2100FF65 00FF8700FF6500FF8700FF8700FF4366FF0088FF0044FF0044FF0044FF0044FF0088FF0066FF00 88FF00AAFF00AAFF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF0066FF0088FF0088FF00 66FF0000FF0000FF0000FF2100FF4300FF4300FF2100FF4300FF6500FF6500FF8700FFA900FFA9 00FFA900FFCB00FF6500FF6500FFCB00FFA900FFA900FFCB00FFA900FFA900FFA900FF8700FF65 00FF6500FF6500FF2100FF2100FF0000FF0022FF0022FF0044FF0022FF0000FF0000FF0022FF00 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0066FF0000FF0000FF0000FF0000FF0000FF 0000FF0088FF0088FF0000FF66FF00FF4300FF2100FF6500FFED00AAFF00FF8700FF8700FF8700 FF8700CCFF00AAFF0088FF0088FF0044FF0022FF0022FF0000FF4300FF8700FF6500FFA900FF87 00FF4300FF2100FF2122FF0044FF0022FF0022FF0066FF0066FF0088FF0088FF0066FF0066FF00 88FF0088FF0088FF00AAFF00AAFF00CCFF00AAFF0066FF0044FF0066FF0066FF0044FF0000FF00 00FF0000FF2100FF2100FF2100FF4300FF2100FF4300FF6500FF8700FFCB00FFA900FFA900FF87 00FF8700FF8700FFA900FFCB00FFA900FFA900FFA900FF8700FF8700FF8700FF6500FF4300FF43 00FF0000FF2100FF2100FF0000FF0022FF0022FF0022FF0044FF0000FF0044FF000000FF0000FF 0066FF0066FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF00FF21AAFF00FF0000FF00000000FF00AAFFAAFF00FFCB00FFCB00FFA900EEFF00 AAFF0088FF0066FF0044FF0000FF0000FF2100FF4300FF6500FF8700FF8700FF4300FF4322FF00 00FF2100FF0066FF0022FF0066FF0066FF0088FF0088FF0088FF0066FF0044FF0066FF00AAFF00 AAFF00AAFF00AAFF00CCFF00AAFF0022FF0044FF0066FF0066FF0044FF0022FF0000FF2100FF43 00FF2100FF2100FF2100FF2100FF2100FF4300FF6500FF6500FF6500FF6500FF8700FF6500FFA9 00FFCB00FFA900FFCB00FFCB00FFCB00FF8700FFA900FF4300FF6500FF6500FF4300FF2100FF43 00FF4300FF2100FF0000FF0044FF0022FF0022FF0022FF0044FF0000CCFF0022FF0088FF0088FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0088FF0066FF0000FF0000FF0000FF00AAFF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 22FF000000FF0000FF00FFCB0000FF00AAFF00FF65EEFF00FFED00FFA900FFED00AAFF00AAFF00 66FF0044FF0000FF0000FF2100FF4300FF4300FF8700FF8700FF2100FF2100FF2122FF0022FF00 44FF0044FF0044FF0066FF0066FF0088FF0066FF0044FF0066FF0088FF00AAFF00AAFF00AAFF00 AAFF00CCFF00AAFF0000FFCB00FFA988FF0066FF0022FF0022FF0000FF2100FF2100FF2100FF00 00FF0000FF0000FF0000FF4300FF4300FF6500FF4300FF4300FF4300FF4300FF8700FFA900FFA9 00FFA900FF8700FF6500FF8700FF8700FF6500FF6500FF4300FF4300FF4300FF4300FF0000FF21 00FF0000FF0022FF0022FF0066FF0066FF0066FF000000FF0000FF0044FF00AAFF0088FF0022FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF00AAFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF00AAFF0000FF0000FF22FF0088FF00CCFF00FFCB00FFED00AAFF00AAFF0088FF0044FF00 22FF0000FF4300FF4300FF4300FF4300FF4300FF0000FF2100FF4300FF4300FF8700FF4300FF21 44FF0066FF0066FF0066FF0044FF0066FF0066FF0088FF00AAFF0088FF00AAFF00CCFF00CCFF00 CCFF0088FF0066FF0088FF0066FF0022FF0000FF0000FF0000FF2100FF2100FF0000FF0000FF00 00FF0000FF2100FF4300FF4300FF4300FF4300FF4300FF4300FF8700FFA900FF8700FF8700FF65 00FF4300FF8700FF8700FF6500FF4300FF4300FF4300FF2100FF2100FF0022FF0044FF0044FF00 44FF0044FF0066FF0066FF0066FF000000FF0022FF0000FF0022FF0000FF00FF000000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00AAFF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FF210000FF0000FF0066FF00AAFF00FFA9 00FFA900AAFFAAFF00AAFF00AAFF00CCFF00EEFF00AAFF00AAFF00AAFF0044FF0044FF0000FF43 00FF4300FF2100FF2100FF2122FF0000FF0000FF6500FF8700FF8700FF6500FF6544FF0022FF00 66FF0066FF0066FF0066FF0088FF0088FF0088FF00AAFF00AAFF00AAFF00CCFF00CCFF00AAFF00 66FF0066FF0066FF0044FF0022FF0022FF0000FF0000FF0000FF0000FF0022FF0000FF0000FF00 00FF4300FF4300FF4300FF4300FF4300FF4300FF6500FF6500FF6500FF4300FF4300FF4300FF65 00FF6500FF6500FF4300FF4300FF2100FF0000FF0044FF0044FF0066FF0066FF0066FF0044FF00 44FF0044FF0066FF000000FF0044FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0066FF0000FF0000FF0022FF0000FF0000FF0000FF0000FF00FF6588FF0066FF00 AAFF00AAFF00AAFF00AAFF00EEFF00AAFF00AAFF00AAFF0066FF0000FF0000FF0000FF4300FF21 22FF0000FF0000FF2100FF4300FF4300FF8700FFA900FF6500FF4300FF0044FF0066FF0088FF00 66FF0066FF0088FF0088FF0088FF00AAFF00AAFF00CCFF00CCFF00CCFF00CCFF00AAFF0044FF00 44FF0022FF0044FF0044FF0000FF0000FF0000FF0022FF0022FF0000FF0022FF0022FF0000FF00 00FF2100FF2100FF4300FF2100FF4300FF4300FF4300FF4300FF4300FF2100FF2100FF0000FF65 00FF4300FF0022FF0022FF0044FF0066FF0066FF0044FF0022FF0066FF0044FF0044FF0044FF00 66FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF00AAFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF00FF8700FFA966FF00AAFF00AAFF00AAFF00AAFF00 AAFF00AAFF00CCFF00CCFF00AAFF00AAFF0088FF0044FF0000FF0000FF4300FF0000FF0022FF00 00FF4300FF4300FF6500FF6500FF6500FF2144FF0044FF0066FF0066FF0066FF0066FF0088FF00 88FF00AAFF0088FF00AAFF00AAFF00CCFF00CCFF00CCFF00AAFF00AAFF00AAFF0088FF0044FF00 66FF0044FF0022FF0000FF0000FF0044FF0022FF0022FF0022FF0022FF0000FF0000FF0000FF43 00FF4300FF2100FF2100FF2100FF0000FF0000FF2100FF2100FF0000FF0000FF2100FF2144FF00 44FF0044FF0044FF0066FF0044FF0044FF0044FF0066FF0066FF0066FF0044FF0066FF000000FF 0000FF0000FF0000FF0000FF0044FF22FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF00CCFF00FFCB44FF00AAFF00AAFF00CCFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00 AAFF00EEFF00AAFF00AAFF0088FF0044FF0000FF0000FF4322FF0022FF0022FF0000FF6500FF43 00FF4300FF4300FF2122FF0066FF0044FF0066FF0066FF0066FF0066FF0066FF0088FF0088FF00 88FF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00CCFF00AAFF00AAFF0088FF00AAFF0044FF00 22FF0000FF0022FF0044FF0022FF0000FF0022FF0000FF0000FF0000FF2100FF2100FF4300FF21 00FF2100FF4300FF0022FF0066FF0066FF0088FF0066FF0022FF0000FF0044FF0044FF0044FF00 44FF0044FF0000FF0022FF0044FF0066FF0088FF0066FF0066FF0066FF000000FF0000FF0000FF 0022FF0000FF0000FF0044FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF00AAFF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF00CCFF0000FF0000FF0000FF0000FF00FFA900FF2122FF0044FF00 22FF00CCFF00EEFF00EEFF00FFCB00FFED00EEFF00CCFF00AAFF00AAFF00AAFF00AAFF00EEFF00 AAFF0088FF00AAFF0044FF0044FF0000FF0022FF0044FF0000FF4300FF6500FF6500FF2100FF00 00FF0022FF0022FF0022FF0044FF0044FF0044FF0066FF0066FF0088FF0088FF0088FF00AAFF00 AAFF00AAFF00AAFF00AAFF00CCFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF0066FF0022FF00 22FF0022FF0022FF0000FF2100FF0000FF0000FF0000FF0000FF2100FF4300FF6500FF0000FF21 00FF0000FF0066FF0066FF0088FF0066FF0022FF0022FF0044FF0044FF0044FF0044FF0022FF00 44FF0022FF0022FF0088FF0088FF0066FF0044FF0044FF000000FF0000FF00AAFF00FF870000FF 0066FF00FFED0000FF0000FF0000FF0000FF0000FF0088FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FF43 0000FF0066FF0088FF00CCFF0000FF0000FF0088FF66FF00FFA900CCFF00CCFF00EEFF00FFCB00 FFA900FFA900FFCB00EEFF00EEFF00EEFF00CCFF00AAFF00AAFF00AAFF00AAFF00AAFF0088FF00 88FF0044FF0066FF0000FF0044FF0044FF0000FF6500FFCB00FF6500FF0000FF0022FF0044FF00 44FF0022FF0044FF0044FF0044FF0044FF0066FF0066FF0088FF0088FF00AAFF00AAFF00AAFF00 AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF0088FF0066FF0044FF0044FF0022FF00 00FF0000FF2100FF0022FF0000FF0000FF0000FF2100FF4300FF4300FF4300FF0000FF0000FF00 44FF0044FF0088FF0066FF0000FF0044FF0044FF0044FF0022FF0022FF0022FF0022FF0022FF00 44FF0044FF0066FF0044FF0044FF0000FF000000FF0000FF0000FF00CCFF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 00FF650000FF00CCFF0000FF0044FF00FF6500CCFFAAFF00EEFF00FFCB00FF8700FFA900FFCB00 FFCB00EEFF00EEFF00EEFF00CCFF00AAFF00AAFF00AAFF0088FF0066FF0066FF0066FF0044FF00 66FF0044FF0044FF0022FF0000FF2100FFA900FFA900FF0000FF0044FF0066FF0044FF0044FF00 66FF0066FF0066FF0066FF0044FF0066FF0088FF0066FF00AAFF0088FF00AAFF00CCFF00AAFF00 AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF0066FF0066FF0044FF0022FF0000FF2100FF00 44FF0044FF0044FF0000FF0000FF0000FF0000FF4300FF4300FF2100FF2100FF0000FF0022FF00 88FF0066FF0000FF0044FF0044FF0022FF0022FF0022FF0022FF0022FF0022FF0022FF0044FF00 66FF0044FF0044FF0022FF000022FF0000FF00FFED0088FF0000FF0000FF0000FF0000FF0000FF 0000FF66FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0088FF0000FF0000FF66FF00 00FF2100FF2100FF4300FFEDEEFF00FFA900FF8700FF8700FFA900FFCB00FFCB00FFED00EEFF00 CCFF00CCFF00CCFF00CCFF00AAFF00AAFF0088FF0066FF0088FF0066FF0088FF0044FF0022FF00 44FF0044FF0000FF4300FF8700FFA900FF8700FF2122FF0044FF0044FF0066FF0044FF0066FF00 66FF0066FF0044FF0066FF0066FF0066FF0088FF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF00 AAFF00AAFF00AAFF00AAFF00AAFF0066FF0066FF0044FF0022FF0000FF0044FF0044FF0044FF00 66FF0044FF0022FF0000FF0000FF2100FF2100FF4300FF4300FF4300FF0000FF0088FF0044FF00 00FF0022FF0022FF0022FF0022FF0022FF0022FF0044FF0044FF0022FF0044FF0066FF0066FF00 44FF0022FF000000FF0000FF0022FF0044FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0066FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0022FF0000FF00FF870088FF00FFCB0000FF0000FF0088FF00FF4344FF00 FFCB00CCFF00FF8700FFA900FF8700FFA900FFA900FFCB00FFCB00FFED00CCFF00CCFF00AAFF00 AAFF00AAFF00AAFF0088FF0066FF0044FF0088FF0088FF0088FF0066FF0022FF0066FF0044FF00 00FF4300FF6500FF6500FF8700FF8700FF2100FF0066FF0066FF0066FF0066FF0088FF0066FF00 66FF0044FF0044FF0044FF0088FF0088FF00AAFF0088FF00AAFF00AAFF00AAFF00AAFF00CCFF00 AAFF00AAFF00AAFF0088FF0088FF0066FF0000FF0022FF0044FF0066FF0066FF0066FF0088FF00 66FF0000FF0000FF0000FF0000FF2100FF4300FF4300FF4300FF0088FF0044FF0022FF0022FF00 22FF0044FF0044FF0088FF0066FF0044FF0044FF0044FF0044FF0044FF0066FF0044FF0022FF00 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0022FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0022FF0000FF0000FF0000FF0000FF 0000FF00EEFF00FFA900FFCB22FF0000CCFF00EEFF00AAFF0022FF00FF65EEFF00FF8700FF8700 FFA900FFA900FFA900FFA900FFCB00FFA900FFCB00FFED00CCFF00AAFF00CCFF00AAFF00AAFF00 88FF0088FF0066FF0066FF0066FF0088FF00AAFF0066FF0066FF0066FF0022FF0000FF2100FF65 00FF6500FF8700FF8700FF4300FF0044FF0022FF0022FF0066FF0066FF0066FF0066FF0044FF00 66FF0044FF0088FF0088FF0088FF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00 AAFF00AAFF0088FF0066FF0022FF0044FF0044FF0066FF0066FF0066FF0088FF0066FF0044FF00 44FF0000FF0000FF0000FF2100FF2100FF4300FF4344FF0044FF0044FF0022FF0066FF0066FF00 66FF0066FF0044FF0044FF0044FF0044FF0044FF0044FF0066FF0044FF0044FF000000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF00FF650000FF0044FF0000FF0000FF0066FF00FF00 00FF430088FF00FF6500FF870088FF00EEFF00FF21FFCB00EEFF00EEFF00FF8700FF8700FF8700 FFA900FFCB00FFA900FFA900FFED00EEFF00AAFF00AAFF00AAFF00AAFF00AAFF0088FF0088FF00 66FF0088FF0066FF0066FF0044FF0066FF0044FF0044FF0044FF0000FF0000FF4300FF4300FF43 00FF4300FF4322FF0044FF0044FF0066FF0088FF0066FF0022FF0022FF0044FF0066FF0088FF00 88FF0088FF0088FF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00 88FF0066FF0044FF0044FF0044FF0022FF0066FF0066FF00AAFF00AAFF0066FF0044FF0044FF00 22FF0000FF0000FF2100FF4300FF2122FF0088FF0066FF0066FF0066FF0066FF0088FF0066FF00 66FF0044FF0044FF0044FF0044FF0044FF0044FF0044FF0044FF000000FF0000FF0000FF0088FF 00FF000088FF00AAFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FFFF00000000FF0000FF0088FF66FF0000FFCB00FFCB 00EEFF00FFED00FF6500FF21EEFF00FF8700FF6500FF8700FF8700FF6500FF8700FFA900FFA900 FFED00FFED00EEFF00EEFF00AAFF00AAFF00AAFF0088FF00AAFF0066FF0066FF0088FF0066FF00 44FF0022FF0000FF0066FF0044FF0044FF0022FF0000FF0000FF2100FF4300FF8700FF2100FF65 00FF6544FF00AAFF0088FF00AAFF0088FF0044FF0044FF0066FF0066FF0066FF0088FF0088FF00 88FF00AAFF00AAFF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF0088FF00AAFF00AAFF0088FF00 66FF0044FF0044FF0066FF0066FF0088FF00AAFF00AAFF0088FF0066FF0044FF0044FF0044FF00 22FF0000FF0000FF0000FF0066FF0088FF0088FF0066FF0066FF0088FF0066FF0066FF0044FF00 44FF0044FF0066FF0066FF0066FF0066FF0088FF000000FF0000FF0000FF0000FF0000FFFF0000 66FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0044FF0022FF0000FF0044FF00FFED00FFA900FF0022FF0000FF21 44FF0088FF0000FF43FFA900FF2100FF4300FF6500FF6500FF6500FFA900FFCB00FFED00EEFF00 FFED00EEFF00EEFF00CCFF00AAFF00AAFF00AAFF0066FF0066FF0066FF0088FF0066FF0044FF00 22FF0044FF0044FF0044FF0044FF0000FF0000FF0000FF0000FF2100FF2100FFA900FFCB00FF21 44FF0066FF00AAFF0088FF0066FF0066FF0066FF0044FF0088FF0088FF0066FF00AAFF00AAFF00 AAFF00AAFF00AAFF00CCFF00AAFF00AAFF00AAFF0088FF0088FF0088FF0088FF0066FF0044FF00 66FF00AAFF00AAFF00AAFF00AAFF0088FF0088FF0066FF0044FF0044FF0044FF0044FF0022FF00 00FF0000FF2122FF0088FF0088FF0088FF0088FF0088FF0066FF0066FF0066FF0044FF0044FF00 66FF0088FF0088FF0088FF00AAFF000000FF0000FF0066FFFF4300FF00000000FF0000FF0000FF 0000FF0000FF0000FF00EEFF00EEFF0000FF0000FF0000FF0000FF0000FF0022FF0000FF0000FF 0000FF0000FF0044FF00FF650000FF0088FF0088FF00FF8766FF0000FF87AAFF00EEFF00FF2100 FF8700FF8700FF4300FF2100FF4300FF6500FF4300FF8700FFED00CCFF00FFED00FFCB00EEFF00 EEFF00CCFF00AAFF00AAFF0066FF0066FF0066FF0088FF00AAFF00AAFF0088FF0088FF0066FF00 44FF0044FF0044FF0022FF0000FF2122FF0000FF2100FF2100FF4300FF8700FFCB00FF8788FF00 AAFF0066FF0088FF0088FF0066FF0066FF0088FF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF00 CCFF00CCFF00AAFF00AAFF00AAFF0088FF0088FF00AAFF0088FF0066FF0066FF00AAFF00AAFF00 AAFF00AAFF00AAFF00AAFF0088FF0088FF0044FF0044FF0044FF0022FF0022FF0022FF0000FF00 22FF0022FF0088FF0088FF0088FF0088FF0088FF0044FF0066FF0044FF0044FF0066FF0088FF00 AAFF00AAFF0088FF000000FF0000FF0000FF00FF650088FF0000FF0088FF0000FF0000FF0000FF 0000FF0000FF0000FF0066FF0088FF0000FF00CCFF0000FF0000FF0000FF0000FF0088FF0000FF 00FF430000FF0000FF00AAFF00FF4300FF43FFED00FF0000FF2100FF0000FFCB00FF0000FF8700 FF2100FF0000FF2100FF4300FF0000FF0000FFED00EEFF00FFCB00FFCB00EEFF00CCFF00AAFF00 AAFF0088FF0044FF0044FF0044FF0044FF00AAFF00AAFF00AAFF0066FF0044FF0044FF0022FF00 44FF0000FF0000FF4300FF0000FF0000FF4322FF0000FF4300FF8700FF8788FF00AAFF00AAFF00 AAFF00AAFF0088FF0088FF0088FF00AAFF00AAFF00AAFF0088FF0088FF00AAFF00AAFF00CCFF00 AAFF00AAFF00AAFF00AAFF00AAFF0088FF0088FF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF00 AAFF00AAFF0088FF0088FF0066FF0066FF0044FF0044FF0044FF0044FF0044FF0044FF0022FF00 22FF0044FF0066FF0088FF0066FF0066FF0066FF0044FF0066FF0066FF0088FF00AAFF00AAFF00 66FF000066FF0000FF0000FF0000FF0000FF0000FF0044FF0088FF0000FF0000FF0000FF00FFED 0088FFFF00000000FF0000FF0044FF0000FF0000FF0000FF0000FF0000FF0088FF0000FF0000FF 0000FF0044FFAAFF0000FF43AAFF00AAFF0044FF00FF4300FF0000FF0000FF0000FF0000FF2100 FF4300FF0000FF0000FF0000FF8700FFCB00FFCB00FFED00CCFF00AAFF00AAFF00AAFF0066FF00 88FF0066FF0088FF0022FF0066FF0088FF00AAFF0066FF0044FF0000FF0044FF0044FF0022FF00 00FF0022FF0000FF0000FF0000FF0044FF0044FF0000FF8700FF21AAFF00AAFF00AAFF00AAFF00 AAFF00AAFF00AAFF00AAFF00AAFF00AAFF0088FF00AAFF00AAFF00AAFF00CCFF00AAFF00AAFF00 AAFF00AAFF00AAFF0088FF0088FF0088FF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00 AAFF0088FF0088FF0088FF0088FF0088FF0066FF0066FF0044FF0044FF0044FF0044FF0022FF00 44FF0044FF0044FF0066FF0066FF0066FF0066FF0066FF0088FF00AAFF0088FF0066FF000000FF 0000FF0088FF0066FF0000FF0000FF0000FF0066FF0000FF0000FF0000FF0000FF0000FF00CCFF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0088FF0022FF0000FF0000FF0044FF 00CCFF0044FF44FF0000FF0044FF00FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF6500EEFF00FFCB00FFCB00EEFF00CCFF00AAFF0066FF0088FF0088FF00AAFF00 88FF0066FF0044FF0044FF00AAFF0088FF0044FF0022FF0022FF0000FF0000FF0000FF0000FF00 00FF0044FF0022FF0044FF0022FF0000FF0000FF00AAFF0088FF0088FF0088FF0088FF00AAFF00 AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00CCFF00CCFF00CCFF00AAFF00AAFF00AAFF00 AAFF00AAFF0066FF0088FF0066FF00AAFF00AAFF00AAFF00AAFF0088FF0066FF0044FF0044FF00 44FF0066FF0066FF0066FF0088FF0088FF0066FF0066FF0066FF0066FF0044FF0066FF0066FF00 66FF0066FF0088FF0066FF0044FF0088FF0088FF00AAFF00AAFF0066FF0000CCFFFF65000088FF 0000FF0000FF0066FF0066FF0066FF0000FF0000FF0000FF0000FF0000FF44FF000000FF66FF00 0000FF0000FF0000FF0022FF0000FF00EEFF0000FF0000FF0000FF0044FF0000FF0000FF0044FF 00EEFF0000FF44FF00FF0000FFA900FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF6500FFCB00FFED00AAFF00EEFF00CCFF00AAFF0088FF0066FF00AAFF00AAFF00AAFF0066FF00 66FF0066FF0088FF0066FF0088FF0022FF0000FF0000FF0000FF0000FF0000FF2122FF0022FF00 00FF0000FF2100FF0044FF0022FF00AAFF0088FF00AAFF0088FF00AAFF00AAFF0088FF00AAFF00 AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00CCFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00 88FF0066FF0066FF00AAFF0088FF0066FF0044FF0044FF0044FF0022FF0022FF0022FF0022FF00 44FF0088FF0088FF0088FF0088FF0088FF0088FF0088FF0088FF0088FF0088FF0088FF0088FF00 88FF0066FF0044FF0088FF00AAFF00AAFF0088FF0066FF0000FFCB00FFED0088FF0088FF0000FF 0000FF0066FF00AAFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00EEFF00FFED 0000FF00FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00CCFF0022FF00AAFF 00FF8700FF21FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF6500 FFED00AAFF0066FF00CCFF00AAFF00AAFF0044FF0066FF00AAFF0088FF0066FF0088FF0066FF00 66FF00AAFF0066FF0000FF0044FF0044FF0044FF0022FF0000FF2144FF0044FF0000FF0000FF00 00FF2166FF0044FF0000FF0000FF0044FF0044FF0088FF0088FF0088FF00AAFF00AAFF00AAFF00 AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF0088FF0066FF0044FF00 66FF0066FF0044FF0022FF0022FF0000FF0022FF0000FF0022FF0022FF0044FF0044FF0044FF00 44FF0044FF0066FF0088FF0088FF0088FF00AAFF0088FF0088FF0088FF0088FF0066FF0044FF00 22FF0088FF00AAFF00AAFF0088FF0066FF0000FFA900EEFF00EEFF0000FF0000FF0000FF0000FF 00CCFFAAFF000000FF0000FF0000FF0000FF0022FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0088FF0000FF0000FF00EEFF 00FF8700FF21CCFF00FF0000AAFF00FF000022FF00FF0000FF4300FF0000FF0000FF4300CCFF00 AAFF00AAFF00AAFF0088FF0066FF0044FF0088FF0066FF0044FF0088FF00AAFF0088FF0066FF00 88FF0066FF0066FF0022FF0044FF0088FF0044FF0000FF2100FF0000FF4300FF0000FF4322FF00 44FF0000FF0000FF0000FF2100FF2188FF0088FF0088FF0088FF00AAFF00AAFF00AAFF00AAFF00 CCFF00AAFF00AAFF00AAFF00AAFF00CCFF00AAFF00AAFF0088FF0044FF0044FF0066FF0044FF00 22FF0044FF0022FF0000FF0000FF2100FF2122FF0022FF0044FF0044FF0044FF0044FF0022FF00 22FF0044FF0088FF00AAFF00AAFF0088FF0088FF0088FF0066FF0066FF0044FF0066FF00AAFF00 AAFF00AAFF00AAFF00AAFF0000FFCB0000FF0022FF0022FFEEFF000000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF00FF650000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0088FF0000FF0000FF0044FF0000FF0000FF0000FF0000FF00EEFF00FF4300FF43 FF650000FF8700FFCB0088FF0000FF0000FF0066FFFF0000FFA900FF0000FFA900EEFF00AAFF00 AAFF00AAFF0088FF0066FF0088FF0044FF0088FF0088FF00AAFF00AAFF00AAFF00FFCB00FFED00 FFED00EEFF00AAFF0088FF0088FF0044FF0000FF2100FF2100FF6500FF4300FF2100FF2100FF00 00FF0000FF4300FF0000FF0044FF0088FF00AAFF00AAFF00AAFF00CCFF00AAFF00AAFF00AAFF00 CCFF00AAFF00CCFF00CCFF00CCFF00CCFF0088FF0044FF0044FF0044FF0044FF0044FF0066FF00 22FF0000FF0000FF0000FF0044FF0044FF0044FF0044FF0066FF0044FF0022FF0044FF0044FF00 44FF0088FF00AAFF00AAFF0088FF0066FF0066FF0066FF0066FF0066FF00AAFF00AAFF00AAFF00 88FF00AAFF000088FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0044FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0066FF0022FF0000FF0000FF0000FF0000FF0000FF0044FF00FF8700FF0000FFCB00EEFF00CCFF 0000FF0000FF0000FF0000FF0044FF0044FF00AAFFFF0000FF4300FF8700AAFF00AAFF00AAFF00 66FF0044FF0066FF0088FF00AAFF00AAFF00AAFF00EEFF00FF6500FF6500FF6500FF6500FF8700 FFCB0088FF00AAFF0066FF0000FF0000FF4300FF0000FF0000FF2100FF2100FF2100FF0000FF00 00FF0000FF2144FF00AAFF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00 CCFF00CCFF00CCFF00AAFF0088FF0066FF0044FF0044FF0044FF0066FF0066FF0022FF0000FF00 22FF0044FF0066FF0066FF0066FF0088FF0088FF0044FF0066FF0066FF0044FF0044FF0044FF00 66FF0088FF0066FF0066FF0088FF0066FF0066FF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF00 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0044FF00EEFF00FFA900FFA900FF650022FF0022FF88FF000000FF0000FF 0000FF0000FF0000FF0022FF0088FF00FF65FF0000FF6500EEFF00AAFF0066FF0088FF00AAFF00 AAFF00AAFF00AAFF00AAFF00CCFF00FFA900FF4300FF2100FF2100FF0000FF4300FFA900CCFF00 AAFF0088FF0088FF0000FF2100FF2100FF4300FF0000FF0000FF2100FF2100FF0022FF0022FF00 22FF0088FF0088FF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00 AAFF00AAFF00AAFF0088FF0066FF0066FF0066FF0066FF0044FF0044FF0044FF0044FF0066FF00 66FF0088FF0088FF0066FF0088FF0088FF00AAFF0066FF0066FF0044FF0044FF0044FF0066FF00 44FF0044FF0066FF0066FF0066FF0088FF0088FF00AAFF00AAFF00AAFF00AAFF000000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FF430000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0022FF0000FF0000FF0000FF 0000FF0000FF0000FF00FFCBFFA9000022FF0088FF0000FF0000FF0000FF0000FF0000FF0000FF 0022FF0022FF00FFCB0088FFFF0000FF0000FF0000EEFF00AAFF00EEFF00CCFF00CCFF00AAFF00 AAFF00AAFF00CCFF00FFCB00FF2100FF0000FF2100FF2100FF4300FF8700FFED0066FF00CCFF00 AAFF00AAFF0066FF0000FF0000FF2100FF2100FF2100FF2100FF0022FF0022FF0000FF0000FF00 88FF0088FF0088FF0088FF00AAFF00AAFF00CCFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00 88FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0088FF00 88FF0088FF00AAFF00AAFF00AAFF00AAFF0088FF0088FF0088FF0066FF0066FF0044FF0044FF00 66FF0066FF0088FF0066FF0066FF0088FF00AAFF00AAFF00AAFF000000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FFEEFF000000FF0000FF00FF870000FF0088FF0000FF0000FF 0000FF0000FFFF4300FF0000FF0000FF0000FF4300FFA900FFCB00FFED00CCFF00CCFF00CCFF00 FFCB00FFCB00FF6500FF0000FF2100FF0000FF2100FF6500FFA900AAFF00CCFF00CCFF00EEFF00 AAFF00AAFF0088FF0088FF00AAFF0088FF0022FF0044FF0000FF0000FF0000FF2144FF0044FF00 88FF00AAFF00AAFF00CCFF00AAFF00CCFF00AAFF00AAFF00AAFF00AAFF00AAFF0088FF0088FF00 88FF0044FF0066FF0066FF0088FF0088FF0088FF0088FF0088FF0088FF0088FF0088FF00AAFF00 88FF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF0088FF0066FF0044FF0066FF0066FF00 66FF0088FF0066FF0088FF00AAFF00AAFF00AAFF000000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0066FF00AAFF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF00EEFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0088FF 00FF00FF0000FF0000FF0000FF4300FFA900FFED00EEFF00EEFF00EEFF00FFA900FFA900FF6500 FF0000FF0000FF0000FF2100FF2100FF2100FF8700EEFF00AAFF00AAFF00AAFF0088FF0066FF00 44FF0066FF0044FF00AAFF00AAFF0088FF0066FF0022FF0000FF0000FF0044FF0066FF0088FF00 88FF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF0088FF0088FF0088FF0088FF0066FF00 66FF0066FF0088FF0088FF0088FF0088FF0088FF00AAFF00AAFF0088FF00AAFF00AAFF00AAFF00 AAFF00AAFF00AAFF00CCFF00CCFF00AAFF00AAFF0088FF0088FF0066FF0066FF0088FF0088FF00 88FF0088FF0088FF00AAFF00AAFF000000FF0000FF0000FF0000FF0000FF0044FF0000FF0000FF 0000FF0000FF0000FF0000FF0022FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0022FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FF2144FF00 FF0000FF0000FF2100FF6500FFCB00FFED00FF8700FF4300FF8700FF8700FF2100FF0000FF0000 FF4300FF2100FF0000FF6500FF4300FFA900FFA900EEFF00AAFF00AAFF0088FF0066FF0044FF00 66FF0022FF0044FF0088FF0088FF0088FF0044FF0022FF0044FF0022FF0066FF0066FF00AAFF00 AAFF00AAFF00AAFF00AAFF00AAFF00AAFF0088FF0088FF0088FF0088FF0088FF0088FF0088FF00 88FF0088FF0088FF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00 AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF0088FF0066FF0066FF0088FF0088FF0088FF00 AAFF00AAFF00AAFF000000FF0000FF0000FF0000FF0000FF0000FF00FFED0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0044FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0066FF0066FF0000FF0000FF0000FF0000FF0000FF0066FF0000FF0022FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00CCFF00CCFFFF0000FF0000 FF0000FF4300FF8700FF8700FF6500FF4300FF8700FF0000FF0000FF0000FF0000FF4300FF0000 FF0000FF4300FF6500FF4300FFA900FFA900FF8700FFCB00FFED00AAFF0088FF0088FF0088FF00 88FF0044FF0044FF0088FF0022FF0022FF0044FF0044FF0022FF0066FF00AAFF00AAFF00AAFF00 AAFF00AAFF00AAFF00AAFF0088FF0088FF0066FF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF00 AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF0088FF0088FF00AAFF00AAFF00AAFF00 AAFF00CCFF00CCFF00CCFF00AAFF00AAFF0088FF00AAFF0088FF00AAFF00AAFF00AAFF00AAFF00 AAFF000000FF0000FF0000FF0044FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0088FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF00FF210000FF0000FF0000FF0000FF0088FF0088FF0000FF0044FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFF0000FF0000FF0000 FF4300FF4300FF6500FF6500FF6500FF2100FF0000FF0000FF2100FF2100FF0000FF0000FF2100 FF8700FF8700FF8700FF8700FF6500FF8700FFA900FF8700FFCB0066FF0088FF0066FF0066FF00 66FF0066FF0044FF0044FF0044FF0088FF0066FF0044FF00AAFF00AAFF00AAFF00AAFF00AAFF00 AAFF00AAFF00AAFF00AAFF0088FF0088FF00AAFF0088FF0088FF00AAFF0088FF00AAFF00AAFF00 AAFF0088FF0088FF00AAFF00AAFF00AAFF0088FF0088FF0088FF00AAFF00AAFF00AAFF00AAFF00 CCFF00CCFF00CCFF00CCFF00AAFF00AAFF00AAFF00AAFF00AAFF00CCFF00AAFF00AAFF000000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0066FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0066FF00EEFF0044FF0000FF0000FF0000FF0000FF0000FF0000FF 00FF870000FF0000FF0000FF0000FF0000FF0000FF0000FFFF6500FF0000FF0000FF0000FF2100 FF4300FF6500FF2100FF2100FF2100FF2100FF4300FF0000FF0000FF0000FF210044FF000000FF 0000FF0000FFFFCB00FF8700FFA900FF8700FFA900FFCB00AAFF0088FF0066FF0066FF0066FF00 44FF0022FF0044FF0088FF0088FF0066FF0044FF00AAFF00AAFF00AAFF00AAFF00AAFF00CCFF00 AAFF00AAFF00AAFF0088FF00AAFF00AAFF00AAFF0088FF0088FF0088FF00AAFF00AAFF00AAFF00 88FF0088FF00AAFF00AAFF00AAFF00AAFF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF00CCFF00 CCFF00CCFF00CCFF00CCFF00AAFF00AAFF00AAFF00CCFF00AAFF00AAFF000000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0022FF0066FF00FF870000FF0000FF0066FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FF870000FF 0000FF0000FF0000FF0000FF0000FFFF0000FF0000FF0000FF0000FF0000FF2100FF4300FF2100 FF2100FF2100FF2100FF6500FF8700FF2100FF0000FF0000FF2100EEFF000000FF00FFA922FF00 FF00000000FFEEFF00FFCB00FFCB00FFCB00FFCB0088FF0044FF0066FF0044FF0044FF0000FF00 22FF0066FF0066FF0066FF0066FF00AAFF00AAFF00CCFF00AAFF00CCFF00CCFF00AAFF00AAFF00 AAFF0088FF00AAFF00AAFF00AAFF00AAFF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00 AAFF00AAFF00AAFF00AAFF0088FF0088FF00AAFF00AAFF00CCFF00CCFF00CCFF00CCFF00CCFF00 CCFF00AAFF00CCFF00AAFF00CCFF00CCFF00AAFF00AAFF00FF00000000FF0000FF0000FF0000FF 0000FF0066FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0044FF0000FF0066FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0088FF0000FF0000FF0000FF 0000FF00FF650088FFFF0000FF0000FF0000FF0000FF2100FF4300FF6500FF2100FF2100FF0000 FF4300FF8700FF2100FF0000FF0000FF0000FF0000FF000000FFEDFF0000FF0000FF00000066FF 0000FF0000FFFFCB00FFCB00FFED00AAFF0066FF0044FF0044FF0022FF0000FF2122FF0022FF00 66FF0066FF0088FF00AAFF00AAFF00CCFF00AAFF00AAFF00CCFF00CCFF00AAFF00AAFF00AAFF00 88FF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00 AAFF0088FF0088FF0066FF00AAFF00AAFF00CCFF00EEFF00CCFF00EEFF00CCFF00CCFF00CCFF00 CCFF00CCFF00CCFF00AAFF00AAFF0088FF000000FF0000FF0000FF00AAFF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF00FFA900AAFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF00FFED0000FF0000FF00FF000000FF0000FF0000FF00FFED 00FF43FF0000FF0000FF0000FF0000FF2100FF6500FF2100FF0000FF0000FF2100FF4300FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00000000FF0000FF 88FF00FFA900FFED00CCFF00AAFF0044FF0022FF0022FF0000FF2100FF2100FF4344FF0066FF00 88FF0066FF0066FF00AAFF00AAFF00AAFF00CCFF00EEFF00AAFF00AAFF00AAFF00AAFF00AAFF00 AAFF00AAFF00AAFF00AAFF00AAFF00AAFF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF0088FF00 88FF0088FF00AAFF00AAFF00AAFF00EEFF00CCFF00CCFF00CCFF00CCFF00CCFF00CCFF00CCFF00 CCFF00AAFF00AAFF0088FF000000FF0000FF0000FF00FFCB0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0088FF0000FF0000FF0044FF0000FFFF43000000FF0000FF00CCFF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF00CCFF0000FF0000FFFF00000000FF0000FF0000FF0000FF66FF00FF0000FF0000 FF6500FF4300FF0000FF0000FF0000FF0000FF0000FF0000FF6500FF4300FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF000044FF000000FF0000FFFFA900 EEFF00AAFF00AAFF0066FF0000FF0000FF2100FF4300FF2100FF4366FF0088FF0066FF0044FF00 22FF0088FF00EEFF00CCFF00CCFF00EEFF00CCFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00 AAFF00AAFF00AAFF00AAFF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF0088FF00 66FF0066FF00AAFF00CCFF00CCFF00CCFF00CCFF00CCFF00CCFF00CCFF00CCFF00CCFF00AAFF00 88FF0088FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0088FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF00EEFF0000FF00CCFF0000FF0088FF00AAFF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0022FFFF0000FF0000FF0000FF0000 FF0000FF0000FF2100FF0000FF0000FF2100FF4300FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00000000FF0000FFAAFF00FFED00AAFF00 88FF0066FF0022FF0000FF4300FF6500FF2100FF4388FF0044FF0022FF0000FF0000FF0088FF00 AAFF00EEFF00EEFF00EEFF00CCFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00 AAFF00AAFF00AAFF00AAFF00CCFF00EEFF00CCFF00AAFF00AAFF00AAFF00AAFF00AAFF0088FF00 88FF00AAFF00CCFF00EEFF00EEFF00CCFF00CCFF00CCFF00CCFF00AAFF00AAFF0088FF0088FF00 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0044FF0088FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF88FF000000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FFCBFF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF00000000FF0000FF88FF00EEFF00AAFF0088FF0066FF00 44FF0000FF6500FF4300FF0000FF4300FF0044FF0022FF0000FF0022FF0066FF00AAFF00CCFF00 EEFF00EEFF00EEFF00AAFF00AAFF00CCFF00CCFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00 AAFF00AAFF00CCFF00CCFF00CCFF00AAFF00AAFF00AAFF00AAFF00AAFF0088FF0088FF00AAFF00 AAFF00CCFF00CCFF00CCFF00CCFF00CCFF00AAFF00AAFF0088FF00AAFF0088FF000000FF0000FF 0000FF0000FF0022FF00FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FFFF430000CCFF0000FF0000FF0000FF0000FF0000FF 0000FF88FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0066FF88FF0000FFA9FF6500FF0000FF8700FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FFCB000000FF0000FF00AAFF0000FFAAFF0044FF0022FF0000FF0000FF43 00FF4322FF0000FF0000FF2144FF0022FF0000FF0044FF0066FF00AAFF00AAFF00FFED00EEFF00 EEFF00CCFF00AAFF00EEFF00CCFF00CCFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00 AAFF00CCFF00EEFF00CCFF00AAFF0088FF00AAFF00AAFF00AAFF0088FF00AAFF00AAFF00AAFF00 AAFF00CCFF00CCFF00AAFF00AAFF0088FF0088FF0088FF0066FF000000FF0000FF0000FF00FF00 0000FF44FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0066FF0000FF0000FF0088FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0088FF0000FF0000FF0000FF00FF4366FF00FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF00000000FF0000FFCCFF0066FF0000FF2100FF2100FF4300FF6522FF00 00FF0000FF0022FF0000FF0000FF0044FF0066FF0066FF00AAFF00EEFF00FFCB00FFED00EEFF00 AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00CCFF00AAFF00AAFF00AAFF00AAFF0066FF00AAFF00 EEFF00CCFF00AAFF0088FF00AAFF00AAFF00AAFF00AAFF0088FF00AAFF00AAFF00AAFF00AAFF00 AAFF00AAFF0088FF0066FF0088FF0066FF0066FF000000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0066FF00AAFF0000FF0000FF00EEFF0000FF0000FF0088FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0066FF0000FF0000FF0088FFAAFF00FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF00000000FF44FF0044FF0000FF0000FF4300FF4300FFA900FF0000FF0022FF00 00FF0000FF2100FF2100FF2144FF0044FF00AAFF00CCFF00FFED00FFCB00FFCB00EEFF00AAFF00 AAFF00AAFF00AAFF0088FF00AAFF00AAFF00AAFF00AAFF0088FF0066FF00AAFF00EEFF00CCFF00 AAFF00AAFF00AAFF0088FF0066FF00AAFF00AAFF00AAFF00AAFF0066FF00AAFF00AAFF00AAFF00 88FF0088FF0044FF0044FF0044FF000000FF0000FF0000FF0000FF0000FF0044FF00AAFF0000FF 0000FF0000FF0066FF0088FF00FFA90000FF0000FF0088FF00FF8700FF8700FF870088FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0088FFEEFF00FF0000FF0000FF0000FF0000FF0000FF2100FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF21000000FF00FFED88FF0022FF0000FF0000FF4300FFA900FF6500FF2100FF2100FF6500FF21 00FF2100FF4300FF0088FF00AAFF00AAFF00EEFF00FFED00FFCB00FFCB00EEFF00CCFF00CCFF00 AAFF00AAFF00AAFF00AAFF00AAFF00AAFF0044FF0044FF0088FF00EEFF00AAFF00AAFF00AAFF00 88FF0088FF0066FF0044FF00AAFF0088FF0088FF0066FF0066FF00AAFF0088FF0088FF0066FF00 44FF0022FF0000FF000000FF0000FF0000FF0000FF0088FF0000FF0000FF0000FF0000FF0000FF 0066FF0000FF0000FF0000FF0000FF00FF000066FF00FFA900FF0000EEFF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00CCFF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FFFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF000000FF650000FF 00FF65AAFF00AAFF0000FF0000FF6500FFA900FFA900FF2100FF2100FF4300FF4300FF4300FF43 00FF4366FF00AAFF00AAFF00CCFF00CCFF00FFED00FFED00EEFF00FFED00EEFF00CCFF00CCFF00 AAFF00AAFF00AAFF0066FF0044FF0044FF0088FF00CCFF00AAFF00AAFF00AAFF0088FF0044FF00 44FF0044FF0044FF0066FF0088FF0066FF0044FF00AAFF00AAFF0088FF0066FF0044FF0022FF00 44FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0088FF0000FF0000FF0000FF0000FF 0000FF0000FF0022FF0000FF00FFCB00FFA988FF0000EEFF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FFCB0000FFEEFF00 0000FF0000FF0000FF0000FF0000FF00FFCB0000FF0000FF0000FF0000FF0000FF00FF000088FF 0000FF0000FFFF0000FF0000FF0000FF4300FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00000044FF0000FFAAFF00 44FF0000FF0000FF8700FF8700FFA900FF4300FF4300FF4300FF0000FF0000FF00AAFF00AAFF00 88FF00AAFF00AAFF0088FF00AAFF00AAFF00EEFF00EEFF00EEFF00CCFF00CCFF00AAFF0088FF00 66FF0022FF0000FF0022FF0066FF00AAFF00AAFF00AAFF0088FF0088FF0044FF0066FF0088FF00 66FF0088FF0044FF0088FF0066FF0066FF0066FF0088FF0066FF0044FF0044FF0022FF000000FF 0000FF0000FF0000FF0000FF0000FF0000FF0022FF00AAFF0000FF00FFA90000FF00FF870000FF 0000FF0000FF00FFCB44FF0044FF0000AAFF00FF210000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFF0000FF0000FF65000000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFF2100 FF0000FF0000FF2100FF4300FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF000000FFA9AAFF0044FF0000FF00 00FF4300FF4300FF6500FF4300FF4300FF0022FF0044FF00AAFF0088FF0088FF0066FF0088FF00 88FF0066FF0044FF0088FF00AAFF00EEFF00EEFF00CCFF00AAFF00AAFF0066FF0044FF0000FF00 00FF0022FF0044FF00AAFF0088FF0066FF0066FF0066FF0044FF0066FF0088FF0088FF0088FF00 44FF0044FF0044FF0044FF0000FF0044FF0000FF0000FF0000FF0022FF000000FF0000FF0000FF 0000FF0000FF0000FF0000FF0022FF00EEFF0022FFFF87000000FF00CCFF0022FF0000FF00AAFF 00FF4388FF00EEFF0000FFED0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 00FFCB0000FF0000FF0000FF0000FF0000FF0088FFFF000000FF43FFA9000000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF22FF000000FF0000FFFF0000FF0000FF0000 FF0000FF0000FF2100FF4300FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF000000FFCBCCFF00AAFF0088FF0022FF0000FF2100FF21 00FF6500FF6500FF4300FF0044FF0088FF0066FF0088FF0088FF0044FF0066FF0044FF0022FF00 44FF00AAFF00EEFF00FFED00CCFF00AAFF00AAFF0088FF0066FF0000FF0000FF2100FF2144FF00 88FF0066FF0066FF0066FF0066FF0044FF0044FF0044FF0088FF00AAFF0088FF0044FF0066FF00 44FF0044FF0044FF0000FF0000FF0000FF2100FF2100FF430000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF00CCFF0088FF0000FF0044FF0088FF00CCFF00CCFF88FF0044FF00 FF000000FFCB0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0044FFAAFF00 0000FF0000FF0000FF0000FF0000FFFF0000FF0000FF00000000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FFED0000FFFF0000FF0000FF0000FF0000 FF4300FF4300FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF000000FF21CCFF0000FF43AAFF0044FF0000FF0022FF0000FF4300FF6500FF87 00FF2100FF4388FF0088FF0088FF0088FF0066FF0000FF2100FFED00FFA900FF0066FF0088FF00 EEFF00EEFF00AAFF00AAFF00AAFF0066FF0044FF0022FF0000FF2100FF2144FF0088FF0066FF00 66FF0066FF0066FF0066FF0044FF0066FF00AAFF00AAFF00AAFF0066FF0088FF0066FF0044FF00 22FF0000FF0000FF0000FF0000FF0000FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FFAAFF00CCFF000000FF0000FF0000FF00AAFF00FFED00AAFF00FFCBFFA900CCFF0000AAFF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0066FFFF87000000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FFFF87000000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFF0000FF0000FF0000FF2100FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 0088FF0088FF00FF2100FFA900FFA966FF0044FF0000FF0000FF4300FF4300FF8700FF4366FF00 AAFF0066FF0088FF0066FF0000FF2100FF8700FF6500FF8722FF0088FF00AAFF00AAFF0088FF00 66FF0088FF0066FF0066FF0044FF0000FF0000FF0022FF0066FF0066FF0066FF0088FF0066FF00 44FF0066FF0066FF0088FF00AAFF00CCFF00AAFF00AAFF00AAFF0088FF0066FF0022FF0022FF00 00FF0000FF0000FF2100FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 00CCFFFF00000000FF0000FF0000FF00EEFF00EEFF0044FF0088FF00FF00FF00000066FFFF4300 00FFED0000FF0000FF0000FF0000FF0000FFCCFF0000FFED0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF00FF210000FF0000FF0000FF0000FF0000FF0066FF0000FF0000FF 0000FFCCFF000000FF0000FF0000FF0000FF0000FF0088FFFF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FFA900FF00000000FF0000FF0000FF00AAFF00AAFF 0022FFFF000000FF65AAFF0000FF0000FF2100FF4300FF4300FF6500FF4366FF0088FF0088FF00 AAFF0044FF0000FF0000FF8700FFA922FF00AAFF00AAFF0066FF0066FF0044FF0044FF0066FF00 44FF0044FF0000FF0000FF2100FF0044FF0066FF0066FF0088FF0088FF0066FF0044FF0066FF00 44FF0044FF0088FF0088FF00AAFF00AAFF00AAFF00AAFF0088FF0066FF0044FF0044FF0022FF00 22FF0044FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0088FF0066FF0044FF66FF00FF000000FF4322FF0000FF000000FF 0000FF0000FF0000FF0000FFFF21000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFF00000000FF44FF000022FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFF8700FFED0000FF43FF0000FF0000 FF0000FF430000FF650088FF0000FF0000FF00FF650000FF0000FF0000FF0000FFFF4300FF0000 FF000066FF0000FF0000FF4300FF6500FF6500FF8700FF2144FF0088FF0066FF0044FF0000FF21 00FF6500FFA900FF2144FF0044FF0044FF0000FF0000FF4300FF2100FF0066FF0044FF0000FF00 00FF2100FF4322FF0044FF0000FF0066FF0088FF00AAFF0066FF0044FF0066FF0044FF0044FF00 44FF0066FF0066FF00AAFF00AAFF00AAFF0066FF0066FF0088FF0044FF0000FF0000FF00AAFF00 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF00AAFF0088FF00EEFF00FFA900AAFFFF0000FF000088FF00AAFF000088FF0000FFFF0000 0000FF0000FF00FFCB00FFA90000FF0066FF00EEFF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FFFF0000FF000000FF43FF00000000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFFCB00FF0000FF0000FF00000000FF 0000FF0000FF0000FF00FFA90000FFFF0000FF21000000FF0000FFFFA900FF0000FF0000EEFF00 66FF0000FF4300FF6522FF0000FF4300FF6500FF2100FF4300FF4300FF0000FF2100FF4322FF00 00FF0000FF0000FF0000FF8700FFCB00FF8700FF4300FF8700FF2100FF2100FF4300FF2100FF00 44FF0000FF0000FF0044FF0088FF00AAFF0066FF0066FF0066FF0066FF0066FF0066FF0066FF00 AAFF00AAFF00AAFF00AAFF00AAFF0088FF0044FF0044FF0022FF0044FF0088FF000000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0088FF00AAFF0000FF0000FF0000FF0000FF0000FF 00FF0000AAFF00AAFF0000FFAAFF00FF0000FF000000FF000088FFFF0000FF0000FF0000CCFF00 00FF21FF00000044FF0000FF00FF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF00FFCB66FF00FF0000FF0000FF0000FF00000022FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00EEFF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF00FF8700FF65FF2100CCFF00AAFF0000FF00 00FF2166FF0000FF2100FF0000FF4300FF4300EEFF00FF2100FF2122FF0000FF2100FF2100FFED 00EEFF00FFA900FFCB00FFCB00FF6500FF6500FF6500FF4300FFA900FF4300FF0022FF0000FF21 00FF2100FF0088FF0088FF0066FF0066FF0066FF0066FF0066FF0088FF00AAFF00AAFF00CCFF00 AAFF00AAFF00AAFF0088FF0066FF0044FF0044FF00AAFF00AAFF000000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0066FF0022FF00EEFF00FFA9FF0000 00FF0000FFEDFF0000FF0000FF000088FF000066FF66FF00FF0000FF000022FF00AAFF0066FF00 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FFFF0000FF0000FF0000FF0000FF87000000FF0000FF0000FF0000FF0000FF00FF650000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0088FF00AAFF 0000FF0000FF0000FF0000FF0000FF00FF8700FFA944FF00AAFF0066FF0000FF0000FF0022FF00 00FF2100FF0000FF0000FF8700CCFF00CCFF00FF0000FF0000FF6500FFA900FF4300FF8700FF87 00FF8700FFA900FF8700FF6500FF4300FF6500FF4300FF0022FF0000FF2100FF2100FF4300FF00 44FF0088FF0066FF0066FF0066FF0088FF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00 AAFF00AAFF0066FF0066FF00AAFF00AAFF00CCFF000000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0044FF0044FF0088FF00EEFFFF8700FF0000FF0000 FF0000FF0000FF0000FF65000088FFFF0000FF00000088FF0066FFFF0000FF00000000FF0000FF 0000FF0000FF0000FF0000FF0022FF0000FF0000FF0000FF0000FF0000FF0000FFFF6500FF0000 FF0000FF0000FF0000FF65000000FF0000FF0000FF0000FF0000FFFF65000000FF0000FF00FF21 0000FF0000FFEEFF000000FF0000FF0000FF0000FF0000FF00FFA90000FF0000FF0000FFFF4300 0088FFFF0000FF650088FF00CCFF00EEFF0088FF0088FF0000FF0000FF2100FF4300FF6500FF65 00FF6500FF4300FFED00CCFF00FF6500FF8700FF6500FF4300FF2100FF6500FFCB00FF6500FF65 00FF8700FF6500FF6500FF6500FF4300FF2122FF0000FF2100FF4300FF2100FF2122FF0000FF00 66FF0088FF0088FF00AAFF00AAFF00AAFF00CCFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00 66FF00AAFF00CCFF00EEFF00EEFF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0022FF00FFA900AAFF0088FF22FF00FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF00000000FF88FF0044FF0000FFCB0000FF0000FF0000FF0000FF 0000FF0000FF0066FF00FFA90000FF0000FF0000FFFFCB00FF0000FF0000FF0000FF0000FF0000 FF00000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0088FF0000FF0000FF00CCFFFF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000AAFF00CCFF0066FF0044FF0000FF2100FF6500FF6500FF6500FF8700FF6500FF43 00FFA900CCFF00FFED00FF8700FF6500FF4300FF2100FF8700FFA900FF4300FF4300FF8700FF65 00FF6500FF2100FF4300FF2100FF0000FF0000FF4300FF0000FF2122FF0000FF0066FF00AAFF00 AAFF0088FF00AAFF00CCFF00CCFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00CCFF00 EEFF00EEFF00CCFF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0088FF0000FF0000FF0088FFFF0000FF0000FF0000FF0000FF0000 00FF0000EEFFFFA9000000FF00FFCB00FFED0000FF0000FF0000FF0000FF0000FF0000FF0000FF 00FF87FF0000FF0000FF4300FF870000FF43FF0000FF0000FF0000FF0000FF0000FF0000CCFF00 0000FF0000FF0000FF00CCFF0000FF0000FF0000FF0000FFFF65000000FFFF0000FF000044FF00 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFCB00 EEFF00AAFF0066FF0022FF0000FF0000FF2100FF4300FF6500FF8700FF8700FF8700FFCB00CCFF 00FFED00FF6500FF8700FF2144FF0000FF6500FF4300FF4300FF2100FF6500FF8700FF2100FF43 00FF0022FF0000FF0000FF0000FF2100FF0000FF0000FF0000FF0088FF0088FF00AAFF00AAFF00 AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00CCFF0088FF0088FF00AAFF00EEFF00EEFF00EEFF00 CCFF000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0044FF00CCFF0044FF0000FFFF0000FF0000FF0000FF000000FF43FF00000000FFFF0000 FF00000000FF0000FFFF00000088FF0000FF0000FF0000FF0000FF0000FF0000FFCCFF00FFA900 FF000000FF43FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00000000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FFFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000CCFF00CCFF00AAFF00 44FF0022FF0000FF0000FF0000FF2100FF6500FF8700FFA900FFA900EEFF00CCFF00FFED00FF43 00FF6500FF2166FF0000FF4300FF2100FF2100FF2100FF6500FF8700FFCB00FF2144FF0066FF00 66FF0044FF0000FF0022FF0044FF0022FF0000FF0088FF0088FF00AAFF00AAFF00CCFF00CCFF00 CCFF00CCFF00AAFF00CCFF00AAFF0088FF00AAFF00CCFF00EEFF00CCFF00CCFF00CCFF000000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00CCFF 0000FF0000FF0000FFFFCB00FF0000FF000066FF0000EEFFCCFF000000FFFF0000FF00000000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00EEFF00CCFFFF0000FF0000FF0000 FF6500FF0000FF0000FF0000FF0000FF0000FF0000FF00000088FF0000FF0044FF0000FF0000FF 0000FF0000FFFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000AAFF0088FF0088FF0044FF0000FF00 00FF0000FF0000FF2100FF4300FF8700FFA900FFCB00EEFF00EEFF00EEFF00FF2100FF6544FF00 44FF0000FF2100FF0000FF4300FF4300FF4300FFA900FF6566FF0088FF0088FF0088FF0066FF00 44FF0000FF0044FF0044FF0066FF0088FF0066FF00AAFF00CCFF00CCFF00CCFF00EEFF00EEFF00 EEFF00CCFF00AAFF00AAFF00AAFF00CCFF00CCFF00EEFF00EEFF00CCFF000000FF0000FFFF0000 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00AAFF0000FF FF0000FF0000FF0000FF0000FF0000FF000000FF430000FF00FF65FFA9000000FF0000FF0000FF 0000FF0044FF0000FF0000FF0000FF0000FF0000FFFF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000CCFF0000AAFF0000FF0000FF0000FFFF00000000FF FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FFED00EEFF0088FF0044FF0000FF0000FF0000FF21 00FF4300FF4300FF8700FFA900FFCB00EEFF00EEFF00EEFF00FF8700FF0066FF0044FF0022FF00 00FF2100FF4300FF8700FF6500FFCB00FF2100FF4300FF00AAFF00AAFF0088FF0088FF0000FF00 22FF0044FF0088FF0044FF0088FF00CCFF00CCFF00CCFF00EEFF00FFED00FFCB00EEFF00CCFF00 AAFF00AAFF00AAFF00CCFF00EEFF00EEFF00EEFF00EEFF000000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0022FF0000FF0000FFFF0000 FF0000AAFF00FF0000CCFF000000FF00FF4344FF00FF00000000FF0000FF0000FF0000FF0000FF FF21000000FF0000FF0000FF0000FFFF4300FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF000000FFCB00EEFFAAFF00FF0000FF0000FF0000AAFF00FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FFCB00FFED00EEFF00CCFF0044FF0000FF2100FF4300FF4300FF65 00FF8700FFA900FFCB00EEFF00EEFF00FFED00FFED00FF6500FF6544FF0000FF0000FF0022FF00 22FF0000FFA900FF4300FFED00FFA922FF0088FF00EEFF0088FF0044FF0000FF0044FF0066FF00 66FF0044FF0088FF00AAFF00CCFF00CCFF00EEFF00EEFF00FFED00EEFF00CCFF00AAFF00AAFF00 AAFF00AAFF00CCFF00AAFF00AAFF00AAFF000000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FFFF000022FF00AAFF00 FF0000FF21000000FF0000FFFF0000FF00000000FF0000FF0000FFFF00000044FFFFCB000000FF 0000FF00FFA90066FFFF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000 FF0000FFA900FFCB00CCFF00CCFF00AAFF0088FF0000FF2100FF2100FF4300FF6500FF6500FF87 00FFA900FFED00FFED00FFED00CCFF00AAFF00FFED00EEFF00FFA900FF0022FF0044FF0000FF00 00FF8700FFCB00FF6500FF21CCFF00EEFF00CCFF00AAFF0066FF0088FF0088FF0044FF0088FF00 88FF00AAFF00CCFF00AAFF00CCFF00FFED00FFCB00FFCB00CCFF00CCFF00AAFF00AAFF00AAFF00 CCFF00CCFF00CCFF00CCFF00 %END_IMAGE % gr_show_at() BEGIN 0 g 0 G 167.4 149.9 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 209.5 149.9 m (32) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 255.0 149.9 m (64) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 300.6 149.9 m (96) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 342.7 149.9 m (128) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 388.3 149.9 m (160) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 433.8 149.9 m (192) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 479.3 149.9 m (224) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 524.8 149.9 m (256) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 170.70 165.01 l 170.70 170.70 l 216.22 170.70 l 216.22 165.01 l 216.22 170.70 l 261.74 170.70 l 261.74 165.01 l 261.74 170.70 l 307.26 170.70 l 307.26 165.01 l 307.26 170.70 l 352.78 170.70 l 352.78 165.01 l 352.78 170.70 l 398.30 170.70 l 398.30 165.01 l 398.30 170.70 l 443.82 170.70 l 443.82 165.01 l 443.82 170.70 l 489.34 170.70 l 489.34 165.01 l 489.34 170.70 l 534.86 170.70 l 534.86 165.01 l 534.86 170.70 l 534.91 170.70 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 344.8 134.7 m (km) sh % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 534.86 m 170.70 534.86 l 170.70 540.55 l 170.70 534.86 l 216.22 534.86 l 216.22 540.55 l 216.22 534.86 l 261.74 534.86 l 261.74 540.55 l 261.74 534.86 l 307.26 534.86 l 307.26 540.55 l 307.26 534.86 l 352.78 534.86 l 352.78 540.55 l 352.78 534.86 l 398.30 534.86 l 398.30 540.55 l 398.30 534.86 l 443.82 534.86 l 443.82 540.55 l 443.82 534.86 l 489.34 534.86 l 489.34 540.55 l 489.34 534.86 l 534.86 534.86 l 534.86 540.55 l 534.86 534.86 l 534.91 534.86 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf % gr_show_at() BEGIN 0 g 0 G 152.5 166.4 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 211.9 m (32) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 257.4 m (64) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 302.9 m (96) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 139.1 348.5 m (128) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 139.1 394.0 m (160) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 139.1 439.5 m (192) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 139.1 485.0 m (224) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 139.1 530.5 m (256) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 165.01 170.70 l 170.70 170.70 l 170.70 216.22 l 165.01 216.22 l 170.70 216.22 l 170.70 261.74 l 165.01 261.74 l 170.70 261.74 l 170.70 307.26 l 165.01 307.26 l 170.70 307.26 l 170.70 352.78 l 165.01 352.78 l 170.70 352.78 l 170.70 398.30 l 165.01 398.30 l 170.70 398.30 l 170.70 443.82 l 165.01 443.82 l 170.70 443.82 l 170.70 489.34 l 165.01 489.34 l 170.70 489.34 l 170.70 534.86 l 165.01 534.86 l 170.70 534.86 l 170.70 534.86 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 133.2 344.8 m 90.00 rotate (km) sh -90.00 rotate % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 534.86 170.70 m 534.86 170.70 l 540.55 170.70 l 534.86 170.70 l 534.86 216.22 l 540.55 216.22 l 534.86 216.22 l 534.86 261.74 l 540.55 261.74 l 534.86 261.74 l 534.86 307.26 l 540.55 307.26 l 534.86 307.26 l 534.86 352.78 l 540.55 352.78 l 534.86 352.78 l 534.86 398.30 l 540.55 398.30 l 534.86 398.30 l 534.86 443.82 l 540.55 443.82 l 534.86 443.82 l 534.86 489.34 l 540.55 489.34 l 534.86 489.34 l 534.86 534.86 l 540.55 534.86 l 534.86 534.86 l 534.86 534.86 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:draw image palette left \minT right \maxT increment \incT %^ scale 1 170.7 0 1.4225 1 170.7 0 1.4225 0 g 0 G q n % turn clipping on for image palette 170.700000 591.760000 moveto 534.860000 591.760000 lineto 534.860000 620.210000 lineto 170.700000 620.210000 lineto 170.700000 591.760000 lineto closepath W 170.343679 591.760000 535.216321 620.210000 1 512 cim 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0022FF0022FF0022FF0022FF 0022FF0022FF0022FF0022FF0022FF0022FF0022FF0022FF0022FF0022FF0022FF0022FF0022FF 0044FF0044FF0044FF0044FF0044FF0044FF0044FF0044FF0044FF0044FF0044FF0044FF0044FF 0044FF0044FF0044FF0044FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF 0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0088FF0088FF0088FF0088FF0088FF 0088FF0088FF0088FF0088FF0088FF0088FF0088FF0088FF0088FF0088FF0088FF0088FF00AAFF 00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF 00AAFF00AAFF00AAFF00CCFF00CCFF00CCFF00CCFF00CCFF00CCFF00CCFF00CCFF00CCFF00CCFF 00CCFF00CCFF00CCFF00CCFF00CCFF00CCFF00CCFF00EEFF00EEFF00EEFF00EEFF00EEFF00EEFF 00EEFF00EEFF00EEFF00EEFF00EEFF00EEFF00EEFF00EEFF00EEFF00EEFF00EEFF00FFED00FFED 00FFED00FFED00FFED00FFED00FFED00FFED00FFED00FFED00FFED00FFED00FFED00FFED00FFED 00FFED00FFED00FFCB00FFCB00FFCB00FFCB00FFCB00FFCB00FFCB00FFCB00FFCB00FFCB00FFCB 00FFCB00FFCB00FFCB00FFCB00FFCB00FFCB00FFA900FFA900FFA900FFA900FFA900FFA900FFA9 00FFA900FFA900FFA900FFA900FFA900FFA900FFA900FFA900FFA900FFA900FF8700FF8700FF87 00FF8700FF8700FF8700FF8700FF8700FF8700FF8700FF8700FF8700FF8700FF8700FF8700FF87 00FF8700FF6500FF6500FF6500FF6500FF6500FF6500FF6500FF6500FF6500FF6500FF6500FF65 00FF6500FF6500FF6500FF6500FF6500FF4300FF4300FF4300FF4300FF4300FF4300FF4300FF43 00FF4300FF4300FF4300FF4300FF4300FF4300FF4300FF4300FF4300FF2100FF2100FF2100FF21 00FF2100FF2100FF2100FF2100FF2100FF2100FF2100FF2100FF2100FF2100FF2100FF2100FF21 00FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF00 00FF0000FF0000FF0000FF0000FF0022FF0022FF0022FF0022FF0022FF0022FF0022FF0022FF00 22FF0022FF0022FF0022FF0022FF0022FF0022FF0022FF0022FF0044FF0044FF0044FF0044FF00 44FF0044FF0044FF0044FF0044FF0044FF0044FF0044FF0044FF0044FF0044FF0044FF0044FF00 66FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF0066FF00 66FF0066FF0066FF0066FF0088FF0088FF0088FF0088FF0088FF0088FF0088FF0088FF0088FF00 88FF0088FF0088FF0088FF0088FF0088FF0088FF0088FF00AAFF00AAFF00AAFF00AAFF00AAFF00 AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00AAFF00CCFF00 CCFF00CCFF00CCFF00CCFF00CCFF00CCFF00CCFF00CCFF00CCFF00CCFF00CCFF00CCFF00CCFF00 CCFF00CCFF00CCFF00EEFF00EEFF00EEFF00EEFF00EEFF00EEFF00EEFF00EEFF00EEFF00EEFF00 EEFF00EEFF00EEFF00EEFF00EEFF00EEFF00EEFF00FFED00FFED00FFED00FFED00FFED00FFED00 FFED00FFED00FFED00FFED00FFED00FFED00FFED00FFED00FFED00FFED00FFED00FFCB00FFCB00 FFCB00FFCB00FFCB00FFCB00FFCB00FFCB00FFCB00FFCB00FFCB00FFCB00FFCB00FFCB00FFCB00 FFCB00FFCB00FFA900FFA900FFA900FFA900FFA900FFA900FFA900FFA900FFA900FFA900FFA900 FFA900FFA900FFA900FFA900FFA900FFA900FF8700FF8700FF8700FF8700FF8700FF8700FF8700 FF8700FF8700FF8700FF8700FF8700FF8700FF8700FF8700FF8700FF8700FF6500FF6500FF6500 FF6500FF6500FF6500FF6500FF6500FF6500FF6500FF6500FF6500FF6500FF6500FF6500FF6500 FF6500FF4300FF4300FF4300FF4300FF4300FF4300FF4300FF4300FF4300FF4300FF4300FF4300 FF4300FF4300FF4300FF4300FF4300FF2100FF2100FF2100FF2100FF2100FF2100FF2100FF2100 FF2100FF2100FF2100FF2100FF2100FF2100FF2100FF2100FF2100FF0000FF0000FF0000FF0000 FF0000FF0000FF0000FF0000FF0000 Q % turn clipping off for image palette % gr_show_at() BEGIN 0 g 0 G 164.0 570.9 m (11) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 285.4 570.9 m (12) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 406.8 570.9 m (13) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 528.2 570.9 m (14) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 591.76 m 170.70 591.76 l 170.70 586.07 l 170.70 591.76 l 292.09 591.76 l 292.09 586.07 l 292.09 591.76 l 413.47 591.76 l 413.47 586.07 l 413.47 591.76 l 534.86 591.76 l 534.86 586.07 l 534.86 591.76 l 534.98 591.76 l S % END GriPath stroke/fill 0.369 w % test 0 g 0 G 1.0 i 0 J 1 j 0.369 w 10.0 M [] 0 d 170.70 591.76 m 170.70 620.21 l 534.86 620.21 l 534.86 591.76 l 170.70 591.76 l S % END GriPath stroke/fill %gri:draw image histogram %^ scale 1 170.7 0 1.4225 1 170.7 0 1.4225 % gr_show_at() BEGIN 0 g 0 G 167.4 642.1 m (5) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 224.7 642.1 m (10) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 285.4 642.1 m (15) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 346.1 642.1 m (20) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 406.8 642.1 m (25) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 467.5 642.1 m (30) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 528.2 642.1 m (35) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 662.88 m 170.70 662.88 l 170.70 657.20 l 170.70 662.88 l 231.39 662.88 l 231.39 657.20 l 231.39 662.88 l 292.09 662.88 l 292.09 657.20 l 292.09 662.88 l 352.78 662.88 l 352.78 657.20 l 352.78 662.88 l 413.47 662.88 l 413.47 657.20 l 413.47 662.88 l 474.17 662.88 l 474.17 657.20 l 474.17 662.88 l 534.86 662.88 l 534.86 657.20 l 534.86 662.88 l 534.92 662.88 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 135.1 658.6 m () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (1) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (0) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh 0.0 5.4 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh (\255) sh () sh /Helvetica-ISOLatin1 findfont 9.00 sc sf (4) sh /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 -5.4 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 135.1 676.3 m () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (1) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (0) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh 0.0 5.4 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh (\255) sh () sh /Helvetica-ISOLatin1 findfont 9.00 sc sf (3) sh /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 -5.4 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 135.1 694.1 m () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (1) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (0) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh 0.0 5.4 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh (\255) sh () sh /Helvetica-ISOLatin1 findfont 9.00 sc sf (2) sh /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 -5.4 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 135.1 711.9 m () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (1) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (0) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh 0.0 5.4 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh (\255) sh () sh /Helvetica-ISOLatin1 findfont 9.00 sc sf (1) sh /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 -5.4 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 152.5 729.7 m (1) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 662.74 m 170.70 662.88 l 165.01 662.88 l 170.70 662.88 l 170.70 668.24 l 167.86 668.24 l 170.70 668.24 l 170.70 671.37 l 167.86 671.37 l 170.70 671.37 l 170.70 673.59 l 167.86 673.59 l 170.70 673.59 l 170.70 675.31 l 167.86 675.31 l 170.70 675.31 l 170.70 676.72 l 167.86 676.72 l 170.70 676.72 l 170.70 677.91 l 167.86 677.91 l 170.70 677.91 l 170.70 678.94 l 167.86 678.94 l 170.70 678.94 l 170.70 679.85 l 167.86 679.85 l 170.70 679.85 l 170.70 680.67 l 165.01 680.67 l 170.70 680.67 l 170.70 686.02 l 167.86 686.02 l 170.70 686.02 l 170.70 689.15 l 167.86 689.15 l 170.70 689.15 l 170.70 691.37 l 167.86 691.37 l 170.70 691.37 l 170.70 693.09 l 167.86 693.09 l 170.70 693.09 l 170.70 694.50 l 167.86 694.50 l 170.70 694.50 l 170.70 695.69 l 167.86 695.69 l 170.70 695.69 l 170.70 696.72 l 167.86 696.72 l 170.70 696.72 l 170.70 697.63 l 167.86 697.63 l 170.70 697.63 l 170.70 698.45 l 165.01 698.45 l 170.70 698.45 l 170.70 703.80 l 167.86 703.80 l 170.70 703.80 l 170.70 706.93 l 167.86 706.93 l 170.70 706.93 l 170.70 709.15 l 167.86 709.15 l 170.70 709.15 l 170.70 710.88 l 167.86 710.88 l 170.70 710.88 l 170.70 712.28 l 167.86 712.28 l 170.70 712.28 l 170.70 713.47 l 167.86 713.47 l 170.70 713.47 l 170.70 714.51 l 167.86 714.51 l 170.70 714.51 l 170.70 715.42 l 167.86 715.42 l 170.70 715.42 l 170.70 716.23 l 165.01 716.23 l 170.70 716.23 l 170.70 721.58 l 167.86 721.58 l 170.70 721.58 l 170.70 724.71 l 167.86 724.71 l 170.70 724.71 l 170.70 726.93 l 167.86 726.93 l 170.70 726.93 l 170.70 728.66 l 167.86 728.66 l 170.70 728.66 l 170.70 730.07 l 167.86 730.07 l 170.70 730.07 l 170.70 731.26 l 167.86 731.26 l 170.70 731.26 l 170.70 732.29 l 167.86 732.29 l 170.70 732.29 l 170.70 733.20 l 167.86 733.20 l 170.70 733.20 l 170.70 734.01 l 165.01 734.01 l 170.70 734.01 l 170.70 734.01 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 662.88 m 170.70 734.01 l 534.86 734.01 l 534.86 662.88 l 170.70 662.88 m 170.70 662.88 l 171.91 662.88 l 173.13 662.88 l 174.34 662.88 l 175.56 692.95 l 176.77 662.88 l 177.98 671.49 l 179.20 675.46 l 180.41 668.33 l 181.62 671.49 l 182.84 671.49 l 184.05 668.33 l 185.27 673.72 l 186.48 671.49 l 187.69 662.88 l 188.91 676.87 l 190.12 662.88 l 191.34 668.33 l 192.55 668.33 l 193.76 662.88 l 194.98 676.87 l 196.19 680.01 l 197.41 675.46 l 198.62 671.49 l 199.83 678.06 l 201.05 673.72 l 202.26 675.46 l 203.47 676.87 l 204.69 675.46 l 205.90 673.72 l 207.12 675.46 l 208.33 675.46 l 209.54 678.06 l 210.76 671.49 l 211.97 682.86 l 213.19 682.24 l 214.40 678.06 l 215.61 676.87 l 216.83 680.01 l 218.04 673.72 l 219.25 679.10 l 220.47 668.33 l 221.68 679.10 l 222.90 682.24 l 224.11 684.93 l 225.32 680.83 l 226.54 683.43 l 227.75 680.01 l 228.97 684.46 l 230.18 680.01 l 231.39 683.96 l 232.61 682.86 l 233.82 683.96 l 235.03 682.24 l 236.25 687.91 l 237.46 688.79 l 238.68 688.51 l 239.89 685.79 l 241.10 690.06 l 242.32 690.29 l 243.53 692.10 l 244.75 693.86 l 245.96 695.30 l 247.17 696.80 l 248.39 702.01 l 249.60 697.55 l 250.82 698.93 l 252.03 699.07 l 253.24 699.22 l 254.46 702.81 l 255.67 704.89 l 256.88 707.58 l 258.10 708.81 l 259.31 712.05 l 260.53 712.08 l 261.74 714.19 l 262.95 711.16 l 264.17 715.13 l 265.38 714.52 l 266.60 714.01 l 267.81 718.19 l 269.02 707.29 l 270.24 703.33 l 271.45 697.81 l 272.66 695.64 l 273.88 693.11 l 275.09 691.74 l 276.31 690.51 l 277.52 692.10 l 278.73 693.42 l 279.95 692.28 l 281.16 689.06 l 282.38 698.47 l 283.59 691.35 l 284.80 689.32 l 286.02 686.56 l 287.23 683.96 l 288.45 687.27 l 289.66 682.24 l 290.87 682.86 l 292.09 681.56 l 293.30 679.10 l 294.51 685.79 l 295.73 679.10 l 296.94 682.24 l 298.16 676.87 l 299.37 684.46 l 300.58 684.46 l 301.80 683.43 l 303.01 686.19 l 304.23 684.93 l 305.44 691.35 l 306.65 684.46 l 307.87 683.96 l 309.08 682.24 l 310.29 675.46 l 311.51 671.49 l 312.72 673.72 l 313.94 668.33 l 315.15 671.49 l 316.36 662.88 l 317.58 662.88 l 318.79 662.88 l 320.01 662.88 l 321.22 662.88 l 322.43 662.88 l 323.65 662.88 l 324.86 662.88 l 326.07 662.88 l 327.29 662.88 l 328.50 662.88 l 329.72 662.88 l 330.93 662.88 l 332.14 662.88 l 333.36 662.88 l 334.57 662.88 l 335.79 662.88 l 337.00 662.88 l 338.21 662.88 l 339.43 662.88 l 340.64 662.88 l 341.86 662.88 l 343.07 662.88 l 344.28 662.88 l 345.50 662.88 l 346.71 662.88 l 347.92 662.88 l 349.14 662.88 l 350.35 662.88 l 351.57 662.88 l 352.78 662.88 l 353.99 662.88 l 355.21 662.88 l 356.42 662.88 l 357.64 662.88 l 358.85 662.88 l 360.06 662.88 l 361.28 662.88 l 362.49 662.88 l 363.70 662.88 l 364.92 662.88 l 366.13 662.88 l 367.35 662.88 l 368.56 662.88 l 369.77 662.88 l 370.99 662.88 l 372.20 662.88 l 373.42 662.88 l 374.63 662.88 l 375.84 662.88 l 377.06 662.88 l 378.27 662.88 l 379.49 662.88 l 380.70 662.88 l 381.91 662.88 l 383.13 662.88 l 384.34 662.88 l 385.55 662.88 l 386.77 662.88 l 387.98 662.88 l 389.20 662.88 l 390.41 662.88 l 391.62 662.88 l 392.84 662.88 l 394.05 662.88 l 395.27 662.88 l 396.48 662.88 l 397.69 662.88 l 398.91 662.88 l 400.12 662.88 l 401.33 662.88 l 402.55 662.88 l 403.76 662.88 l 404.98 662.88 l 406.19 662.88 l 407.40 662.88 l 408.62 662.88 l 409.83 662.88 l 411.05 662.88 l 412.26 662.88 l 413.47 662.88 l 414.69 662.88 l 415.90 662.88 l 417.11 662.88 l 418.33 662.88 l 419.54 662.88 l 420.76 662.88 l 421.97 662.88 l 423.18 662.88 l 424.40 662.88 l 425.61 662.88 l 426.83 662.88 l 428.04 662.88 l 429.25 662.88 l 430.47 662.88 l 431.68 662.88 l 432.90 662.88 l 434.11 662.88 l 435.32 662.88 l 436.54 662.88 l 437.75 662.88 l 438.96 662.88 l 440.18 662.88 l 441.39 662.88 l 442.61 662.88 l 443.82 662.88 l 445.03 662.88 l 446.25 662.88 l 447.46 662.88 l 448.68 662.88 l 449.89 662.88 l 451.10 662.88 l 452.32 662.88 l 453.53 662.88 l 454.74 662.88 l 455.96 662.88 l 457.17 662.88 l 458.39 662.88 l 459.60 662.88 l 460.81 662.88 l 462.03 662.88 l 463.24 662.88 l 464.46 662.88 l 465.67 662.88 l 466.88 662.88 l 468.10 662.88 l 469.31 662.88 l 470.53 662.88 l 471.74 662.88 l 472.95 662.88 l 474.17 662.88 l 475.38 662.88 l 476.59 662.88 l 477.81 662.88 l 479.02 662.88 l 480.24 662.88 l S % END GriPath stroke/fill %gri:draw title "Example 6: colorscale" %^ scale 1 170.7 0 1.4225 1 170.7 0 1.4225 % gr_show_at() BEGIN 0 g 0 G 293.9 762.5 m (Example 6: colorscale) sh % gr_show_at() END %gri:quit showpage %%Trailer %%BoundingBox: 123 130 547 773 %%DocumentFonts: Courier Helvetica Palatino-Roman Palatino-Italic Symbol Times-Roman %%Pages: 1 gri/doc/examples/example8.ps0000644000175000017500000011603013147557614014473 0ustar psgpsg%!PS-Adobe-2.0 EPSF-1.2 %%Creator: Gri2.12.2 (released 2002-nov-23). User=kelley, commandfile=example8 %%Title: example8.ps %%CreationDate: Thu Dec 5 19:19:48 2002 %%Pages: (atend) %%BoundingBox: (atend) %%TemplateBox: 0 0 612 792 %%DocumentFonts: (atend) %%Endcomments % NOTE: The Gri postscript dictionary is being converted to the Adobe % Illustrator 3.0 dialect of PostScript, as described in the Adobe % documents stored at URL % http://www.adobe.com/Support/TechNotes.html % (as of Jan 1996, this doc is number 5007). When the conversion % is complete, the Adobe Illustrator drawing program -- and any % program compatible with AI -- will be able to edit Gri output. % % The IslandDraw (TM) program is able to read Gri output % at this time; remarkably, it can read/edit arbitrary PostScript. % % The definitions below are presented in the same order as the Adobe % manual. The stack configuration before and after is shown in curly % brackets. All the operators are listed, but only some are defined % here. Most things are faithful, except that no distinction is made % between colors for stroking and filling paths. The string 'WRONGLY' % appears with commands that are approximations. % % PDF-style abbreviations: /rg {setrgbcolor} def % {red green blue} {-} set RGB color /RG {setrgbcolor} def % {red green blue} {-} set RGB color /q {gsave} def /Q {grestore} def /W {clip} def /W* {eoclip} def % % Gri-specific abbreviations: /hsb {sethsbcolor} def % {hue saturation brightness} {-} set HSB color % % Following all try to mimic Adobe Illustrator % % Mimicking section 5.1 of Adobe manual: %A % {flag A} {-} Determine whether % following object can % be selected. Flag=1 % prevents selection; % flag=0 allows it. % Mimicking section 5.2 of Adobe manual: %u % {u} {-} start group %U % end group %q % as 'u' but first item is a clip path %Q % as 'U' but first item is a clip path % Mimicking section 5.3 of Adobe manual: /g {setgray} def % {gray g} {-} Set gray for fill % path, WRONGLY used % for stroking also. /G {setgray} def % As 'g', but for filling path. %k % Set cmyk color for filling path. %K % As 'k', but for stroking path. %x % Set cmyk custom color for filling path. %X % As 'x' but for stroking path. %p % Define pattern for filling path. %P % As 'p' but for stroking path. %O % Specify whether overprinting for fill paths %R % As 'O' but for stroking path. % Mimicking section 5.4 of Adobe manual: /d {setdash} def % {[array] phase d} {-} Set dash. /i {setflat} def % {flatness i} {-} Set flatness. /j {setlinejoin} def % {linejoin j} {-} Set line join. /J {setlinecap} def % {linecap J} {-} Set line cap. /M {setmiterlimit} def % {miterlimit M} {-} Set miter limit. /w {setlinewidth} def % {linewidth w} {-} Set line width. % Mimicking section 5.5 of Adobe manual: /m {moveto} def % {x y m} {-} Move to locn /l {lineto} def % {x y l} {-} Draw line to locn % not a smooth point. % WRONGLY, no % distinction is made % between smooth and % corner. %L % {x y L} {-} As 'l' but a corner %c % Bezier curve to smooth point. %C % As 'c' but to corner point. %v % Something else to do with Bezier. %V % %y % %Y % % Mimicking section 5.6 of Adobe manual: %N % {N} {-} As 'n' for nondrawn stuff /n {newpath} def % {n} {-} WRONGLY interpreted % as path constructor /F {fill} def % {F} {-} Fill current path. %f % {f} {-} 'F' but close first /S {stroke} def % {S} {-} Stroke current path. %s % {s} {-} 'S' but close first %B % {B} {-} As 's' but don't empty path. %b % {b} {-} As 'f' but don't empty path. %H % no-op (weird huh?) /h {closepath} def % {h} {-} Close current path %W % Used to create masks. % Mimicking section 5.7 of Adobe manual: %a % Begin text block ... %e % Similar to 'a' but ... %I % Similar to 'a' but ... %o % Similar to 'a' but ... %r % Similar to 'a' but ... %t % {len (string) t} {-} Render string. %T % End block of text % That's the end of the Illustrator stuff. Following are some Gri % definitions which provide a temporary way of handling fonts. /sf {setfont} def % {fontname sf} {-} Set font name. /sh {show} def % {(text) sh} {-} Show text. /sc {scalefont} def % {size sc} {-} Scale font. % Gri items which should be translated to Illustrator format: /rl {rlineto} def /rm {rmoveto} def % Procedures /cimdict 7 dict def /cim { cimdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def q xll yll translate xur xll sub yur yll sub scale /do cl 3 mul string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop} false 3 colorimage Q end } def /imdict 14 dict def /im { imdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def /imagemap exch def q % Until version 2.6.0 used a 'settransfer' here, but that % triggers a bug in ps2pdf xll yll translate xur xll sub yur yll sub scale /do cl string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop dup length 1 sub 0 1 3 -1 roll { 1 index exch 2 copy get imagemap exch get 255 mul cvi put } for }image Q end } bind def /frdict 5 dict def /fr { frdict begin /yt exch def /xr exch def /yb exch def /xl exch def n xl yb m xl yt l xr yt l xr yb l h F n end } def /plusdict 3 dict def /_plus { plusdict begin dup 0.5 mul /t0 exch def /t1 exch def 0 t0 rm 0 t1 neg rl t0 neg t0 rm t1 0 rl t0 neg 0 rm end } def /timesdict 3 dict def /_times { timesdict begin dup 0.353553 mul /t0 exch def 0.707106 mul /t1 exch def t0 neg t0 rm t1 dup neg rl t1 neg 0 rm t1 dup rl t0 neg dup rm end } def /boxdict 3 dict def /_box { boxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm end } def /filledboxdict 3 dict def /_filledbox { filledboxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm F end } def /diamonddict 2 dict def /_diamond { diamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm end } def /filleddiamonddict 2 dict def /_filleddiamond { filleddiamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm F end } def /triangleupdict 5 dict def /_triangleup { triangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm end } def /filledtriangleupdict 5 dict def /_filledtriangleup { filledtriangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm F end } def /trianglerightdict 5 dict def /_triangleright { trianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm end } def /filledtrianglerightdict 5 dict def /_filledtriangleright { filledtrianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm F end } def /triangledowndict 5 dict def /_triangledown { triangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm end } def /filledtriangledowndict 5 dict def /_filledtriangledown { filledtriangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm F end } def /triangleleftdict 5 dict def /_triangleleft { triangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm end } def /filledtriangleleftdict 5 dict def /_filledtriangleleft { filledtriangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm F end } def /circdict 5 dict def /_circ { circdict begin 0.5 mul /t0 exch def currentpoint /t2 exch def /t1 exch def S n t1 t2 t0 0 360 arc t1 t2 m end } def /bulldict 3 dict def /_bull { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 360 arc h F S end } def /filledhalfmoonupdict 3 dict def /_filledhalfmoonup { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 180 arc h F S end } def /filledhalfmoondowndict 3 dict def /_filledhalfmoondown { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 180 360 arc h F S end } def 1 1 scale 10.0 M 1 j /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-ISOLatin1 exch definefont pop /Courier-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Oblique-ISOLatin1 exch definefont pop /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Bold-ISOLatin1 exch definefont pop /Courier-BoldOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-BoldOblique-ISOLatin1 exch definefont pop /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-ISOLatin1 exch definefont pop /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Bold-ISOLatin1 exch definefont pop /Helvetica-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Oblique-ISOLatin1 exch definefont pop /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Roman-ISOLatin1 exch definefont pop /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Italic-ISOLatin1 exch definefont pop /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Bold-ISOLatin1 exch definefont pop /Palatino-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-BoldItalic-ISOLatin1 exch definefont pop /Symbol findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Symbol-ISOLatin1 exch definefont pop /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Roman-ISOLatin1 exch definefont pop /Times-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Italic-ISOLatin1 exch definefont pop /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Bold-ISOLatin1 exch definefont pop /Times-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-BoldItalic-ISOLatin1 exch definefont pop %%EndProlog %%Page: 1 1 /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:# Gri was invoked by user named %gri:# kelley %gri:# on host named %gri:# kelley-home %gri:# using the command %gri:# gri example8 %gri:# at local time Thu Dec 5 19:19:48 2002. %gri:# Example 8 -- Plot T=T(x,rho) section of eubex data %gri: %gri:`Initialize Parameters' %gri:{ %gri: \FILE_DATA = "example8a.dat" # T vs rho %gri: \FILE_LOCN = "example8b.dat" # section distances %gri: set missing value -99.0 %gri: # %gri: # Following values from ~/eubex/processing/to_rho_bins/do_rho_inter %gri: \RHO_MIN = "28.1" %gri: \RHO_MAX = "27.5" %gri: \RHO_INC = "-0.002" %gri: \NY = "301" %gri: \xmin = "350" %gri: \xmax = "0" %gri: \xinc = "-100" %gri: \ymin = "28.1" %gri: \ymax = "27.8" %gri: \yinc = "-0.1" %gri: \zmin = "0" %gri: \zmax = "2.5" %gri:} %gri:`Initialize Axes' %gri:/* %gri:Set up axes %gri:*/ %gri:{ %gri: set x name "km" %gri: set x size 10 %gri: set x axis \xmin \xmax \xinc %gri: set y name "$\sigma_T$" %gri: set y size 5 %gri: set y axis name horizontal %gri: set y axis \ymin \ymax \yinc %gri: set y format "%.1f" %gri:} %gri:`Initialize Files' %gri:{ %gri: query \data "Data file? " ("\FILE_DATA") %gri: query \locn "Station locn?" ("\FILE_LOCN") %gri:} %gri:`Read Data' %gri:{ %gri: # Read x-locations %gri: system awk '{print $2}' < \locn > TMP %gri: system wc TMP | awk '{print $1}' > NUM %gri: open NUM %gri: read .gridx_number. %gri: close %gri: system rm NUM %gri: open TMP %gri: read grid x .gridx_number. %gri: close %gri: system rm TMP %gri: # Create y-locations %gri: set y grid \RHO_MIN \RHO_MAX \RHO_INC %gri: # %gri: # Read data %gri: open \data %gri: read grid data \NY .gridx_number. %gri: close %gri:} %gri:`Plot Contours' %gri:{ %gri: set graylevel .contour_graylevel. %gri: set clip on %gri: set line width 0.5 %gri: draw contour -3 3 0.25 unlabelled %gri: # %gri: # wide line at 0 degrees %gri: set line width 2 %gri: draw contour 0 unlabelled %gri:} %gri:`Plot Image And Maybe Contours' %gri:{ %gri: \imagefile = "image" %gri: set image range \zmin \zmax %gri: convert grid to image box \xmin \ymin \xmax \ymax %gri: query \dohisto "Do histogram scaling? (yes|no)" ("yes") %gri: \incs = "no" %gri: if {"\dohisto" == "yes"} %gri: set image grayscale using histogram %gri: else %gri: \zinc = "0.25" %gri: query \incs "In linear scaling, band at an increment of \zinc?" ("yes") %gri: if {"\incs" == "yes"} %gri: set image grayscale black \zmin white \zmax increment \zinc %gri: else %gri: set image grayscale black \zmin white \zmax %gri: end if %gri: end if %gri: write image rasterfile to \imagefile %gri: show "wrote image rasterfile `\imagefile '" %gri: draw image %gri: draw image palette %gri: query \do_contours "Do contours as well (yes|no)" ("yes") %gri: if {"\do_contours" == "yes"} %gri: Plot Contours %gri: end if %gri: draw title "Example 8 -- \data black=\zmin white=\zmax" %gri: if {"\dohisto" == "yes"} %gri: draw title "Histogram enhanced grayscales" %gri: else %gri: if {"\incs" == "yes"} %gri: draw title "Grayscale banded at intervals of \zinc" %gri: end if %gri: end if %gri:} %gri:Initialize Parameters %gri:Initialize Axes %gri:Initialize Files %gri:Read Data %gri:query \doimage "Draw image (yes|no)" ("no") %gri:if {"\doimage" == "yes"} %gri: .contour_graylevel. = 1 # white contours %gri: Plot Image And Maybe Contours %gri:else %gri: .contour_graylevel. = 0 # black contours %gri: Plot Contours %^ scale 1 170.7 350 -0.812857 1 170.7 28.1 -474.167 0.500 w 0 g 0 G 1.0 i 0 J 1 j 0.500 w 10.0 M [] 0 d 455.16 278.31 m 444.19 278.48 l 439.64 278.81 l 440.93 279.23 l 441.14 279.34 l 442.34 279.76 l 442.44 280.14 l 442.63 280.33 l 442.74 280.71 l 440.37 281.15 l 440.44 281.22 l 436.73 281.66 l 439.36 282.12 l 439.38 282.14 l 441.49 282.60 l 440.37 283.04 l 439.98 283.10 l 439.09 283.55 l 436.67 283.95 l 436.50 284.11 l 434.64 284.50 l 433.93 284.82 l 432.97 285.16 l 432.30 285.45 l 432.26 285.72 l 431.50 286.15 l 431.46 286.40 l 431.03 286.63 l 430.63 287.12 l 430.24 287.34 l 429.72 287.54 l 429.20 288.11 l 428.77 288.29 l 427.17 288.41 l 427.24 289.12 l 426.34 289.24 l 425.97 289.32 l 423.19 289.77 l 416.28 289.34 l 415.61 289.24 l 415.73 289.13 l 415.87 288.40 l 415.99 288.29 l 415.33 288.18 l 414.49 287.47 l 413.63 287.34 l 413.42 287.20 l 412.72 286.55 l 412.48 286.40 l 411.98 286.23 l 410.54 285.63 l 409.96 285.45 l 409.61 285.25 l 407.51 284.73 l 407.13 284.50 l 407.32 284.27 l 406.66 283.79 l 406.85 283.55 l 406.47 283.31 l 407.43 282.84 l 407.03 282.60 l 406.33 282.36 l 410.46 281.84 l 409.73 281.66 l 406.77 281.41 l 400.54 281.04 l 397.07 280.71 l 396.61 280.32 l 396.53 280.15 l 396.07 279.76 l 397.36 279.38 l 398.53 279.17 l 399.85 278.81 l 401.16 278.49 l 402.41 278.17 l 403.64 277.86 l 401.85 277.55 l 400.49 277.25 l 398.51 276.91 l 401.01 276.59 l 403.87 276.25 l 406.10 275.97 l 404.64 275.69 l 399.25 275.37 l 397.95 275.02 l 397.13 274.63 l 397.81 274.44 l 396.85 274.07 l 395.82 273.67 l 395.90 273.52 l 394.77 273.12 l 395.05 272.71 l 395.11 272.58 l 395.39 272.17 l 396.23 271.78 l 396.62 271.61 l 397.46 271.22 l 396.62 270.83 l 397.47 270.65 l 396.47 270.28 l 399.37 269.92 l 403.05 269.62 l 405.77 269.33 l 408.44 269.11 l 415.68 268.49 l 417.02 268.38 l 417.16 268.29 l 414.92 267.55 l 415.10 267.43 l 413.55 267.29 l 405.00 266.75 l 402.55 266.48 l 402.13 266.17 l 401.46 265.85 l 401.05 265.53 l 401.34 265.21 l 401.11 264.91 l 401.39 264.58 l 399.07 264.23 l 397.54 264.01 l 395.11 263.64 l 396.40 263.24 l 396.75 263.08 l 397.99 262.69 l 398.46 262.32 l 398.46 262.10 l 398.91 261.74 l 399.88 261.40 l 400.97 261.12 l 401.93 260.79 l 403.70 260.50 l 408.43 260.06 l 409.95 259.84 l 410.86 259.66 l 412.57 259.05 l 413.31 258.89 l 414.50 258.77 l 423.19 258.40 l 438.45 258.44 l 447.17 258.66 l 455.16 258.78 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 1 j 0.500 w 10.0 M [] 0 d 455.16 288.57 m 446.93 289.00 l 445.10 289.24 l 443.55 289.59 l 442.79 289.82 l 440.98 290.19 l 440.35 290.63 l 440.19 290.69 l 439.60 291.14 l 439.86 291.59 l 439.87 291.63 l 440.12 292.09 l 439.55 292.55 l 439.54 292.57 l 438.93 293.03 l 434.59 293.37 l 433.84 293.67 l 431.25 293.98 l 430.72 294.21 l 427.48 294.80 l 427.13 294.93 l 427.13 295.05 l 426.90 295.77 l 426.90 295.88 l 426.89 295.99 l 426.40 296.73 l 426.39 296.83 l 426.35 296.92 l 425.25 297.72 l 425.22 297.78 l 425.22 297.84 l 424.92 298.67 l 424.93 298.72 l 424.93 298.78 l 424.74 299.63 l 424.74 299.67 l 424.75 299.72 l 424.75 300.58 l 424.76 300.62 l 424.54 300.66 l 424.37 301.53 l 424.23 301.57 l 424.16 301.60 l 423.35 302.51 l 423.34 302.52 l 423.32 302.52 l 423.19 302.53 l 422.61 302.53 l 422.30 302.52 l 422.15 302.50 l 417.57 301.65 l 416.64 301.57 l 415.94 301.46 l 415.09 300.74 l 414.16 300.62 l 413.61 300.48 l 413.61 299.81 l 412.99 299.67 l 412.69 299.52 l 411.76 298.89 l 411.43 298.72 l 411.25 298.55 l 409.85 297.97 l 409.67 297.78 l 409.18 297.57 l 405.09 297.09 l 404.56 296.83 l 404.67 296.56 l 403.26 296.17 l 403.36 295.88 l 403.76 295.59 l 403.14 295.23 l 403.52 294.93 l 400.23 294.59 l 395.56 294.39 l 393.06 293.98 l 387.49 293.56 l 384.58 293.42 l 378.64 293.03 l 376.80 292.77 l 373.18 292.30 l 371.67 292.09 l 371.84 291.89 l 371.41 291.32 l 371.58 291.14 l 371.65 290.95 l 372.62 290.39 l 372.70 290.19 l 371.13 290.01 l 371.75 289.43 l 370.47 289.24 l 370.67 289.07 l 371.87 288.49 l 372.09 288.29 l 371.05 288.11 l 363.25 287.41 l 362.80 287.34 l 362.72 287.29 l 361.06 286.43 l 361.00 286.40 l 360.91 286.36 l 358.74 285.78 l 357.46 285.47 l 357.38 285.45 l 357.35 285.43 l 358.03 284.51 l 358.01 284.50 l 357.99 284.49 l 358.74 284.31 l 360.92 283.58 l 360.94 283.55 l 360.89 283.52 l 358.74 283.11 l 355.11 282.66 l 354.70 282.60 l 353.83 282.53 l 343.51 281.89 l 341.24 281.66 l 340.18 281.37 l 338.34 281.02 l 337.23 280.71 l 335.82 280.35 l 335.39 280.12 l 333.84 279.76 l 333.69 279.37 l 333.94 279.19 l 333.78 278.81 l 332.73 278.41 l 333.47 278.25 l 332.18 277.86 l 329.25 277.41 l 328.93 277.37 l 326.16 276.91 l 326.68 276.46 l 326.43 276.42 l 327.08 275.97 l 329.75 275.52 l 330.91 275.44 l 334.24 275.02 l 330.51 274.58 l 329.42 274.52 l 326.54 274.07 l 322.82 273.67 l 321.07 273.49 l 317.58 273.12 l 316.16 272.83 l 310.89 272.39 l 309.62 272.17 l 309.77 271.98 l 308.59 271.40 l 308.73 271.22 l 307.36 271.06 l 307.36 270.43 l 306.28 270.28 l 307.40 270.12 l 311.67 269.55 l 313.22 269.33 l 316.39 269.03 l 318.65 268.71 l 322.68 268.38 l 326.20 267.93 l 326.53 267.88 l 330.17 267.43 l 326.63 266.97 l 326.24 266.93 l 322.64 266.48 l 320.89 266.11 l 318.65 265.87 l 316.86 265.53 l 316.95 265.23 l 314.91 264.86 l 315.00 264.58 l 312.78 264.34 l 311.91 263.87 l 310.19 263.64 l 310.53 263.43 l 305.91 262.83 l 306.22 262.69 l 306.17 262.55 l 297.97 261.75 l 297.96 261.74 l 298.01 261.72 l 296.99 261.27 l 296.68 260.79 l 296.67 260.79 l 296.66 260.79 l 296.33 259.85 l 296.31 259.84 l 296.31 259.84 l 296.99 259.57 l 304.71 259.01 l 310.42 258.89 l 308.87 258.71 l 307.28 258.10 l 306.14 257.95 l 328.20 257.48 l 328.50 257.46 l 341.90 257.00 l 344.76 256.78 l 358.74 256.46 l 361.68 256.09 l 362.32 256.05 l 362.82 255.99 l 365.02 255.19 l 365.95 255.10 l 366.93 254.98 l 367.33 254.28 l 368.65 254.15 l 369.77 253.99 l 371.82 253.40 l 373.29 253.20 l 376.32 252.95 l 379.80 252.57 l 383.76 252.26 l 400.23 251.92 l 423.19 251.81 l 437.06 251.72 l 441.46 251.71 l 455.16 251.65 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 1 j 0.500 w 10.0 M [] 0 d 455.16 293.20 m 446.18 293.72 l 443.99 293.98 l 443.16 294.34 l 443.24 294.58 l 442.26 294.93 l 442.27 295.31 l 442.35 295.50 l 442.36 295.88 l 442.32 296.26 l 442.41 296.45 l 442.37 296.83 l 442.20 297.21 l 442.29 297.39 l 442.11 297.78 l 442.16 298.16 l 442.26 298.34 l 442.30 298.72 l 442.32 299.11 l 442.37 299.29 l 442.39 299.67 l 442.44 300.05 l 442.50 300.25 l 442.56 300.62 l 440.23 301.06 l 439.79 301.11 l 437.94 301.57 l 436.95 301.98 l 436.83 302.11 l 435.93 302.52 l 434.00 302.84 l 428.18 303.32 l 426.97 303.47 l 426.79 303.57 l 426.26 304.32 l 426.11 304.41 l 426.03 304.50 l 425.43 305.30 l 425.37 305.36 l 425.35 305.43 l 425.57 306.24 l 425.55 306.31 l 425.49 306.38 l 424.78 307.21 l 424.74 307.26 l 424.47 307.30 l 424.37 308.17 l 424.20 308.21 l 424.16 308.24 l 423.80 309.14 l 423.78 309.16 l 423.75 309.17 l 423.19 309.46 l 416.74 309.25 l 414.43 309.16 l 413.54 309.01 l 409.89 308.40 l 408.66 308.21 l 408.44 307.99 l 407.77 307.49 l 407.55 307.26 l 407.00 307.02 l 403.67 306.60 l 403.11 306.31 l 400.62 305.98 l 401.39 305.68 l 398.00 305.36 l 389.79 304.91 l 387.74 304.84 l 377.15 304.41 l 373.24 304.20 l 358.74 303.70 l 357.97 303.48 l 357.91 303.47 l 357.84 303.45 l 354.02 302.59 l 353.65 302.52 l 353.26 302.43 l 348.57 301.73 l 347.90 301.57 l 347.14 301.39 l 344.61 300.84 l 343.69 300.62 l 343.17 300.38 l 342.05 299.93 l 341.49 299.67 l 341.21 299.40 l 340.93 299.00 l 340.65 298.72 l 340.11 298.44 l 340.17 298.06 l 339.60 297.78 l 339.04 297.47 l 339.59 297.12 l 338.99 296.83 l 338.73 296.52 l 339.44 296.18 l 339.18 295.88 l 337.19 295.55 l 337.99 295.25 l 335.41 294.93 l 335.79 294.58 l 338.21 294.30 l 338.64 293.98 l 332.54 293.58 l 330.08 293.48 l 325.28 293.03 l 323.51 292.63 l 323.28 292.49 l 321.65 292.09 l 320.49 291.73 l 318.97 291.48 l 317.78 291.14 l 317.71 290.82 l 317.06 290.50 l 316.99 290.19 l 316.74 289.89 l 315.72 289.53 l 315.47 289.24 l 315.30 288.96 l 313.58 288.55 l 313.41 288.29 l 311.37 288.07 l 309.91 287.54 l 308.38 287.34 l 307.84 287.18 l 304.89 286.52 l 304.48 286.40 l 304.04 286.29 l 300.87 285.51 l 300.63 285.45 l 300.55 285.39 l 297.49 284.51 l 297.48 284.50 l 297.46 284.49 l 296.99 284.44 l 288.85 283.63 l 288.47 283.55 l 287.49 283.46 l 282.18 282.74 l 280.51 282.60 l 279.97 282.45 l 276.31 281.85 l 275.67 281.66 l 274.65 281.45 l 273.24 280.93 l 272.10 280.71 l 270.04 280.46 l 266.32 280.04 l 264.01 279.76 l 262.55 279.44 l 261.70 279.14 l 260.15 278.81 l 256.23 278.43 l 254.13 278.26 l 250.13 277.86 l 247.22 277.40 l 247.10 277.37 l 244.05 276.91 l 241.03 276.48 l 240.31 276.39 l 237.29 275.97 l 236.51 275.57 l 236.07 275.40 l 235.29 275.02 l 235.86 274.63 l 236.05 274.45 l 236.63 274.07 l 236.27 273.68 l 237.33 273.52 l 237.01 273.12 l 231.46 272.78 l 222.87 272.44 l 217.92 272.17 l 217.24 271.96 l 214.54 271.41 l 213.92 271.22 l 213.92 271.04 l 213.92 270.46 l 213.92 270.28 l 215.04 270.08 l 217.56 269.54 l 218.84 269.33 l 221.25 269.08 l 226.33 268.67 l 229.02 268.38 l 230.71 268.04 l 231.89 267.78 l 233.66 267.43 l 234.71 267.06 l 236.77 266.87 l 237.71 266.48 l 242.16 266.04 l 243.33 265.99 l 246.87 265.53 l 245.40 265.06 l 245.39 265.06 l 243.90 264.58 l 243.39 264.13 l 243.32 264.09 l 242.81 263.64 l 238.54 263.23 l 235.54 263.07 l 230.95 262.69 l 228.61 262.37 l 224.56 262.02 l 222.34 261.74 l 221.16 261.49 l 216.63 261.00 l 215.57 260.79 l 214.95 260.60 l 211.15 260.00 l 210.61 259.84 l 210.70 259.69 l 209.73 259.04 l 209.82 258.89 l 209.39 258.75 l 205.33 258.05 l 205.00 257.95 l 205.27 257.84 l 200.20 257.05 l 200.36 257.00 l 200.32 256.94 l 200.32 256.11 l 200.29 256.05 l 200.31 255.99 l 203.88 255.19 l 203.91 255.10 l 204.15 255.01 l 208.90 254.29 l 209.23 254.15 l 209.28 254.01 l 209.55 253.35 l 209.60 253.20 l 208.98 253.07 l 201.18 252.32 l 200.85 252.26 l 201.07 252.19 l 199.12 251.35 l 199.30 251.31 l 199.62 251.26 l 196.80 250.38 l 196.98 250.36 l 197.58 250.33 l 205.99 249.52 l 208.46 249.41 l 211.16 249.25 l 215.01 248.66 l 219.22 248.46 l 235.58 248.08 l 241.39 247.95 l 259.15 247.51 l 270.42 247.27 l 296.99 246.57 l 321.83 246.00 l 336.29 245.62 l 343.95 245.39 l 358.74 244.96 l 366.52 244.78 l 370.58 244.67 l 380.63 244.35 l 387.72 244.15 l 398.24 243.72 l 405.61 243.46 l 423.19 242.96 l 433.29 243.07 l 443.32 243.12 l 455.16 243.37 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 1 j 0.500 w 10.0 M [] 0 d 455.16 243.97 m 446.18 244.40 l 445.62 244.67 l 448.57 244.87 l 455.16 245.23 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 1 j 0.500 w 10.0 M [] 0 d 194.16 234.54 m 202.64 234.32 l 204.98 234.24 l 218.59 234.01 l 237.86 233.69 l 262.41 233.29 l 274.07 233.08 l 296.99 232.70 l 315.08 232.62 l 333.41 232.34 l 346.76 232.16 l 356.47 231.43 l 357.48 231.39 l 357.93 231.38 l 358.74 231.36 l 359.63 231.38 l 360.00 231.39 l 360.37 231.42 l 368.38 232.20 l 371.01 232.34 l 374.85 232.58 l 380.65 232.97 l 386.13 233.29 l 397.18 233.67 l 411.82 234.07 l 417.50 234.24 l 420.12 234.28 l 423.19 234.30 l 436.31 234.80 l 442.33 235.19 l 444.77 235.49 l 448.28 235.93 l 449.90 236.14 l 450.70 236.27 l 455.16 237.05 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 1 j 0.500 w 10.0 M [] 0 d 194.16 245.03 m 204.70 244.77 l 207.13 244.67 l 208.15 244.54 l 219.64 243.96 l 221.10 243.72 l 220.47 243.48 l 218.73 243.00 l 218.13 242.77 l 216.85 242.56 l 209.05 241.96 l 208.10 241.82 l 207.79 241.70 l 201.59 240.95 l 201.40 240.88 l 201.23 240.81 l 194.16 239.99 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 1 j 0.500 w 10.0 M [] 0 d 455.16 301.13 m 452.03 301.48 l 451.65 301.57 l 451.38 301.68 l 448.93 302.33 l 448.51 302.52 l 447.08 302.76 l 446.31 303.20 l 444.16 303.47 l 443.56 303.81 l 442.92 304.05 l 442.32 304.41 l 441.94 304.81 l 441.76 304.97 l 441.38 305.36 l 441.29 305.77 l 441.20 305.90 l 441.10 306.31 l 440.71 306.74 l 440.62 306.83 l 440.23 307.26 l 437.25 307.68 l 437.23 307.79 l 435.13 308.21 l 434.73 308.55 l 434.63 308.82 l 434.25 309.16 l 433.83 309.47 l 433.16 309.81 l 432.75 310.10 l 432.47 310.38 l 432.16 310.79 l 431.90 311.05 l 431.65 311.30 l 431.36 311.76 l 431.12 312.00 l 430.92 312.23 l 430.81 312.72 l 430.63 312.95 l 430.43 313.16 m 351.67 313.06 m 351.41 312.95 l 351.09 312.83 l 349.70 312.14 l 349.31 312.00 l 349.09 311.85 l 347.57 311.22 l 347.32 311.05 l 346.73 310.87 l 343.98 310.33 l 343.30 310.10 l 342.13 309.85 l 340.56 309.44 l 339.25 309.16 l 338.68 308.85 l 338.26 308.52 l 337.66 308.21 l 336.83 307.87 l 336.80 307.60 l 335.90 307.26 l 335.47 306.90 l 335.68 306.67 l 335.23 306.31 l 333.83 305.93 l 333.05 305.76 l 331.65 305.36 l 330.02 304.92 l 329.71 304.86 l 328.13 304.41 l 325.96 303.97 l 325.54 303.91 l 323.30 303.47 l 321.41 303.09 l 320.16 302.87 l 318.33 302.52 l 316.92 302.21 l 316.11 301.86 l 314.84 301.57 l 313.75 301.31 l 311.96 300.85 l 310.99 300.62 l 310.53 300.41 l 309.48 299.87 l 309.06 299.67 l 308.87 299.49 l 308.05 298.89 l 307.87 298.72 l 307.57 298.56 l 304.92 297.90 l 304.68 297.78 l 304.47 297.66 l 300.21 296.88 l 300.10 296.83 l 300.07 296.78 l 296.99 295.97 l 296.30 295.89 l 296.25 295.88 l 296.08 295.87 l 275.12 295.13 l 271.67 294.93 l 269.79 294.68 l 266.66 294.26 l 264.57 293.98 l 264.17 293.68 l 263.31 293.35 l 262.92 293.03 l 262.92 292.72 l 262.14 292.41 l 262.14 292.09 l 260.72 291.75 l 258.53 291.49 l 257.14 291.14 l 256.24 290.76 l 255.76 290.57 l 254.85 290.19 l 252.74 289.78 l 252.31 289.65 l 250.10 289.24 l 245.73 288.77 l 245.71 288.77 l 240.93 288.29 l 238.54 287.88 l 237.35 287.74 l 234.92 287.34 l 231.92 287.00 l 228.79 286.72 l 225.93 286.40 l 223.71 286.12 l 218.99 285.68 l 217.05 285.45 l 216.31 285.24 l 215.14 284.69 l 214.46 284.50 l 213.49 284.32 l 213.29 283.73 l 212.41 283.55 l 210.70 283.40 l 198.61 282.64 l 198.11 282.60 l 197.99 282.57 l 197.39 281.68 l 197.29 281.66 l 197.16 281.63 l 194.16 281.22 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 1 j 0.500 w 10.0 M [] 0 d 194.16 221.35 m 213.58 221.14 l 231.87 220.96 l 267.94 220.69 l 296.99 220.37 l 317.58 220.33 l 349.38 220.16 l 358.74 220.13 l 375.02 220.72 l 387.38 220.96 l 392.17 221.42 l 392.31 221.46 l 396.33 221.91 l 397.41 222.29 l 399.02 222.50 l 400.17 222.86 l 400.97 223.19 l 406.78 223.57 l 407.63 223.81 l 408.28 224.03 l 423.19 224.54 l 423.76 224.74 l 423.85 224.76 l 423.92 224.78 l 426.53 225.60 l 426.87 225.70 l 427.59 225.83 l 431.25 226.41 l 432.48 226.65 l 433.39 226.95 l 434.19 227.27 l 435.20 227.60 l 437.02 228.01 l 437.17 228.13 l 439.48 228.55 l 443.63 228.89 l 453.26 229.44 l 454.13 229.50 l 454.24 229.52 l 455.16 229.63 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 1 j 0.500 w 10.0 M [] 0 d 455.16 307.30 m 447.25 307.97 l 446.06 308.21 l 445.74 308.49 l 445.06 308.86 l 444.73 309.16 l 444.29 309.48 l 444.06 309.78 l 443.61 310.10 l 443.26 310.46 l 442.98 310.69 l 442.63 311.05 l 442.24 311.44 l 442.00 311.61 l 441.61 312.00 l 441.25 312.41 l 441.08 312.53 l 440.73 312.95 l 440.33 313.39 m 320.72 313.31 m 319.85 312.95 l 318.93 312.61 l 317.91 312.32 l 317.02 312.00 l 316.57 311.70 l 316.38 311.35 l 315.94 311.05 l 315.06 310.78 l 314.65 310.38 l 313.84 310.10 l 312.73 309.86 l 309.92 309.36 l 308.98 309.16 l 308.65 308.98 l 307.15 308.36 l 306.85 308.21 l 306.49 308.06 l 302.95 307.35 l 302.70 307.26 l 302.60 307.17 l 299.88 306.36 l 299.83 306.31 l 299.68 306.27 l 297.28 305.37 l 297.27 305.36 l 297.25 305.36 l 296.99 305.24 l 289.72 304.48 l 289.13 304.41 l 287.23 304.32 l 271.23 303.70 l 266.75 303.47 l 261.02 303.13 l 256.19 302.89 l 250.08 302.52 l 245.83 302.05 l 245.80 302.04 l 241.47 301.57 l 237.23 301.17 l 236.09 301.01 l 232.21 300.62 l 230.15 300.29 l 228.44 299.99 l 226.49 299.67 l 225.87 299.38 l 226.04 299.02 l 225.44 298.72 l 222.70 298.46 l 219.07 298.01 l 216.78 297.78 l 214.65 297.59 l 210.31 296.98 l 208.74 296.83 l 207.87 296.70 l 204.40 295.97 l 203.78 295.88 l 202.25 295.81 l 194.53 294.94 l 194.47 294.93 l 194.45 294.93 l 194.16 294.89 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 1 j 0.500 w 10.0 M [] 0 d 194.16 215.88 m 206.42 215.38 l 211.30 215.27 l 250.01 214.84 l 296.99 214.32 l 344.54 214.54 l 358.74 214.75 l 370.92 215.09 l 382.91 215.27 l 405.77 215.53 l 423.19 215.83 l 424.72 216.17 l 424.85 216.22 l 425.05 216.28 l 427.95 217.03 l 428.46 217.17 l 428.99 217.34 l 430.47 217.90 l 431.15 218.12 l 434.21 218.44 l 435.77 218.69 l 440.26 219.07 l 441.24 219.48 l 441.59 219.61 l 442.56 220.01 l 445.30 220.31 l 447.23 220.73 l 448.99 220.96 l 449.19 221.14 l 450.20 221.76 l 450.37 221.91 l 450.75 222.04 l 454.53 222.84 l 454.59 222.86 l 454.63 222.87 l 455.16 223.07 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 1 j 0.500 w 10.0 M [] 0 d 455.16 309.21 m 454.49 310.09 l 454.46 310.10 l 454.44 310.13 l 453.41 311.00 l 453.36 311.05 l 453.30 311.11 l 452.18 311.91 l 452.10 312.00 l 452.02 312.09 l 450.94 312.82 l 450.83 312.95 l 450.71 313.08 m 262.13 313.27 m 258.43 312.95 l 253.19 312.55 l 251.34 312.42 l 246.11 312.00 l 242.00 311.56 l 240.62 311.48 l 236.03 311.05 l 232.90 310.70 l 229.52 310.43 l 226.46 310.10 l 220.75 309.86 l 212.79 309.33 l 209.26 309.16 l 208.16 309.03 l 204.26 308.30 l 203.51 308.21 l 202.42 308.13 l 196.90 307.29 l 196.58 307.26 l 196.31 307.24 l 194.16 307.10 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 1 j 0.500 w 10.0 M [] 0 d 194.16 209.80 m 207.94 209.71 l 218.03 209.58 l 248.40 209.13 l 257.82 208.99 l 282.30 208.63 l 287.48 208.55 l 296.99 208.42 l 318.79 208.02 l 344.63 207.68 l 353.34 207.60 l 358.74 207.55 l 364.08 207.61 l 367.95 207.68 l 382.18 208.03 l 389.33 208.18 l 401.71 208.63 l 406.48 208.88 l 423.19 209.55 l 423.32 209.58 l 423.33 209.58 l 423.35 209.59 l 425.29 210.47 l 425.52 210.53 l 425.87 210.61 l 427.44 211.35 l 428.09 211.48 l 429.73 211.67 l 434.45 212.09 l 436.70 212.43 l 439.66 212.89 l 439.75 212.92 l 442.18 213.37 l 443.59 213.72 l 444.90 214.02 l 446.16 214.32 l 447.56 214.55 l 452.27 215.19 l 452.84 215.27 l 453.04 215.33 l 454.51 216.20 l 454.57 216.22 l 454.62 216.24 l 455.16 216.40 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 1 j 0.500 w 10.0 M [] 0 d 194.16 202.87 m 201.50 202.88 l 223.54 202.94 l 281.53 203.09 l 296.99 203.11 l 301.89 203.02 l 304.81 202.94 l 308.12 202.77 l 318.99 202.33 l 324.16 201.99 l 336.50 201.65 l 358.74 201.37 l 381.39 201.38 l 407.94 201.27 l 423.19 201.28 l 427.14 201.88 l 427.78 201.99 l 428.26 202.15 l 430.38 202.73 l 431.05 202.94 l 432.87 203.23 l 435.12 203.54 l 437.22 203.89 l 438.07 204.33 l 438.10 204.40 l 439.04 204.84 l 440.36 205.28 l 440.55 205.36 l 441.83 205.79 l 443.93 206.12 l 446.42 206.48 l 448.12 206.74 l 448.74 206.93 l 450.46 207.55 l 450.91 207.68 l 451.28 207.80 l 454.23 208.61 l 454.32 208.63 l 454.42 208.66 l 455.16 208.80 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 1 j 0.500 w 10.0 M [] 0 d 194.16 196.78 m 243.95 196.79 l 246.27 196.79 l 296.99 196.79 l 319.66 196.65 l 336.35 196.30 l 342.88 196.06 l 358.74 195.69 l 385.72 195.75 l 396.21 195.75 l 423.19 195.84 l 425.73 196.23 l 426.26 196.30 l 427.64 196.44 l 433.06 196.96 l 436.16 197.25 l 438.84 197.72 l 438.92 197.74 l 441.92 198.20 l 445.69 198.48 l 447.33 198.92 l 449.38 199.15 l 449.88 199.31 l 454.13 200.07 l 454.24 200.10 l 454.37 200.12 l 455.16 200.29 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 1 j 0.500 w 10.0 M [] 0 d 453.08 193.46 m 453.42 193.51 l 455.16 193.82 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 201.3 149.9 m (300) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 282.6 149.9 m (200) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 363.9 149.9 m (100) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 451.9 149.9 m (0) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 211.34 170.70 l 211.34 165.01 l 211.34 170.70 l 292.63 170.70 l 292.63 165.01 l 292.63 170.70 l 373.91 170.70 l 373.91 165.01 l 373.91 170.70 l 455.20 170.70 l 455.20 165.01 l 455.20 170.70 l 455.28 170.70 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 305.0 134.7 m (km) sh % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 312.95 m 211.34 312.95 l 211.34 318.64 l 211.34 312.95 l 292.63 312.95 l 292.63 318.64 l 292.63 312.95 l 373.91 312.95 l 373.91 318.64 l 373.91 312.95 l 455.20 312.95 l 455.20 318.64 l 455.20 312.95 l 455.28 312.95 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf % gr_show_at() BEGIN 0 g 0 G 135.7 166.4 m (28.1) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 135.7 213.8 m (28.0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 135.7 261.2 m (27.9) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 135.7 308.6 m (27.8) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 165.01 170.70 l 170.70 170.70 l 170.70 218.12 l 165.01 218.12 l 170.70 218.12 l 170.70 265.53 l 165.01 265.53 l 170.70 265.53 l 170.70 312.95 l 165.01 312.95 l 170.70 312.95 l 170.70 312.95 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 115.3 237.5 m () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Symbol findfont 12.00 sc sf (\163) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh 0.0 -3.2 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf (T) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 3.2 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 455.20 170.70 m 455.20 170.70 l 460.89 170.70 l 455.20 170.70 l 455.20 218.12 l 460.89 218.12 l 455.20 218.12 l 455.20 265.53 l 460.89 265.53 l 455.20 265.53 l 455.20 312.95 l 460.89 312.95 l 455.20 312.95 l 455.20 312.95 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf %^ scale 1 170.7 350 -0.812857 1 170.7 28.1 -474.167 2.000 w 0 g 0 G 1.0 i 0 J 1 j 2.000 w 10.0 M [] 0 d 194.16 196.78 m 243.95 196.79 l 246.27 196.79 l 296.99 196.79 l 319.66 196.65 l 336.35 196.30 l 342.88 196.06 l 358.74 195.69 l 385.72 195.75 l 396.21 195.75 l 423.19 195.84 l 425.73 196.23 l 426.26 196.30 l 427.64 196.44 l 433.06 196.96 l 436.16 197.25 l 438.84 197.72 l 438.92 197.74 l 441.92 198.20 l 445.69 198.48 l 447.33 198.92 l 449.38 199.15 l 449.88 199.31 l 454.13 200.07 l 454.24 200.10 l 454.37 200.12 l 455.16 200.29 l S % END GriPath stroke/fill %gri: draw title "Example 8" % gr_show_at() BEGIN 0 g 0 G 284.5 341.4 m (Example 8) sh % gr_show_at() END %gri:end if %gri: showpage %%Trailer %%BoundingBox: 113 130 463 352 %%DocumentFonts: Courier Helvetica Palatino-Roman Palatino-Italic Symbol Times-Roman %%Pages: 1 gri/doc/examples/example11.gri0000644000175000017500000000743413147557614014713 0ustar psgpsg# Example 11 -- Fancy plot .thin. = 0.5 # for whole data set .thick. = 2 # for bravo time period .gray_for_guiding_lines. = 0.75 # for guiding lines .tmin. = 1964 # time axis .tmax. = 1974 .tinc. = 5 .tincinc. = 1 .missing_value. = -9 \file = "./example11.dat" # # Guiding lines to draw on both panels. # .1xl. = 1962 .1yb. = -3 .1xr. = 1968 .1yt. = 3 .1slope. = {rpn .1yt. .1yb. - .1xr. .1xl. - /} .1intercept. = {rpn .1yb. .1slope. .1xl. * -} .2xl. = 1966.4 .2yb. = 3 .2xr. = 1980 .2yt. = -1 .2slope. = {rpn .2yt. .2yb. - .2xr. .2xl. - /} .2intercept. = {rpn .2yb. .2slope. .2xl. * -} # # PANEL 1: Bravo time period. # set x margin 3 set x size 15 set y margin 3 set y size 5 # Draw border big enough for this and next panel. draw border box {rpn ..xmargin.. 2 -} {rpn ..ymargin.. 2 -} {rpn ..xmargin.. ..xsize.. + 2 +} {rpn ..ymargin.. ..ysize.. 2 * 3 + + 2 +} 0.2 0.75 set missing value .missing_value. set ignore error eof set x name "Year" set x axis .tmin. .tmax. .tinc. .tincinc. set y name "Area / 10$^5$km$^2$" set y axis -3 3 1 draw axes # # Draw index lines 1 and 2. # # Upward sloped line. set line width .thin. set graylevel .gray_for_guiding_lines. if {rpn .1intercept. ..xright.. .1slope. * + ..ytop.. <} draw line from \ ..xleft.. \ {rpn .1intercept. ..xleft.. .1slope. * +} \ to \ {rpn ..ytop.. .1intercept. - .1slope. /} \ ..ytop.. else draw line from \ ..xleft.. \ {rpn .1intercept. ..xleft.. .1slope. * +} \ to \ ..xright.. \ {rpn .1intercept. ..xright.. .1slope. * +} end if set graylevel 0 # # Downward sloped line. set line width .thin. set graylevel .gray_for_guiding_lines. if {rpn .2intercept. ..xleft.. .2slope. * + ..ytop.. <} draw line from \ {rpn ..ytop.. .2intercept. - .2slope. /} \ ..ytop.. \ to \ ..xright.. \ {rpn .2intercept. ..xright.. .2slope. * +} else draw line from \ ..xleft.. \ {rpn .2intercept. ..xleft.. .2slope. * +} \ to \ ..xright.. \ {rpn .2intercept. ..xright.. .2slope. * +} end if set graylevel 0 # # Finally, draw the data curve on top, after first # whiting out a background. set input data window x .tmin. .tmax. open \file read columns x y close y /= 1e5 set line width ..linewidthaxis.. draw zero line set line width {rpn .thick. 3 *} set graylevel 1 draw curve set graylevel 0 set line width .thick. draw curve # # PANEL 2: Longer timescale. # delete x scale set x margin bigger 5 set x size 10 set x name "" set y name "" set y margin bigger {rpn ..ysize.. 3 +} # # Draw long data set in thin pen. set input data window x off open \file read columns x y close y /= 1e5 # # Draw guiding lines, axes, etc. set x axis 1952 1980 5 1 draw axes frame set line width .thin. set graylevel .gray_for_guiding_lines. draw line from .1xl. .1yb. to .1xr. .1yt. draw line from .2xl. .2yb. to .2xr. .2yt. set graylevel 0 set line width ..linewidthaxis.. draw zero line draw x axis at bottom .old. = ..fontsize.. set font size 0 draw y axis at left set font size .old. delete .old. # # Draw full curve (first whiting out region around it). set line width {rpn .thin. 4 *} set graylevel 1 draw curve set graylevel 0 set line width .thin. draw curve # # Draw bravo time period (first whiting out region around it). set input data window x .tmin. .tmax. open \file read columns x y close y /= 1e5 set line width {rpn .thick. 3 *} set graylevel 1 draw curve set graylevel 0 set line width .thick. draw curve # # Done set font size 20 \label = "Example 11 (Arctic ice anomaly)" draw label "\label" at \ {rpn 8.5 2.54 * "\label" width - 2 /} \ {rpn ..ytop.. yusertocm 0.7 +} \ cm if !..publication.. draw time stamp end if gri/doc/examples/FEM.gri0000644000175000017500000000036413147557614013520 0ustar psgpsgset missing value -99.99 # Create data using perl-script system perl FEM.pl model.nodes model.elements > tmp open tmp read columns x y close draw curve # Comment-out the next line if you want to inspect # the temporary output. system rm tmp gri/doc/examples/example10color.ps0000644000175000017500000054023613147557614015614 0ustar psgpsg%!PS-Adobe-2.0 EPSF-1.2 %%Creator: Gri2.2.4 (released 1999-Oct-20). User=kelley, commandfile=example10color.gri %%Title: example10color.ps %%CreationDate: Thu Oct 21 11:30:29 1999 %%Pages: (atend) %%BoundingBox: (atend) %%TemplateBox: 0 0 612 792 %%DocumentFonts: (atend) %%Endcomments % NOTE: The Gri postscript dictionary is being converted to the Adobe % Illustrator 3.0 dialect of PostScript, as described in the Adobe % documents stored at URL % http://www.adobe.com/Support/TechNotes.html % (as of Jan 1996, this doc is number 5007). When the conversion % is complete, the Adobe Illustrator drawing program -- and any % program compatible with AI -- will be able to edit Gri output. % % The IslandDraw (TM) program is able to read Gri output % at this time; remarkably, it can read/edit arbitrary PostScript. % % The definitions below are presented in the same order as the Adobe % manual. The stack configuration before and after is shown in curly % brackets. All the operators are listed, but only some are defined % here. Most things are faithful, except that no distinction is made % between colors for stroking and filling paths. The string 'WRONGLY' % appears with commands that are approximations. % % PDF-style abbreviations: /rg {setrgbcolor} def % {red green blue} {-} set RGB color /RG {setrgbcolor} def % {red green blue} {-} set RGB color /q {gsave} def /Q {grestore} def /W {clip} def /W* {eoclip} def % % Gri-specific abbreviations: /hsb {sethsbcolor} def % {hue saturation brightness} {-} set HSB color % % Following all try to mimic Adobe Illustrator % % Mimicking section 5.1 of Adobe manual: %A % {flag A} {-} Determine whether % following object can % be selected. Flag=1 % prevents selection; % flag=0 allows it. % Mimicking section 5.2 of Adobe manual: %u % {u} {-} start group %U % end group %q % as 'u' but first item is a clip path %Q % as 'U' but first item is a clip path % Mimicking section 5.3 of Adobe manual: /g {setgray} def % {gray g} {-} Set gray for fill % path, WRONGLY used % for stroking also. /G {setgray} def % As 'g', but for filling path. %k % Set cmyk color for filling path. %K % As 'k', but for stroking path. %x % Set cmyk custom color for filling path. %X % As 'x' but for stroking path. %p % Define pattern for filling path. %P % As 'p' but for stroking path. %O % Specify whether overprinting for fill paths %R % As 'O' but for stroking path. % Mimicking section 5.4 of Adobe manual: /d {setdash} def % {[array] phase d} {-} Set dash. /i {setflat} def % {flatness i} {-} Set flatness. /j {setlinejoin} def % {linejoin j} {-} Set line join. /J {setlinecap} def % {linecap J} {-} Set line cap. /M {setmiterlimit} def % {miterlimit M} {-} Set miter limit. /w {setlinewidth} def % {linewidth w} {-} Set line width. % Mimicking section 5.5 of Adobe manual: /m {moveto} def % {x y m} {-} Move to locn /l {lineto} def % {x y l} {-} Draw line to locn % not a smooth point. % WRONGLY, no % distinction is made % between smooth and % corner. %L % {x y L} {-} As 'l' but a corner %c % Bezier curve to smooth point. %C % As 'c' but to corner point. %v % Something else to do with Bezier. %V % %y % %Y % % Mimicking section 5.6 of Adobe manual: %N % {N} {-} As 'n' for nondrawn stuff /n {newpath} def % {n} {-} WRONGLY interpreted % as path constructor /F {fill} def % {F} {-} Fill current path. %f % {f} {-} 'F' but close first /S {stroke} def % {S} {-} Stroke current path. %s % {s} {-} 'S' but close first %B % {B} {-} As 's' but don't empty path. %b % {b} {-} As 'f' but don't empty path. %H % no-op (weird huh?) /h {closepath} def % {h} {-} Close current path %W % Used to create masks. % Mimicking section 5.7 of Adobe manual: %a % Begin text block ... %e % Similar to 'a' but ... %I % Similar to 'a' but ... %o % Similar to 'a' but ... %r % Similar to 'a' but ... %t % {len (string) t} {-} Render string. %T % End block of text % That's the end of the Illustrator stuff. Following are some Gri % definitions which provide a temporary way of handling fonts. /sf {setfont} def % {fontname sf} {-} Set font name. /sh {show} def % {(text) sh} {-} Show text. /sc {scalefont} def % {size sc} {-} Scale font. % Gri items which should be translated to Illustrator format: /rl {rlineto} def /rm {rmoveto} def % Procedures /cimdict 7 dict def /cim { cimdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def q xll yll translate xur xll sub yur yll sub scale /do cl 3 mul string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop} false 3 colorimage Q end } def /imdict 14 dict def /im { imdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def /imagemap exch def q % Add the mapping to the transfer function (ref: white book, p 743. [{255 mul cvi imagemap exch get} /exec load currenttransfer /exec load] cvx settransfer xll yll translate xur xll sub yur yll sub scale /do cl string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop}image Q end } def /frdict 5 dict def /fr { frdict begin /yt exch def /xr exch def /yb exch def /xl exch def n xl yb m xl yt l xr yt l xr yb l h F n end } def /plusdict 3 dict def /_plus { plusdict begin dup 0.5 mul /t0 exch def /t1 exch def 0 t0 rm 0 t1 neg rl t0 neg t0 rm t1 0 rl t0 neg 0 rm end } def /timesdict 3 dict def /_times { timesdict begin dup 0.353553 mul /t0 exch def 0.707106 mul /t1 exch def t0 neg t0 rm t1 dup neg rl t1 neg 0 rm t1 dup rl t0 neg dup rm end } def /boxdict 3 dict def /_box { boxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm end } def /filledboxdict 3 dict def /_filledbox { filledboxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm F end } def /diamonddict 2 dict def /_diamond { diamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm end } def /filleddiamonddict 2 dict def /_filleddiamond { filleddiamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm F end } def /triangleupdict 5 dict def /_triangleup { triangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm end } def /filledtriangleupdict 5 dict def /_filledtriangleup { filledtriangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm F end } def /trianglerightdict 5 dict def /_triangleright { trianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm end } def /filledtrianglerightdict 5 dict def /_filledtriangleright { filledtrianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm F end } def /triangledowndict 5 dict def /_triangledown { triangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm end } def /filledtriangledowndict 5 dict def /_filledtriangledown { filledtriangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm F end } def /triangleleftdict 5 dict def /_triangleleft { triangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm end } def /filledtriangleleftdict 5 dict def /_filledtriangleleft { filledtriangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm F end } def /circdict 5 dict def /_circ { circdict begin 0.5 mul /t0 exch def currentpoint /t2 exch def /t1 exch def S n t1 t2 t0 0 360 arc t1 t2 m end } def /bulldict 3 dict def /_bull { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 360 arc h F S end } def /filledhalfmoonupdict 3 dict def /_filledhalfmoonup { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 180 arc h F S end } def /filledhalfmoondowndict 3 dict def /_filledhalfmoondown { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 180 360 arc h F S end } def 1 1 scale 10.0 M 1 j /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-ISOLatin1 exch definefont pop /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Bold-ISOLatin1 exch definefont pop /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-ISOLatin1 exch definefont pop /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Bold-ISOLatin1 exch definefont pop /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Roman-ISOLatin1 exch definefont pop /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Bold-ISOLatin1 exch definefont pop /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Italic-ISOLatin1 exch definefont pop /Symbol findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Symbol-ISOLatin1 exch definefont pop /Times findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-ISOLatin1 exch definefont pop /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Bold-ISOLatin1 exch definefont pop /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Roman-ISOLatin1 exch definefont pop %%EndProlog %%Page: 1 1 /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:# Example 10 -- Draw color image plot %gri:# $Id: example10color.ps,v 1.1 2000/05/11 15:07:54 dankelley Exp $ %gri: %gri:# Test various colorscales. %gri:# INSTRUCTIONS: Uncomment one of the following '\scale = ' statements %gri: %gri:# CASE 1: From black at high values to white at low values %gri:#\scale = "rgb 0 0 0 20.0 rgb 1 1 1 0.0 increment 5" %gri: %gri:# CASE 2: From skyblue at 20 to tan for 0; traverse RGB space %gri:# See also case 5, which names the colors. %gri:#\scale = "rgb 0.529 0.808 0.922 20.0 rgb 0.824 0.706 0.549 0.0 increment 5" %gri: %gri:# CASE 3: From skyblue at 20 to tan for 0; traverse HSB space %gri:# Is it just me, or is this uglier than case 2? %gri:#\scale = "hsb 0.548 0.426 0.922 20.0 hsb 0.095 0.334 0.824 0.0 increment 5" %gri: %gri:# CASE 4: Use a spectrum; traverse HSB space %gri:#\scale = "hsb 0 1 1 20.0 hsb 0.6666 1 1 0.0 increment 5" %gri: %gri:# CASE 5: From skyblue to tan, traversing RGB space (by default) %gri:# (Compare case 2, which uses similar endpoints, with %gri:# colors specified with RGB values, and larger increment.) %gri:#\scale = "skyblue 20.0 tan 0.0 increment 2" %gri: %gri:# CASE 6: From skyblue to tan, traversing RGB space (by default) %gri:# Compare 2 and 5; note this has continuous increment %gri:#\scale = "skyblue 20.0 tan 0.0" %gri: %gri:# CASE 7: From blue to brown %gri:\scale = "blue 20.0 brown 0.0 increment 2.5" %gri: %gri:open example10.dat %gri:read line \header %gri:read \D %gri:read .nx. %gri:read .ny. %gri:set x name "distance along cove" %gri:set y name "time" %gri:set x grid 0 1 /.nx. %gri:set x axis 0 1 0.5 0.1 %gri:set y grid 0 .ny. / .ny. %gri:set y axis 0 .ny. %gri:read grid data * * .ny. .nx. %gri:set image range 0 20 %gri:convert grid to image %gri:set image colorscale \scale %gri:draw image %^ scale 1 170.7 0 284.5 1 170.7 0 3.51235 %BEGIN_IMAGE 169.579921 169.579921 456.320079 456.320079 128 128 cim 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204D41204D4 1204D41204D41204D41204D41204D42409D42409D42409D42409D42409D42409D40000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204D41204D41204D41204D42409D42409D42409D42409BD2409BD2409BD360EBD360EBD360EA5 4912A54912A54912A549128D5B178D5B178D5B17766D1C766D1C760000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204D41204D41204D41204D41204D42409D42409D42409D42409D42409D42409BD 2409BD360EBD360EBD360EBD360EA5360EA54912A54912A549128D49128D5B178D5B178D5B1776 5B17766D1C766D1C766D1C5E6D1C5E80205E80205E0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204D41204D41204D41204D41204D41204D42409D42409D4 2409D42409D42409D42409BD2409BD360EBD360EBD360EBD360EBD360EA5360EA54912A54912A5 4912A549128D49128D5B178D5B178D5B178D5B17765B17766D1C766D1C766D1C766D1C5E6D1C5E 6D1C5E80205E80205E80205E80205E0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204D41204D41204D41204D41204D42409D4 2409D42409D42409D42409D42409D42409BD2409BD2409BD2409BD360EBD360EBD360EBD360EA5 360EA5360EA54912A54912A54912A549128D49128D49128D5B178D5B178D5B178D5B17765B1776 5B17766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E 80205E80205E80205E0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204D41204D41204D4 1204D41204D42409D42409D42409D42409D42409D42409D42409D42409BD2409BD2409BD360EBD 360EBD360EBD360EBD360EA5360EA5360EA54912A54912A54912A54912A549128D49128D49128D 5B178D5B178D5B178D5B178D5B17765B17766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204D41204D41204D41204D41204D41204D42409D42409D42409D42409D42409D42409D42409BD 2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EA5360EA5360EA54912A54912A54912A5 4912A549128D49128D49128D5B178D5B178D5B178D5B178D5B17765B17765B17766D1C766D1C76 6D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204D41204D41204D41204D41204D41204D41204D42409D42409D42409D4 2409D42409D42409D42409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EA5 360EA5360EA54912A54912A54912A54912A549128D49128D49128D5B178D5B178D5B178D5B178D 5B178D5B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204D41204D41204D41204D41204D4 1204D41204D42409D42409D42409D42409D42409D42409D42409D42409BD2409BD2409BD360EBD 360EBD360EBD360EBD360EBD360EA5360EA5360EA54912A54912A54912A54912A54912A549128D 49128D49128D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204D41204D41204D41204D41204D41204D42409D42409D42409D42409D42409D42409D4 2409D42409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5 360EA54912A54912A54912A54912A549128D49128D49128D49128D5B178D5B178D5B178D5B178D 5B178D5B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204D41204D41204D41204D41204D41204D4 1204D42409D42409D42409D42409D42409D42409D42409D42409D42409BD2409BD2409BD2409BD 360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA54912A54912A54912A54912A54912A5 49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B1776 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204D41204D41204D41204D41204D41204D41204D41204D42409D42409D42409D42409D4 2409D42409D42409D42409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD 360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A549128D49128D49128D5B178D 5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204D41204D41204D4 1204D41204D41204D41204D41204D42409D42409D42409D42409D42409D42409D42409D42409BD 2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5 360EA54912A54912A54912A54912A54912A549128D49128D49128D49128D5B178D5B178D5B178D 5B178D5B178D5B178D5B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204D41204D41204D41204D41204D41204D41204D4 1204D42409D42409D42409D42409D42409D42409D42409D42409D42409BD2409BD2409BD2409BD 2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA54912A5 4912A54912A54912A54912A549128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204D41204D41204D41204D41204D41204D41204D41204D41204D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409BD2409BD2409BD2409BD2409BD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA54912A54912A54912A5 4912A54912A54912A54912A549128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409BD2409BD2409BD2409BD2409BD2409BD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA54912A54912A5 4912A54912A54912A54912A54912A549128D49128D49128D49128D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA54912A5 4912A54912A54912A54912A54912A54912A549128D49128D49128D49128D49128D49128D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B1776 5B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E 80205E80205E80205E80205E80205E1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409BD2409BD2409BD2409BD2409BD2409BD2409BD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5 360EA54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D 49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B1776 5B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409BD2409BD2409BD2409BD2409BD2409BD 2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5 360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A549128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17765B17765B17766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C5E1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A549128D49128D49128D49128D49128D49128D49128D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B1776 5B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C761204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D 49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17761204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A549128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D49128D49128D 49128D49128D49128D5B178D5B178D5B178D1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D 49128D49128D49128D49128D1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D 49128D49128D1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D 5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17766D1C766D1C761204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D41204D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A54912A5 4912A54912A549128D49128D49128D49128D5B178D5B178D5B178D5B178D5B17765B17765B1776 6D1C766D1C766D1C766D1C5E6D1C5E6D1C5E80205E80205E80205E1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5 360EA54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D5B178D5B178D 5B178D5B178D5B178D5B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E 6D1C5E6D1C5E80205E80205E80205E80205E80205E1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5 360EA5360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A54912A54912A549128D 49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E 80205E80205E80205E80205E80205E1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A5 4912A54912A54912A549128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D 5B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5 360EA54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D49128D5B178D 5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EA5360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A54912A549128D 49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B1776 5B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E1204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA54912A54912A5 4912A54912A54912A54912A54912A549128D49128D49128D49128D5B178D5B178D5B178D5B178D 5B178D5B178D5B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E1204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D41204D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EA5360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A54912A549128D49128D 49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B1776 5B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E1204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA54912A5 4912A54912A54912A54912A54912A54912A549128D49128D49128D49128D5B178D5B178D5B178D 5B178D5B178D5B178D5B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E1204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EA5360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A54912A5 4912A549128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B1776 5B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E1204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409BD2409BD2409BD2409BD 2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5 360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A54912A54912A549128D49128D 49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B1776 5B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5 360EA54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D49128D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B1776 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA54912A5 4912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D49128D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B1776 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E2409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA54912A54912A5 4912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D49128D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B1776 5B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E2409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA54912A54912A5 4912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D49128D49128D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B1776 5B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E2409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D 49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B17765B17765B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E 80205E80205E80205E80205E80205E2409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D 49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17765B17765B17766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A549128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B1776 5B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A549128D49128D49128D49128D49128D49128D49128D49128D 49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B17765B17765B17765B17765B17765B17765B17765B17765B17765B17766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C762409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B1776 5B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C762409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B17765B17765B17765B17765B17765B17765B17765B17762409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A549128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B17765B17762409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A549128D49128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D2409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A549128D49128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 49128D49128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17766D1C76 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D 49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B1776 6D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E80205E80205E80205E2409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A549128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E2409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A549128D49128D49128D49128D49128D49128D49128D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E 80205E80205E80205E80205E80205E80205E80205E2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D 49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B1776 5B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A549128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D49128D49128D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B1776 5B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A5 4912A54912A54912A54912A54912A54912A549128D49128D49128D49128D49128D49128D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A54912A54912A54912A54912A5 49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A5 4912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D49128D 49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B1776 5B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A5 4912A54912A54912A54912A549128D49128D49128D49128D49128D49128D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A549128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D 49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D 49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B17765B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D 49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B17765B17765B17765B17765B17765B17765B17765B17766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D 49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17765B17765B17765B1776 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D 49128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B1776 5B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E 80205E80205E80205E80205E80205E360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A549128D49128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B1776 5B17765B17765B17765B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A549128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17765B17765B17765B17765B1776 5B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A549128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B1776 5B17765B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B1776 5B17765B17765B17765B17765B17765B17765B17765B17765B17765B17765B17765B17765B1776 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17765B17765B17765B17765B1776 5B17765B17765B17765B17765B17766D1C766D1C766D1C76360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17765B1776 5B17765B17765B17765B17765B17765B1776360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B1776 5B17765B17765B17765B1776360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17765B17765B1776 5B17765B1776360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A549128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B1776 5B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A549128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 80205E80205E80205E80205E80205E80205E80205E80205E80205E360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B1776 5B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A549128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B17765B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D 49128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17765B1776 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A549128D49128D49128D49128D49128D49128D49128D49128D 49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B1776 5B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D 49128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17765B17766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A549128D49128D49128D49128D49128D49128D49128D49128D 49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B1776 5B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 49128D49128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17765B1776 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D 49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B17765B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A549128D49128D49128D49128D49128D49128D49128D49128D 49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B1776 5B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A549128D49128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B1776 5B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B1776 5B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B1776 5B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E4912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B1776 5B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E4912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B1776 5B17765B17765B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E4912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B17765B17765B17765B17765B17765B17765B17765B17765B17765B17765B17765B17766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E 80205E80205E80205E80205E80205E4912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17765B17765B17765B1776 5B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B1776 5B17765B17765B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B1776 5B17765B17765B17765B17765B17765B17765B17765B17765B17765B17765B17765B17765B1776 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E4912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B17765B17765B17765B17765B17765B17765B17765B17765B17765B17765B1776 5B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C764912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17765B17765B17765B1776 5B17765B17765B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C764912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17765B17765B1776 5B17765B17765B17765B17765B17765B17765B17765B17765B17765B17766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C764912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A549128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17765B17765B1776 5B17765B17765B17765B17765B17765B17765B17765B17765B17765B17766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C764912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A549128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B17765B17765B17765B17765B17765B17765B17765B17765B17765B17765B17765B1776 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E 6D1C5E6D1C5E4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B1776 5B17765B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B17765B17765B17765B17765B17765B17765B17765B17765B17765B17766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E4912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A549128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17765B1776 5B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E4912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B1776 5B17765B17765B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E4912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A549128D49128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17765B17765B17765B17766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E4912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B1776 5B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A549128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B17765B17765B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A549128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B1776 5B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E4912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A549128D49128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B17765B17765B17765B17765B17765B17765B17765B17765B17766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E4912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A549128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B1776 5B17765B17765B17765B17765B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E4912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A549128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17765B1776 5B17765B17766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E4912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A549128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B17765B17765B17765B17765B17765B17765B17765B17765B17766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E %END_IMAGE % gr_show_at() BEGIN 0 g 0 G 167.4 149.9 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 304.6 149.9 m (0.5) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 451.9 149.9 m (1) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 170.70 165.01 l 170.70 170.70 l 199.15 170.70 l 199.15 167.86 l 199.15 170.70 l 227.60 170.70 l 227.60 167.86 l 227.60 170.70 l 256.05 170.70 l 256.05 167.86 l 256.05 170.70 l 284.50 170.70 l 284.50 167.86 l 284.50 170.70 l 312.95 170.70 l 312.95 165.01 l 312.95 170.70 l 341.40 170.70 l 341.40 167.86 l 341.40 170.70 l 369.85 170.70 l 369.85 167.86 l 369.85 170.70 l 398.30 170.70 l 398.30 167.86 l 398.30 170.70 l 426.75 170.70 l 426.75 167.86 l 426.75 170.70 l 455.20 170.70 l 455.20 165.01 l 455.20 170.70 l 455.34 170.70 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 259.8 134.7 m (distance along cove) sh % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 455.20 m 170.70 455.20 l 170.70 460.89 l 170.70 455.20 l 199.15 455.20 l 199.15 458.05 l 199.15 455.20 l 227.60 455.20 l 227.60 458.05 l 227.60 455.20 l 256.05 455.20 l 256.05 458.05 l 256.05 455.20 l 284.50 455.20 l 284.50 458.05 l 284.50 455.20 l 312.95 455.20 l 312.95 460.89 l 312.95 455.20 l 341.40 455.20 l 341.40 458.05 l 341.40 455.20 l 369.85 455.20 l 369.85 458.05 l 369.85 455.20 l 398.30 455.20 l 398.30 458.05 l 398.30 455.20 l 426.75 455.20 l 426.75 458.05 l 426.75 455.20 l 455.20 455.20 l 455.20 460.89 l 455.20 455.20 l 455.34 455.20 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf % gr_show_at() BEGIN 0 g 0 G 152.5 166.4 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 450.9 m (81) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 165.01 170.70 l 170.70 170.70 l 170.70 455.20 l 165.01 455.20 l 170.70 455.20 l 170.70 455.20 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 139.9 301.6 m 90.00 rotate (time) sh -90.00 rotate % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 455.20 170.70 m 455.20 170.70 l 460.89 170.70 l 455.20 170.70 l 455.20 455.20 l 460.89 455.20 l 455.20 455.20 l 455.20 455.20 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri: %gri:# Draw contours in white ink %gri:set graylevel 1.0 %gri:draw contour 0 20 1 unlabelled %^ scale 1 170.7 0 284.5 1 170.7 0 3.51235 0.709 w 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 426.53 m 454.06 426.48 l 441.36 426.48 l 440.23 426.40 l 438.29 426.29 l 427.19 426.29 l 425.25 426.06 l 421.07 425.76 l 414.46 425.76 l 410.28 425.00 l 404.60 424.54 l 399.02 423.19 l 396.23 422.97 l 395.31 422.83 l 392.86 422.61 l 384.37 422.23 l 380.33 421.57 l 374.28 421.07 l 367.11 419.64 l 365.79 419.54 l 365.36 419.47 l 364.22 419.37 l 353.95 418.79 l 350.38 418.24 l 343.73 417.66 l 335.96 416.21 l 335.41 416.12 l 335.29 416.11 l 335.14 416.08 l 323.76 415.29 l 320.44 414.76 l 313.73 414.12 l 306.10 412.68 l 305.46 412.57 l 305.33 412.56 l 305.18 412.53 l 294.42 411.59 l 290.49 410.88 l 285.02 410.27 l 278.71 408.97 l 276.68 408.69 l 275.52 408.44 l 270.07 407.68 l 267.34 407.35 l 260.54 405.84 l 259.40 405.68 l 258.24 405.41 l 251.13 404.09 l 245.57 402.51 l 243.97 402.24 l 242.57 401.86 l 237.18 400.29 l 234.16 399.15 l 231.80 398.30 l 231.45 398.10 l 230.59 397.59 l 226.09 395.81 l 223.63 394.74 l 221.61 393.32 l 219.73 392.16 l 218.24 391.19 l 217.85 390.66 l 215.62 388.70 l 214.30 387.95 l 213.58 387.63 l 212.17 386.81 l 210.08 385.39 l 207.30 384.08 l 205.44 382.94 l 200.65 380.91 l 199.74 380.73 l 198.51 380.52 l 191.87 379.05 l 185.67 377.85 l 181.93 377.85 l 174.44 377.85 l 170.70 377.85 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 426.31 m 452.92 426.21 l 442.50 426.21 l 440.23 426.06 l 436.34 425.83 l 429.13 425.83 l 425.25 425.36 l 418.24 424.86 l 411.21 423.42 l 410.28 423.25 l 410.11 423.23 l 409.95 423.19 l 398.96 422.33 l 395.31 421.76 l 388.80 421.18 l 380.48 419.64 l 380.38 419.63 l 380.33 419.62 l 380.20 419.61 l 369.10 418.75 l 365.36 418.20 l 358.93 417.61 l 350.89 416.20 l 350.38 416.12 l 350.25 416.11 l 350.09 416.08 l 339.27 415.17 l 335.41 414.58 l 329.32 413.97 l 321.17 412.53 l 320.69 412.47 l 320.44 412.42 l 319.56 412.32 l 310.36 411.36 l 305.46 410.51 l 301.08 410.01 l 295.74 408.97 l 292.57 408.48 l 290.49 408.03 l 283.77 407.01 l 276.61 405.41 l 276.07 405.28 l 275.52 405.12 l 268.30 403.57 l 262.28 401.86 l 261.66 401.59 l 260.54 401.07 l 255.69 399.45 l 252.80 398.30 l 251.19 396.96 l 249.53 395.68 l 248.35 394.74 l 248.34 394.09 l 247.58 391.66 l 247.56 391.19 l 248.02 390.60 l 248.96 388.44 l 249.74 387.63 l 251.35 386.26 l 251.89 385.58 l 254.17 384.08 l 255.63 382.91 l 259.89 380.67 l 260.14 380.52 l 260.21 380.44 l 260.54 380.20 l 263.45 377.65 l 264.70 376.96 l 265.53 375.78 l 266.06 374.72 l 267.09 373.41 l 266.53 371.98 l 266.09 371.17 l 265.53 369.85 l 264.11 369.00 l 260.54 366.62 l 260.13 366.39 l 259.97 366.29 l 258.67 365.85 l 253.99 364.29 l 250.06 362.74 l 247.91 362.18 l 245.57 361.40 l 241.12 360.24 l 237.82 359.18 l 234.18 358.33 l 230.59 357.19 l 227.33 356.40 l 224.92 355.63 l 220.23 354.53 l 215.62 353.06 l 213.39 352.60 l 211.43 352.07 l 205.73 350.86 l 200.65 349.51 l 197.96 349.15 l 194.10 348.51 l 188.84 347.76 l 185.67 347.23 l 180.28 347.23 l 176.09 347.23 l 170.70 347.23 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 426.08 m 451.79 425.94 l 443.64 425.94 l 440.23 425.71 l 434.40 425.37 l 431.08 425.37 l 425.25 424.67 l 420.48 424.33 l 414.96 423.19 l 412.03 422.78 l 410.28 422.49 l 405.01 421.94 l 401.68 421.68 l 395.31 420.69 l 392.09 420.40 l 387.97 419.64 l 382.71 419.07 l 380.33 418.74 l 373.69 418.06 l 372.41 417.96 l 365.36 416.93 l 362.78 416.69 l 359.28 416.08 l 353.13 415.43 l 350.38 415.03 l 343.11 414.25 l 341.72 414.02 l 335.41 413.07 l 333.80 412.91 l 331.64 412.53 l 324.23 411.62 l 320.44 410.98 l 314.85 410.30 l 307.65 408.97 l 306.40 408.75 l 305.46 408.55 l 299.62 407.58 l 297.63 407.27 l 290.49 405.73 l 289.66 405.61 l 288.79 405.41 l 282.23 403.82 l 276.07 401.99 l 275.62 401.86 l 275.59 401.84 l 275.52 401.80 l 270.15 399.57 l 267.34 398.30 l 266.36 396.92 l 265.48 395.92 l 264.59 394.74 l 265.17 393.64 l 265.44 392.35 l 266.18 391.19 l 268.48 389.52 l 269.32 389.10 l 271.87 387.63 l 272.99 387.03 l 275.52 386.07 l 278.42 384.77 l 280.58 384.08 l 284.19 382.58 l 290.49 380.67 l 290.75 380.58 l 290.98 380.52 l 291.64 380.25 l 296.02 378.27 l 299.96 376.96 l 301.41 376.00 l 305.46 373.91 l 306.08 373.55 l 306.40 373.41 l 306.46 373.17 l 306.99 370.21 l 307.09 369.85 l 306.65 369.57 l 305.46 368.74 l 302.57 366.98 l 301.54 366.29 l 296.68 364.82 l 291.49 362.97 l 290.80 362.74 l 290.63 362.70 l 290.49 362.67 l 284.50 361.31 l 282.96 360.97 l 282.56 360.85 l 276.65 359.18 l 276.00 359.07 l 275.52 358.95 l 268.86 357.60 l 267.95 357.42 l 266.96 357.15 l 261.29 355.63 l 260.87 355.55 l 260.54 355.46 l 254.55 354.20 l 252.95 353.87 l 252.08 353.61 l 246.69 352.07 l 246.12 351.94 l 245.57 351.76 l 238.73 350.14 l 233.54 348.51 l 232.26 348.12 l 230.59 347.46 l 225.83 346.09 l 222.59 344.96 l 219.97 343.92 l 215.62 342.05 l 214.38 341.69 l 213.43 341.40 l 209.43 339.93 l 208.42 339.56 l 203.64 337.84 l 202.64 337.37 l 200.65 336.61 l 195.17 335.59 l 187.44 334.29 l 186.51 334.09 l 185.67 333.95 l 184.25 333.95 l 172.13 333.95 l 170.70 333.95 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 425.86 m 450.65 425.67 l 444.78 425.67 l 440.23 425.37 l 432.91 424.93 l 431.90 424.77 l 425.25 423.98 l 422.72 423.80 l 419.79 423.19 l 413.84 422.35 l 410.28 421.77 l 404.04 421.12 l 395.41 419.64 l 395.34 419.63 l 395.31 419.62 l 395.18 419.61 l 385.04 418.52 l 380.33 417.85 l 375.11 417.32 l 367.48 416.08 l 366.12 415.90 l 365.36 415.79 l 362.94 415.51 l 355.93 414.76 l 350.38 413.96 l 346.22 413.51 l 340.25 412.53 l 337.23 412.09 l 335.41 411.79 l 328.36 410.85 l 327.78 410.78 l 320.44 409.54 l 318.84 409.35 l 316.78 408.97 l 310.30 407.82 l 305.46 406.79 l 302.05 406.22 l 298.34 405.41 l 294.74 404.40 l 290.49 403.10 l 287.91 402.47 l 285.80 401.86 l 282.60 400.17 l 281.95 399.83 l 279.06 398.30 l 278.88 397.50 l 277.81 395.29 l 277.67 394.74 l 278.42 394.05 l 279.88 392.22 l 281.23 391.19 l 284.18 389.69 l 288.38 388.13 l 289.63 387.63 l 289.94 387.50 l 290.49 387.33 l 296.02 385.39 l 301.05 384.08 l 302.88 383.46 l 305.46 382.80 l 309.82 381.55 l 314.49 380.52 l 316.94 379.69 l 320.44 378.74 l 323.78 377.76 l 327.17 376.96 l 330.01 375.68 l 335.41 373.61 l 335.72 373.48 l 335.93 373.41 l 336.02 373.26 l 337.55 370.36 l 337.91 369.85 l 337.22 369.42 l 335.41 368.17 l 333.26 366.81 l 332.47 366.29 l 326.70 364.81 l 320.44 362.82 l 320.28 362.78 l 320.16 362.74 l 311.71 361.25 l 305.46 359.75 l 304.19 359.48 l 303.01 359.18 l 295.35 358.03 l 290.49 356.94 l 287.37 356.37 l 284.34 355.63 l 279.15 354.76 l 275.52 353.89 l 271.29 353.07 l 267.40 352.07 l 263.81 351.29 l 260.54 350.34 l 256.68 349.43 l 253.66 348.51 l 250.20 347.41 l 245.57 345.63 l 244.31 345.25 l 243.51 344.96 l 241.55 344.00 l 239.24 342.90 l 236.30 341.40 l 235.20 340.31 l 232.92 338.40 l 232.32 337.84 l 232.27 337.45 l 230.83 334.34 l 230.82 334.29 l 230.84 334.23 l 230.84 330.79 l 230.87 330.73 l 230.92 330.65 l 231.50 327.39 l 231.69 327.18 l 231.90 326.87 l 232.54 324.08 l 232.93 323.62 l 233.18 323.01 l 233.18 320.68 l 233.47 320.06 l 233.37 319.40 l 232.02 316.84 l 231.96 316.51 l 231.68 316.25 l 230.59 315.32 l 227.93 313.58 l 226.85 312.95 l 222.81 311.24 l 222.04 310.92 l 218.43 309.39 l 217.20 309.02 l 215.62 308.42 l 210.41 307.07 l 206.41 305.84 l 203.53 305.15 l 200.65 304.36 l 195.13 303.59 l 187.55 302.28 l 186.35 302.12 l 185.67 302.01 l 184.52 302.01 l 171.85 302.01 l 170.70 302.01 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 425.64 m 449.51 425.40 l 445.92 425.40 l 440.23 425.02 l 434.07 424.66 l 426.02 423.38 l 425.25 423.28 l 424.96 423.26 l 424.62 423.19 l 415.65 421.92 l 410.28 421.05 l 406.15 420.62 l 400.43 419.64 l 397.28 419.17 l 395.31 418.88 l 388.99 418.14 l 387.38 417.96 l 380.33 416.97 l 377.72 416.70 l 373.91 416.08 l 368.42 415.35 l 365.36 414.92 l 358.63 414.12 l 354.32 413.46 l 350.38 412.89 l 349.33 412.78 l 347.81 412.53 l 340.08 411.42 l 335.41 410.65 l 330.88 410.04 l 324.78 408.97 l 322.44 408.49 l 320.44 408.07 l 314.10 406.92 l 307.12 405.41 l 306.42 405.18 l 305.46 404.88 l 299.61 403.25 l 295.03 401.86 l 293.85 401.06 l 290.49 398.99 l 289.58 398.52 l 289.17 398.30 l 289.10 397.97 l 289.10 395.07 l 289.01 394.74 l 289.32 394.47 l 290.49 393.72 l 293.12 391.81 l 294.32 391.19 l 298.52 389.54 l 302.41 388.36 l 304.71 387.63 l 305.03 387.53 l 305.46 387.41 l 311.87 385.60 l 318.87 384.08 l 319.59 383.87 l 320.44 383.68 l 327.04 382.09 l 335.21 380.52 l 335.30 380.49 l 335.41 380.47 l 342.53 378.65 l 348.72 377.36 l 350.38 377.01 l 350.48 376.98 l 350.60 376.96 l 351.04 376.81 l 356.43 374.84 l 361.18 373.41 l 361.87 372.58 l 364.08 370.15 l 364.34 369.85 l 363.69 369.45 l 360.37 367.48 l 358.48 366.29 l 353.86 365.47 l 350.38 364.54 l 346.51 363.66 l 343.31 362.74 l 338.17 362.08 l 335.41 361.54 l 329.47 360.59 l 323.07 359.18 l 321.35 358.96 l 320.44 358.80 l 316.16 358.17 l 312.07 357.61 l 305.46 356.30 l 303.78 356.02 l 302.01 355.63 l 295.08 354.54 l 290.49 353.55 l 286.91 352.92 l 283.36 352.07 l 279.23 351.19 l 275.52 350.19 l 271.85 349.38 l 268.78 348.51 l 265.33 347.37 l 260.54 345.55 l 259.46 345.21 l 258.76 344.96 l 257.47 344.23 l 254.82 342.76 l 252.48 341.40 l 251.74 339.93 l 251.19 339.18 l 250.45 337.84 l 251.03 336.55 l 251.16 335.62 l 251.85 334.29 l 253.64 332.65 l 254.42 332.19 l 256.40 330.73 l 257.44 330.00 l 260.54 328.52 l 262.24 327.58 l 263.29 327.18 l 265.94 325.89 l 267.20 325.20 l 271.37 323.62 l 272.50 322.90 l 275.52 321.52 l 277.41 320.51 l 278.58 320.06 l 279.86 319.03 l 281.09 317.83 l 283.00 316.51 l 282.91 314.75 l 282.89 314.70 l 282.79 312.95 l 280.82 311.69 l 278.64 310.13 l 277.54 309.39 l 276.71 309.11 l 275.52 308.62 l 270.83 306.95 l 268.03 305.84 l 264.42 304.92 l 260.54 303.70 l 257.73 302.95 l 255.69 302.28 l 250.59 301.09 l 245.57 299.59 l 243.78 299.15 l 242.42 298.72 l 236.58 297.30 l 230.59 295.39 l 230.13 295.28 l 229.76 295.17 l 222.95 293.43 l 222.13 293.16 l 217.28 291.61 l 216.56 291.39 l 215.62 291.04 l 209.54 289.50 l 204.50 288.06 l 202.82 287.54 l 200.65 286.83 l 194.86 285.87 l 186.51 284.50 l 186.02 284.42 l 185.67 284.36 l 185.07 284.36 l 171.30 284.36 l 170.70 284.36 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 425.42 m 448.37 425.13 l 447.06 425.13 l 440.23 424.68 l 435.23 424.38 l 427.77 423.19 l 426.60 422.87 l 425.25 422.62 l 418.99 421.71 l 417.46 421.49 l 410.28 420.33 l 408.26 420.12 l 405.46 419.64 l 399.22 418.71 l 395.31 418.15 l 389.50 417.46 l 380.33 416.08 l 370.73 414.81 l 365.36 414.05 l 361.08 413.54 l 354.50 412.53 l 352.10 412.12 l 350.38 411.84 l 342.93 410.74 l 342.70 410.70 l 335.41 409.51 l 333.96 409.31 l 332.01 408.97 l 325.78 407.70 l 320.44 406.57 l 317.68 406.07 l 314.64 405.41 l 310.78 404.15 l 305.46 402.44 l 304.33 402.13 l 303.44 401.86 l 302.35 401.12 l 300.16 399.56 l 298.20 398.30 l 298.60 396.67 l 298.78 396.33 l 299.23 394.74 l 300.96 393.67 l 305.46 391.55 l 305.95 391.30 l 306.24 391.19 l 308.50 390.47 l 312.22 389.24 l 318.39 387.63 l 319.34 387.37 l 320.44 387.13 l 326.91 385.61 l 335.09 384.08 l 335.25 384.04 l 335.41 384.00 l 338.01 383.46 l 343.17 382.36 l 350.38 381.08 l 351.72 380.84 l 353.77 380.52 l 359.72 379.18 l 365.36 378.09 l 367.92 377.57 l 371.51 376.96 l 375.36 375.78 l 380.33 374.41 l 382.25 373.86 l 384.07 373.41 l 385.47 372.18 l 386.43 371.30 l 388.16 369.85 l 385.05 368.73 l 381.01 366.46 l 380.68 366.29 l 380.45 366.27 l 380.33 366.24 l 379.71 366.15 l 371.09 364.93 l 365.36 363.60 l 363.33 363.22 l 361.49 362.74 l 354.04 361.87 l 350.38 361.22 l 345.01 360.46 l 338.69 359.18 l 336.55 358.91 l 335.41 358.72 l 330.73 358.07 l 327.07 357.61 l 320.44 356.41 l 318.39 356.11 l 316.02 355.63 l 309.62 354.64 l 305.46 353.81 l 301.14 353.09 l 296.43 352.07 l 293.30 351.40 l 290.49 350.69 l 285.69 349.65 l 281.39 348.51 l 278.98 347.69 l 275.52 346.38 l 272.98 345.56 l 271.34 344.96 l 268.99 343.41 l 268.48 343.07 l 265.94 341.40 l 265.81 340.15 l 265.49 339.02 l 265.36 337.84 l 266.77 336.36 l 267.13 335.85 l 268.90 334.29 l 270.80 333.17 l 275.52 331.18 l 276.14 330.88 l 276.56 330.73 l 278.37 330.05 l 281.80 328.67 l 286.91 327.18 l 288.30 326.66 l 290.49 326.01 l 294.75 324.63 l 298.86 323.62 l 301.41 322.66 l 305.46 321.42 l 307.84 320.63 l 309.98 320.06 l 313.33 318.38 l 314.31 317.96 l 317.57 316.51 l 317.82 315.88 l 319.30 313.22 l 319.42 312.95 l 318.89 312.58 l 315.77 310.50 l 314.25 309.39 l 310.42 308.22 l 305.46 306.48 l 304.29 306.12 l 303.51 305.84 l 296.66 304.37 l 290.49 302.68 l 289.67 302.48 l 288.99 302.28 l 281.45 300.87 l 275.52 299.37 l 274.08 299.07 l 272.84 298.72 l 266.16 297.39 l 260.54 295.86 l 259.05 295.52 l 257.84 295.17 l 251.83 293.68 l 245.57 291.68 l 245.43 291.65 l 245.32 291.61 l 244.76 291.42 l 239.18 289.57 l 235.30 288.06 l 233.82 287.29 l 230.59 285.53 l 229.00 284.88 l 228.14 284.50 l 226.74 283.59 l 224.90 282.30 l 222.67 280.94 l 221.46 279.56 l 220.09 278.45 l 219.02 277.39 l 218.74 276.65 l 216.12 273.95 l 216.06 273.83 l 216.04 273.73 l 215.62 273.12 l 213.23 270.84 l 212.10 270.27 l 209.92 268.92 l 209.05 268.28 l 206.00 266.72 l 204.49 265.81 l 200.65 264.18 l 198.34 263.71 l 194.66 263.16 l 189.58 262.23 l 185.67 261.64 l 179.26 261.64 l 177.12 261.64 l 170.70 261.64 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 425.20 m 448.05 424.89 l 446.86 424.77 l 440.23 424.33 l 436.39 424.10 l 430.67 423.19 l 428.15 422.51 l 425.25 421.97 l 419.18 421.08 l 410.45 419.64 l 410.36 419.62 l 410.28 419.61 l 409.94 419.56 l 401.16 418.25 l 395.31 417.41 l 391.57 416.97 l 385.68 416.08 l 382.53 415.56 l 380.33 415.25 l 373.02 414.26 l 372.11 414.13 l 365.36 413.17 l 363.54 412.96 l 360.74 412.53 l 354.69 411.50 l 350.38 410.81 l 345.61 410.10 l 338.85 408.97 l 337.12 408.56 l 335.41 408.20 l 329.11 406.91 l 322.04 405.41 l 321.42 405.18 l 320.44 404.84 l 315.16 403.11 l 311.27 401.86 l 310.10 400.76 l 307.54 398.79 l 306.97 398.30 l 307.27 397.87 l 308.47 395.46 l 309.04 394.74 l 312.76 393.01 l 312.88 392.95 l 317.33 391.19 l 318.66 390.76 l 320.44 390.31 l 325.73 388.89 l 331.41 387.63 l 333.42 387.16 l 335.41 386.78 l 341.58 385.54 l 350.23 384.08 l 350.31 384.06 l 350.38 384.05 l 350.93 383.95 l 358.70 382.49 l 365.36 381.43 l 367.63 381.06 l 371.38 380.52 l 376.21 379.54 l 380.33 378.82 l 384.80 378.02 l 391.42 376.96 l 393.19 376.46 l 395.31 375.93 l 400.45 374.63 l 405.79 373.41 l 406.84 372.59 l 410.28 370.16 l 410.60 369.93 l 410.72 369.85 l 410.40 369.82 l 410.28 369.79 l 408.52 369.43 l 402.15 368.22 l 400.53 367.53 l 397.07 366.29 l 395.91 366.15 l 395.31 366.04 l 392.74 365.68 l 386.17 364.91 l 380.33 363.72 l 377.84 363.33 l 375.30 362.74 l 368.65 361.96 l 365.36 361.42 l 359.29 360.62 l 351.54 359.18 l 350.80 359.08 l 350.38 359.02 l 348.75 358.79 l 341.10 357.83 l 335.41 356.88 l 332.08 356.42 l 327.87 355.63 l 323.40 354.92 l 320.44 354.37 l 314.67 353.44 l 307.91 352.07 l 306.64 351.79 l 305.46 351.51 l 298.84 350.08 l 292.60 348.51 l 291.77 348.21 l 290.49 347.73 l 285.64 346.11 l 282.52 344.96 l 280.95 343.67 l 279.02 342.23 l 277.96 341.40 l 278.12 340.78 l 278.27 338.50 l 278.46 337.84 l 280.06 336.76 l 281.42 335.69 l 283.87 334.29 l 286.21 333.27 l 290.49 331.81 l 292.27 331.15 l 293.74 330.73 l 298.91 329.17 l 305.46 327.57 l 306.26 327.36 l 307.17 327.18 l 313.50 325.53 l 320.44 324.02 l 321.31 323.83 l 322.42 323.62 l 328.45 321.97 l 335.41 320.34 l 335.99 320.20 l 336.66 320.06 l 338.98 319.22 l 342.01 318.07 l 346.78 316.51 l 347.32 315.78 l 349.66 313.12 l 349.80 312.95 l 349.49 312.74 l 346.08 310.42 l 344.63 309.39 l 340.09 308.28 l 335.41 306.86 l 333.41 306.31 l 331.93 305.84 l 325.07 304.74 l 320.44 303.71 l 317.11 303.07 l 313.86 302.28 l 308.67 301.52 l 305.46 300.87 l 300.27 299.96 l 294.85 298.72 l 292.30 298.30 l 290.49 297.89 l 284.11 296.68 l 277.87 295.17 l 276.66 294.90 l 275.52 294.58 l 269.28 293.09 l 264.25 291.61 l 262.74 291.09 l 260.54 290.23 l 256.72 288.96 l 254.42 288.06 l 252.00 286.53 l 250.74 285.73 l 248.80 284.50 l 248.49 283.81 l 246.82 281.24 l 246.68 280.94 l 246.83 280.64 l 247.46 277.84 l 247.74 277.39 l 248.53 276.68 l 249.99 274.88 l 251.45 273.83 l 253.71 272.21 l 255.04 271.58 l 257.41 270.27 l 258.22 269.72 l 260.54 268.67 l 263.08 267.32 l 264.66 266.72 l 267.13 265.15 l 267.55 264.83 l 270.84 263.16 l 271.63 262.24 l 274.79 259.78 l 274.96 259.61 l 274.93 259.47 l 274.43 256.31 l 274.36 256.05 l 273.70 255.62 l 270.59 253.66 l 268.86 252.49 l 265.48 251.32 l 260.54 249.36 l 259.81 249.11 l 259.39 248.94 l 252.98 247.18 l 252.61 247.05 l 247.50 245.38 l 246.54 245.15 l 245.57 244.85 l 239.31 243.31 l 234.46 241.82 l 232.54 241.36 l 230.59 240.73 l 225.51 239.48 l 221.61 238.27 l 218.75 237.53 l 215.62 236.49 l 211.80 235.62 l 208.43 234.71 l 204.70 233.75 l 200.65 232.51 l 197.18 231.98 l 192.09 231.16 l 188.20 230.56 l 185.67 230.14 l 181.40 230.14 l 174.98 230.14 l 170.70 230.14 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 424.97 m 448.84 424.70 l 444.85 424.29 l 440.23 423.99 l 437.55 423.83 l 433.56 423.19 l 429.69 422.14 l 425.25 421.31 l 420.89 420.67 l 414.60 419.64 l 412.32 419.15 l 410.28 418.85 l 403.10 417.79 l 401.56 417.57 l 395.31 416.67 l 393.65 416.48 l 391.03 416.08 l 384.73 415.04 l 380.33 414.42 l 375.26 413.73 l 366.90 412.53 l 366.06 412.36 l 365.36 412.25 l 361.36 411.58 l 357.28 410.89 l 350.38 409.78 l 348.29 409.47 l 345.33 408.97 l 340.33 407.80 l 335.41 406.75 l 332.39 406.13 l 329.00 405.41 l 325.71 404.16 l 320.44 402.35 l 319.56 402.07 l 318.91 401.86 l 318.39 401.37 l 316.44 399.25 l 315.33 398.30 l 316.07 397.26 l 318.00 395.32 l 318.46 394.74 l 319.13 394.43 l 320.44 393.94 l 324.90 392.25 l 328.19 391.19 l 331.60 390.28 l 335.41 389.44 l 339.33 388.56 l 344.09 387.63 l 347.48 386.94 l 350.38 386.44 l 356.13 385.44 l 365.06 384.08 l 365.23 384.04 l 365.36 384.02 l 366.05 383.91 l 374.04 382.58 l 380.33 381.65 l 383.28 381.22 l 388.59 380.52 l 392.40 379.83 l 395.31 379.35 l 401.25 378.37 l 409.33 377.19 l 410.28 377.04 l 410.49 377.01 l 410.85 376.96 l 418.10 375.26 l 425.25 373.71 l 425.92 373.57 l 426.73 373.41 l 427.66 372.83 l 430.47 371.09 l 432.53 369.85 l 426.45 369.57 l 425.25 369.36 l 420.75 368.78 l 416.41 368.39 l 410.28 366.67 l 409.43 366.50 l 408.86 366.29 l 399.98 365.18 l 395.31 364.33 l 391.07 363.74 l 386.26 362.74 l 382.47 362.23 l 380.33 361.90 l 372.92 360.94 l 372.39 360.85 l 365.36 359.71 l 363.92 359.52 l 362.09 359.18 l 354.62 358.18 l 350.38 357.52 l 345.33 356.83 l 338.44 355.63 l 336.68 355.32 l 335.41 355.10 l 328.42 353.96 l 327.82 353.87 l 320.44 352.50 l 319.36 352.32 l 318.09 352.07 l 311.55 350.62 l 305.46 349.17 l 304.01 348.86 l 302.65 348.51 l 297.85 346.76 l 297.42 346.60 l 292.97 344.96 l 292.52 344.47 l 290.49 342.62 l 289.38 341.66 l 289.05 341.40 l 289.13 341.08 l 290.49 338.32 l 290.69 337.89 l 290.72 337.84 l 290.93 337.74 l 295.19 335.40 l 297.71 334.29 l 300.84 333.19 l 305.46 331.89 l 307.66 331.25 l 309.79 330.73 l 314.91 329.42 l 320.44 328.25 l 322.81 327.74 l 325.85 327.18 l 330.73 326.06 l 335.41 325.17 l 338.99 324.47 l 344.06 323.62 l 347.19 322.86 l 350.38 322.20 l 355.10 321.18 l 361.08 320.06 l 362.87 319.47 l 365.36 318.76 l 369.58 317.51 l 373.36 316.51 l 374.83 315.20 l 376.54 313.85 l 377.61 312.95 l 375.65 311.84 l 373.91 310.92 l 371.49 309.39 l 367.78 308.82 l 365.36 308.24 l 359.89 307.14 l 355.11 305.84 l 352.02 305.45 l 350.38 305.15 l 342.95 304.05 l 342.17 303.89 l 335.41 302.55 l 334.76 302.44 l 334.07 302.28 l 325.38 301.11 l 320.44 300.19 l 316.71 299.61 l 312.47 298.72 l 308.31 298.05 l 305.46 297.47 l 299.89 296.49 l 294.02 295.17 l 292.21 294.76 l 290.49 294.31 l 284.66 293.00 l 279.64 291.61 l 278.01 291.02 l 275.52 290.04 l 272.08 288.87 l 269.94 288.06 l 267.64 286.37 l 267.27 286.10 l 265.09 284.50 l 265.05 283.43 l 264.66 281.92 l 264.61 280.94 l 265.93 279.66 l 266.59 278.82 l 268.31 277.39 l 270.44 276.18 l 275.52 274.09 l 275.89 273.92 l 276.15 273.83 l 277.28 273.41 l 281.56 271.71 l 286.48 270.27 l 288.05 269.70 l 290.49 269.00 l 294.64 267.70 l 298.58 266.72 l 301.24 265.72 l 305.46 264.45 l 307.77 263.71 l 309.89 263.16 l 313.30 261.47 l 314.27 261.07 l 317.68 259.61 l 317.91 259.01 l 319.10 256.37 l 319.22 256.05 l 318.64 255.62 l 315.85 253.58 l 314.37 252.49 l 310.42 251.32 l 305.46 249.60 l 304.29 249.22 l 303.54 248.94 l 296.77 247.44 l 290.49 245.76 l 289.70 245.57 l 289.03 245.38 l 281.54 243.95 l 275.52 242.39 l 274.28 242.12 l 273.24 241.82 l 266.35 240.44 l 260.54 238.87 l 259.23 238.58 l 258.15 238.27 l 252.05 236.73 l 246.57 234.95 l 245.81 234.71 l 245.71 234.68 l 245.57 234.62 l 239.51 232.59 l 235.85 231.16 l 234.20 230.30 l 230.59 228.31 l 229.51 227.86 l 228.93 227.60 l 228.01 226.99 l 225.60 225.23 l 223.66 224.04 l 222.28 222.46 l 221.61 221.91 l 220.20 220.49 l 219.84 219.48 l 218.02 217.50 l 217.76 216.93 l 217.65 216.45 l 215.62 214.09 l 214.91 213.54 l 214.55 213.37 l 214.04 213.00 l 211.76 210.74 l 210.18 209.82 l 207.20 208.26 l 204.39 207.15 l 202.31 206.26 l 201.76 206.00 l 200.65 205.55 l 193.99 204.29 l 185.67 202.71 l 170.70 202.71 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 424.75 m 449.64 424.52 l 442.84 423.81 l 440.23 423.64 l 438.72 423.55 l 436.46 423.19 l 431.24 421.77 l 425.25 420.66 l 422.59 420.27 l 418.76 419.64 l 414.29 418.69 l 410.28 418.08 l 405.08 417.32 l 396.36 416.08 l 395.80 415.96 l 395.31 415.89 l 392.84 415.50 l 386.92 414.52 l 380.33 413.58 l 377.49 413.20 l 372.82 412.53 l 368.76 411.72 l 365.36 411.17 l 359.92 410.26 l 351.84 408.97 l 351.15 408.79 l 350.38 408.62 l 343.58 407.03 l 335.98 405.41 l 335.78 405.32 l 335.41 405.19 l 330.10 403.12 l 326.49 401.86 l 325.68 400.61 l 324.42 399.25 l 323.74 398.30 l 325.02 397.21 l 326.14 396.10 l 327.92 394.74 l 330.87 393.67 l 335.41 392.24 l 337.36 391.65 l 339.04 391.19 l 344.89 389.88 l 350.38 388.79 l 353.11 388.28 l 356.78 387.63 l 361.70 386.76 l 365.36 386.19 l 370.76 385.36 l 379.89 384.08 l 380.15 384.03 l 380.33 384.00 l 381.11 383.89 l 389.34 382.66 l 395.31 381.85 l 398.90 381.37 l 405.68 380.52 l 408.38 380.07 l 410.28 379.78 l 417.57 378.69 l 418.51 378.56 l 425.25 377.61 l 426.99 377.37 l 430.11 376.96 l 435.42 375.82 l 440.23 374.86 l 443.55 374.20 l 447.71 373.41 l 449.86 372.14 l 453.01 370.37 l 453.92 369.85 l 441.70 369.50 l 440.23 369.36 l 436.88 369.06 l 429.96 368.73 l 425.25 367.93 l 420.80 367.35 l 416.80 366.29 l 413.01 365.64 l 410.28 365.16 l 403.85 364.26 l 395.85 362.74 l 395.53 362.68 l 395.31 362.65 l 394.43 362.53 l 385.97 361.40 l 380.33 360.54 l 376.64 360.06 l 371.51 359.18 l 367.76 358.61 l 365.36 358.25 l 358.40 357.28 l 355.16 356.76 l 350.38 356.02 l 349.34 355.87 l 347.92 355.63 l 340.64 354.38 l 335.41 353.46 l 331.93 352.90 l 327.55 352.07 l 324.00 351.22 l 320.44 350.40 l 316.33 349.49 l 312.24 348.51 l 309.72 347.50 l 305.46 345.90 l 303.89 345.33 l 302.88 344.96 l 302.15 344.17 l 300.77 342.51 l 299.66 341.40 l 300.44 340.21 l 301.79 338.72 l 302.42 337.84 l 303.39 337.35 l 305.46 336.48 l 308.80 335.08 l 311.03 334.29 l 315.30 333.07 l 320.44 331.81 l 322.68 331.27 l 325.17 330.73 l 330.50 329.57 l 335.41 328.64 l 338.86 327.99 l 343.79 327.18 l 347.38 326.46 l 350.38 325.95 l 356.05 324.96 l 364.74 323.62 l 365.06 323.55 l 365.36 323.49 l 368.08 322.97 l 373.33 321.96 l 380.33 320.74 l 382.00 320.46 l 384.48 320.06 l 389.58 318.70 l 395.31 317.32 l 397.01 316.91 l 398.80 316.51 l 400.61 315.25 l 401.68 314.46 l 403.97 312.95 l 399.42 311.97 l 395.31 310.09 l 394.17 309.66 l 393.64 309.39 l 384.97 308.29 l 380.33 307.32 l 376.66 306.71 l 373.00 305.84 l 367.98 305.22 l 365.36 304.78 l 358.70 303.86 l 350.88 302.40 l 350.38 302.31 l 350.31 302.30 l 350.22 302.28 l 340.72 301.02 l 335.41 300.12 l 331.77 299.59 l 327.24 298.72 l 323.22 298.06 l 320.44 297.54 l 314.60 296.56 l 307.85 295.17 l 306.64 294.89 l 305.46 294.60 l 299.02 293.14 l 293.09 291.61 l 292.10 291.23 l 290.49 290.60 l 286.22 289.07 l 283.59 288.06 l 281.87 286.55 l 280.94 285.79 l 279.43 284.50 l 279.77 283.49 l 280.01 282.01 l 280.41 280.94 l 283.08 279.19 l 283.23 279.11 l 286.31 277.39 l 287.82 276.75 l 290.49 275.86 l 293.92 274.65 l 296.79 273.83 l 300.64 272.68 l 305.46 271.53 l 308.04 270.89 l 310.99 270.27 l 315.49 269.10 l 320.44 268.03 l 323.27 267.39 l 326.85 266.72 l 330.85 265.63 l 335.41 264.57 l 338.36 263.86 l 341.83 263.16 l 345.24 261.94 l 350.38 260.32 l 351.64 259.90 l 352.66 259.61 l 353.30 258.91 l 354.82 257.10 l 355.83 256.05 l 354.41 255.09 l 350.89 252.61 l 350.72 252.49 l 350.54 252.46 l 350.38 252.41 l 343.22 250.64 l 337.47 248.94 l 336.17 248.76 l 335.41 248.61 l 330.30 247.72 l 327.49 247.26 l 320.44 245.69 l 319.73 245.55 l 319.05 245.38 l 310.70 244.14 l 305.46 243.06 l 302.48 242.53 l 299.38 241.82 l 294.20 240.94 l 290.49 240.11 l 286.18 239.29 l 281.96 238.27 l 278.66 237.52 l 275.52 236.65 l 271.46 235.68 l 268.23 234.71 l 265.16 233.62 l 260.54 231.76 l 259.49 231.41 l 258.85 231.16 l 257.82 230.51 l 255.19 228.87 l 253.16 227.60 l 252.48 225.96 l 252.28 225.64 l 251.56 224.04 l 252.40 222.42 l 252.46 222.12 l 253.46 220.49 l 255.02 219.18 l 257.92 217.56 l 258.84 216.93 l 259.28 216.63 l 260.54 216.04 l 263.92 214.18 l 266.02 213.37 l 269.13 211.86 l 274.15 210.14 l 275.03 209.82 l 275.17 209.74 l 275.52 209.58 l 279.88 207.30 l 282.50 206.26 l 284.35 204.80 l 286.09 203.75 l 287.61 202.71 l 287.61 202.02 l 287.99 199.74 l 287.99 199.15 l 286.63 198.23 l 284.68 196.97 l 282.70 195.59 l 279.74 194.59 l 275.52 192.93 l 273.98 192.40 l 273.02 192.04 l 266.98 190.51 l 260.54 188.48 l 253.12 186.69 l 247.44 184.92 l 246.49 184.71 l 245.57 184.43 l 239.11 182.90 l 234.22 181.37 l 232.53 180.91 l 230.59 180.23 l 225.70 178.98 l 222.11 177.81 l 219.26 176.95 l 215.62 175.61 l 212.80 174.93 l 210.41 174.26 l 206.19 172.94 l 200.65 171.12 l 199.61 170.95 l 198.15 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 369.37 m 452.44 369.19 l 444.00 368.95 l 440.23 368.60 l 433.22 367.96 l 428.27 367.01 l 425.25 366.49 l 424.71 366.42 l 424.21 366.29 l 416.12 364.91 l 410.28 363.86 l 407.29 363.45 l 403.56 362.74 l 398.72 361.93 l 395.31 361.41 l 389.38 360.59 l 380.41 359.18 l 380.37 359.17 l 380.33 359.17 l 380.17 359.14 l 371.24 357.78 l 365.36 356.90 l 361.97 356.43 l 356.94 355.63 l 353.28 354.94 l 350.38 354.44 l 344.57 353.45 l 336.78 352.07 l 336.13 351.90 l 335.41 351.74 l 328.63 350.12 l 321.67 348.51 l 321.24 348.32 l 320.44 348.00 l 315.70 346.08 l 312.75 344.96 l 311.78 343.46 l 311.20 342.76 l 310.24 341.40 l 311.85 339.88 l 312.24 339.45 l 314.12 337.84 l 316.46 336.90 l 320.44 335.53 l 322.62 334.81 l 324.35 334.29 l 329.82 332.96 l 335.41 331.75 l 337.70 331.28 l 340.56 330.73 l 346.02 329.69 l 350.38 328.95 l 354.80 328.22 l 361.75 327.18 l 363.82 326.81 l 365.36 326.57 l 372.84 325.40 l 380.33 324.30 l 382.14 324.05 l 385.39 323.62 l 391.12 322.62 l 395.31 321.95 l 400.06 321.19 l 407.71 320.06 l 408.98 319.75 l 410.28 319.46 l 416.70 318.03 l 423.98 316.51 l 424.33 316.29 l 425.25 315.73 l 428.58 313.74 l 429.98 312.95 l 426.10 312.75 l 425.25 312.60 l 421.66 312.10 l 416.24 311.53 l 410.28 309.77 l 409.46 309.59 l 408.94 309.39 l 400.16 308.24 l 395.31 307.34 l 391.38 306.77 l 387.01 305.84 l 382.79 305.25 l 380.33 304.87 l 373.36 303.94 l 369.59 303.29 l 365.36 302.59 l 364.54 302.48 l 363.50 302.28 l 355.23 301.13 l 350.38 300.37 l 346.05 299.75 l 340.20 298.72 l 337.44 298.24 l 335.41 297.88 l 328.73 296.75 l 320.44 295.17 l 312.83 293.42 l 305.46 291.61 l 299.75 289.41 l 296.26 288.06 l 295.26 286.92 l 293.50 285.22 l 292.83 284.50 l 293.31 283.83 l 294.37 281.87 l 295.10 280.94 l 298.49 279.29 l 299.92 278.70 l 302.99 277.39 l 304.01 277.04 l 305.46 276.64 l 310.86 275.11 l 316.21 273.83 l 318.28 273.32 l 320.44 272.87 l 326.14 271.63 l 333.43 270.27 l 334.44 270.04 l 335.41 269.86 l 342.68 268.45 l 344.15 268.20 l 350.38 267.13 l 351.38 266.96 l 352.92 266.72 l 359.49 265.32 l 365.36 264.23 l 367.85 263.76 l 371.29 263.16 l 375.31 261.97 l 380.33 260.63 l 382.38 260.09 l 384.39 259.61 l 386.23 258.21 l 386.96 257.62 l 389.12 256.05 l 385.91 254.73 l 383.56 253.26 l 382.11 252.49 l 380.96 252.34 l 380.33 252.21 l 376.22 251.52 l 372.15 250.88 l 365.36 249.23 l 364.70 249.09 l 364.13 248.94 l 355.15 247.81 l 350.38 246.95 l 346.35 246.34 l 341.72 245.38 l 337.69 244.84 l 335.41 244.46 l 328.56 243.45 l 321.86 242.16 l 320.44 241.90 l 320.25 241.87 l 320.04 241.82 l 311.42 240.41 l 305.46 239.19 l 303.23 238.80 l 300.88 238.27 l 295.55 237.07 l 290.49 235.74 l 288.28 235.24 l 286.36 234.71 l 282.07 233.16 l 279.26 232.05 l 276.96 231.16 l 276.67 230.88 l 275.52 229.93 l 273.17 228.16 l 272.41 227.60 l 272.39 226.86 l 272.74 224.70 l 272.72 224.04 l 273.27 223.51 l 275.52 221.97 l 277.03 220.85 l 277.69 220.49 l 280.51 219.30 l 282.22 218.52 l 286.81 216.93 l 288.26 216.40 l 290.49 215.77 l 294.92 214.43 l 299.35 213.37 l 302.04 212.56 l 305.46 211.72 l 309.25 210.72 l 313.47 209.82 l 316.47 208.88 l 320.44 207.84 l 323.53 207.00 l 326.74 206.26 l 329.83 204.94 l 335.41 202.86 l 335.66 202.77 l 335.84 202.71 l 335.95 202.58 l 338.03 199.77 l 338.59 199.15 l 337.77 198.59 l 335.41 196.89 l 334.03 195.92 l 333.60 195.59 l 327.67 193.87 l 326.43 193.46 l 322.06 192.04 l 321.10 191.88 l 320.44 191.73 l 313.39 190.36 l 312.90 190.27 l 305.46 188.48 l 296.74 187.00 l 290.49 185.54 l 289.06 185.26 l 287.70 184.92 l 280.78 183.67 l 275.52 182.38 l 273.24 181.91 l 271.24 181.37 l 265.89 180.10 l 260.54 178.47 l 259.18 178.14 l 258.15 177.81 l 253.28 176.09 l 253.10 176.02 l 248.72 174.26 l 247.84 173.72 l 245.57 172.32 l 243.38 171.22 l 242.45 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 424.53 m 450.43 424.33 l 440.83 423.34 l 440.23 423.30 l 439.88 423.28 l 439.36 423.19 l 433.42 421.58 l 432.80 421.40 l 432.36 421.33 l 425.25 420.00 l 424.30 419.86 l 422.92 419.64 l 416.25 418.22 l 410.28 417.32 l 407.06 416.85 l 401.65 416.08 l 398.28 415.37 l 395.31 414.95 l 389.23 413.97 l 382.68 413.08 l 380.33 412.75 l 379.73 412.67 l 378.73 412.53 l 371.46 411.08 l 365.36 410.10 l 362.57 409.63 l 358.43 408.97 l 354.66 407.95 l 350.38 407.03 l 346.95 406.23 l 343.11 405.41 l 340.46 404.21 l 335.41 402.36 l 334.60 402.05 l 334.05 401.86 l 333.80 401.47 l 332.67 398.95 l 332.20 398.30 l 332.90 397.70 l 335.41 396.01 l 336.89 395.09 l 337.54 394.74 l 343.24 393.05 l 347.89 391.78 l 350.05 391.19 l 350.22 391.15 l 350.38 391.12 l 351.83 390.84 l 358.53 389.57 l 365.36 388.35 l 367.15 388.06 l 369.77 387.63 l 376.14 386.64 l 380.33 386.03 l 385.58 385.32 l 395.00 384.08 l 395.19 384.05 l 395.31 384.03 l 395.72 383.98 l 404.75 382.76 l 410.28 382.05 l 414.56 381.53 l 423.14 380.52 l 424.43 380.32 l 425.25 380.21 l 428.35 379.78 l 433.90 379.02 l 440.23 378.17 l 443.53 377.75 l 449.68 376.96 l 452.67 376.36 l 455.20 375.88 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 312.93 m 455.08 312.92 l 442.13 312.50 l 440.23 312.31 l 435.73 311.88 l 430.83 311.63 l 425.25 310.63 l 421.97 310.17 l 419.13 309.39 l 414.03 308.50 l 410.28 307.82 l 405.07 307.07 l 398.64 305.84 l 396.70 305.51 l 395.31 305.29 l 389.59 304.48 l 387.35 304.17 l 380.33 303.09 l 378.17 302.79 l 375.19 302.28 l 369.25 301.36 l 365.36 300.77 l 360.00 300.00 l 352.10 298.72 l 351.15 298.54 l 350.38 298.41 l 345.34 297.53 l 342.53 297.03 l 335.41 295.76 l 333.95 295.52 l 332.14 295.17 l 326.36 293.76 l 320.44 292.37 l 318.82 292.00 l 317.25 291.61 l 313.02 289.85 l 312.97 289.83 l 308.53 288.06 l 308.16 287.42 l 305.94 284.61 l 305.86 284.50 l 306.01 284.37 l 308.64 281.70 l 309.57 280.94 l 313.70 279.34 l 317.28 278.14 l 319.45 277.39 l 319.90 277.26 l 320.44 277.13 l 327.37 275.48 l 335.04 273.83 l 335.23 273.79 l 335.41 273.75 l 336.87 273.48 l 343.61 272.22 l 350.38 271.08 l 352.39 270.75 l 355.52 270.27 l 361.19 269.28 l 365.36 268.63 l 370.22 267.87 l 378.30 266.72 l 379.42 266.50 l 380.33 266.34 l 385.90 265.40 l 388.12 265.01 l 395.31 263.86 l 397.08 263.58 l 399.91 263.16 l 405.05 261.92 l 410.28 260.75 l 412.77 260.20 l 415.58 259.61 l 418.27 257.95 l 418.95 257.55 l 421.43 256.05 l 413.73 255.23 l 410.28 254.19 l 406.59 253.37 l 404.29 252.49 l 398.51 251.73 l 395.31 251.13 l 389.61 250.29 l 383.30 248.94 l 381.42 248.68 l 380.33 248.51 l 376.15 247.94 l 371.82 247.40 l 365.36 246.34 l 362.81 245.99 l 359.60 245.38 l 353.82 244.57 l 350.38 244.02 l 344.61 243.20 l 336.77 241.82 l 335.99 241.69 l 335.41 241.59 l 331.86 240.98 l 327.23 240.21 l 320.44 238.92 l 318.84 238.65 l 317.01 238.27 l 311.16 236.92 l 305.46 235.53 l 303.71 235.13 l 302.10 234.71 l 297.69 233.00 l 296.79 232.65 l 292.93 231.16 l 292.53 230.67 l 290.49 228.57 l 289.69 227.79 l 289.48 227.60 l 289.55 227.38 l 290.49 225.66 l 291.25 224.22 l 291.39 224.04 l 292.27 223.62 l 295.87 221.77 l 298.90 220.49 l 301.60 219.57 l 305.46 218.49 l 308.45 217.64 l 311.41 216.93 l 315.81 215.83 l 320.44 214.85 l 323.70 214.15 l 327.92 213.37 l 331.78 212.51 l 335.41 211.83 l 340.05 210.92 l 346.56 209.82 l 348.46 209.36 l 350.38 208.97 l 356.44 207.70 l 364.26 206.26 l 364.73 206.11 l 365.36 205.93 l 371.39 204.14 l 376.79 202.71 l 377.52 202.04 l 380.33 199.80 l 380.94 199.30 l 381.14 199.15 l 380.85 199.03 l 380.33 198.71 l 376.41 196.52 l 374.96 195.59 l 369.14 194.70 l 365.36 193.78 l 361.45 192.97 l 358.02 192.04 l 353.04 191.41 l 350.38 190.93 l 344.12 189.97 l 336.88 188.48 l 335.94 188.35 l 335.41 188.26 l 332.98 187.90 l 326.58 187.02 l 320.44 185.88 l 318.02 185.50 l 315.28 184.92 l 309.47 183.97 l 305.46 183.17 l 301.12 182.40 l 296.57 181.37 l 293.47 180.66 l 290.49 179.88 l 286.03 178.87 l 282.15 177.81 l 279.53 176.86 l 275.52 175.25 l 273.84 174.66 l 272.83 174.26 l 271.57 173.32 l 269.87 172.04 l 268.03 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 368.86 m 449.50 368.50 l 446.31 368.41 l 440.23 367.83 l 435.55 367.40 l 429.74 366.29 l 427.72 365.71 l 425.25 365.22 l 419.20 364.18 l 411.20 362.74 l 410.72 362.63 l 410.28 362.56 l 407.89 362.17 l 401.91 361.17 l 395.31 360.17 l 392.67 359.81 l 388.69 359.18 l 383.92 358.33 l 380.33 357.80 l 374.74 356.95 l 365.81 355.63 l 365.57 355.57 l 365.36 355.54 l 363.68 355.23 l 357.20 354.01 l 350.38 352.85 l 348.47 352.52 l 345.91 352.07 l 340.90 350.76 l 335.41 349.51 l 333.30 349.01 l 331.15 348.51 l 327.44 346.85 l 325.97 346.27 l 322.74 344.96 l 322.57 344.45 l 320.94 341.52 l 320.90 341.40 l 321.15 341.23 l 324.55 338.82 l 326.13 337.84 l 330.04 336.57 l 335.41 334.98 l 336.76 334.61 l 337.98 334.29 l 344.58 332.91 l 350.38 331.79 l 352.94 331.34 l 356.41 330.73 l 361.66 329.85 l 365.36 329.28 l 370.87 328.48 l 380.15 327.18 l 380.26 327.16 l 380.33 327.15 l 380.63 327.11 l 389.61 325.82 l 395.31 325.06 l 399.24 324.55 l 406.64 323.62 l 408.81 323.27 l 410.28 323.05 l 416.41 322.16 l 418.09 321.92 l 425.25 320.91 l 427.54 320.60 l 431.63 320.06 l 436.23 319.11 l 440.23 318.31 l 444.39 317.49 l 449.52 316.51 l 451.23 315.56 l 455.20 313.38 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 424.31 m 451.22 424.14 l 442.06 423.19 l 441.62 422.86 l 440.23 422.50 l 434.71 420.95 l 427.23 419.64 l 426.39 419.37 l 425.25 419.17 l 418.30 417.73 l 415.78 417.39 l 410.28 416.56 l 409.03 416.38 l 406.95 416.08 l 400.76 414.79 l 395.31 414.00 l 391.60 413.40 l 385.10 412.53 l 382.71 411.96 l 380.33 411.57 l 374.31 410.40 l 366.06 409.13 l 365.36 409.02 l 365.23 409.00 l 365.03 408.97 l 362.53 408.30 l 358.20 407.11 l 351.85 405.76 l 350.38 405.44 l 350.32 405.43 l 350.24 405.41 l 350.08 405.34 l 345.37 403.05 l 342.27 401.86 l 341.89 400.32 l 341.62 399.77 l 341.21 398.30 l 343.86 396.75 l 345.51 395.90 l 347.65 394.74 l 348.86 394.38 l 350.38 393.97 l 356.14 392.55 l 361.82 391.19 l 363.78 390.81 l 365.36 390.53 l 372.59 389.35 l 374.23 389.08 l 380.33 388.09 l 381.52 387.91 l 383.38 387.63 l 390.94 386.59 l 395.31 386.01 l 400.68 385.35 l 409.57 384.24 l 410.28 384.15 l 410.51 384.13 l 410.96 384.08 l 420.39 382.92 l 425.25 382.34 l 430.48 381.76 l 439.06 380.80 l 440.23 380.67 l 440.66 380.62 l 441.59 380.52 l 450.40 379.38 l 455.20 378.77 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 312.22 m 450.95 311.94 l 445.26 311.75 l 440.23 311.26 l 434.62 310.73 l 427.83 309.39 l 426.68 309.06 l 425.25 308.77 l 418.15 307.52 l 414.86 306.93 l 410.28 306.10 l 409.60 306.00 l 408.76 305.84 l 400.92 304.51 l 395.31 303.65 l 391.71 303.14 l 386.30 302.28 l 382.91 301.67 l 380.33 301.29 l 373.80 300.28 l 368.62 299.50 l 365.36 299.01 l 364.62 298.90 l 363.53 298.72 l 356.24 297.33 l 350.38 296.33 l 347.57 295.84 l 343.83 295.17 l 339.86 294.11 l 335.41 293.09 l 332.34 292.34 l 329.25 291.61 l 326.25 290.23 l 321.37 288.28 l 320.84 288.06 l 320.81 287.97 l 320.44 287.17 l 319.39 284.75 l 319.23 284.50 l 319.49 284.27 l 320.44 283.59 l 323.34 281.63 l 324.49 280.94 l 329.15 279.46 l 335.41 277.62 l 335.88 277.50 l 336.31 277.39 l 343.86 275.84 l 350.38 274.59 l 352.21 274.26 l 354.69 273.83 l 360.98 272.79 l 365.36 272.12 l 370.18 271.42 l 378.26 270.27 l 379.50 270.08 l 380.33 269.96 l 383.54 269.51 l 388.91 268.76 l 395.31 267.90 l 398.56 267.49 l 404.66 266.72 l 408.02 266.18 l 410.28 265.84 l 417.33 264.84 l 419.43 264.55 l 425.25 263.73 l 426.79 263.53 l 429.53 263.16 l 435.24 261.98 l 440.23 260.98 l 443.41 260.36 l 447.39 259.61 l 449.76 258.31 l 452.90 256.60 l 453.90 256.05 l 441.89 255.65 l 440.23 255.49 l 436.27 255.11 l 430.50 254.80 l 425.25 253.86 l 421.64 253.35 l 418.56 252.49 l 413.81 251.65 l 410.28 251.01 l 404.85 250.23 l 398.22 248.94 l 396.52 248.65 l 395.31 248.46 l 390.31 247.75 l 387.16 247.32 l 380.33 246.26 l 377.98 245.94 l 374.72 245.38 l 369.07 244.50 l 365.36 243.94 l 359.84 243.13 l 351.81 241.82 l 351.02 241.67 l 350.38 241.57 l 346.28 240.85 l 342.37 240.17 l 335.41 238.93 l 333.78 238.66 l 331.78 238.27 l 326.22 236.90 l 320.44 235.52 l 318.71 235.12 l 317.03 234.71 l 312.81 232.97 l 312.37 232.80 l 308.24 231.16 l 307.91 230.57 l 305.66 227.65 l 305.63 227.60 l 305.70 227.54 l 308.56 224.78 l 309.48 224.04 l 313.63 222.43 l 316.69 221.38 l 319.22 220.49 l 319.78 220.33 l 320.44 220.17 l 327.29 218.56 l 334.94 216.93 l 335.19 216.88 l 335.41 216.84 l 337.23 216.50 l 343.56 215.31 l 350.38 214.16 l 352.34 213.84 l 355.38 213.37 l 361.13 212.37 l 365.36 211.71 l 370.19 210.97 l 378.15 209.82 l 379.35 209.59 l 380.33 209.42 l 386.15 208.44 l 388.09 208.11 l 395.31 206.96 l 397.09 206.69 l 399.94 206.26 l 405.02 205.01 l 410.28 203.81 l 412.68 203.28 l 415.40 202.71 l 418.19 201.03 l 418.74 200.70 l 421.31 199.15 l 413.72 198.33 l 410.28 197.31 l 406.57 196.47 l 404.29 195.59 l 398.54 194.83 l 395.31 194.22 l 389.61 193.39 l 383.25 192.04 l 381.41 191.78 l 380.33 191.61 l 376.17 191.05 l 371.82 190.50 l 365.36 189.44 l 362.82 189.08 l 359.61 188.48 l 353.83 187.66 l 350.38 187.11 l 344.63 186.29 l 336.91 184.92 l 336.05 184.77 l 335.41 184.66 l 331.55 184.01 l 327.27 183.30 l 320.44 182.00 l 318.89 181.74 l 317.09 181.37 l 311.18 180.01 l 305.46 178.61 l 303.76 178.22 l 302.20 177.81 l 297.74 176.09 l 296.98 175.80 l 292.99 174.26 l 292.57 173.76 l 290.49 171.69 l 289.67 170.89 l 289.45 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 368.35 m 448.38 367.91 l 445.63 367.58 l 440.23 367.07 l 437.88 366.85 l 434.96 366.29 l 430.59 365.03 l 425.25 363.97 l 422.24 363.45 l 418.26 362.74 l 414.15 361.82 l 410.28 361.22 l 405.22 360.38 l 397.06 359.18 l 396.15 358.98 l 395.31 358.86 l 390.23 357.98 l 387.48 357.48 l 380.33 356.43 l 378.26 356.12 l 374.94 355.63 l 369.89 354.55 l 365.36 353.79 l 361.28 353.04 l 355.48 352.07 l 353.18 351.40 l 350.38 350.76 l 345.88 349.58 l 341.17 348.51 l 339.35 347.58 l 335.41 345.94 l 334.02 345.29 l 333.21 344.96 l 333.02 344.39 l 332.66 342.05 l 332.42 341.40 l 333.20 340.88 l 335.41 339.59 l 337.72 338.39 l 338.84 337.84 l 344.22 336.38 l 350.38 334.76 l 351.41 334.53 l 352.46 334.29 l 359.82 332.97 l 365.36 332.00 l 368.59 331.50 l 373.38 330.73 l 377.68 330.10 l 380.33 329.73 l 387.24 328.82 l 389.86 328.47 l 395.31 327.75 l 396.91 327.56 l 399.94 327.18 l 406.66 326.31 l 410.28 325.85 l 416.57 325.11 l 421.37 324.54 l 425.25 324.08 l 426.59 323.94 l 429.36 323.62 l 436.30 322.69 l 440.23 322.16 l 446.02 321.44 l 453.40 320.49 l 455.20 320.26 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 424.08 m 452.02 423.95 l 444.68 423.19 l 443.62 422.39 l 440.23 421.51 l 436.62 420.49 l 431.73 419.64 l 428.99 418.75 l 425.25 418.12 l 420.67 417.17 l 412.68 416.08 l 411.55 415.78 l 410.28 415.59 l 403.34 414.17 l 400.97 413.87 l 395.31 413.05 l 393.98 412.84 l 391.64 412.53 l 385.98 411.18 l 380.33 410.27 l 377.32 409.68 l 372.65 408.97 l 369.50 407.99 l 365.36 407.06 l 362.13 406.18 l 358.54 405.41 l 356.06 404.06 l 351.04 402.01 l 350.69 401.86 l 350.70 401.78 l 350.60 398.35 l 350.61 398.30 l 350.88 398.18 l 355.78 396.03 l 358.79 394.74 l 362.02 393.95 l 365.36 393.15 l 369.78 392.24 l 374.63 391.19 l 378.00 390.63 l 380.33 390.26 l 387.21 389.26 l 390.62 388.74 l 395.31 388.04 l 396.42 387.90 l 398.23 387.63 l 406.19 386.66 l 410.28 386.15 l 416.23 385.49 l 422.45 384.74 l 425.25 384.41 l 426.24 384.31 l 428.29 384.08 l 436.45 383.18 l 440.23 382.76 l 446.79 382.08 l 450.21 381.70 l 455.20 381.17 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 198.97 m 454.15 198.90 l 442.86 198.52 l 440.23 198.27 l 433.95 197.66 l 431.97 197.55 l 425.25 196.34 l 423.28 196.06 l 421.59 195.59 l 415.10 194.45 l 410.28 193.57 l 406.28 192.99 l 401.36 192.04 l 397.83 191.44 l 395.31 191.05 l 388.55 190.09 l 384.12 189.38 l 380.33 188.79 l 379.50 188.68 l 378.35 188.48 l 370.49 187.26 l 365.36 186.48 l 361.30 185.89 l 355.38 184.92 l 352.61 184.40 l 350.38 184.01 l 343.98 182.89 l 335.41 181.37 l 328.09 179.55 l 320.81 177.81 l 320.69 177.75 l 320.44 177.65 l 315.27 175.48 l 312.18 174.26 l 311.42 172.84 l 310.78 171.96 l 310.04 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 255.19 m 450.17 254.85 l 445.86 254.71 l 440.23 254.16 l 435.24 253.68 l 429.22 252.49 l 427.45 251.97 l 425.25 251.54 l 419.00 250.42 l 410.87 248.94 l 410.57 248.87 l 410.28 248.82 l 408.67 248.56 l 401.82 247.39 l 395.31 246.39 l 392.64 246.01 l 388.64 245.38 l 383.92 244.53 l 380.33 244.00 l 374.79 243.14 l 366.10 241.82 l 365.71 241.74 l 365.36 241.68 l 362.42 241.13 l 357.38 240.16 l 350.38 238.97 l 348.68 238.67 l 346.42 238.27 l 341.24 236.88 l 335.41 235.52 l 333.75 235.11 l 332.08 234.71 l 328.55 233.08 l 328.14 232.88 l 323.97 231.16 l 323.76 230.37 l 322.79 228.16 l 322.63 227.60 l 323.93 226.77 l 326.01 225.37 l 328.22 224.04 l 331.28 223.06 l 335.41 221.85 l 338.12 221.13 l 340.63 220.49 l 345.88 219.42 l 350.38 218.55 l 354.30 217.86 l 359.68 216.93 l 363.04 216.38 l 365.36 216.02 l 372.25 215.01 l 375.20 214.59 l 380.33 213.86 l 381.65 213.69 l 384.00 213.37 l 391.09 212.37 l 395.31 211.81 l 400.78 211.12 l 409.17 210.08 l 410.28 209.94 l 410.64 209.90 l 411.35 209.82 l 419.99 208.57 l 425.25 207.84 l 429.47 207.26 l 436.86 206.26 l 438.64 205.89 l 440.23 205.57 l 446.90 204.29 l 455.20 202.71 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 311.51 m 448.21 311.05 l 446.10 310.79 l 440.23 310.21 l 437.77 309.98 l 434.79 309.39 l 430.53 308.14 l 425.25 307.10 l 422.21 306.56 l 418.23 305.84 l 414.15 304.92 l 410.28 304.31 l 405.26 303.47 l 397.26 302.28 l 396.25 302.06 l 395.31 301.92 l 389.45 300.89 l 387.60 300.56 l 380.33 299.48 l 378.40 299.18 l 375.34 298.72 l 370.10 297.60 l 365.36 296.80 l 361.53 296.08 l 356.11 295.17 l 353.54 294.42 l 350.38 293.69 l 346.27 292.59 l 342.02 291.61 l 339.97 290.53 l 335.41 288.61 l 334.64 288.24 l 334.21 288.06 l 334.13 287.75 l 333.90 284.86 l 333.80 284.50 l 334.23 284.22 l 335.41 283.55 l 338.93 281.78 l 340.70 280.94 l 345.27 279.73 l 350.38 278.40 l 352.58 277.91 l 354.84 277.39 l 360.87 276.32 l 365.36 275.54 l 369.70 274.86 l 376.09 273.83 l 378.72 273.45 l 380.33 273.22 l 386.08 272.47 l 388.33 272.17 l 395.31 271.25 l 398.07 270.93 l 403.33 270.27 l 407.86 269.70 l 410.28 269.39 l 417.56 268.55 l 417.84 268.51 l 425.25 267.64 l 427.93 267.35 l 433.50 266.72 l 437.80 266.14 l 440.23 265.82 l 447.52 264.89 l 448.38 264.78 l 455.20 263.91 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 367.83 m 450.08 367.51 l 440.28 366.31 l 440.23 366.30 l 440.20 366.30 l 440.17 366.29 l 439.94 366.23 l 433.64 364.30 l 425.33 362.74 l 425.30 362.73 l 425.25 362.72 l 424.10 362.46 l 417.58 361.00 l 410.28 359.87 l 408.57 359.59 l 405.81 359.18 l 400.35 357.98 l 395.31 357.24 l 391.38 356.56 l 384.69 355.63 l 382.56 355.10 l 380.33 354.72 l 374.39 353.48 l 365.48 352.07 l 365.43 352.05 l 365.36 352.04 l 358.77 350.08 l 351.91 348.51 l 351.48 348.25 l 350.38 347.75 l 346.90 345.78 l 345.03 344.96 l 345.03 343.68 l 345.22 342.63 l 345.22 341.40 l 346.87 340.56 l 350.38 338.88 l 352.03 338.23 l 353.02 337.84 l 359.34 336.41 l 365.36 335.01 l 367.02 334.68 l 368.87 334.29 l 375.81 333.21 l 380.33 332.49 l 385.03 331.85 l 392.35 330.73 l 394.25 330.48 l 395.31 330.34 l 398.58 329.95 l 404.23 329.29 l 410.28 328.55 l 414.26 328.12 l 422.03 327.18 l 424.19 326.92 l 425.25 326.79 l 428.18 326.48 l 434.50 325.81 l 440.23 325.17 l 444.80 324.71 l 454.67 323.62 l 455.02 323.58 l 455.20 323.55 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 423.86 m 452.81 423.76 l 447.31 423.19 l 445.61 421.91 l 440.23 420.52 l 438.53 420.04 l 436.22 419.64 l 431.58 418.13 l 425.25 417.07 l 423.03 416.61 l 419.16 416.08 l 415.00 414.96 l 410.28 414.25 l 406.37 413.45 l 399.11 412.53 l 397.38 412.03 l 395.31 411.69 l 389.56 410.33 l 380.33 408.97 l 374.06 406.90 l 367.31 405.41 l 366.81 405.07 l 365.36 404.38 l 362.44 402.55 l 360.88 401.86 l 361.05 400.83 l 361.70 399.17 l 361.87 398.30 l 363.10 397.76 l 365.36 396.81 l 368.97 395.60 l 371.38 394.74 l 376.18 393.76 l 380.33 392.86 l 384.39 392.15 l 389.22 391.19 l 393.03 390.65 l 395.31 390.30 l 402.61 389.37 l 403.57 389.23 l 410.28 388.28 l 412.11 388.07 l 415.21 387.63 l 422.11 386.88 l 425.25 386.52 l 432.44 385.78 l 433.59 385.65 l 440.23 384.92 l 442.76 384.68 l 448.03 384.08 l 453.06 383.57 l 455.20 383.34 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 197.84 m 447.80 197.35 l 447.44 197.31 l 440.23 196.60 l 437.23 196.31 l 433.62 195.59 l 429.88 194.50 l 425.25 193.58 l 421.54 192.92 l 416.74 192.04 l 413.45 191.29 l 410.28 190.79 l 404.58 189.83 l 395.49 188.48 l 395.39 188.46 l 395.31 188.45 l 394.76 188.35 l 386.88 186.93 l 380.33 185.97 l 377.67 185.56 l 373.49 184.92 l 369.26 184.00 l 365.36 183.34 l 360.73 182.47 l 354.23 181.37 l 352.52 180.86 l 350.38 180.38 l 345.29 179.02 l 340.05 177.81 l 338.64 177.05 l 335.41 175.64 l 333.53 174.70 l 332.46 174.26 l 332.26 173.51 l 332.01 171.51 l 331.78 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 254.29 m 449.29 253.90 l 442.62 253.06 l 440.23 252.83 l 439.23 252.73 l 438.02 252.49 l 432.32 250.81 l 425.25 249.41 l 424.12 249.21 l 422.66 248.94 l 416.31 247.50 l 410.28 246.56 l 407.37 246.07 l 402.72 245.38 l 398.87 244.53 l 395.31 244.01 l 390.02 243.08 l 381.04 241.82 l 380.69 241.74 l 380.33 241.68 l 374.03 240.33 l 372.79 240.06 l 365.36 238.81 l 364.08 238.57 l 362.27 238.27 l 356.97 236.70 l 350.38 235.18 l 349.47 234.93 l 348.53 234.71 l 347.06 233.92 l 344.68 232.51 l 341.72 231.16 l 341.80 229.64 l 341.74 229.10 l 341.83 227.60 l 344.63 226.23 l 348.18 224.57 l 349.28 224.04 l 349.80 223.91 l 350.38 223.76 l 357.50 222.18 l 364.85 220.49 l 365.14 220.44 l 365.36 220.40 l 366.45 220.23 l 374.20 219.03 l 380.33 218.04 l 383.28 217.63 l 387.82 216.93 l 392.65 216.30 l 395.31 215.95 l 402.56 215.10 l 403.54 214.98 l 410.28 214.15 l 412.52 213.91 l 417.02 213.37 l 422.60 212.74 l 425.25 212.43 l 432.57 211.64 l 432.80 211.61 l 440.23 210.76 l 443.01 210.48 l 448.96 209.82 l 453.07 209.31 l 455.20 209.05 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 310.81 m 450.54 310.50 l 441.71 309.39 l 441.36 309.12 l 440.23 308.82 l 434.77 307.13 l 427.95 305.84 l 426.82 305.47 l 425.25 305.20 l 418.92 303.79 l 413.16 302.97 l 410.28 302.51 l 409.70 302.42 l 408.78 302.28 l 401.79 300.74 l 395.31 299.77 l 392.76 299.33 l 388.45 298.72 l 384.48 297.74 l 380.33 297.05 l 376.15 296.16 l 369.98 295.17 l 368.06 294.53 l 365.36 293.90 l 361.11 292.62 l 356.71 291.61 l 354.95 290.53 l 350.38 288.39 l 349.97 288.15 l 349.75 288.06 l 349.76 287.91 l 350.38 285.21 l 350.58 284.55 l 350.60 284.50 l 350.94 284.37 l 356.24 282.34 l 359.74 280.94 l 362.63 280.29 l 365.36 279.66 l 370.68 278.65 l 376.59 277.39 l 378.86 277.04 l 380.33 276.80 l 386.17 276.00 l 388.28 275.72 l 395.31 274.67 l 397.63 274.38 l 401.47 273.83 l 407.43 273.15 l 410.28 272.81 l 417.62 272.02 l 418.22 271.94 l 425.25 271.13 l 427.78 270.88 l 432.91 270.27 l 437.99 269.74 l 440.23 269.49 l 446.01 268.90 l 448.42 268.67 l 455.20 267.93 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 367.32 m 451.78 367.11 l 445.17 366.29 l 444.01 365.39 l 440.23 364.38 l 437.20 363.46 l 433.38 362.74 l 429.99 361.61 l 425.25 360.81 l 421.71 360.02 l 415.75 359.18 l 413.23 358.48 l 410.28 358.03 l 404.97 356.89 l 395.31 355.63 l 388.02 353.80 l 386.88 353.62 l 380.33 352.53 l 379.30 352.31 l 377.75 352.07 l 372.53 350.37 l 365.36 348.71 l 364.99 348.60 l 364.60 348.51 l 364.12 348.22 l 361.05 345.98 l 359.03 344.96 l 359.54 343.57 l 360.03 342.67 l 360.53 341.40 l 362.35 340.69 l 365.36 339.49 l 368.39 338.56 l 370.49 337.84 l 375.92 336.80 l 380.33 335.86 l 384.20 335.21 l 388.82 334.29 l 392.96 333.73 l 395.31 333.38 l 402.64 332.47 l 403.42 332.36 l 410.28 331.40 l 412.19 331.19 l 415.45 330.73 l 422.29 330.03 l 425.25 329.68 l 432.70 328.94 l 432.87 328.92 l 440.23 328.11 l 443.05 327.84 l 448.74 327.18 l 453.31 326.73 l 455.20 326.52 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 423.64 m 453.60 423.57 l 449.93 423.19 l 447.61 421.44 l 445.29 420.84 l 441.00 419.64 l 440.80 419.50 l 440.23 419.38 l 434.88 417.35 l 425.87 416.08 l 425.63 415.99 l 425.25 415.93 l 418.72 414.08 l 414.73 413.58 l 410.28 412.91 l 409.40 412.73 l 407.77 412.53 l 402.09 410.91 l 395.31 409.79 l 393.58 409.38 l 390.80 408.97 l 386.65 407.47 l 380.33 406.01 l 379.29 405.66 l 378.16 405.41 l 377.02 404.63 l 375.26 403.06 l 373.05 401.86 l 374.01 400.35 l 374.55 399.67 l 375.49 398.30 l 377.48 397.62 l 380.33 396.60 l 384.02 395.62 l 386.83 394.74 l 391.74 393.90 l 395.31 393.20 l 400.47 392.41 l 407.02 391.19 l 409.16 390.92 l 410.28 390.76 l 413.77 390.36 l 419.26 389.77 l 425.25 388.97 l 429.14 388.55 l 435.92 387.63 l 438.98 387.34 l 440.23 387.20 l 443.29 386.90 l 449.74 386.33 l 455.20 385.75 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 196.72 m 451.50 196.47 l 444.50 195.59 l 443.50 194.82 l 440.23 193.94 l 436.75 192.86 l 432.40 192.04 l 429.43 191.05 l 425.25 190.32 l 421.29 189.42 l 414.72 188.48 l 412.67 187.91 l 410.28 187.54 l 404.51 186.30 l 396.82 185.29 l 395.31 185.06 l 394.98 185.00 l 394.41 184.92 l 387.51 183.22 l 380.33 182.02 l 378.91 181.71 l 376.78 181.37 l 372.00 179.79 l 365.36 178.23 l 364.59 178.00 l 363.78 177.81 l 362.83 177.21 l 360.40 175.43 l 358.18 174.26 l 358.86 172.71 l 359.21 172.16 l 359.91 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 253.39 m 452.24 253.20 l 446.64 252.49 l 445.14 251.33 l 440.23 250.00 l 438.29 249.40 l 435.87 248.94 l 431.43 247.47 l 425.25 246.42 l 423.01 245.91 l 419.26 245.38 l 415.14 244.23 l 410.28 243.48 l 406.62 242.69 l 399.97 241.82 l 397.88 241.21 l 395.31 240.77 l 390.22 239.48 l 382.35 238.27 l 381.57 237.97 l 380.33 237.68 l 375.34 235.90 l 370.25 234.71 l 369.10 233.82 l 365.36 231.83 l 364.67 231.32 l 364.36 231.16 l 364.45 230.94 l 365.36 229.38 l 366.57 227.89 l 366.82 227.60 l 372.01 226.02 l 372.75 225.80 l 378.00 224.04 l 379.30 223.80 l 380.33 223.58 l 386.88 222.49 l 388.00 222.31 l 395.31 220.87 l 396.32 220.73 l 397.57 220.49 l 406.09 219.49 l 410.28 218.91 l 415.98 218.28 l 424.63 217.08 l 425.25 217.00 l 425.45 216.98 l 425.79 216.93 l 436.22 215.98 l 440.23 215.54 l 446.74 214.92 l 450.59 214.47 l 455.20 213.97 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 310.10 m 452.87 309.95 l 448.46 309.39 l 446.53 307.90 l 440.23 306.20 l 439.56 306.00 l 438.72 305.84 l 434.85 304.56 l 433.25 303.94 l 430.63 303.56 l 425.25 302.64 l 424.47 302.47 l 423.18 302.28 l 417.23 300.63 l 410.28 299.57 l 408.42 299.17 l 405.10 298.72 l 400.72 297.44 l 395.31 296.51 l 392.55 295.82 l 388.27 295.17 l 385.23 294.01 l 380.33 292.82 l 378.31 292.09 l 376.25 291.61 l 374.41 290.21 l 373.81 289.60 l 371.29 288.06 l 372.84 286.28 l 374.46 284.50 l 377.02 283.71 l 380.33 282.58 l 383.70 281.74 l 386.39 280.94 l 391.71 280.09 l 395.31 279.38 l 400.49 278.62 l 406.99 277.39 l 409.20 277.13 l 410.28 276.98 l 413.49 276.63 l 419.49 276.02 l 425.25 275.26 l 429.46 274.83 l 436.80 273.83 l 439.28 273.61 l 440.23 273.50 l 442.55 273.28 l 450.14 272.63 l 455.20 272.08 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 366.81 m 453.48 366.70 l 450.16 366.29 l 447.95 364.57 l 447.95 364.46 l 442.18 362.74 l 441.67 362.39 l 440.23 362.08 l 435.62 360.28 l 428.03 359.18 l 426.95 358.78 l 425.25 358.50 l 419.88 356.90 l 410.84 355.76 l 410.28 355.67 l 410.17 355.65 l 409.99 355.63 l 408.66 355.24 l 403.59 353.66 l 399.23 353.00 l 395.31 352.33 l 394.77 352.20 l 393.93 352.07 l 391.56 351.18 l 388.91 350.03 l 382.51 348.51 l 382.11 348.09 l 380.33 346.93 l 378.76 345.33 l 378.16 344.96 l 378.52 344.53 l 380.33 342.59 l 381.58 341.70 l 381.96 341.40 l 388.37 339.75 l 391.71 338.70 l 394.49 337.84 l 394.97 337.76 l 395.31 337.70 l 396.88 337.47 l 404.40 336.45 l 410.28 335.37 l 413.21 334.98 l 417.02 334.29 l 422.79 333.70 l 425.25 333.38 l 432.04 332.67 l 433.05 332.58 l 440.23 331.68 l 443.06 331.40 l 447.92 330.73 l 453.27 330.27 l 455.20 330.06 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 423.42 m 454.40 423.38 l 452.55 423.19 l 451.34 422.28 l 451.34 420.55 l 448.07 419.64 l 446.03 418.26 l 440.23 417.01 l 438.73 416.44 l 436.20 416.08 l 431.91 414.50 l 425.25 413.41 l 423.56 412.93 l 420.31 412.53 l 416.23 411.11 l 410.28 410.07 l 408.23 409.46 l 404.90 408.97 l 401.49 407.50 l 395.31 405.99 l 394.41 405.62 l 393.50 405.41 l 392.88 404.84 l 391.48 402.76 l 390.24 401.86 l 391.36 400.92 l 394.13 398.58 l 394.46 398.30 l 394.86 398.19 l 395.31 398.05 l 402.52 396.46 l 408.53 394.74 l 409.62 394.59 l 410.28 394.47 l 412.93 394.11 l 419.36 393.35 l 425.25 392.32 l 428.38 391.93 l 432.41 391.19 l 437.99 390.66 l 440.23 390.37 l 446.22 389.77 l 448.40 389.57 l 455.20 388.72 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 195.59 m 455.20 192.04 l 455.20 188.48 l 455.20 184.92 l 455.20 181.37 l 455.20 177.81 l 455.20 174.26 l 455.20 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 252.49 m 455.20 248.94 l 455.20 245.38 l 455.20 241.82 l 455.20 238.27 l 455.20 234.71 l 455.20 231.16 l 455.20 227.60 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 309.39 m 455.20 305.84 l 455.20 302.28 l 455.20 298.72 l 455.20 295.17 l 455.20 291.61 l 455.20 288.06 l 455.20 284.50 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 366.30 m 455.18 366.30 l 455.15 366.29 l 455.13 366.28 l 455.20 362.74 l 455.20 359.18 l 455.20 355.63 l 455.20 352.07 l 455.20 348.51 l 455.20 344.96 l 455.20 341.40 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 455.20 423.20 m 455.19 423.20 l 455.17 423.19 l 455.16 423.18 l 455.16 419.65 l 455.13 419.64 l 455.09 419.61 l 455.20 416.08 l 455.20 412.53 l 455.20 408.97 l 455.20 405.41 l 455.20 401.86 l 455.20 398.30 l S % END GriPath stroke/fill %gri:set graylevel 0.0 %gri: %gri:draw axes # redraw in case whited out % gr_show_at() BEGIN 0 g 0 G 167.4 149.9 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 304.6 149.9 m (0.5) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 451.9 149.9 m (1) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 170.70 165.01 l 170.70 170.70 l 199.15 170.70 l 199.15 167.86 l 199.15 170.70 l 227.60 170.70 l 227.60 167.86 l 227.60 170.70 l 256.05 170.70 l 256.05 167.86 l 256.05 170.70 l 284.50 170.70 l 284.50 167.86 l 284.50 170.70 l 312.95 170.70 l 312.95 165.01 l 312.95 170.70 l 341.40 170.70 l 341.40 167.86 l 341.40 170.70 l 369.85 170.70 l 369.85 167.86 l 369.85 170.70 l 398.30 170.70 l 398.30 167.86 l 398.30 170.70 l 426.75 170.70 l 426.75 167.86 l 426.75 170.70 l 455.20 170.70 l 455.20 165.01 l 455.20 170.70 l 455.34 170.70 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 259.8 134.7 m (distance along cove) sh % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 455.20 m 170.70 455.20 l 170.70 460.89 l 170.70 455.20 l 199.15 455.20 l 199.15 458.05 l 199.15 455.20 l 227.60 455.20 l 227.60 458.05 l 227.60 455.20 l 256.05 455.20 l 256.05 458.05 l 256.05 455.20 l 284.50 455.20 l 284.50 458.05 l 284.50 455.20 l 312.95 455.20 l 312.95 460.89 l 312.95 455.20 l 341.40 455.20 l 341.40 458.05 l 341.40 455.20 l 369.85 455.20 l 369.85 458.05 l 369.85 455.20 l 398.30 455.20 l 398.30 458.05 l 398.30 455.20 l 426.75 455.20 l 426.75 458.05 l 426.75 455.20 l 455.20 455.20 l 455.20 460.89 l 455.20 455.20 l 455.34 455.20 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf % gr_show_at() BEGIN 0 g 0 G 152.5 166.4 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 450.9 m (81) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 165.01 170.70 l 170.70 170.70 l 170.70 455.20 l 165.01 455.20 l 170.70 455.20 l 170.70 455.20 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 139.9 301.6 m 90.00 rotate (time) sh -90.00 rotate % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 455.20 170.70 m 455.20 170.70 l 460.89 170.70 l 455.20 170.70 l 455.20 455.20 l 460.89 455.20 l 455.20 455.20 l 455.20 455.20 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:draw image palette left -1 right 21 increment 5 %^ scale 1 170.7 0 284.5 1 170.7 0 3.51235 q n % turn clipping on for image palette 170.700000 512.100000 moveto 455.200000 512.100000 lineto 455.200000 540.550000 lineto 170.700000 540.550000 lineto 170.700000 512.100000 lineto closepath W 170.421624 512.100000 455.478376 540.550000 1 512 cim A42A2AA42A2AA42A2AA42A2AA42A2AA42A2AA42A2AA42A2AA42A2AA42A2AA42A2AA42A2AA42A2A A42A2AA42A2AA42A2AA42A2AA42A2AA42A2AA42A2AA42A2AA42A2AA42A2AA42A2AA42A2A92252F 92252F92252F92252F92252F92252F92252F92252F92252F92252F92252F92252F92252F92252F 92252F92252F92252F92252F92252F92252F92252F92252F92252F922546922546922546922546 922546922546922546922546922546922546922546922546922546922546922546922546922546 922546922546922546922546922546922546922546922546922546922546922546922546922546 922546922546922546802046802046802046802046802046802046802046802046802046802046 802046802046802046802046802046802046802046802046802046802046802046802046802046 80204680204680204680205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E80205E 80205E80205E80205E80205E80205E80205E80205E80205E80205E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E 6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C5E6D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C766D1C76 6D1C766D1C766D1C765B17765B17765B17765B17765B17765B17765B17765B17765B17765B1776 5B17765B17765B17765B17765B17765B17765B17765B17765B17765B17765B17765B17765B1776 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D 5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D5B178D49128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D49128D 49128D49128D49128D49128D49128D49128D49128D4912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A54912A5 4912A54912A5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5360EA5 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD 360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD360EBD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD2409BD 2409BD2409BD2409BD2409BD2409BD2409BD2409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D42409D4 2409D42409D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D41204D4 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC1204EC 1204EC1204EC1204EC1204EC1204EC1204EC0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF 0000FF0000FF0000FF0000FF0000FF S Q % turn clipping off for image palette % gr_show_at() BEGIN 0 g 0 G 180.3 491.3 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 244.9 491.3 m (5) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 306.3 491.3 m (10) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 370.9 491.3 m (15) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 435.6 491.3 m (20) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 512.10 m 183.63 512.10 l 183.63 506.41 l 183.63 512.10 l 248.29 512.10 l 248.29 506.41 l 248.29 512.10 l 312.95 512.10 l 312.95 506.41 l 312.95 512.10 l 377.61 512.10 l 377.61 506.41 l 377.61 512.10 l 442.27 512.10 l 442.27 506.41 l 442.27 512.10 l 455.26 512.10 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 512.10 m 170.70 540.55 l 455.20 540.55 l 455.20 512.10 l S % END GriPath stroke/fill %gri:set font size 9 /Helvetica-ISOLatin1 findfont 9.00 sc sf %gri: %gri:# Title tells what method used %gri:draw title "Used `draw image colorscale \scale'" %^ scale 1 170.7 0 284.5 1 170.7 0 3.51235 % gr_show_at() BEGIN 0 g 0 G 184.7 569.0 m (Used `draw image colorscale blue 20.0 brown 0.0 increment 2.5') sh % gr_show_at() END %gri: %gri:quit showpage %%Trailer %%BoundingBox: 129 130 463 577 %%DocumentFonts: Courier Helvetica Palatino-Roman Palatino-Italic Symbol Times-Roman %%Pages: 1 gri/doc/examples/example6histogram.ps0000644000175000017500000020641113147557614016412 0ustar psgpsg%!PS-Adobe-2.0 EPSF-1.2 %%Creator: Gri2.6.0 (released 2000-Jul-26). User=kelley, commandfile=example6histogram.gri %%Title: example6histogram.ps %%CreationDate: Mon Mar 5 18:23:59 2001 %%Pages: (atend) %%BoundingBox: (atend) %%TemplateBox: 0 0 612 792 %%DocumentFonts: (atend) %%Endcomments % NOTE: The Gri postscript dictionary is being converted to the Adobe % Illustrator 3.0 dialect of PostScript, as described in the Adobe % documents stored at URL % http://www.adobe.com/Support/TechNotes.html % (as of Jan 1996, this doc is number 5007). When the conversion % is complete, the Adobe Illustrator drawing program -- and any % program compatible with AI -- will be able to edit Gri output. % % The IslandDraw (TM) program is able to read Gri output % at this time; remarkably, it can read/edit arbitrary PostScript. % % The definitions below are presented in the same order as the Adobe % manual. The stack configuration before and after is shown in curly % brackets. All the operators are listed, but only some are defined % here. Most things are faithful, except that no distinction is made % between colors for stroking and filling paths. The string 'WRONGLY' % appears with commands that are approximations. % % PDF-style abbreviations: /rg {setrgbcolor} def % {red green blue} {-} set RGB color /RG {setrgbcolor} def % {red green blue} {-} set RGB color /q {gsave} def /Q {grestore} def /W {clip} def /W* {eoclip} def % % Gri-specific abbreviations: /hsb {sethsbcolor} def % {hue saturation brightness} {-} set HSB color % % Following all try to mimic Adobe Illustrator % % Mimicking section 5.1 of Adobe manual: %A % {flag A} {-} Determine whether % following object can % be selected. Flag=1 % prevents selection; % flag=0 allows it. % Mimicking section 5.2 of Adobe manual: %u % {u} {-} start group %U % end group %q % as 'u' but first item is a clip path %Q % as 'U' but first item is a clip path % Mimicking section 5.3 of Adobe manual: /g {setgray} def % {gray g} {-} Set gray for fill % path, WRONGLY used % for stroking also. /G {setgray} def % As 'g', but for filling path. %k % Set cmyk color for filling path. %K % As 'k', but for stroking path. %x % Set cmyk custom color for filling path. %X % As 'x' but for stroking path. %p % Define pattern for filling path. %P % As 'p' but for stroking path. %O % Specify whether overprinting for fill paths %R % As 'O' but for stroking path. % Mimicking section 5.4 of Adobe manual: /d {setdash} def % {[array] phase d} {-} Set dash. /i {setflat} def % {flatness i} {-} Set flatness. /j {setlinejoin} def % {linejoin j} {-} Set line join. /J {setlinecap} def % {linecap J} {-} Set line cap. /M {setmiterlimit} def % {miterlimit M} {-} Set miter limit. /w {setlinewidth} def % {linewidth w} {-} Set line width. % Mimicking section 5.5 of Adobe manual: /m {moveto} def % {x y m} {-} Move to locn /l {lineto} def % {x y l} {-} Draw line to locn % not a smooth point. % WRONGLY, no % distinction is made % between smooth and % corner. %L % {x y L} {-} As 'l' but a corner %c % Bezier curve to smooth point. %C % As 'c' but to corner point. %v % Something else to do with Bezier. %V % %y % %Y % % Mimicking section 5.6 of Adobe manual: %N % {N} {-} As 'n' for nondrawn stuff /n {newpath} def % {n} {-} WRONGLY interpreted % as path constructor /F {fill} def % {F} {-} Fill current path. %f % {f} {-} 'F' but close first /S {stroke} def % {S} {-} Stroke current path. %s % {s} {-} 'S' but close first %B % {B} {-} As 's' but don't empty path. %b % {b} {-} As 'f' but don't empty path. %H % no-op (weird huh?) /h {closepath} def % {h} {-} Close current path %W % Used to create masks. % Mimicking section 5.7 of Adobe manual: %a % Begin text block ... %e % Similar to 'a' but ... %I % Similar to 'a' but ... %o % Similar to 'a' but ... %r % Similar to 'a' but ... %t % {len (string) t} {-} Render string. %T % End block of text % That's the end of the Illustrator stuff. Following are some Gri % definitions which provide a temporary way of handling fonts. /sf {setfont} def % {fontname sf} {-} Set font name. /sh {show} def % {(text) sh} {-} Show text. /sc {scalefont} def % {size sc} {-} Scale font. % Gri items which should be translated to Illustrator format: /rl {rlineto} def /rm {rmoveto} def % Procedures /cimdict 7 dict def /cim { cimdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def q xll yll translate xur xll sub yur yll sub scale /do cl 3 mul string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop} false 3 colorimage Q end } def /imdict 14 dict def /im { imdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def /imagemap exch def q % Until version 2.6.0 used a 'settransfer' here, but that % triggers a bug in ps2pdf xll yll translate xur xll sub yur yll sub scale /do cl string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop dup length 1 sub 0 1 3 -1 roll { 1 index exch 2 copy get imagemap exch get 255 mul cvi put } for }image Q end } bind def /frdict 5 dict def /fr { frdict begin /yt exch def /xr exch def /yb exch def /xl exch def n xl yb m xl yt l xr yt l xr yb l h F n end } def /plusdict 3 dict def /_plus { plusdict begin dup 0.5 mul /t0 exch def /t1 exch def 0 t0 rm 0 t1 neg rl t0 neg t0 rm t1 0 rl t0 neg 0 rm end } def /timesdict 3 dict def /_times { timesdict begin dup 0.353553 mul /t0 exch def 0.707106 mul /t1 exch def t0 neg t0 rm t1 dup neg rl t1 neg 0 rm t1 dup rl t0 neg dup rm end } def /boxdict 3 dict def /_box { boxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm end } def /filledboxdict 3 dict def /_filledbox { filledboxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm F end } def /diamonddict 2 dict def /_diamond { diamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm end } def /filleddiamonddict 2 dict def /_filleddiamond { filleddiamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm F end } def /triangleupdict 5 dict def /_triangleup { triangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm end } def /filledtriangleupdict 5 dict def /_filledtriangleup { filledtriangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm F end } def /trianglerightdict 5 dict def /_triangleright { trianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm end } def /filledtrianglerightdict 5 dict def /_filledtriangleright { filledtrianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm F end } def /triangledowndict 5 dict def /_triangledown { triangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm end } def /filledtriangledowndict 5 dict def /_filledtriangledown { filledtriangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm F end } def /triangleleftdict 5 dict def /_triangleleft { triangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm end } def /filledtriangleleftdict 5 dict def /_filledtriangleleft { filledtriangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm F end } def /circdict 5 dict def /_circ { circdict begin 0.5 mul /t0 exch def currentpoint /t2 exch def /t1 exch def S n t1 t2 t0 0 360 arc t1 t2 m end } def /bulldict 3 dict def /_bull { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 360 arc h F S end } def /filledhalfmoonupdict 3 dict def /_filledhalfmoonup { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 180 arc h F S end } def /filledhalfmoondowndict 3 dict def /_filledhalfmoondown { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 180 360 arc h F S end } def 1 1 scale 10.0 M 1 j /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-ISOLatin1 exch definefont pop /Courier-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Oblique-ISOLatin1 exch definefont pop /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Bold-ISOLatin1 exch definefont pop /Courier-BoldOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-BoldOblique-ISOLatin1 exch definefont pop /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-ISOLatin1 exch definefont pop /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Bold-ISOLatin1 exch definefont pop /Helvetica-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Oblique-ISOLatin1 exch definefont pop /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Roman-ISOLatin1 exch definefont pop /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Italic-ISOLatin1 exch definefont pop /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Bold-ISOLatin1 exch definefont pop /Palatino-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-BoldItalic-ISOLatin1 exch definefont pop /Symbol findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Symbol-ISOLatin1 exch definefont pop /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Roman-ISOLatin1 exch definefont pop /Times-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Italic-ISOLatin1 exch definefont pop /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Bold-ISOLatin1 exch definefont pop /Times-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-BoldItalic-ISOLatin1 exch definefont pop %%EndProlog %%Page: 1 1 /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:# Gri was invoked by user named %gri:# kelley %gri:# on host named %gri:# Intrusion.phys.ocean.dal.ca %gri:# using the command %gri:# gri -y -p example6histogram.gri %gri:# at time Mon Mar 5 18:23:59 2001. %gri:# %gri:# The user's ~/.grirc file ... %gri:# ... end of users ~/.grirc file. %gri: %gri:# Example 6 -- Plot IR image of Gulf of Maine %gri: %gri:# define characteristics of norda images %gri:\0val = "5" # 0 in image %gri:\255val = "30.5" # 255 in image %gri:.rows. = 128 %gri:.cols. = 128 %gri:.pixel_width. = 2 %gri:.km. = {rpn .cols. .pixel_width. *} %gri: %gri:# get filenames %gri:query \filename "Name image file" ("example6image.dat") %gri:query \maskname "Name mask file" ("example6mask.dat") %gri: %gri:# get data %gri:open \filename binary uchar %gri:set image range \0val \255val %gri:read image .rows. .cols. box 0 0 .km. .km. %gri:close %gri:open \maskname binary uchar %gri:read image mask .rows. .cols. %gri:close %gri: %gri:# find out what grayscale method to use %gri:query \histo "Do histogram enhancement? (yes|no)" ("yes") %gri:query \minT "T/deg for white on page? " ("10") %gri:query \maxT "T/deg for black on page? " ("15") %gri:\incT = "1" %gri: %gri:# set up scales. %gri:set x size 12.8 %gri:set y size 12.8 %gri:set x name "km" %gri:set y name "km" %gri:set x axis 0 .km. 32 %gri:set y axis 0 .km. 32 %gri: %gri:# plot image, grayscale, and histogram %gri:if {"\histo" == "yes"} %gri: set image grayscale using histogram black \maxT white \minT %gri:else %gri: set image grayscale black \maxT white \minT %gri:end if %gri:draw image %^ scale 1 170.7 0 1.4225 1 170.7 0 1.4225 % Push map onto stack, then image stuff. [ 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.9961 0.9961 0.9922 0.9922 0.9882 0.9882 0.9843 0.9804 0.9804 0.9765 0.9725 0.9647 0.9569 0.9490 0.9333 0.9255 0.9137 0.9020 0.8902 0.8706 0.8471 0.8118 0.7725 0.7098 0.6510 0.5686 0.5137 0.4235 0.3373 0.2588 0.1255 0.0902 0.0706 0.0627 0.0549 0.0510 0.0471 0.0431 0.0392 0.0314 0.0275 0.0235 0.0157 0.0078 0.0078 0.0039 0.0039 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 ] %BEGIN_IMAGE 169.266299 169.266299 536.293701 536.293701 128 128 im 1A253A251D1A0B0A0B1915161B19191D27221822191C2E142B291C4F2531221C22333A2C25262F 312E341C29242E3E3136525455503955253066271C190B25150F11180B161206180F1A13152235 3B1E2C322C353E333829202938363D27414646464343423A4243424040403D403E3E3D3A3B3832 23061E192C211A1A040404211C1F25282D150F121522221B09172C233213081C171B131117051F 222D1319282B333B312120333A251C1E2A33371F345553535240594A3438171A0404261C1D1018 110B1C22143B4740453D303F2822293D2336343C34313F3838412C464747464343424243424040 4040403F3D3D3C3C3B37332823312A2C2C351C20040825222A2A221314140919111506222E2F15 100709050B221C121805041119132525283438202D2F15332918211F3C2212232A57575448514E 261C121D270824271B1109131C2C36224F4551393E2F3937264635283733372B42433940404246 46474643414040424141404141403F3D3D3C3A383735281F2E27123936232A3023250F1C290B07 10100B06111F2E2B31251619152F27282E34233715123C0C12121B233D260C271B1C1714161C23 2829231C17222D5C5D46291D141230352C2A2E20101A190543434B51412A2D38433333263C422D 30393722404241414244464646454441403F404040404040403F3E3E3C3A38373536372B2B2634 180D302A2D12151C1821111A08141F222B33202024102222223536312E39323137641C342A1F22 240C0C131C1D24221419152329250A14262A5850312E1C171A2C2F20201E14191B0704374B4D4B 33204337373E292527483026373A30424044454645464645444242403F404140404040403F3E3A 3A3A3A2F232B322715252D0F042E2C0B10271C0C0509121315250D363740612F1D120D1C2A2B33 31332D261966341220381A0B0816041F181F2929210F262B1210222D294A6031201B0B18402422 2C1904081E0A1B2C474D4D092C383D3D401D2A284535303B3A4043404346454646454543424140 3E42414140403F3E3C3C3B3E3D3B383234361E2B372C2C2C33302E1E212528091116101A1D1B33 57634F32390F1A1C2C262F34333D271A13042735391D11091F0F1F411C1F362F2832231811181B 1B2A3D231B20131F35223330181F1D3842234247443F232B404243412B2A26403C403D3F434340 454546464545444343423C39413F3E403E3F3D3C3C3D3C3A3820323735303C30162B242B262625 2926240F0F171117102240646139383B28331A2D292C2C3037311819151015130D11212D242E31 2723343B363411101C481324272214111D101A1C2939222813214744422F48373A213043444441 402F2C3D4142404345474748484747444443434342414140403F3E3F3E3D3E3C3D3D3B38343638 28223522182B241E2A22212D2C172F19130C1C304031344C2A2C3F363F25122E33373147302625 12090A0A161B1D26322723201127222E2F1D20180A0C26272117101C0D1524302F2A312A3B462C 04042E203840464744434241344646454242424546474849474745434344424140403E403F3C3F 3E3C3D3B3C3C3B38303A3C1418381B153035322422171A2715262F1513181A272B1F302331393D 1F2942150D23132522292E260D11261C122A28241823181E33142E262E1F2612111D201C1B0C19 18182523252D2C334649311C042D45474747474432404041454440454345464848494947444343 4443414040403F403F3D3E3E3F3E3E403E3F3F363F3D2335333637262A30242627222B3727262C 211A111B30212228344E43232B5B4E290A172C292D321C11122A4065213D3310210F202615221E 231E1E2222201D1813221F19132B26222E382D48462F403540464A4A4948443145454244424545 444647494A49484645444343414140403F3E3E403F3E3F3F40404040403F3F4037363F112F3E25 282E3A20312E2958261F2B1F1A1C24383E3D222F384F4432414633131F2E302A2E300A1E291827 200C0F1C0F0A0A0B1C361A2615141C192313221A28302213201B271F2F264442483B3F2C3F4048 3F444344494543424344464547494A49494745454342414240403F404040404040404140414041 4140404040393D2D333A1627362E14152531571F272E1C1B282623263C44332E4F4A4A37575416 1E30371B1F28281D1929351F150C29231112071C4022282619222522151A1A221F1C18171D2634 1C3A494548454638361922324045454945434346484746484A4A49474645434241404040404040 414241424141414141414141414040403E3C33371819041A16042F161C22452435181616292614 2B2F554B4C434F4D4E4B411525301E1F272C1C3E39261D182F161D290414263027222D2E21221B 141D1B1C1523231B2D29303236474945333D424A484A44494B4B47454548494948484949494848 45434341404040404141424243454542424241403F3E3F3F403F3F3E3F17261804040404042F29 091B2C1B232519203C253228273C57454F5253594F4A222F2C401A292C3131424B4B241A290726 1613142C402331361719202020231A1324221D1D251D2B2E46493104042D4B4B4B494349454545 38484A494848494747474745444343414141404142434343444544424141403C3E3E3D3C3A3D39 3236381404040F0A0F2D2A11231C2120241B292F312222223D2B4F5853595D48563B2F45606039 271D26393E34271C2013281515233040202923221F2119251F15141D1F2822211F27273B463704 414F4D4C4B3B40424446494A474B49494746474846464645434442414142424245434344454642 4240403F3E3E3C3B393A321F393207183323151C3132151D231F1B262F1D22362E321B552F272E 50595F605B5952343C263128212C2B5F5F483E30041B2F1B12372B19212E20172B172022171A25 2222262120202C3B4A4F4F504F4E3F283741474A494A4A4B4A4A46464849484747474544414241 42434346494544444646424140403F403F3E3D3B392D2F32202F2B1B3615201A231A191F1D2523 3921222C27472234292A263A406059626663474028314F3129253C5052375C4C0F23242F2E2E11 15261A241C201B1B1613232A2F342724313C3B4B5051504F4D411D3F464B4A494A4A48473A1A35 4747474746464443414242434344454A4745434545414245444142413F3B2E381D34382F363609 362C220F1329312F1D25232F181C2A224B313D27212E3635363C6666272F2E2E323E25173B4217 312F29381A1D35262C221C21422928181D1C18142226282F3D4147483C4A4F4F504F4E4A383C4B 4B4C4B4A4A4B47474947474746474645444546464746474648494B494645474542434544454441 3D3D36343A3D37223A2A04293015091D29342A18142823131A262B2D5C241D22303532383A5631 271E212B31394043242B2B333833412212333732231B37382A302A1615131620192E494D434B4A 43474F50504F4F474B4C4B4B4B4942494B4B4A49484647464545444545454748494A4A4A4A4A4B 48464748444345464645443D3D3B393C3B3A37363317042204161926282C2E15110C152535171D 2423282225353D393E4030222F312E243F41262D26202F3725342C2933312D323411352B2C1919 21192D2A25394F4D4A4C4B4D505050504F4F4E4C4B4B4B483F474A4B4A49484745454545444444 4446494A4B4C4B4A494A4B49464649484846474746423834373B3D40403C332C23040407131F24 21392A20181B21252F2252161F1417273635362B333E2D3243392636372F17141019302C202C26 3233262E2A3128202F181F301A2D423A2F504E4C4C4C5050505050504F4D4D4B4A4B4A4A4A4A4B 4A48474745444444454447494B4B4C4C4B4B4B4B4A4B4A494A4A4949484947473E373D3F3E3E34 3E3B25041C14040C3339283022244935232D191C221F22140C1B2A2D223E2A22322C1B302B353B 2A1E27142D1A2D302B2A222935291F1B1B2916271924191522283E42514F4E4D4D515050505050 4E4D4C4C4B4C4A4A494949484745454545444545484A4C4E4E4D4B4A4A4A494948494A4A4B4949 4949484745403F3F3F3F3F39391B252B0D0404302C22242231351C20151222181712171F27272F 292622312C251C1E222933462F36244822322C11172B2E2C28252D21191C1614142311212E232A 504B504F5051505150504F4E4C4B4A4B4B4A494848474646474545474748494A4C4F504F4F4C48 4B4B494A4B4B4B4B4A4A49494949474540403E3E3D3E3E3A2E0F0404040418212017222D301C23 261418261D20201B27312A282E2328171E1D11262920242D3D3A332D21170B1A222C2528173226 22200D0D0C191A28241B244B4B4F50515050504F504F4D4B4B4B4B4B4A46454545464849494948 4B4A4C4D4F4F4F4F4F4B47494A4A4A4B4B4A4A4949494A4A484745403F3E3E3E3C33371F242304 04042C2E36222E242513202922203135271F28202C3D241420291F1D301B1C2B221D2E3530312B 3228071320342225161E192E1A191B122018171E22394C4D4F5051504F504F504D4B4A4A4B4A4A 48474545464748484A4A4C4C4D4E4F5050504E4F4B474849494A4C4B49484749484A4948464440 403C3C3D3916150404060404043836342A28332D2B1F1B2D2F363F3E222424252F301D2F1A1C21 2031363B191D2A3624302931100411173033221B11100B10212B2B1B191826474C4D4E4F505050 4F4F4F504C4B4B4A4B4A494846454547494A4A4C4C4E4F4F4F50504F4D4C4D4C484749494A4A48 484746464748494746453F3F3B3635222E28152E22040F1B3A42313C3B2A30171318252C323832 191F14253239221F412A25252E333122261C222F31241B0B040A1A36401B20130B141E2522301F 222336504F4E4F4F504F4E4E4F4F504B4C4B4A4A4A4A4847464647474A4B4D4E4E4F50504E4D4D 4A4B4B4C4B494948474948474747484648494946433E2E142C312F3C383632341F0C073B43261D 2B2B3926140B25353B37221B0F22242E282819281C21251F2C262C332822302C26100404081B2A 334A200A161815262A2230292E4450504F4E4E4D4E4E4E4E4F4D4B4C4B494A4B4A494746454747 464B4E4F4F50504E4B4B4A494B4B4A494948474647474747474748484847453E3A3C3C3E3D3D3C 3B3428090C040439483321171A14261814191F361B15151C15271A121413110F181620142C3440 3E1D1F161E0D05080414222F1F131011191B292F2D48434C5050504E4E4D4B4D4D4E4E4E4E4D4D 4B494A4B4A48464545464C4D4B5050504F4E4B4B4A494A4A494948494847474747474848484748 474544413F403E3E3D3C3D3B3A35231504041D45331C282A251612141A1B2F2815121C13141922 151711160409111A313B3C48222318220B0C0B09222A230F09161A1223263B4B474D4E5050504E 4E4C4B4B4E4E4E4D4E4D4C4B48494A4948464344464A4A4E5051504D4C4C4A4B49494949484848 48474848484848474747464544423F3F403D3E3D3C3C363C3B3A36251D1B2A3125422E2F20141F 1C11161B080D17122012161F28231C1F151C2B36302E2D2A221D2110091726221F0D121028221D 212F424D4F505050504F4E4E4D4B4B4D4E4E4D4E4D4B4948484846444543444748494F50504D4C 4C4B4B4A4948494847484848484848484748474646454343403F40403F3C3B3B363D3D3D3D3E40 38191E271C301F2B222E2422131623181014221C0D18212B3228302F343233382C3B262021271A 14232E1D1C090F15201820252D4D4E505151504F4D4D4D4C4C4B4D4E4E4D4D4C49484847474646 45434648494B4E50504D4D4D4C4C4B4847474747484848484848494847474545434242403E3E3E 3F3D3B3A3B3A3E3F3F3F402E36331F222D2E191525201F221A2B1D0D0D1F160C232E3337231F39 39362D282A34331E212B1B26251B1B11130C0D19141A2B3B4F50515150504F4E4E4D4D4C4B4E4F 4E4E4D4C4746464747464545444747494D4F50504D4E4D4C4D4A48474847474848494948484847 474645434143433F3F3F3F3F3D3D3D3D3B3F40403E40223D43403A20321D0C1722191F1C302314 0D2019161C232E303720554D37312934302821281F1C1B2722150C150625212E25314C50515252 51504F4E4E4D4D4A4C4D4F4D4D4D4D48464747484746454546484A4C50504F4D4E4D4C4D4B494A 4A484748484A49494948474544444442414242403E3F3D3C3D3F3F3C3E40414242323740402213 1D1F14212B4D2D19221F1F272E170D131F2326222831403336322D312D2B29222F2C2B222C1811 1922323C3635435151535251504F4E4D4D4B4A4D4E4E4D4B4D4B49474747494848484748484A4D 4F504F4E4E4E4D4D4C4A4A494949494A4A4A494948474644454643424241403F3E3D3E3E403F3F 40403E43424137282738141B2A182B3238282E2C121A32311516272A2B411F30222C39393A373A 2A2E2D2A2A302216241D212623363937324052525352504F4E4E4D4B4A4B4D4D4D4B4949484746 474849494A4948494B4B4E4F504F4E4E4D4C4B4B4C4B4A4A494949494A4A484744444648474541 4242403F3E3D3D4040414140424343424435252E301B1D242529202C24281F0B20231910193733 3456331F26323A403D3D473B282F302C2D30252C2A29262F403C3C334F52525351504E4D4E4D4B 4B4B4D4C4A4A47474846464749494B4C4B4C4B4C4D4E50504F4D4E4D4D4C4C4D4C4B4B4A4A4A4B 494A4A48464546464949434242413F404040404040414242434646472127242723302A2C261C33 1F182A15241A0B1315223B414932333F4639413E3F333A292026222F271D1D2F2017293F3D3A3E 5052525452504D494C4D4C4B4D4B4B4A494747494746494A4B4D4D4D4D4D4F5050504F4F4E4F4D 4D4B4D4D4D4B4B4B4A4B4A4A4B4B4948474847494A494341404040414342424241424344464849 2A3434232F2625251F18161B233125281D10141426243D402B353D3A3326363B2F33242028232A 28342321181B22342931505252525352504E4A4A4D4B4B4C4B4B4A49484748474649494C4D4D4B 4C4E50505050504F504E4D4C4C4D4D4D4D4B4B4A4B4B4D4D4C4A49494A494A4A4A454142384444 4544454344464546484949322B3A382E19232517192A2C2E2B212A18171E1F101D342F2C2E2E30 2F2635343830301E292C252939212122191D3133384F52535353524F4E4A4B4D4B494B4B494A4A 484749484748494C4D4C4C4E4F50505050504E4F4D4B4B4C4D4D4D4D4C4D4C4D4D4D4E4E4D4B4B 4A4A494A4B4947424345474846474647474748494A4B242C2E3B272C171125332438322C25271A 2322231329382C202D473937272E3034332E252527305951492320191B222C485253535353504E 4D4A4C4D4C4A4A494A4A4A4846484949484C4D4C4B4C4F50505051504E4D4C4B4B4A4B4D4D4D4C 4D4D4D4E4D4D4E4F4E4D4C4A4A4A4A4A4B49464443464949484849494A494A4C4B27223E322E2B 1F302332242F362A272F1929212B2B28342C1F314A4E4F33383E3229292C2824285B262A3C3A30 2222324F5352525352504E4C4B4B4C4C4B494A4B4A4A484747494B4C4D4C4B4B4F505050505250 4F4E4D4C4B4B4B4C4C4C4B4C4D4D4E4E4D4E4E4F4E4C4B4A4A4B4A4A4A48454646484A4A494A4B 4B4B4B4B4B33312C393733373A232C2C2B1F3A2F2A2525232F2F35252F1C2C3A4C503933362D2B 221F29274E5936362C4336412D3A535352535350504D4C4B4B4B4A494A4B4B4A4B4746454B4B4C 4B4B4A4C505051505050504E4D4E4B4B4B4C4C4C4B4B4C4D4D4D4D4D4D4D4D4B4C4B4B4A4B4C4B 4A4A47464647494A4A4A4B4A4B4B4B4B37261A2E3640272822282E162030292B2623221B2A3439 292226323A383935353B2D1C1D2D39676A5F37343D4F413E505454535352504E4C4C4B4B4A4949 4B4C4C4B4B4A47474A4A4A4A4B4B4F5050505150504E4D4D4D4A4B4C4C4C4D4C4C4C4C4C4D4D4D 4B4B4A4B4B4B4B4B4C4C4B4A4B494948474949494B4B4B4B4B4A4A3A2E2F3538361F1F1B262120 1F27272222242B36263339322F253A31342C352D2A22221B2033383247333037374F5052525454 5351504D4D4C4B4B4A4A494B4C4D4B4B4A4A4A4A49494A4C4D505050505050504F4D4D4D4B4B4B 4B4B4D4D4D4E4D4D4E4D4C4B4A4B4B4B4B4C4B4B4B4B4B4B4B4A49494A4A494A4B4A4B49494927 252F34362C18231928261D2E2928322E2C233D26122134333F313031282E292922182A2621352A 2C3036303451505353535452514F4E4C4B4B4B4C4B4C4E4E4D4B4B4A49494B4B4B4C4D4F504F50 505050504E4D4D4C4D4A4A4B4B4C4C4C4D4D4D4D4C4C4A4A4A4B4B4B4C4C4A4B4B494A4A4B494A 4A4A494A4A4949484848242B33402A23221F1C1F282E242E2B392F30262527172830333029282B 27222828311F2A272221181F2A282F4051525353535352504F4C4A4A4A4C4C4D4D4D4D4D4C4B4B 49494A4D4B4D4E4F50505050504F4E4E4D4C4C4E4A4A4B4C4C4C4C4C4D4D4C4B4B494A4A4B4A4A 4B4B4B4A4A4A4B4A4A4A494A4A494A494849494948412C352A2C282C22292C3C373B3233403736 4E4D3923153134382C27282C262F2428252F32262A22252B303A5152535453525453514F494949 494B4C4B4C4B4A4C4C4B494A49494B4B4B4F50504E504F4F4F4D4E4C4C4C4C4A4B4C4C4D4D4D4D 4D4D4C4B4A494948484A4A4B4B4B4A494A4949484A4A4A4A4A4A48484B4A4A492D261F33333325 22202C3A454328293F342C5B3B361C252A313622222C27232A24252E302E282D2727252E505153 535352505453514E4C48494A4B4C4B4A494A4B4B4A49494A4B4B4B4B4D504F4F504F4F4F4E4E4D 4C4B4D4B4B4C4B4C4D4D4C4B4C4A4B4B48494948474A49494A494A4A49494949494A4949494847 4B4A4A481C252D252D2225393E2B3B403D3727332F1F3222181C2D2F312E283332322F2A252C36 311D232728272F314D5253525253525452504D4B484A4A4B4B4B4A494B4C4C4C4A48484B4B4B4D 4D4E4E4F504E4E4F4F4E4D4D4D4D4C4B4C4C4C4D4D4B4B4B4B4B4A4948474846494746484A4A4A 494949494A4949494948484A4B4A492E343D391D261F2B4032353D402722312F1D211E222C3234 323632312E3A3B43262A26383226263331344B5252535251525253524F4D4948484B4A4A494849 4A4C4D4D4A474748494B4D4E4E5050504D4E4F4F4E4C4D4E4D4D4D4D4C4C4D4D4C4B4B4C4B4947 47474747464546494A4A494947494849494949484848494A4A4920293440381B3E36433F433738 22212025251D222C2F322E323A4B36383540573629242C372B3230353750525251515151525250 4F4B4A4847494A49494B4A4B4D4D4D4B484647494D4F4E4F504F4B4D4D4E4E4E4D4D4D4D4D4D4C 4C4C4D4D4D4B4B4B4A494747474747464545494A494946464647484847474848494948494A1C2C 3F3B3D1F263945463D2B1B172120191F20291D2C32282C333E4433313639302D28303433313937 48525251515151515252504E4B4948474849494C4C4C4C4C4E4E4D4947464B4E4D4E4F4F4E4D4E 4D4F4E4D4D4D4D4E4D4C4B4B4C4D4E4D4C4B4A4B494A4949474645454849494847414245474848 484849494949484A4B3F33403E2E383F3C3C3E3A38221C1C221920282C222223383F423F423639 3A5C342C2A2938393A403F47525151515251515151504D4B4A484748494A4A4B4D4D4D4E4F4D4A 464A4B4C4D4F4E4E4E4E4E4E4F4E4C4E4E4E4C4C4C4B4B4C4D4E4E4D4B4B4B4B4B4A4949464546 4748494745414243464849474A4949494949494A3B4238293C3A363C2F28212E2124281F1D2423 2326252B3237553333343E352B2C33452D3B3C3C3E3C4D5251525252515151504F4D4B4A474948 49484B4D4D4D4E4E4E4B49484B4B4D4D4D4D4F4E4E4E4E4F4E4E4E4D4D4C4C4D4D4D4C4D4D4E4D 4C4C4C4C484A4A4949474747474847444042444548484A4A4A49484948494B3A363A3032312B20 372B1D141F232D1D1C2520212526302B37342934393E35292E315532383A4039363A5151505251 515050504E4D4B49484948484A4D4D4D4E4E4D4E4C49494A4C4C4D4D4E4E4E4E4D4E4F4E4E4E4D 4D4E4D4D4E4D4D4D4E4F4D4D4C4B4B4C4B4949463F4647464746444245454548494B4B4A484849 4A4A4B3C31342D303E2A2824211F233730271B192223212228272B2E4025263A3A33372C353531 48504E35384251505051515050504F4E4B4A4846474A4B4E4E4D4E4D4D4D4D4D4B4A4B4C4C4D4D 4E4E4E4E4E4F4E4F4F4E4E4E4D4D4C4C4C4E4E4E504E4E4D4D4B414A4B4A444744484747454444 454645484A4B4B494949494B4B4B3B3F3A1D353E322D28331E263B2F201E1D2323221F2B2C3834 2A2F2B2C2E2E342D3033333E353450614D52515150505150504F4E4C494746474B4F4E4D4E4D4C 4D4D4D4C4B4A4D4D4D4D4E4F4E4F4F4F4F4F50504F4F4E4F4E4D4B4B4C4C4C4F4F4E4E4D4C4B4A 4949484648484645444546464546474A4B4B4A49494B4C4C4C4039382A34433C33333D212B2935 372520313E1C2A2E464B3F2D2833372B323B3E422F3636251D2F313B52525251505150504F4D4B 4A48494E4F4F4E4D4B4A4A4B4D4D4C4B494D4E4E4E4F4F4E4F4F4F4F50504F504F4E4E4E4E4D4C 4C4B4C4C4D4E4D4C4B494A484A494848484644444444464748494A4B4B4B4B4B4C4C4C4C382533 3F3336223241423F2B212D2C2C252D2B28283237312F2723203A33364134392D4335282E2F3839 535352525050504F4E4E4C4B49494E4E4D4A4B4B4A49494E4E4D4B494D4E4E4E504F4F4F504F50 505050504F4F4F4F4E4D4C4B4C4C4B4B4A494B4947494749484A494846444343434648494A4B4C 4A4B4B4C4D4C4B4B282E313F2A3A2B3B45484636352F2E3933262D3B302C20302C2C3223312D3A 314130312C2D262E303C5049535351505050504F4E4D4C4B494D4D4A4A4B4B4B4A4A4A4D4D4D4B 4D4D4F4F504E4F50504F50505050505050504F4E4E4C4C4C4B4A4A494849484748464648494949 46444342434648494B4B4B4B4C4C4C4D4D4B4B2934323B353C2C323642312F252B292A2E2B393A 2E232940322C303330363E3A292F40312F2F333136514E54535351505051504F4E4E4D4B4E4D4B 4B4B4C4C4A4A49494D4D4B4D4E4F4F4F4E4F5050504F505050505050504F4F4D4B4B4A4A4A4848 474647464745454849484846454443434548494A4B4B4B4C4C4C4D4B4B4B223136363839382428 2E342225232B3329222F4034253C363728393B382F2C402C2F3B393623342F3B56405453545453 535252524F4F4E4E4E4E4B4B4B4B4B4A4948494A4E4D4D4E4D4D4F4E505050505050505050504F 504F4E4D4A4A4A4B4A4849484746464544454948474645454444464747494A4A4B4B4B4D4D4D4C 4A4B2E313836343F3432211D282A22251F23312130432A23252C2B38354740355636333D37312C 32383A323D4E55555755555A59585553504F4E4F4E4C4C4A4A4847484747494E4F4D4D4D4D4F4E 4F50504F5050505050504E4F4F4E4B4B4A49494A49484847464646454848454646454646464748 48484A4A4B4B4C4C4D4C4B4B4C2C323936242D2637292B1B2723221920293239382728232A272D 2A31303136333A3F372A2B252D3A4040394E58595753505656565651504F4F4D4C4C4947484647 494A4A4C4D4C4C4E4E4F4F4E4E4F4F4F505051504E4D4E4E4D4B4B4A4A4A494A49484745464647 474746454646464747474849494B4A4A4B4B4C4C4C4D4B4D36333F3F332B2431372623261A1D28 2524332E2B242E242337342C28343135312A282C312D2A303335292E4A505C5C36415054545552 504F4E4D4B4A4948474749494C4A4B4E4C4E4E4F4F4F4E4D4E5050505051504C4D4E4E4D4C4A49 4A4A4A4A4A494848484847484645464545454746494848494A49494A4B4B4D4C4C4C4D423D4040 3C36221F2E33382622282F2D2C2637293B403F282F3B412A31363C382A29292A39333025242726 4C3938453A41485253555350504E4D4B4A494947474A4A4A4C4C4D4D4D4E4E4F4E4D4E4F505050 50515045464F4E4C4C4A4A4A4B4B4B4B4949484949494947464646474847474848494949494B4A 4B4B4C4C4E4E4E37383E41403D2A222C2528302A25282D2D332B37323839262D242A272534342C 24222E2832412A2E2E2A322C2E3041393C4C4F51545350504F4D4C49494949494B4A494947494A 4D4E4E4E4D4E4E4F504F505151514F4E4F4E4C4B4B4A4A4B4B4B4B4A4949494949494746474748 494747484949494A4A4B4C4D4D4D4D4E4E4E363D393D384B362C25231C212C202C2C2D2F2F362C 2E2A2C29242223323A283541312731362C312D304A322E3F4146464150505051525050504D4D49 494A4A4A4C4B48474748484D4C4E4E4E4E4F4F4F5050505151504E4E4E4D4C4C4B4B4B4B4C4B4B 49494949494948484849494948484849494A4B4B4D4D4E4E4E4D4D4D4E2B3E362A32372C1F291F 20222C32292C2E2A3233292D302C302B25232B2D312E3B30253039353F35323D2D30363C484F4E 50505050525050504E4B4B494A4C4B4A4949474648494B4D4E4F4E4E4F4F4F505051515151504D 4D4C4D4D4B4B4B4C4C4B4C4C4B4A4A494A49494949494A4A4B48494B4C4C4D4E4E4D4C4E4D4D4D 4E26303C34392E2D282B221729272B41242F292229252E2D32322A2B28312B2F26262C34383932 383C2F313C3747464E505050505050515150504F4D4B494B4B4C49494848484A4D4D4E4E4E4E4F 4F504F50505151515050504F4D4E4D4C4B4B4D4C4C4C4C4B4B49494A4A4A4B4B4A4A4B4B4A4A4D 4D4D4D4E4D4D4D4E4E4E4D4E242E3736393E4C2D261839312C3326212C242629282732342F292D 272829212E313836313B353B3B3A42454D505051505050505050505250504F4D4B494C4C4C4849 49494A4C4E4D4E4E4E4E4E4F4F4F5050505050505150504F504D4C4B4C4D4C4B4C4B4B4A4A494A 4A494B4C4E4E4F4E4C4B4D4D4D4D4D4B4C4D4E4F4E4E4E2B35353D39393E332B33292F2C36262D 28232925272A3241302A2E29282C242B33423A3A3A39464A4C4D4C515252545352515050505052 504F504D4D4B4C4D4948484A4B4B4C4C4C4D4D4D4E4E4F4F4F5050505050515050505050504E4C 4C4C4C4A4B4B4B4B4A49484B4A4B4B4E4E4F4E4C4C4D4D4D4D4C4D4C4C4F4F4E4D4D382B414734 3F443823282B284030312F3B282D2E2D251F2E2A302E312936492F3F4042393A404E5551515254 5555545252525150505050504F4F4D4E4B4D4D4845484B4B4C4D4D4C4D4D4D4D4E4E4F4F505050 50505050505050504F4E4D4D4C4B4A4B4C4B4B4A4949494B4B4B4D4D4F4E4B4D4D4D4C4C4C4C4C 4D4D4E4D4D4B37303B423930242222272C333B39282C3B292A25302D20222E2E323A2F3538362C 483C423B3E484250525456555454525252515050504F4E4E4E4D4E4D4D4C4A46464B4B4D4E4D4D 4E4E4E4E4D4E4F4E504F505150505050505050504E4E4D4C4A4B4D4D4D4B4B4B49494A4A4B4B4C 4F4E4B4D4D4C4C4C4C4C4C4C4D4E4D4D4C3D3B44403C1F1F1F182C4E3A3133262B2E2923262E2D 1F2A2F353A3A36353C403C3A4E4A4A49445255565655545453525151515150504F4E4F4E4F4D4C 4D4D494746474A4C4D4D4E4D4E4E4E4D4E4E4E4F4F505050505050505050504E4E4D4C4B4D4D4D 4E4D4C4B4A4A4949494B4B4F4D4B4C4C4C4C4C4C4D4D4C4D4E4E4D4C32263D3E32362E1A192E35 3F3825372B2D212A2B301C282B3331363D354740453C3840494D54515655565555545453515150 5050504F4E4D4F4F4F4E4C4E4D49484847474A4B4E4E4E4E4F4E4E4D4D4D4F4F504F5050505051 5050504F4F4E4B4C4D4E4E4E4F4E4B4B4B4A4949494B4F4D4C4C4C4D4D4F4E4D4D4D4D4D4E4D4C 3A1B2537312E1C1C2B3835323D382C292E2B2328313D2C2E3C39354346454C4243413D48525656 555555555455545351505150504F4F4E4E4E4F504E4E4E4C4A48484747494B4D4C4C4E4E4E4E4D 4E4D4F4F4F4F5050505050505050504F4E4C4D4D4E4E4E4F4E4D4D4B4B4A4A49494D4D4D4C4E4E 4E4E4D4D4D4D4D4D4E4D4D372F2231362A2525312B323A232B27362E2C2A332848303E39393F4B 4940484740434A54525256565655545555535250505050504F4F4E4F4E4E4D4E4D4D4D4B494949 49494C4D4D4E4F4E4C4C4D4E4F4F4F4F4F5050505050505050504F4E4D4D4D4C4E4E50504E4D4D 4C4B4A494A4C4F4E4E4E4E4F4E4E4D4D4D4D4D4D4D4D363620404B40412A362E3932282A2A312F 251E332229275E3C36404E45454344484A525657565657565555535352525050504F504E4E4F4E 4D4C4B4E4D4D4C4B4A49474A48484D504F504F4D4D4E4E4E4F4F4F50504F50505050504F50504F 4E4D4D4E4E4F50504F4E4D4D4D4C4B4B4B4E4F4F4E4E4F4E4E4D4D4D4E4E4E4E4F2B2B2E203C6D 4E2E31363538322E38322E2B22382F232B3E3D3B3E44464B4C4A4D4F4955595857575755545352 535252515050504E4E4E4F4E4D4C4D4D4D4D4B4B4B4A4A46454A4D4E504F4E4E4E4D4F4F4E5050 505050515050504F4F4F4F4E4D4E505050504F4F4E4D4D4D4D4C4B4A4C4F4F4F4F4F4E4E4E4D4D 4E4F4F4F5022253F585E3537322E3A2F434335331A232E3D252A25353E483B4040474E47505259 56565859585758565351535452525150504E4E4E4F50504F4F4E4D4D4D4C4A4C4A4A494745474F 504E4F4F4E4E4F4F505050505051515050504F4F504F4E4E5050505050504F4F4D4D4D4C4C4C4B 4C4C4F4F4F4F4F4D4E4D4D4E4F50504F2A26364840344038372C343A3C3F403B422733322C4038 493B3B41494953645960545C56595A59585B5A53525454525150504F4D4D4D4D5050504E4D4D4C 4D4B494B4B494C4947474F505050504F4F4F5050504F4F50505150505050504F4F4F5050505050 50504F4F4E4E4D4D4D4D4D4D4C4C4D4E4F4E4E4E4D4E4E4F50504E3F35353832313E40372A2C44 405D3A3A3E312E343B2E403B393A3E504950504D585F5C5C5C59585B5C5C56545453515050504E 4F4E4F4C4E4F504E4D4B4D4D4C4B4C4B4B4B4D4D474A505050505050505050504F505050515050 5050504F4F4F4F505050505050504F4F4F4F4F4E4E4D4D4D4D4C4D4D4D4E4E4E4E4E4F504F4E3B 38403F3A373C3F372625303342362D313A32302B30403D393A3E423E4D4B4D5F5F605D5F5C5C5E 5D5C575254545251504E4F4F504F4E4D4D504F4D4C4C4B4B4B4B4B4D4C4D4C4B4B504F4F4F4F50 5050505050505051515150505050504E4F4E505050504F4E4D4D4D4E4E4E4F4F4E4E4E4E4D4E4E 4E4E4F4E4D4F4F50504E42574036283F3F3F2D3B2A33354D384E3939383D34433537383E34333E 433A4D5B5566615C605D5E5C5C575453505251504F4E5050504E4E4E4F4E4F4C4B4B4B4B4A4C4C 4B4A4B4D4C504F504F50504F50505050505050515050505050504F4E4E504F4E4D4D4D4C4C4C4C 4D4F4F4F4F4F4F4F4F4F4F4F4F4F4E4D4F50504F4E45444040353B3F4122242F2E3133383A4344 304B31322F2833312A3A423D41474A5E6A6C63635B5C605C5A5753504E5150504D4E504F4E4F4E 4E504E4B4D4D4D4C4A4D4D4B4B4A4E4D4B4B4D4D4F4F4F505050505050505050505050504F4E4D 4E4E4D4C4C4B4C4B4C4C4D4D4D4D4D4E4F4F4F504F4F4F4F4E4D4C4F50504F4E4643433C36363A 42502922232B3D3435342F2724242A2227232B353935403A3843474A516650664C5B585F5C5851 5050504F4E4D4F4E4D4F504F4E4F4E4E4C4D4F4D4A4B494B494C4D4B4B4A4A4F4F4F4F50505050 51505050505150504F4D4D4E4D4C4D4C4B4A4A4C4C4D4D4D4D4C4C4D4F50504F4F4F4E4E4D4E50 50505050453C3D3D5237222831373C35353037483B2C39302732222C40343B3E3B363132434949 57474540343C3F5C555B55525050504F4E4F4D4F4F50505054535352504F4F4D4A4A48494A4A4B 4B494B4B4D4F505050515050505150515151514F4D4D4D4D4D4E4C4B4B4B4D4D4D4D4E4D4C4D4D 4D4F50504F4E4E4E4E4E5050504F5040392B3A2C2B28212237353E233C3334342B2E2024293431 3F3D3837233A373E474B45434234252D2C3E3E415F58565050504E4D4E4F505050525757575756 544F504E4B494B4B4A4A4A4B4B4B4A4D504F5050505050505050515151504F4E4D4D4D4E4E4C4B 4C4D4E4E4E4F4F4D4E4E4D4D4D4E4F4E4E4F4E4E4F5050505050392C2B3532262F1F3129233C2F 3B2F25392C22231D222F333C332F30293E434646483D3D4F3335333A3B3D40485F5752504E4F50 5050505051555859595A585551504F4F4A4A494B4B4A4A4B4C4C4C4F4F4F505050505050505050 5050504F4E4E4E4E4D4D4D4D4E4E4F4F4E4F4F504E4E4D4D4D4E4D4D4E4E4E4F4F505050503B30 3130231A28302C2825313349312F322B27221D2329233D382D182E343C45553D403C3C3C362C31 3D3D45405C5F5C52505251515050505154595A59595856534E5150504E4B4A4A4A4A4B4C4C4B4B 4F4F4F4F5050515050505050504F4E4E4E4E4E4E4E4E4E4E4E4F4F4F505050504F4F4F4E4E4D4D 4E4E4F4E4E4F50505030303736303030342B1D292C36313826212F1B221C1A272C2C302B243B30 2F3638393552353347334035333A3A585E5E5A585554535151515454575A595A59575550515152 50504F4F504F4C4D4B4B4A4D4D4F505051505150505050504F4F4F4D4E4E4F4F4F4F4F4F4F4F50 4F505050505050504F4E4D4E4E4E4F4E4F505050292D372B2F291C2F2B1C26293F413728232E21 2222221C302F373032322C36353734364330322F3739313331404B5F5D5A585553525252555557 5B5A5A59595956525050504F4E4D4E4D50504F4E4C4B4B4D4E4F4F505050505050504F4F4F4F4E 4E4E4F4F4F4F4F50504F505050505050515150504F4F4E4E4F4F4F4F4F505025263131383E3533 221C25323D2F3826221F322025222227293B3D2F352D3B353B2E3338353829222D2C2C333C4A4D 5D5C5957545356585656595B5A58595A575855555250504F4E4D4E4C4D4F4F4F4D4C4D4C4E4E50 5050505050504F4F4F4F4F4F4F4F4F4F4F505050505050505050505050505050504F4E4E4F4F4F 505050293C2E3B36314432211928352F2C3E222A30292127272222233F3F39333033393F363D3B 3A312529362A2F2E3542425E5C5A5856565758565A5B5A5A585C5C5857585555565453504F4F4F 4F4D4D4F4C4C4D4D4C4E505050505050504F4F4E4F505050505050505050505050504F4F505050 5051515150504F504F50505050502D333A3E262E35302A1F2340261B2926222E342B2B25303835 304A3839303240403A3E3A2F2E2D252D26212F34352F235C5D5C5858575757595A5A59595C5B59 5656565657565556544E4F4E4E4E4E4D4D4D4F4E4D5050505050505050504F4F504F4F504F5050 504F4F5050504F4F4F505050505151515150505050505150502B2B333B34282433291E20323A23 2420312F31313F2037333B332E313B37343F433E372A38292D26471F272C25363B3A575D5C5A59 585759595959585A5C5C594D3B3339545655565554504F4E4E4E4D4C4D4F4F4E4D505050505051 5050504F5050504F4F4F5050504F4F505050504F50505050505151515151505050515050302F2F 35322F312C3225263836252B2A23243D3F47333A3F3A3225323C373137343C2F2C23292E3B4736 302E3337385A5F5E5C5B5958595959595756595C5C595236464C603652545454544F4D4E4D4D4B 4C4E4E4E4E5050515051515050504F505050504F505050505050505050504F4F50505151515151 51505150515150506F33363038353F3135223831302227252C22373838373E353F35292F303533 29312E2B25251F263240352F333C484066615F5C59585759595A5856595A5C5D5C5C445E5E613F 2538545453504E4D4D4C4A4C4C4E4E4F505051505051515050504F4F5050505050505050505050 504F4F4E50505152515251515151515150504F342B19412E212A3A3B2B2A2D2B3B272A272D1D37 394641352E31222A312B2827232623242A1B442D3A4B2D2A3544496D685D5D5957595A5A59585A 5A5C5C5D5F5F605D63625C392C4F555351504D4C4C4A4A494D4E4F4E4E50505051525050505050 5050505050504F50505050504F4F4F50505052515151515151515150504F1F152B45363C25332E 252C2C36402F2A3E3958353B42362E272B25262A261D1F221F282A2442312D5F2131272C4E6960 57585C5B5A5C5B5A57585B5C5C5C5E5E5E5E6465615D4D2E2C555250504E4B4A494A494E4F4E4D 4C4F5251515251505050505050505050504F505050505050504F4E4E5051515151515151515150 4F4F221F242E293A1A4021221E2D29303335433242324041352D293232222E221C242B1D282E28 24221F1A1C2630323D6662605B5A5B595C5B59585C5C5C5C5C5D5D5D5E63636161632C2A505350 4F4E4C49484A494F4D4C4B4B4F505252525150505050505050505050505051525150505050504F 4F505152525151515150504F4F1F323727302D2725252923232D312B31313B32313E4032222524 39293A2529304F2C332B2222201B1F232C373C3B4568645D5D5B5B5C5C5C5C5C5C5C5D5D5D5D5C 5F61625E665A1C2B4F52504F4E4D48494B494B4D4C4B4C4E505152525250505151505050505050 505051515150505050504F4F5050515151515150504F504F25282C363D4B373B271B29372F333A 303138332F3458422A352C2528294F2E26303029201E20121D1D272A2C2C3F4F46575C565F5F5C 5D5C5E5C5C5C5C5B5A5E5D5E6166676A542C2C4136504D4C4B49494C4B4A4D4C4B4D4E50505352 5251505251515050505050505050515251504F5050504F50505050515150504F4F4F4E1F1D224B 3A4D362C302D32322E363B3B383F38384038382F2925202328302D2A232F27241F212023222634 2E3836403A241F494E5F5E5C5D5C5C5C5B5C5C5C5C5E5E6166696C6E645A3625514E4A4A49484C 4B4B4C4B4B4D4E4E505254535250505050505051505050504E505251504F505050504F50505050 50504F4E4F4E4E1E1C2C2D2B34332C3137373F41363B433C3A403C292D302D281C23232A2F372B 2527221F2522232F2F33322D23321B3F1D1340505D5E5D5C5C5C5B5A5C5D5E5E5D5F6063646F70 6771652B4D4D4B4949464B4B4C4B4A4A4A4D4D505153545452505050504F505050504F4E505251 5050504F4E505050504E5050504F4F4D4D4D2124272B343E413A37303F40463C37404747474035 28282023283C2927333A2B252323312F342F2B2B292C2B2E2C303322152840525E5C5C5C5C595B 5C5D5D5F5E5F6162616B7472765931444F4C4B4946484A4A484A4A494B4F505052535454525151 5050505050504D4D4F525050504F4F4E4D504F4F4E4E504F4F4E4D4C4B22272230403A38383A33 3F3836363B4B3F464B43342B312125223C2B2F2A22232A23422F3425242D252B2B2E282B0A1707 301F37305C5C5A5C5C5B5C5C5D5F605F616361646C746F7048354850504B4846464A4A49494949 494E50505151535352535251515050504E4D4D4F515050504F4D4D4D4D4E4F4E4D50504F4E4D4C 4D2D37302F383A3840373132372A2E3D3C45464F4337222F211B21282423302522252230453552 262822222E45310F0912044B402A395C5C5A585A5B5C5C5C5F6060636361646C736C706E3E3250 4D4B4747464949494B4B4B50504F50504F50505252525151504F4E4C4B4C4E5050504F4F4D4E4F 4E4F4D4F4E4E4E4F4E4D4D4C1F2F2B3834272E3D4139463A47373B3C454D4D414A2F251D20312C 2B212C291C2221322C777657232E23292D2D20200B06131C2C595D5B59585C5B5A5C6061616165 636266676A6F716F5C46504D4B49494849494B4C4D504F4F4E4F4F4E4D4F5052525150504E4D4B 4B4C4D504F4E4E4E4D4E4F4F4F4D4D4D4D4B4D4B4B4B4C212D26353225333D433D562D423D3841 494F52443133282022222124324522212A2526405D4955222B28232E2C1704041B4C2B355D5C5C 5A5A59585C5D6161636466626567686A6F736A4551504F4C4A4A4848494B4D4F4E4F4F4D4E4D4C 4D5052535150504F4E4B4A4A4D4F4E4E4E4E4D4D4D4F504F4D4E4D4D4D4B4B4A4A492030232D33 23342E314240223E4042424F4D5A4533312820221F22292E3E502D2B332037675C5E36221A2F31 252210172E131044355C5C5C5A58585C5E60616266666666686A6E70714A5149504D4B4C494847 4A494F4F4F4F4E4A44464B4E4F52525050504E4D4C4A4A4D4F4E4E4E4E4E4D4E5050504E4F4E4D 4C4B4B4B4B4B262E2B28292E23335051322D374144414555514137332E2525201F2D3F56292A29 20182633393656292B272728292830151F1935383362605A595B5B5D606063626668696E6B6B6F 40404A46464E4D4B494947494E504E4F4E4A4748474C4F50504F4E4F4E4E4D4B4B4C4E4E4E4F4E 4D4E4E4F50515050504F4E4C4C4B4B4A4B23311C212230313722426B30333643433E404B5C3F58 44262C2D21315144322F1E2E27262B2C2B4A372F3233313F353438512B30312C32405C5B5C5D5D 606165666668555A39373C41413D6448504B4A494948494E4F4F504D4B47464C50504E4E4D4D4E 4D4D4B4A4B4D4E4E4F4F4E4D4E4D4D4F4F505050504F4E4D4D4C4C4D222C1A1E152C2C362F2B2B 26373839403F3E4E66494C4B302A383130593B2C230B2322253136282526222231335C354D3D36 25171E2B38352D335653496062635848403C3B483938273458715A4E4B494848474A4D4F4E4D4A 48464A4D4D4D4B494A4B4E4D4B4A494C4D4B4E4F504E4D4E4D4D4D4E4E5050504E4E4F4D4B4B50 2222231D23292E232129323539364140434641666C4F504030633A3C45462E3F432C2D20292622 28221B172A3671684963332B1D070D19342A2F233654606066382C3532462B5F59373455636452 4E49484C49484A49494B4A494C4B4B4B47454749474A4A494A4B4D4B4B4D4F504E4E4E4E4E4E4E 50505050504F4D4D4C4D4F231B181E222C2F2F404130373A373B4B414137506C6A4B405C676D51 4A743E384B292E1A31202E1A1E2A2D454E63746F6D3D2733060A1A3339302D2C3B393A363C3843 2B2C2F2E282E3847485951504B4A4E4A4B4949434A4A4C4A4A44434645454848484946494B4C4A 4A4B4F4F4E4E4E4E4E4F5050515050504F4E4D4D50502F240C181F22393433392A343F3D43466C 4B44686C6C4F3F4E735A4C504E323A2E23352E37272E2924292D3C726A70685638301E1229482D 232335393A3B372731322E4041342E292D3C47464D504E4B4B4C4A4B4B4742424B4B4846494747 474647484948494B4C4A4A494B4D4F4E4E4E4F4F50505050505050504E4E505051312F11133124 34372A381F2F3E3E4043566F6C6B6B6657405E74403F5C662C331A1D291D3D362F2E273A355772 727069572B3028222257282B4A2C3052383B293039463A373B584066574F51524F4F4B4A494848 48494442484748494A4845484847484848494A4C4A494A4A4C4B4E4F4F50505051505050505050 4E5051525229281B1D222D33332B271D29383D4641404C6C645D6E675F6E5F364F4D4539213C2E 2D383F463636385462616F70716F39292D23302A2B2E2F2F2B323A3A40393442676F666D6E6E6E 656150514E4D4A4848484748494642444748494A474649494748484A494A4B4B494B4A4C4B4E50 504F50515150505050505050515252512521272A2422252E2B1F2238303540373A406B6A62686D 4B43552F45443B33222634253547606A585649716F6F70716F512F331C4226142427573862774D 746E716E6D6D716F6F6F6E5C5452504E4C4B4A494847474745424448474A4D4849494A48474A49 4B4C4B4B4A4B4B4B4B4F4F5050505050505050514F4F5052525251211723281B2A232930222034 363E423E395B6B6965496B39636A3B285D40392B312829395155704970706F6F6F71716A343833 2E1D22202F5C635C787777776D726E6A6B6D6F71706D675151504D4C4B4B4A4847464643424449 484A4E494A4A4A4847454A4D4E4E4D4B4C4D4C4B4F4F5050515151515051504F50515251515117 282C2D191D242D3828243C35423A3934546A6B4E4351396C643129292D3A3733332343426D6F60 576F6F6E6F71706F403B3E29291E225E717675737574757372706C6B6E6F716F6C66504F4F4D4B 4B4B4A494746454343434A484D4D4A4B49494946484E4F4F4F4E4D4B4D4D4E4F4E505151515252 52515050505151525251202F5B321B12232C34322E26373B4139666B6A5A686649344855353222 2E3E282B2A253C696D6F6E6D6C6F6D6F6F717051412934375A3A6A7372717272717170706F6B6B 6D6F6F6C6B6253524F4D4B4B4A4949474645434343474B4E4D4C4A494748454A494B50504F4F4B 4C4D4F4D4F51515152535452515050505152525252232D312C1C10293A2938341F29333D333769 5E50685136494D5A3126363C3A5933313A29586D6D6B6D6D6D6E6F706F604543505F5C61507272 716F6F70706F6F6F6A68686A6E6867645E545352514D4A4949484746454343444448484D4B4B4C 4C464944464C4F524F4D4B4D4E4E4D4F5051515252535251505050505150505023332E33291B22 3A293A272B282F332F30614C5064592A375D6536382F5D3E542E33463F656A6C6B6B6C6D6E6F6F 6A5D68656B6D6F6F7071726F717070706F6C6A6866666A6A66636155545151504F4A4A49484847 4644444442414443464B4C4D4B4745484A515251504E4F4F4D4F4F505150515354545151505050 51515151 %END_IMAGE % gr_show_at() BEGIN 0 g 0 G 167.4 149.9 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 209.5 149.9 m (32) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 255.0 149.9 m (64) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 300.6 149.9 m (96) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 342.7 149.9 m (128) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 388.3 149.9 m (160) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 433.8 149.9 m (192) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 479.3 149.9 m (224) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 524.8 149.9 m (256) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 170.70 165.01 l 170.70 170.70 l 216.22 170.70 l 216.22 165.01 l 216.22 170.70 l 261.74 170.70 l 261.74 165.01 l 261.74 170.70 l 307.26 170.70 l 307.26 165.01 l 307.26 170.70 l 352.78 170.70 l 352.78 165.01 l 352.78 170.70 l 398.30 170.70 l 398.30 165.01 l 398.30 170.70 l 443.82 170.70 l 443.82 165.01 l 443.82 170.70 l 489.34 170.70 l 489.34 165.01 l 489.34 170.70 l 534.86 170.70 l 534.86 165.01 l 534.86 170.70 l 534.91 170.70 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 344.8 134.7 m (km) sh % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 534.86 m 170.70 534.86 l 170.70 540.55 l 170.70 534.86 l 216.22 534.86 l 216.22 540.55 l 216.22 534.86 l 261.74 534.86 l 261.74 540.55 l 261.74 534.86 l 307.26 534.86 l 307.26 540.55 l 307.26 534.86 l 352.78 534.86 l 352.78 540.55 l 352.78 534.86 l 398.30 534.86 l 398.30 540.55 l 398.30 534.86 l 443.82 534.86 l 443.82 540.55 l 443.82 534.86 l 489.34 534.86 l 489.34 540.55 l 489.34 534.86 l 534.86 534.86 l 534.86 540.55 l 534.86 534.86 l 534.91 534.86 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf % gr_show_at() BEGIN 0 g 0 G 152.5 166.4 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 211.9 m (32) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 257.4 m (64) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 302.9 m (96) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 139.1 348.5 m (128) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 139.1 394.0 m (160) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 139.1 439.5 m (192) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 139.1 485.0 m (224) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 139.1 530.5 m (256) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 165.01 170.70 l 170.70 170.70 l 170.70 216.22 l 165.01 216.22 l 170.70 216.22 l 170.70 261.74 l 165.01 261.74 l 170.70 261.74 l 170.70 307.26 l 165.01 307.26 l 170.70 307.26 l 170.70 352.78 l 165.01 352.78 l 170.70 352.78 l 170.70 398.30 l 165.01 398.30 l 170.70 398.30 l 170.70 443.82 l 165.01 443.82 l 170.70 443.82 l 170.70 489.34 l 165.01 489.34 l 170.70 489.34 l 170.70 534.86 l 165.01 534.86 l 170.70 534.86 l 170.70 534.86 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 133.2 344.8 m 90.00 rotate (km) sh -90.00 rotate % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 534.86 170.70 m 534.86 170.70 l 540.55 170.70 l 534.86 170.70 l 534.86 216.22 l 540.55 216.22 l 534.86 216.22 l 534.86 261.74 l 540.55 261.74 l 534.86 261.74 l 534.86 307.26 l 540.55 307.26 l 534.86 307.26 l 534.86 352.78 l 540.55 352.78 l 534.86 352.78 l 534.86 398.30 l 540.55 398.30 l 534.86 398.30 l 534.86 443.82 l 540.55 443.82 l 534.86 443.82 l 534.86 489.34 l 540.55 489.34 l 534.86 489.34 l 534.86 534.86 l 540.55 534.86 l 534.86 534.86 l 534.86 534.86 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:draw image palette left \minT right \maxT increment \incT %^ scale 1 170.7 0 1.4225 1 170.7 0 1.4225 0 g 0 G q n % turn clipping on for image palette 170.700000 591.760000 moveto 534.860000 591.760000 lineto 534.860000 620.210000 lineto 170.700000 620.210000 lineto 170.700000 591.760000 lineto closepath W % Push map onto stack, then image stuff. [ 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.9961 0.9961 0.9922 0.9922 0.9882 0.9882 0.9843 0.9804 0.9804 0.9765 0.9725 0.9647 0.9569 0.9490 0.9333 0.9255 0.9137 0.9020 0.8902 0.8706 0.8471 0.8118 0.7725 0.7098 0.6510 0.5686 0.5137 0.4235 0.3373 0.2588 0.1255 0.0902 0.0706 0.0627 0.0549 0.0510 0.0471 0.0431 0.0392 0.0314 0.0275 0.0235 0.0157 0.0078 0.0078 0.0039 0.0039 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 ] 170.343679 591.760000 535.216321 620.210000 1 512 im 323232323232333333333333333333333434343434343434343435353535353535353535363636 36363636363636373737373737373737373738383838383838383838393939393939393939393A 3A3A3A3A3A3A3A3A3A3B3B3B3B3B3B3B3B3B3B3B3C3C3C3C3C3C3C3C3C3C3D3D3D3D3D3D3D3D3D 3D3E3E3E3E3E3E3E3E3E3E3F3F3F3F3F3F3F3F3F3F404040404040404040404041414141414141 414141424242424242424242424343434343434343434344444444444444444444444545454545 454545454546464646464646464646474747474747474747474848484848484848484849494949 494949494949494A4A4A4A4A4A4A4A4A4A4B4B4B4B4B4B4B4B4B4B4C4C4C4C4C4C4C4C4C4C4D4D 4D4D4D4D4D4D4D4D4D4E4E4E4E4E4E4E4E4E4E4F4F4F4F4F4F4F4F4F4F50505050505050505050 515151515151515151515252525252525252525252535353535353535353535454545454545454 545455555555555555555555565656565656565656565657575757575757575757585858585858 58585858595959595959595959595A5A5A5A5A5A5A5A5A5A5B5B5B5B5B5B5B5B5B5B5B5C5C5C5C 5C5C5C5C5C5C5D5D5D5D5D5D5D5D5D5D5E5E5E5E5E5E5E5E5E5E5F5F5F5F5F5F5F5F5F5F5F6060 606060606060606061616161616161616161626262626262626262626363636363636363636364 6464646464 Q % turn clipping off for image palette % gr_show_at() BEGIN 0 g 0 G 164.0 570.9 m (10) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 236.8 570.9 m (11) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 309.7 570.9 m (12) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 382.5 570.9 m (13) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 455.3 570.9 m (14) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 528.2 570.9 m (15) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 591.76 m 170.70 591.76 l 170.70 586.07 l 170.70 591.76 l 243.53 591.76 l 243.53 586.07 l 243.53 591.76 l 316.36 591.76 l 316.36 586.07 l 316.36 591.76 l 389.20 591.76 l 389.20 586.07 l 389.20 591.76 l 462.03 591.76 l 462.03 586.07 l 462.03 591.76 l 534.86 591.76 l 534.86 586.07 l 534.86 591.76 l 534.93 591.76 l S % END GriPath stroke/fill 0.369 w % test 0 g 0 G 1.0 i 0 J 1 j 0.369 w 10.0 M [] 0 d 170.70 591.76 m 170.70 620.21 l 534.86 620.21 l 534.86 591.76 l 170.70 591.76 l S % END GriPath stroke/fill %gri:draw image histogram %^ scale 1 170.7 0 1.4225 1 170.7 0 1.4225 % gr_show_at() BEGIN 0 g 0 G 167.4 642.1 m (5) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 224.7 642.1 m (10) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 285.4 642.1 m (15) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 346.1 642.1 m (20) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 406.8 642.1 m (25) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 467.5 642.1 m (30) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 528.2 642.1 m (35) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 662.88 m 170.70 662.88 l 170.70 657.20 l 170.70 662.88 l 231.39 662.88 l 231.39 657.20 l 231.39 662.88 l 292.09 662.88 l 292.09 657.20 l 292.09 662.88 l 352.78 662.88 l 352.78 657.20 l 352.78 662.88 l 413.47 662.88 l 413.47 657.20 l 413.47 662.88 l 474.17 662.88 l 474.17 657.20 l 474.17 662.88 l 534.86 662.88 l 534.86 657.20 l 534.86 662.88 l 534.92 662.88 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 135.1 658.6 m () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (1) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (0) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh 0.0 5.4 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh (\255) sh () sh /Helvetica-ISOLatin1 findfont 9.00 sc sf (4) sh /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 -5.4 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 135.1 676.3 m () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (1) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (0) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh 0.0 5.4 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh (\255) sh () sh /Helvetica-ISOLatin1 findfont 9.00 sc sf (3) sh /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 -5.4 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 135.1 694.1 m () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (1) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (0) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh 0.0 5.4 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh (\255) sh () sh /Helvetica-ISOLatin1 findfont 9.00 sc sf (2) sh /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 -5.4 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 135.1 711.9 m () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (1) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (0) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh 0.0 5.4 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh (\255) sh () sh /Helvetica-ISOLatin1 findfont 9.00 sc sf (1) sh /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 -5.4 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 152.5 729.7 m (1) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 662.74 m 170.70 662.88 l 165.01 662.88 l 170.70 662.88 l 170.70 668.24 l 167.86 668.24 l 170.70 668.24 l 170.70 671.37 l 167.86 671.37 l 170.70 671.37 l 170.70 673.59 l 167.86 673.59 l 170.70 673.59 l 170.70 675.31 l 167.86 675.31 l 170.70 675.31 l 170.70 676.72 l 167.86 676.72 l 170.70 676.72 l 170.70 677.91 l 167.86 677.91 l 170.70 677.91 l 170.70 678.94 l 167.86 678.94 l 170.70 678.94 l 170.70 679.85 l 167.86 679.85 l 170.70 679.85 l 170.70 680.67 l 165.01 680.67 l 170.70 680.67 l 170.70 686.02 l 167.86 686.02 l 170.70 686.02 l 170.70 689.15 l 167.86 689.15 l 170.70 689.15 l 170.70 691.37 l 167.86 691.37 l 170.70 691.37 l 170.70 693.09 l 167.86 693.09 l 170.70 693.09 l 170.70 694.50 l 167.86 694.50 l 170.70 694.50 l 170.70 695.69 l 167.86 695.69 l 170.70 695.69 l 170.70 696.72 l 167.86 696.72 l 170.70 696.72 l 170.70 697.63 l 167.86 697.63 l 170.70 697.63 l 170.70 698.45 l 165.01 698.45 l 170.70 698.45 l 170.70 703.80 l 167.86 703.80 l 170.70 703.80 l 170.70 706.93 l 167.86 706.93 l 170.70 706.93 l 170.70 709.15 l 167.86 709.15 l 170.70 709.15 l 170.70 710.88 l 167.86 710.88 l 170.70 710.88 l 170.70 712.28 l 167.86 712.28 l 170.70 712.28 l 170.70 713.47 l 167.86 713.47 l 170.70 713.47 l 170.70 714.51 l 167.86 714.51 l 170.70 714.51 l 170.70 715.42 l 167.86 715.42 l 170.70 715.42 l 170.70 716.23 l 165.01 716.23 l 170.70 716.23 l 170.70 721.58 l 167.86 721.58 l 170.70 721.58 l 170.70 724.71 l 167.86 724.71 l 170.70 724.71 l 170.70 726.93 l 167.86 726.93 l 170.70 726.93 l 170.70 728.66 l 167.86 728.66 l 170.70 728.66 l 170.70 730.07 l 167.86 730.07 l 170.70 730.07 l 170.70 731.26 l 167.86 731.26 l 170.70 731.26 l 170.70 732.29 l 167.86 732.29 l 170.70 732.29 l 170.70 733.20 l 167.86 733.20 l 170.70 733.20 l 170.70 734.01 l 165.01 734.01 l 170.70 734.01 l 170.70 734.01 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 662.88 m 170.70 734.01 l 534.86 734.01 l 534.86 662.88 l 170.70 662.88 m 170.70 662.88 l 171.91 662.88 l 173.13 662.88 l 174.34 662.88 l 175.56 692.95 l 176.77 662.88 l 177.98 671.49 l 179.20 675.46 l 180.41 668.33 l 181.62 671.49 l 182.84 671.49 l 184.05 668.33 l 185.27 673.72 l 186.48 671.49 l 187.69 662.88 l 188.91 676.87 l 190.12 662.88 l 191.34 668.33 l 192.55 668.33 l 193.76 662.88 l 194.98 676.87 l 196.19 680.01 l 197.41 675.46 l 198.62 671.49 l 199.83 678.06 l 201.05 673.72 l 202.26 675.46 l 203.47 676.87 l 204.69 675.46 l 205.90 673.72 l 207.12 675.46 l 208.33 675.46 l 209.54 678.06 l 210.76 671.49 l 211.97 682.86 l 213.19 682.24 l 214.40 678.06 l 215.61 676.87 l 216.83 680.01 l 218.04 673.72 l 219.25 679.10 l 220.47 668.33 l 221.68 679.10 l 222.90 682.24 l 224.11 684.93 l 225.32 680.83 l 226.54 683.43 l 227.75 680.01 l 228.97 684.46 l 230.18 680.01 l 231.39 683.96 l 232.61 682.86 l 233.82 683.96 l 235.03 682.24 l 236.25 687.91 l 237.46 688.79 l 238.68 688.51 l 239.89 685.79 l 241.10 690.06 l 242.32 690.29 l 243.53 692.10 l 244.75 693.86 l 245.96 695.30 l 247.17 696.80 l 248.39 702.01 l 249.60 697.55 l 250.82 698.93 l 252.03 699.07 l 253.24 699.22 l 254.46 702.81 l 255.67 704.89 l 256.88 707.58 l 258.10 708.81 l 259.31 712.05 l 260.53 712.08 l 261.74 714.19 l 262.95 711.16 l 264.17 715.13 l 265.38 714.52 l 266.60 714.01 l 267.81 718.19 l 269.02 707.29 l 270.24 703.33 l 271.45 697.81 l 272.66 695.64 l 273.88 693.11 l 275.09 691.74 l 276.31 690.51 l 277.52 692.10 l 278.73 693.42 l 279.95 692.28 l 281.16 689.06 l 282.38 698.47 l 283.59 691.35 l 284.80 689.32 l 286.02 686.56 l 287.23 683.96 l 288.45 687.27 l 289.66 682.24 l 290.87 682.86 l 292.09 681.56 l 293.30 679.10 l 294.51 685.79 l 295.73 679.10 l 296.94 682.24 l 298.16 676.87 l 299.37 684.46 l 300.58 684.46 l 301.80 683.43 l 303.01 686.19 l 304.23 684.93 l 305.44 691.35 l 306.65 684.46 l 307.87 683.96 l 309.08 682.24 l 310.29 675.46 l 311.51 671.49 l 312.72 673.72 l 313.94 668.33 l 315.15 671.49 l 316.36 662.88 l 317.58 662.88 l 318.79 662.88 l 320.01 662.88 l 321.22 662.88 l 322.43 662.88 l 323.65 662.88 l 324.86 662.88 l 326.07 662.88 l 327.29 662.88 l 328.50 662.88 l 329.72 662.88 l 330.93 662.88 l 332.14 662.88 l 333.36 662.88 l 334.57 662.88 l 335.79 662.88 l 337.00 662.88 l 338.21 662.88 l 339.43 662.88 l 340.64 662.88 l 341.86 662.88 l 343.07 662.88 l 344.28 662.88 l 345.50 662.88 l 346.71 662.88 l 347.92 662.88 l 349.14 662.88 l 350.35 662.88 l 351.57 662.88 l 352.78 662.88 l 353.99 662.88 l 355.21 662.88 l 356.42 662.88 l 357.64 662.88 l 358.85 662.88 l 360.06 662.88 l 361.28 662.88 l 362.49 662.88 l 363.70 662.88 l 364.92 662.88 l 366.13 662.88 l 367.35 662.88 l 368.56 662.88 l 369.77 662.88 l 370.99 662.88 l 372.20 662.88 l 373.42 662.88 l 374.63 662.88 l 375.84 662.88 l 377.06 662.88 l 378.27 662.88 l 379.49 662.88 l 380.70 662.88 l 381.91 662.88 l 383.13 662.88 l 384.34 662.88 l 385.55 662.88 l 386.77 662.88 l 387.98 662.88 l 389.20 662.88 l 390.41 662.88 l 391.62 662.88 l 392.84 662.88 l 394.05 662.88 l 395.27 662.88 l 396.48 662.88 l 397.69 662.88 l 398.91 662.88 l 400.12 662.88 l 401.33 662.88 l 402.55 662.88 l 403.76 662.88 l 404.98 662.88 l 406.19 662.88 l 407.40 662.88 l 408.62 662.88 l 409.83 662.88 l 411.05 662.88 l 412.26 662.88 l 413.47 662.88 l 414.69 662.88 l 415.90 662.88 l 417.11 662.88 l 418.33 662.88 l 419.54 662.88 l 420.76 662.88 l 421.97 662.88 l 423.18 662.88 l 424.40 662.88 l 425.61 662.88 l 426.83 662.88 l 428.04 662.88 l 429.25 662.88 l 430.47 662.88 l 431.68 662.88 l 432.90 662.88 l 434.11 662.88 l 435.32 662.88 l 436.54 662.88 l 437.75 662.88 l 438.96 662.88 l 440.18 662.88 l 441.39 662.88 l 442.61 662.88 l 443.82 662.88 l 445.03 662.88 l 446.25 662.88 l 447.46 662.88 l 448.68 662.88 l 449.89 662.88 l 451.10 662.88 l 452.32 662.88 l 453.53 662.88 l 454.74 662.88 l 455.96 662.88 l 457.17 662.88 l 458.39 662.88 l 459.60 662.88 l 460.81 662.88 l 462.03 662.88 l 463.24 662.88 l 464.46 662.88 l 465.67 662.88 l 466.88 662.88 l 468.10 662.88 l 469.31 662.88 l 470.53 662.88 l 471.74 662.88 l 472.95 662.88 l 474.17 662.88 l 475.38 662.88 l 476.59 662.88 l 477.81 662.88 l 479.02 662.88 l 480.24 662.88 l S % END GriPath stroke/fill %gri:if {"\histo" == "yes"} %gri: draw title "Example 6: grayscale histogram enhanced" %^ scale 1 170.7 0 1.4225 1 170.7 0 1.4225 % gr_show_at() BEGIN 0 g 0 G 239.0 762.5 m (Example 6: grayscale histogram enhanced) sh % gr_show_at() END %gri:else %gri: draw title "Example 6: grayscale linear \minT to \maxT" %gri:end if %gri:quit showpage %%Trailer %%BoundingBox: 123 130 547 773 %%DocumentFonts: Courier Helvetica Palatino-Roman Palatino-Italic Symbol Times-Roman %%Pages: 1 gri/doc/examples/example10.gri0000644000175000017500000000144513147557614014706 0ustar psgpsg# Example 10 -- Draw image plot of flushing of dye out of cove if !..publication.. draw time stamp end if \file = "example10.dat" query \contours "Superimpose contours? (yes|no)" ("yes") query \file "Input file name " ("\file") open \file read line \header read \D read .nx. read .ny. set x name "distance along cove" set y name "time" set x grid 0 1 /.nx. set x axis 0 1 0.5 0.1 set y grid 0 .ny. / .ny. set y axis 0 .ny. read grid data * * .ny. .nx. set image range 0 20 set image grayscale black 20 white 0 increment 5 convert grid to image draw image if {"\contours" == "yes"} set graylevel 1.0 draw contour 0 20 1 unlabelled set graylevel 0.0 end if draw axes draw image palette left -1 right 21 increment 5 draw title "Example 10 -- file=\file header=`\header'" gri/doc/examples/example5.gri0000644000175000017500000000105513147557614014627 0ustar psgpsg# Example 5 - Contouring ungridded data # Data from figure # 5 of Koch et al., 1983, J. Climate Appl. Met., # volume 22, pages 1487-1503. open example5.dat read columns x y z close set x size 12 set x axis 0 12 2 set y size 10 set y axis 0 10 2 draw axes set line width symbol 0.2 set symbol size 0.2 draw symbol bullet set font size 8 draw values set x grid 0 12 0.25 set y grid 0 10 0.25 # Use default method (Barnes) convert columns to grid set font size 10 draw contour 0 40 2 set font size 12 draw title "Example 5 -- wind (Fig5 Koch et al, 1983)" gri/doc/examples/example11.dat0000644000175000017500000002274613147557614014705 0ustar psgpsg 1.9530046e+03 5.7088000e+03 -1.1512386e+05 1.9531026e+03 3.0052000e+03 -9.8263319e+04 1.9532984e+03 1.0404600e+04 -6.8197536e+04 1.9535160e+03 7.2741000e+03 -4.0154877e+04 1.9537772e+03 -4.6656400e+04 -1.3334872e+04 1.9538479e+03 -6.7574000e+04 -7.2619921e+03 1.9540601e+03 -8.3795900e+04 8.1344390e+03 1.9543594e+03 -6.6008800e+04 2.3235682e+04 1.9544736e+03 -8.8634000e+04 2.7146940e+04 1.9546858e+03 -8.9914600e+04 3.1952752e+04 1.9548436e+03 -7.9527000e+04 3.3617911e+04 1.9551918e+03 -7.5400400e+04 3.2228915e+04 1.9553169e+03 -6.8570100e+04 3.0223040e+04 1.9554584e+03 -6.4016600e+04 2.7112062e+04 1.9555672e+03 -2.6877200e+04 2.4158715e+04 1.9557413e+03 -2.0900700e+04 1.8516360e+04 1.9558120e+03 2.0365400e+04 1.5929062e+04 1.9559426e+03 3.7014100e+04 1.0747384e+04 1.9560569e+03 4.2990600e+04 5.8190492e+03 1.9562092e+03 4.1709900e+04 -1.2592779e+03 1.9562690e+03 3.2602900e+04 -4.1823574e+03 1.9563071e+03 1.8800100e+04 -6.0807711e+03 1.9563126e+03 7.2741000e+03 -6.3543241e+03 1.9563942e+03 -3.2559000e+03 -1.0524178e+04 1.9565356e+03 -7.2402000e+03 -1.8022639e+04 1.9565955e+03 -2.0046900e+04 -2.1286251e+04 1.9566009e+03 -1.4070400e+04 -2.1585398e+04 1.9566934e+03 -1.2540000e+02 -2.6727894e+04 1.9568131e+03 1.8373200e+04 -3.3525099e+04 1.9570199e+03 3.0610800e+04 -4.5553183e+04 1.9571124e+03 3.6871800e+04 -5.1016402e+04 1.9571504e+03 1.6096500e+04 -5.3275786e+04 1.9572157e+03 -4.0990000e+02 -5.7158532e+04 1.9574388e+03 -4.3525900e+04 -7.0457979e+04 1.9575041e+03 -6.8285500e+04 -7.4342544e+04 1.9575966e+03 -8.5076500e+04 -7.9825424e+04 1.9576564e+03 -9.3756600e+04 -8.3355661e+04 1.9577544e+03 -8.9487700e+04 -8.9093502e+04 1.9578577e+03 -9.4752700e+04 -9.5085464e+04 1.9579611e+03 -9.0910700e+04 -1.0099657e+05 1.9579937e+03 -8.1803700e+04 -1.0284418e+05 1.9581134e+03 -8.1234500e+04 -1.0953113e+05 1.9583419e+03 -7.0562300e+04 -1.2185567e+05 1.9583964e+03 -6.0032300e+04 -1.2469331e+05 1.9585269e+03 -4.6656400e+04 -1.3133457e+05 1.9586412e+03 -4.1960600e+04 -1.3693634e+05 1.9587881e+03 -5.4482700e+04 -1.4382879e+05 1.9588806e+03 -6.6151100e+04 -1.4797851e+05 1.9589513e+03 -7.6254100e+04 -1.5104801e+05 1.9590492e+03 -8.7495600e+04 -1.5514414e+05 1.9590492e+03 -9.7029500e+04 -1.5514414e+05 1.9590873e+03 -1.0770200e+05 -1.5668751e+05 1.9590928e+03 -1.1353600e+05 -1.5690570e+05 1.9592886e+03 -1.0058700e+05 -1.6436611e+05 1.9595063e+03 -9.2333700e+04 -1.7171847e+05 1.9595498e+03 -9.0341500e+04 -1.7306581e+05 1.9595824e+03 -9.5179600e+04 -1.7404880e+05 1.9595879e+03 -1.0400200e+05 -1.7421030e+05 1.9596586e+03 -1.1097500e+05 -1.7624962e+05 1.9597293e+03 -1.1894300e+05 -1.7817565e+05 1.9597293e+03 -1.3872200e+05 -1.7817565e+05 1.9598327e+03 -1.7216200e+05 -1.8078378e+05 1.9600775e+03 -2.1243200e+05 -1.8596030e+05 1.9602734e+03 -2.5398300e+05 -1.8906551e+05 1.9604747e+03 -2.8827600e+05 -1.9127854e+05 1.9606107e+03 -3.0051400e+05 -1.9220636e+05 1.9607739e+03 -3.0065600e+05 -1.9271226e+05 1.9609045e+03 -3.4263400e+05 -1.9263906e+05 1.9610297e+03 -3.4434100e+05 -1.9217068e+05 1.9611711e+03 -3.5387500e+05 -1.9117354e+05 1.9613235e+03 -3.4405700e+05 -1.8954805e+05 1.9615030e+03 -3.4135300e+05 -1.8690518e+05 1.9615900e+03 -3.1744700e+05 -1.8534380e+05 1.9617914e+03 -2.9026800e+05 -1.8104376e+05 1.9619219e+03 -2.8030800e+05 -1.7774848e+05 1.9620416e+03 -2.7703500e+05 -1.7438523e+05 1.9620852e+03 -2.7120100e+05 -1.7308219e+05 1.9621559e+03 -2.7177000e+05 -1.7087493e+05 1.9623844e+03 -2.3263800e+05 -1.6299930e+05 1.9625258e+03 -2.3093100e+05 -1.5757069e+05 1.9626238e+03 -2.1157800e+05 -1.5357303e+05 1.9627707e+03 -2.0745200e+05 -1.4722079e+05 1.9631679e+03 -1.5750600e+05 -1.2803242e+05 1.9632930e+03 -1.6846200e+05 -1.2141927e+05 1.9636847e+03 -9.0483800e+04 -9.9149441e+04 1.9638534e+03 -9.4752700e+04 -8.8900242e+04 1.9640003e+03 -9.3045200e+04 -7.9686997e+04 1.9642451e+03 -1.0229400e+05 -6.3802879e+04 1.9644247e+03 -8.8064800e+04 -5.1787901e+04 1.9644845e+03 -5.8467000e+04 -4.7722686e+04 1.9646749e+03 -2.3604300e+04 -3.4613340e+04 1.9647783e+03 3.0183900e+04 -2.7399599e+04 1.9648490e+03 3.7725600e+04 -2.2430271e+04 1.9649850e+03 4.1283000e+04 -1.2808523e+04 1.9651972e+03 8.6818000e+04 2.3319728e+03 1.9653169e+03 9.6636500e+04 1.0918277e+04 1.9655074e+03 1.0375100e+05 2.4604847e+04 1.9656053e+03 9.8201700e+04 3.1640874e+04 1.9657467e+03 1.1143500e+05 4.1781105e+04 1.9658936e+03 1.4316800e+05 5.2260854e+04 1.9659100e+03 1.5953200e+05 5.3421001e+04 1.9660949e+03 1.6764300e+05 6.6492513e+04 1.9662473e+03 1.6422800e+05 7.7127244e+04 1.9664051e+03 1.5455100e+05 8.7985957e+04 1.9664921e+03 1.4686700e+05 9.3898148e+04 1.9665193e+03 1.4473300e+05 9.5733058e+04 1.9666608e+03 1.5227400e+05 1.0517023e+05 1.9667043e+03 1.4316800e+05 1.0803656e+05 1.9667805e+03 1.3591000e+05 1.1300719e+05 1.9668947e+03 1.4829000e+05 1.2034835e+05 1.9669872e+03 1.6408500e+05 1.2618371e+05 1.9670852e+03 1.8301100e+05 1.3225054e+05 1.9670960e+03 1.7646500e+05 1.3291722e+05 1.9672212e+03 1.8927200e+05 1.4047337e+05 1.9673517e+03 2.0506700e+05 1.4812999e+05 1.9675041e+03 1.6693100e+05 1.5674804e+05 1.9676292e+03 1.2552300e+05 1.6355767e+05 1.9677380e+03 1.3804500e+05 1.6927079e+05 1.9678849e+03 1.5512000e+05 1.7666094e+05 1.9679339e+03 1.4387900e+05 1.7903894e+05 1.9679992e+03 1.6109700e+05 1.8214129e+05 1.9681733e+03 1.8827600e+05 1.9002046e+05 1.9683202e+03 2.3238800e+05 1.9620596e+05 1.9683256e+03 2.1047400e+05 1.9642665e+05 1.9684562e+03 2.5501300e+05 2.0153992e+05 1.9686303e+03 2.6881600e+05 2.0779461e+05 1.9686738e+03 2.5003200e+05 2.0925507e+05 1.9688588e+03 2.3352600e+05 2.1498876e+05 1.9689241e+03 2.1872700e+05 2.1682601e+05 1.9690220e+03 2.0592000e+05 2.1939583e+05 1.9691853e+03 1.6166600e+05 2.2317398e+05 1.9692125e+03 2.0364400e+05 2.2374146e+05 1.9693322e+03 1.5341300e+05 2.2602415e+05 1.9695117e+03 1.7518400e+05 2.2878530e+05 1.9696151e+03 2.1659300e+05 2.3000908e+05 1.9698055e+03 2.4391400e+05 2.3155362e+05 1.9698654e+03 2.4562100e+05 2.3184743e+05 1.9700068e+03 2.3238800e+05 2.3217491e+05 1.9700721e+03 2.2754900e+05 2.3215146e+05 1.9702408e+03 2.2868800e+05 2.3157873e+05 1.9703659e+03 2.2342300e+05 2.3067590e+05 1.9704638e+03 1.7831500e+05 2.2968547e+05 1.9706651e+03 9.3790500e+04 2.2686930e+05 1.9706760e+03 6.9457800e+04 2.2668729e+05 1.9710297e+03 1.0161700e+05 2.1912751e+05 1.9712582e+03 1.5625900e+05 2.1257657e+05 1.9714921e+03 2.2128800e+05 2.0456079e+05 1.9714976e+03 2.2683800e+05 2.0435901e+05 1.9716771e+03 2.2385000e+05 1.9731997e+05 1.9717152e+03 1.9581700e+05 1.9573341e+05 1.9718240e+03 1.8158800e+05 1.9102499e+05 1.9719056e+03 1.7746100e+05 1.8732670e+05 1.9720416e+03 1.8614100e+05 1.8085498e+05 1.9721722e+03 1.8642600e+05 1.7429410e+05 1.9723082e+03 1.9894800e+05 1.6711531e+05 1.9723898e+03 2.0207800e+05 1.6264763e+05 1.9724279e+03 1.8856000e+05 1.6052317e+05 1.9725095e+03 1.7105800e+05 1.5588895e+05 1.9725150e+03 1.6152400e+05 1.5557617e+05 1.9726347e+03 1.8728000e+05 1.4857641e+05 1.9727652e+03 1.9297100e+05 1.4069741e+05 1.9728849e+03 1.9097900e+05 1.3327150e+05 1.9730264e+03 1.6067000e+05 1.2427102e+05 1.9730808e+03 1.0560100e+05 1.2075108e+05 1.9732712e+03 4.6405700e+04 1.0821347e+05 1.9734834e+03 1.2976000e+03 9.3929323e+04 1.9735650e+03 -1.2220600e+04 8.8374139e+04 1.9737718e+03 -1.0228400e+04 7.4222653e+04 1.9738099e+03 -3.0150000e+04 7.1611430e+04 1.9739894e+03 -3.1430600e+04 5.9328359e+04 1.9744138e+03 -7.0277700e+04 3.0955595e+04 1.9746695e+03 -6.0032300e+04 1.4780558e+04 1.9748490e+03 -6.1028400e+04 4.0687732e+03 1.9750830e+03 -3.8972400e+04 -8.8485383e+03 1.9752516e+03 -1.0370700e+04 -1.7273776e+04 1.9754584e+03 -2.9713000e+03 -2.6389014e+04 1.9756325e+03 -9.2323000e+03 -3.2868214e+04 1.9758501e+03 7.7010000e+03 -3.9191307e+04 1.9759970e+03 3.4595100e+04 -4.2203421e+04 1.9761385e+03 3.0610800e+04 -4.4042394e+04 1.9763561e+03 7.7711000e+04 -4.4628014e+04 1.9764595e+03 9.0944600e+04 -4.3869141e+04 1.9766227e+03 9.6494200e+04 -4.1190921e+04 1.9767370e+03 5.7931700e+04 -3.8166705e+04 1.9767370e+03 7.1165300e+04 -3.8166705e+04 1.9768784e+03 3.6729500e+04 -3.3019004e+04 1.9769056e+03 4.6405700e+04 -3.1842998e+04 1.9771994e+03 1.8657800e+04 -1.5037399e+04 1.9772538e+03 8.7070000e+02 -1.1053898e+04 1.9772973e+03 -6.6710000e+03 -7.6597708e+03 1.9774606e+03 -3.8251000e+03 6.7702021e+03 1.9775748e+03 9.9777000e+03 1.8542011e+04 1.9777326e+03 7.4164000e+03 3.7195714e+04 1.9777707e+03 2.0792300e+04 4.2132058e+04 1.9778197e+03 -6.7574000e+04 4.8734430e+04 1.9778251e+03 -3.2284400e+04 4.9486039e+04 1.9778305e+03 -5.6749000e+03 5.0241129e+04 1.9780046e+03 -8.1803700e+04 7.6363446e+04 gri/doc/examples/example10.txt0000644000175000017500000000001613147557614014735 0ustar psgpsgexample10.gri gri/doc/examples/model.nodes0000644000175000017500000000005013147557614014530 0ustar psgpsg1 1 1 2 2 1 3 1 2 4 3 1.5 5 2 2 6 1.5 3 gri/doc/examples/Makefile.am0000644000175000017500000001051113147557614014435 0ustar psgpsg## Process this file with automake to produce Makefile.in # gri/doc/examples/ srcdir = @srcdir@ VPATH = @srcdir@ txt_files = example1.txt example2.txt example3.txt example4.txt example5.txt\ example6histogram.txt example6.txt\ example7.txt example8.txt example9.txt\ example10color.txt example10.txt\ example11.txt example12.txt example13.txt\ FEM.txt html_files = example1.html example2.html example3.html example4.html \ example5.html example6.html example6histogram.html \ example7.html example8.html example9.html example10.html \ example10color.html example11.html example12.html example13.html \ FEM.html logo.html eps_files = example1.eps example2.eps example3.eps example4.eps example5.eps\ example6.eps example6histogram.eps\ example7.eps example8.eps example9.eps example10.eps\ example10color.eps example11.eps example12.eps example13.eps\ FEM.eps logo.eps svg_files = example1.svg example2.svg example3.svg example4.svg example5.svg\ example6.svg example6histogram.svg\ example7.svg example8.svg example9.svg example10.svg\ example10color.svg example11.svg example12.svg example13.svg\ FEM.svg logo.svg png_files = FEM.png example1.png example2.png example3.png example4.png \ example5.png example6.png example6histogram.png \ example7.png example8.png example9.png example10.png \ example10color.png example11.png example12.png example13.png \ FEM-tiny.png example1-tiny.png example2-tiny.png example3-tiny.png \ example4-tiny.png example5-tiny.png example6-tiny.png \ example6histogram-tiny.png example7-tiny.png \ example8-tiny.png example9-tiny.png example10-tiny.png \ example10color-tiny.png example11-tiny.png example12-tiny.png \ example13-tiny.png logo.png EXTRA_DIST = \ example1.txt example2.txt example3.txt example4.txt example5.txt\ example6histogram.txt example6.txt\ example7.txt example8.txt example9.txt\ example10color.txt example10.txt\ example11.txt example12.txt example13.txt FEM.txt\ example1.gri example2.gri example3.gri example4.gri example5.gri\ example6.gri example6histogram.gri example7.gri example8.gri\ example9.gri example10.gri example10color.gri example11.gri\ example12.gri example13.gri\ FEM.gri logo.gri\ example1.dat example5.dat example6image.dat example6mask.dat\ example7a.dat example7b.dat example7c.dat example7d.dat example7e.dat\ example7f.dat example7g.dat \ example8a.dat example8b.dat \ example9a.dat example9b.dat\ example10.dat example11.dat\ example12.dat example13.dat\ FEM.pl \ model.elements model.nodes\ example1.ps example2.ps example3.ps example4.ps example5.ps \ example6.ps example6histogram.ps example7.ps example8.ps \ example9.ps example10.ps example10color.ps example11.ps \ example12.ps example13.ps \ logo.ps FEM.ps DISTCLEANFILES = $(png_files) $(eps_files) $(html_files) $(txt_files) $(svg_files) %.svg : %.gri gri -output $@ $< %.txt : %.gri echo "$<" | cat >$@ chmod +w $@ %.eps : %.ps cp $< $@ chmod +w $@ %.png : %.ps -convert -strip -background white $< $@ %-tiny.png : %.png -convert -strip -background white -geometry 90x999 $< $@ %.pdf : %.ps convert $< $@ # ps2pdf $< $@ %.html : %.gri perl $(srcdir)/../gri2html $< $@ all: html png eps txt html: $(html_files) eps: $(eps_files) png: $(png_files) txt: $(txt_files) # Everything below this line is old, or is provide # for the developer's use only. GRITEST = ../../gri -directory ../.. -y GRI = gri -y -p #%.ps : %.gri # $(GRI) $< old_all_target: ${MAKE} eps ${MAKE} html ${MAKE} png pdf: FEM.pdf example1.pdf example2.pdf example3.pdf example4.pdf \ example5.pdf example6.pdf example6histogram.pdf \ example7.pdf example8.pdf example9.pdf example10.pdf \ example10color.pdf example11.pdf example12.pdf example13.pdf logo.pdf ps: FEM.ps example1.ps example2.ps example3.ps example4.ps \ example5.ps example6.ps example6histogram.ps \ example7.ps example8.ps example9.ps example10.ps \ example10color.ps example11.ps example12.ps example13.ps logo.ps testps: $(GRITEST) FEM.gri $(GRITEST) example1.gri $(GRITEST) example2.gri $(GRITEST) example3.gri $(GRITEST) example4.gri $(GRITEST) example5.gri $(GRITEST) example6.gri $(GRITEST) example6histogram.gri $(GRITEST) example7.gri $(GRITEST) example8.gri $(GRITEST) example9.gri $(GRITEST) example10.gri $(GRITEST) example10color.gri $(GRITEST) example11.gri $(GRITEST) example12.gri $(GRITEST) example13.gri svg: $(svg_files) gri/doc/examples/example7c.dat0000644000175000017500000000723213147557614014766 0ustar psgpsg 0.421 -0.376 0.225 -0.648 0.396 -0.402 0.218 -0.662 0.028 -1.553 0.576 -0.240 0.189 -0.724 0.543 -0.265 0.327 -0.485 0.147 -0.833 0.098 -1.009 0.041 -1.387 0.151 -0.821 0.193 -0.714 1.606 0.206 0.480 -0.319 0.164 -0.785 0.446 -0.351 0.264 -0.578 0.144 -0.842 0.160 -0.796 0.456 -0.341 0.099 -1.004 0.063 -1.201 0.218 -0.662 0.384 -0.416 0.336 -0.474 0.246 -0.609 0.363 -0.440 0.081 -1.092 0.278 -0.556 0.609 -0.215 0.340 -0.469 0.202 -0.695 0.567 -0.246 0.354 -0.451 0.193 -0.714 0.196 -0.708 0.229 -0.640 0.126 -0.900 0.700 -0.155 0.387 -0.412 0.480 -0.319 0.283 -0.548 0.173 -0.762 0.253 -0.597 0.348 -0.458 0.329 -0.483 0.236 -0.627 0.205 -0.688 0.212 -0.674 1.351 0.131 0.423 -0.374 0.235 -0.629 0.133 -0.876 0.315 -0.502 0.124 -0.907 0.150 -0.824 0.268 -0.572 0.137 -0.863 0.381 -0.419 0.345 -0.462 0.228 -0.642 0.195 -0.710 0.161 -0.793 0.636 -0.197 0.172 -0.764 0.287 -0.542 0.403 -0.395 0.220 -0.658 0.172 -0.764 0.299 -0.524 0.184 -0.735 0.303 -0.519 0.294 -0.532 0.101 -0.996 0.065 -1.187 0.149 -0.827 1.188 0.075 0.308 -0.511 0.284 -0.547 0.272 -0.565 0.185 -0.733 0.283 -0.548 0.314 -0.503 0.262 -0.582 0.436 -0.361 0.510 -0.292 1.372 0.137 0.078 -1.108 0.079 -1.102 0.331 -0.480 0.176 -0.754 0.121 -0.917 0.156 -0.807 0.156 -0.807 0.119 -0.924 0.380 -0.420 0.251 -0.600 0.568 -0.246 0.224 -0.650 0.239 -0.622 0.287 -0.542 0.378 -0.423 0.268 -0.572 0.177 -0.752 0.321 -0.493 0.228 -0.642 0.584 -0.234 0.175 -0.757 0.264 -0.578 0.151 -0.821 0.185 -0.733 0.227 -0.644 0.334 -0.476 0.156 -0.807 0.119 -0.924 0.380 -0.420 0.251 -0.600 0.670 -0.174 0.892 -0.050 1.211 0.083 0.386 -0.413 0.571 -0.243 0.358 -0.446 0.503 -0.298 0.169 -0.772 0.468 -0.330 0.148 -0.830 0.332 -0.479 0.261 -0.583 0.211 -0.676 0.342 -0.466 0.292 -0.535 0.460 -0.337 0.315 -0.502 0.180 -0.745 0.082 -1.086 0.220 -0.658 0.259 -0.587 0.917 -0.038 0.324 -0.489 0.258 -0.588 0.198 -0.703 1.768 0.247 0.310 -0.509 0.376 -0.425 0.936 -0.029 0.194 -0.712 0.346 -0.461 0.317 -0.499 0.182 -0.740 0.309 -0.510 0.397 -0.401 0.354 -0.451 0.237 -0.625 0.185 -0.733 0.438 -0.359 0.126 -0.900 0.407 -0.390 0.494 -0.306 0.209 -0.680 0.277 -0.558 0.497 -0.304 0.175 -0.757 0.377 -0.424 0.390 -0.409 0.172 -0.764 0.198 -0.703 0.160 -0.796 0.370 -0.432 0.596 -0.225 0.112 -0.951 0.981 -0.008 0.121 -0.917 0.173 -0.762 0.402 -0.396 0.196 -0.708 gri/doc/examples/logo.ps0000644000175000017500000004405513147557614013717 0ustar psgpsg%!PS-Adobe-2.0 EPSF-1.2 %%Creator: Gri2.6.4 (released 2001-06-23). User=rhogee, commandfile=/deb/src/gri/unoff/gri-2.7.0/doc/examples/logo.gri %%Title: logo.ps %%CreationDate: Tue Jul 17 10:45:04 2001 %%Pages: (atend) %%BoundingBox: (atend) %%TemplateBox: 0 0 612 792 %%DocumentFonts: (atend) %%Endcomments % NOTE: The Gri postscript dictionary is being converted to the Adobe % Illustrator 3.0 dialect of PostScript, as described in the Adobe % documents stored at URL % http://www.adobe.com/Support/TechNotes.html % (as of Jan 1996, this doc is number 5007). When the conversion % is complete, the Adobe Illustrator drawing program -- and any % program compatible with AI -- will be able to edit Gri output. % % The IslandDraw (TM) program is able to read Gri output % at this time; remarkably, it can read/edit arbitrary PostScript. % % The definitions below are presented in the same order as the Adobe % manual. The stack configuration before and after is shown in curly % brackets. All the operators are listed, but only some are defined % here. Most things are faithful, except that no distinction is made % between colors for stroking and filling paths. The string 'WRONGLY' % appears with commands that are approximations. % % PDF-style abbreviations: /rg {setrgbcolor} def % {red green blue} {-} set RGB color /RG {setrgbcolor} def % {red green blue} {-} set RGB color /q {gsave} def /Q {grestore} def /W {clip} def /W* {eoclip} def % % Gri-specific abbreviations: /hsb {sethsbcolor} def % {hue saturation brightness} {-} set HSB color % % Following all try to mimic Adobe Illustrator % % Mimicking section 5.1 of Adobe manual: %A % {flag A} {-} Determine whether % following object can % be selected. Flag=1 % prevents selection; % flag=0 allows it. % Mimicking section 5.2 of Adobe manual: %u % {u} {-} start group %U % end group %q % as 'u' but first item is a clip path %Q % as 'U' but first item is a clip path % Mimicking section 5.3 of Adobe manual: /g {setgray} def % {gray g} {-} Set gray for fill % path, WRONGLY used % for stroking also. /G {setgray} def % As 'g', but for filling path. %k % Set cmyk color for filling path. %K % As 'k', but for stroking path. %x % Set cmyk custom color for filling path. %X % As 'x' but for stroking path. %p % Define pattern for filling path. %P % As 'p' but for stroking path. %O % Specify whether overprinting for fill paths %R % As 'O' but for stroking path. % Mimicking section 5.4 of Adobe manual: /d {setdash} def % {[array] phase d} {-} Set dash. /i {setflat} def % {flatness i} {-} Set flatness. /j {setlinejoin} def % {linejoin j} {-} Set line join. /J {setlinecap} def % {linecap J} {-} Set line cap. /M {setmiterlimit} def % {miterlimit M} {-} Set miter limit. /w {setlinewidth} def % {linewidth w} {-} Set line width. % Mimicking section 5.5 of Adobe manual: /m {moveto} def % {x y m} {-} Move to locn /l {lineto} def % {x y l} {-} Draw line to locn % not a smooth point. % WRONGLY, no % distinction is made % between smooth and % corner. %L % {x y L} {-} As 'l' but a corner %c % Bezier curve to smooth point. %C % As 'c' but to corner point. %v % Something else to do with Bezier. %V % %y % %Y % % Mimicking section 5.6 of Adobe manual: %N % {N} {-} As 'n' for nondrawn stuff /n {newpath} def % {n} {-} WRONGLY interpreted % as path constructor /F {fill} def % {F} {-} Fill current path. %f % {f} {-} 'F' but close first /S {stroke} def % {S} {-} Stroke current path. %s % {s} {-} 'S' but close first %B % {B} {-} As 's' but don't empty path. %b % {b} {-} As 'f' but don't empty path. %H % no-op (weird huh?) /h {closepath} def % {h} {-} Close current path %W % Used to create masks. % Mimicking section 5.7 of Adobe manual: %a % Begin text block ... %e % Similar to 'a' but ... %I % Similar to 'a' but ... %o % Similar to 'a' but ... %r % Similar to 'a' but ... %t % {len (string) t} {-} Render string. %T % End block of text % That's the end of the Illustrator stuff. Following are some Gri % definitions which provide a temporary way of handling fonts. /sf {setfont} def % {fontname sf} {-} Set font name. /sh {show} def % {(text) sh} {-} Show text. /sc {scalefont} def % {size sc} {-} Scale font. % Gri items which should be translated to Illustrator format: /rl {rlineto} def /rm {rmoveto} def % Procedures /cimdict 7 dict def /cim { cimdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def q xll yll translate xur xll sub yur yll sub scale /do cl 3 mul string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop} false 3 colorimage Q end } def /imdict 14 dict def /im { imdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def /imagemap exch def q % Until version 2.6.0 used a 'settransfer' here, but that % triggers a bug in ps2pdf xll yll translate xur xll sub yur yll sub scale /do cl string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop dup length 1 sub 0 1 3 -1 roll { 1 index exch 2 copy get imagemap exch get 255 mul cvi put } for }image Q end } bind def /frdict 5 dict def /fr { frdict begin /yt exch def /xr exch def /yb exch def /xl exch def n xl yb m xl yt l xr yt l xr yb l h F n end } def /plusdict 3 dict def /_plus { plusdict begin dup 0.5 mul /t0 exch def /t1 exch def 0 t0 rm 0 t1 neg rl t0 neg t0 rm t1 0 rl t0 neg 0 rm end } def /timesdict 3 dict def /_times { timesdict begin dup 0.353553 mul /t0 exch def 0.707106 mul /t1 exch def t0 neg t0 rm t1 dup neg rl t1 neg 0 rm t1 dup rl t0 neg dup rm end } def /boxdict 3 dict def /_box { boxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm end } def /filledboxdict 3 dict def /_filledbox { filledboxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm F end } def /diamonddict 2 dict def /_diamond { diamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm end } def /filleddiamonddict 2 dict def /_filleddiamond { filleddiamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm F end } def /triangleupdict 5 dict def /_triangleup { triangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm end } def /filledtriangleupdict 5 dict def /_filledtriangleup { filledtriangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm F end } def /trianglerightdict 5 dict def /_triangleright { trianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm end } def /filledtrianglerightdict 5 dict def /_filledtriangleright { filledtrianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm F end } def /triangledowndict 5 dict def /_triangledown { triangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm end } def /filledtriangledowndict 5 dict def /_filledtriangledown { filledtriangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm F end } def /triangleleftdict 5 dict def /_triangleleft { triangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm end } def /filledtriangleleftdict 5 dict def /_filledtriangleleft { filledtriangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm F end } def /circdict 5 dict def /_circ { circdict begin 0.5 mul /t0 exch def currentpoint /t2 exch def /t1 exch def S n t1 t2 t0 0 360 arc t1 t2 m end } def /bulldict 3 dict def /_bull { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 360 arc h F S end } def /filledhalfmoonupdict 3 dict def /_filledhalfmoonup { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 180 arc h F S end } def /filledhalfmoondowndict 3 dict def /_filledhalfmoondown { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 180 360 arc h F S end } def 1 1 scale 10.0 M 1 j /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-ISOLatin1 exch definefont pop /Courier-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Oblique-ISOLatin1 exch definefont pop /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Bold-ISOLatin1 exch definefont pop /Courier-BoldOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-BoldOblique-ISOLatin1 exch definefont pop /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-ISOLatin1 exch definefont pop /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Bold-ISOLatin1 exch definefont pop /Helvetica-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Oblique-ISOLatin1 exch definefont pop /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Roman-ISOLatin1 exch definefont pop /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Italic-ISOLatin1 exch definefont pop /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Bold-ISOLatin1 exch definefont pop /Palatino-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-BoldItalic-ISOLatin1 exch definefont pop /Symbol findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Symbol-ISOLatin1 exch definefont pop /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Roman-ISOLatin1 exch definefont pop /Times-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Italic-ISOLatin1 exch definefont pop /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Bold-ISOLatin1 exch definefont pop /Times-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-BoldItalic-ISOLatin1 exch definefont pop %%EndProlog %%Page: 1 1 /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:# Gri was invoked by user named %gri:# rhogee %gri:# on host named %gri:# mixing %gri:# using the command %gri:# gri-2.6.4 -directory /usr/share/gri/2.6.4/ -y -b /deb/src/gri/unoff/gri-2.7.0/doc/examples/logo.gri %gri:# at time Tue Jul 17 10:45:04 2001. %gri:# %gri:# The user's ~/.grirc file ... %gri:# ... end of users ~/.grirc file. %gri: %gri:set x size 5 %gri:set y size 5 %gri:set x axis 0 1 0.25 %gri:set y axis 0 20 10 %gri:set font size 0 /Helvetica-ISOLatin1 findfont 0.00 sc sf %gri:\background_color = "hsb 0.60 0.24 1" %gri:\line_color = "red" %gri:\word_color = "black" %gri: %gri:read columns x y %gri:0.0 12.5 %gri:0.25 19 %gri:0.5 12 %gri:0.75 15 %gri:1 13 %gri: %gri:set color \background_color %gri:set line width axis rapidograph 6 %gri:draw curve filled to ..ybottom.. y %^ scale 1 170.7 0 142.25 1 170.7 0 7.1125 0.76 0.856 1 rg 0.76 0.856 1 RG 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 170.70 m 170.70 259.61 l 206.26 305.84 l 241.82 256.05 l 277.39 277.39 l 312.95 263.16 l 312.95 170.70 l h F % END GriPath stroke/fill 0.76 0.856 1 rg 0.76 0.856 1 RG 1.0 i 0 J 0 j 3.969 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 170.70 165.01 l 170.70 170.70 l 206.26 170.70 l 206.26 165.01 l 206.26 170.70 l 241.82 170.70 l 241.82 165.01 l 241.82 170.70 l 277.39 170.70 l 277.39 165.01 l 277.39 170.70 l 312.95 170.70 l 312.95 165.01 l 312.95 170.70 l 312.99 170.70 l S % END GriPath stroke/fill 0.76 0.856 1 rg 0.76 0.856 1 RG 1.0 i 0 J 0 j 3.969 w 10.0 M [] 0 d 170.70 312.95 m 170.70 312.95 l 170.70 318.64 l 170.70 312.95 l 206.26 312.95 l 206.26 318.64 l 206.26 312.95 l 241.82 312.95 l 241.82 318.64 l 241.82 312.95 l 277.39 312.95 l 277.39 318.64 l 277.39 312.95 l 312.95 312.95 l 312.95 318.64 l 312.95 312.95 l 312.99 312.95 l S % END GriPath stroke/fill 0.76 0.856 1 rg 0.76 0.856 1 RG 1.0 i 0 J 0 j 3.969 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 165.01 170.70 l 170.70 170.70 l 170.70 241.82 l 165.01 241.82 l 170.70 241.82 l 170.70 312.95 l 165.01 312.95 l 170.70 312.95 l 170.70 312.95 l S % END GriPath stroke/fill 0.76 0.856 1 rg 0.76 0.856 1 RG 1.0 i 0 J 0 j 3.969 w 10.0 M [] 0 d 312.95 170.70 m 312.95 170.70 l 318.64 170.70 l 312.95 170.70 l 312.95 241.82 l 318.64 241.82 l 312.95 241.82 l 312.95 312.95 l 318.64 312.95 l 312.95 312.95 l 312.95 312.95 l S % END GriPath stroke/fill %gri:set color black %gri:draw axes 0 g 0 G 1.0 i 0 J 0 j 3.969 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 170.70 165.01 l 170.70 170.70 l 206.26 170.70 l 206.26 165.01 l 206.26 170.70 l 241.82 170.70 l 241.82 165.01 l 241.82 170.70 l 277.39 170.70 l 277.39 165.01 l 277.39 170.70 l 312.95 170.70 l 312.95 165.01 l 312.95 170.70 l 312.99 170.70 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 0 j 3.969 w 10.0 M [] 0 d 170.70 312.95 m 170.70 312.95 l 170.70 318.64 l 170.70 312.95 l 206.26 312.95 l 206.26 318.64 l 206.26 312.95 l 241.82 312.95 l 241.82 318.64 l 241.82 312.95 l 277.39 312.95 l 277.39 318.64 l 277.39 312.95 l 312.95 312.95 l 312.95 318.64 l 312.95 312.95 l 312.99 312.95 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 0 j 3.969 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 165.01 170.70 l 170.70 170.70 l 170.70 241.82 l 165.01 241.82 l 170.70 241.82 l 170.70 312.95 l 165.01 312.95 l 170.70 312.95 l 170.70 312.95 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 0 j 3.969 w 10.0 M [] 0 d 312.95 170.70 m 312.95 170.70 l 318.64 170.70 l 312.95 170.70 l 312.95 241.82 l 318.64 241.82 l 312.95 241.82 l 312.95 312.95 l 318.64 312.95 l 312.95 312.95 l 312.95 312.95 l S % END GriPath stroke/fill %gri: %gri:set color \line_color %gri:set line width rapidograph 7 %gri:draw curve %^ scale 1 170.7 0 142.25 1 170.7 0 7.1125 5.669 w 1 0 0 rg 1 0 0 RG 1.0 i 0 J 1 j 5.669 w 10.0 M [] 0 d 170.70 259.61 m 206.26 305.84 l 241.82 256.05 l 277.39 277.39 l 312.95 263.16 l S % END GriPath stroke/fill %gri:set symbol size 0.4 %gri:draw symbol bullet %^ scale 1 170.7 0 142.25 1 170.7 0 7.1125 1 0 0 rg 1 0 0 RG 0.369 w 0.369 w n 170.7 259.6 m 11.4 _bull S n 206.3 305.8 m 11.4 _bull S n 241.8 256.1 m 11.4 _bull S n 277.4 277.4 m 11.4 _bull S n 312.9 263.2 m 11.4 _bull S %gri: %gri:set color \word_color %gri:set font size 80 /Helvetica-ISOLatin1 findfont 80.00 sc sf %gri:set font to TimesRoman /Times-Roman-ISOLatin1 findfont 80.00 sc sf %gri:draw label "Gri" at 0.1 2 %^ scale 1 170.7 0 142.25 1 170.7 0 7.1125 % gr_show_at() BEGIN 0 g 0 G S n 184.9 184.9 m (Gri) sh % gr_show_at() END %gri: showpage %%Trailer %%BoundingBox: 163 163 321 321 %%DocumentFonts: Courier Helvetica Palatino-Roman Palatino-Italic Symbol Times-Roman %%Pages: 1 gri/doc/examples/example6histogram.gri0000644000175000017500000000244713147557614016554 0ustar psgpsg# Example 6 -- Plot IR image of Gulf of Maine # define characteristics of norda images \0val = "5" # 0 in image \255val = "30.5" # 255 in image .rows. = 128 .cols. = 128 .pixel_width. = 2 .km. = {rpn .cols. .pixel_width. *} # get filenames query \filename "Name image file" ("example6image.dat") query \maskname "Name mask file" ("example6mask.dat") # get data open \filename binary uchar set image range \0val \255val read image .rows. .cols. box 0 0 .km. .km. close open \maskname binary uchar read image mask .rows. .cols. close # find out what grayscale method to use query \histo "Do histogram enhancement? (yes|no)" ("yes") query \minT "T/deg for white on page? " ("10") query \maxT "T/deg for black on page? " ("15") \incT = "1" # set up scales. set x size 12.8 set y size 12.8 set x name "km" set y name "km" set x axis 0 .km. 32 set y axis 0 .km. 32 # plot image, grayscale, and histogram if {"\histo" == "yes"} set image grayscale using histogram black \maxT white \minT else set image grayscale black \maxT white \minT end if draw image draw image palette left \minT right \maxT increment \incT draw image histogram if {"\histo" == "yes"} draw title "Example 6: grayscale histogram enhanced" else draw title "Example 6: grayscale linear \minT to \maxT" end if gri/doc/examples/example8b.dat0000644000175000017500000000007613147557614014765 0ustar psgpsg517.0 0.05 516.0 39.38 514.0 118.67 512.0 194.63 508.0 321.14 gri/doc/examples/example1.dat0000644000175000017500000000042513147557614014612 0ustar psgpsg0.05 12.5 // first point 0.25 19 // second point 0.5 15 // third point 0.75 15 // fourth point 0.95 13 // fifth point gri/doc/examples/example9b.dat0000644000175000017500000000007613147557614014766 0ustar psgpsg517.0 0.05 516.0 39.38 514.0 118.67 512.0 194.63 508.0 321.14 gri/doc/examples/example9.gri0000644000175000017500000000350713147557614014637 0ustar psgpsg# Example 9 -- Plot dTdrho-rho section `Initialize Parameters' { \FILE_DATA = "example9a.dat" # T vs rho \FILE_LOCN = "example9b.dat" # section distances # # Following values from ~/eubex/processing/to_rho_bins/do_rho_inter \RHO_MIN = "28.1" \RHO_MAX = "27.5" \RHO_INC = "-0.002" \NY = "301" set missing value -99.0 \xmin = "350" \xmax = "0" \xinc = "-100" \ymin = "28.1" \ymax = "27.8" \yinc = "-0.1" \zmin = "-10" # black \zmax = "0" # white } `Initialize Axes' Set up axes. { set x name "km" set x size 10 set x axis \xmin \xmax \xinc set y size 5 set y name "$\sigma_T$" set y axis name horizontal set y axis \ymin \ymax \yinc set y format %.1lf draw axes none } `Initialize Files' { query \data "Data file? " ("\FILE_DATA") query \locn "Station locn?" ("\FILE_LOCN") } `Read Data' { # Read x-locations system awk '{print $2}' < \locn > TMP system wc TMP | awk '{print $1}' > NUM open NUM read .gridx_number. close system rm NUM open TMP read grid x .gridx_number. close system rm TMP # Create y-locations set y grid \RHO_MIN \RHO_MAX \RHO_INC # # Read data open \data read grid data \NY .gridx_number. close } Initialize Parameters Initialize Axes Initialize Files Read Data set image range \zmin \zmax set image colorscale hsb 0 1 1 \zmin hsb .6 1 1 \zmax convert grid to image box \xmin \ymin \xmax \ymax # # Draw the image, then draw the axes. Note that the image has # extends beyond the axes frame, so we will turn clipping # on before drawing it, to make a clean picture. set clip postscript on draw image set clip postscript off draw axes # # All done. draw title "Example 9" if {"\dohisto" == "yes"} draw title "Histogram enhanced grayscales" end if gri/doc/examples/example6image.dat0000644000175000017500000004000013147557614015613 0ustar psgpsg%:% '"".+)O%1""3:,%&/1.4)$.>16RTUP9U%0f' % "5;,2,5>38) )86='AFFFCCB:BCB@@@=@>>=:;82#,!!%(-"" ,#2"-(+3;1! 3:%*374USSR@YJ48& ";G@E=0?(")=#64<41?88A,FGGFCCBBCB@@@@@?==<<;73(#1*,,5 %"**" "./  "%%(48 -/3)!<"#*WWTHQN&'$' ,6"OEQ9>/97&F5(737+BC9@@BFFGFCA@@BAA@AA@?==<:875(.'96#*0#%)  .+1%/'(.4#7< #=& '#()#"-\]F)05,*. CCKQA*-8C33&><:87567++&4 0*-!"+3 $"""561.9217d4*"$ $"#)% &*XP1.,/ 7KMK3 C77>)%'H0&7:0B@DEFEFFEDBB@?@A@@@@@?>::::/#+2'%-., '  % 67@a/ *+313-&f4 8 ))!&+"-)J`1  @$", ,GMM ,8==@*(E50;:@C@CFEFFEECBA@>BAA@@?><<;>=;8246+7,,,30.!%( 3WcO29,&/43=''59 A6/(2#*=# 5"308B#BGD?#+@BCA+*&@<@=?CC@EEFFEEDCCB<9A?>@>?=<<=<:8 2750<0+$+&&%)&$"@da98;(3-),,071 !-$.1'#4;64H$'")9"(!GDB/H7:!0CDDA@/,=AB@CEGGHHGGDDCCCBAA@@?>?>=><==;8468("5"+$*"!-,/ 0@14L*,?6?%.371G0&% &2'# '"./  &'! $0/*1*;F,. 8@FGDCBA4FFEBBBEFGHIGGECCDBA@@>@?<=;<<;80:<8052$"'&/'+0#19=)B #%").& &*($#3.&.&  %#%-,3FI1-EGGGGD2@@AED@ECEFHHIIGDCCDCA@@@?@?=>>?>>@>??6?=#5367&*0$&'"+7'&,!0!"(4NC#+[N) ,)-2*@e!=3! &"#"" "+&".8-HF/@5@FJJIHD1EEBDBEEDFGIJIHFEDCCAA@@?>>@?>??@@@@@??@76?/>%(.: 1.)X&+$8>="/8OD2AF3.0*.0 )'  6&#"(0" '/&DBH;?,?@H?DCDIECBCDFEGIJIIGEECBAB@@?@@@@@@@A@A@AA@@@@9=-3:'6.%1W'.(&#&<37/"E$5)&+/UKLCOMNKA%0',>9&/)&0'"-.!"##-)026GIE3=BJHJDIKKGEEHIIHHIIIHHECCA@@@@AABBCEEBBBA@?>??@??>?&/) ,#% <%2('>=<:=9268 -*#! $)/1"""=+OXSY]HV;/E``9'&9>4' (#0@ )#"!%("!'';F7AOMLK;@BDFIJGKIIGFGHFFFECDBAABBBECCDEFBB@@?>><;9:2923#12#&/"6.2U/'.PY_`[YR4<&1(!,+__H>0/7+!. + "%""&! ,;JOOPON?(7AGJIJJKJJFFHIHGGGEDABABCCFIEDDFFBA@@?@?>=;9-/2 /+6 #%#9!",'G"4)*&:@`YbfcG@(1O1)%%;B1/)85&,"!B)("&(/=AGH@0"/1.$?A&-& /7%4,)31-245+,!-*%9OMJLKMPPPPOONLKKKH?GJKJIHGEEEEDDDDFIJKLKJIJKIFFIHHFGGFB847;=@@<3,#$!9* !%/"R'656+3>-2C9&67/0, ,&23&.*1( /0-B:/PNLLLPPPPPPOMMKJKJJJJKJHGGEDDDEDGIKKLLKKKKJKJIJJIIHIGG>7=?>>4>;% 39(0"$I5#-"" *-">*"2,0+5;*'--0+*")5))'$"(>BQONMMQPPPPPNMLLKLJJIIIHGEEEEDEEHJLNNMKJJJIIHIJJKIIIIHGE@?????99%+ 0,"$"15 "''/)&"1,%")3F/6$H"2,+.,(%-!#!.#*PKPOPQPQPPONLKJKKJIHHGFFGEEGGHIJLOPOOLHKKIJKKKKJJIIIIGE@@>>=>>:.! "-0#&& '1*(.#(&) $-=:3-! ",%(2&" ($$KKOPQPPPOPOMKKKKKJFEEEFHIIIHKJLMOOOOOKGIJJJKKJJIIIJJHGE@?>>><37$#,.6".$% )" 15'( ,=$ )0+".501+2( 4"%. "9LMOPQPOPOPMKJJKJJHGEEFGHHJJLLMNOPPPNOKGHIIJLKIHGIHJIHFD@@<<=9864*(3-+-/6?>"$$%/0/! 16;*6$0)103" !++&GLMNOPPPOOOPLKKJKJIHFEEGIJJLLNOOOPPOMLMLHGIIJJHHGFFGHIGFE??;65".(.":B1<;*0%,282%29"A*%%.31"&"/1$  6@  %"0"#6PONOOPONNOOPKLKJJJJHGFFGGJKMNNOPPNMMJKKLKIIHGIHGGGHFHIIFC>.,1/<8624 ;C&++9& %5;7""$.(((!%,&,3("0,&*3J &*"0).DPPONNMNNNNOMKLKIJKJIGFEGGFKNOOPPNKKJIKKJIIHGFGGGGGGHHHGE>:<<>==<;4( 9H3!&6' ,4@> "/)/-HCLPPPNNMKMMNNNNMMKIJKJHFEEFLMKPPPONKKJIJJIIHIHGGGGGHHHGHGEDA?@>>=<=;:5#E3(*%/(" 1;=<<6<;:6%*1%B./   (#+60.-*"! &" ("!/BMOPPPPONNMKKMNNMNMKIHHHFDECDGHIOPPMLLKKJIHIHGHHHHHHHGHGFFECC@?@@?<;;6====>@8'0+".$"#" !+2(0/4238,;& !'#.   %-MNPQQPOMMMLLKMNNMMLIHHGGFFECFHIKNPPMMMLLKHGGGGHHHHHHIHGGEECBB@>>>?=;:;:>???@.63"-.% "+  #.37#996-(*43!+&% +;OPQQPPONNMMLKNONNMLGFFGGFEEDGGIMOPPMNMLMJHGHGGHHIIHHHGGFECACC?????====;?@@>@"=C@: 2 "0# #.07 UM71)40(!('" %!.%1LPQRRQPONNMMJLMOMMMMHFGGHGFEEFHJLPPOMNMLMKIJJHGHHJIIIHGEDDDBABB@>?=<=??<>@ABB27@@"!+M-"'. #&"(1@362-1-+)"/,+","2<65CQQSRQPONMMKJMNNMKMKIGGGIHHHGHHJMOPONNNMMLJJIIIIJJJIIHGFDEFCBBA@?>=>>@??@@>CBA7('8*+28(.,21'*+A0",99:7:*.-**0"$!ᬼ@RRSRPONNMKJKMMMKIIHGFGHIIJIHIKKNOPONNMLKKLKJJIIIIJJHGDDFHGEABB@?>==@@AA@BCCBD5%.0$%) ,$( #734V3&2:@==G;(/0,-0%,*)&/@<<3ORRSQPNMNMKKKMLJJGGHFFGIIKLKLKLMNPPOMNMMLLMLKKJJJKIJJHFEFFIICBBA?@@@@@@ABBCFFG!'$'#0*,&3*$ ";AI23?F9A>?3:) &"/'/ )?=:>PRRTRPMILMLKMKKJIGGIGFIJKMMMMMOPPPOONOMMKMMMKKKJKJJKKIHGHGIJICA@@@ACBBBABCDFHI*44#/&%%#1%(&$=@+5=:3&6;/3$ (#*(4#!"4)1PRRRSRPNJJMKKLKKJIHGHGFIILMMKLNPPPPPOPNMLLMMMMKKJKKMMLJIIJIJJJEAB8DDEDECDFEFHII2+:8.#%*,.+!*4/,..0/&54800),%)9!!"138ORSSSRONJKMKIKKIJJHGIHGHILMLLNOPPPPPNOMKKLMMMMLMLMMMNNMKKJJIJKIGBCEGHFGFGGGHIJK$,.;',%3$82,%'#"#)8, -G97'.043.%%'0YQI# ",HRSSSSPNMJLMLJJIJJJHFHIIHLMLKLOPPPQPNMLKKJKMMMLMMMNMMNONMLJJJJJKIFDCFIIHHIIJIJLK'">2.+0#2$/6*'/)!++(4,1JNO38>2)),($([&*<:0""2OSRRSRPNLKKLLKIJKJJHGGIKLMLKKOPPPPRPONMLKKKLLLKLMMNNMNNONLKJJKJJJHEFFHJJIJKKKKKK31,9737:#,,+:/*%%#//5%/,:LP936-+")'NY66,C6A-:SSRSSPPMLKKKJIJKKJKGFEKKLKKJLPPQPPPPNMNKKKLLLKKLMMMMMMMMKLKKJKLKJJGFFGIJJJKJKKKK7&.6@'("(. 0)+&#"*49)"&2:8955;--9gj_74=OA>PTTSSRPNLLKKJIIKLLKKJGGJJJJKKOPPPQPPNMMMJKLLLMLLLLLMMMKKJKKKKKLLKJKIIHGIIIKKKKKJJ:./586&! ''""$+6&392/%:14,5-*"" 382G3077OPRRTTSQPMMLKKJJIKLMKKJJJJIIJLMPPPPPPPOMMMKKKKKMMMNMMNMLKJKKKKLKKKKKKKJIIJJIJKJKIII'%/46,#(&.)(2.,#=&!43?101(.))"*&!5*,0604QPSSSTRQONLKKKLKLNNMKKJIIKKKLMOPOPPPPPNMMLMJJKKLLLMMMMLLJJJKKKLLJKKIJJKIJJJIJJIIHHH$+3@*#"(.$.+9/0&%'(030)(+'"((1*'"!*(/@QRSSSSRPOLJJJLLMMMMMLKKIIJMKMNOPPPPPONNMLLNJJKLLLLLMMLKKIJJKJJKKKJJJKJJJIJJIJIHIIIHA,5*,(,"),<7;23@76NM9#148,'(,&/$(%/2&*"%+0:QRSTSRTSQOIIIIKLKLKJLLKIJIIKKKOPPNPOOOMNLLLLJKLLMMMMMMLKJIIHHJJKKKJIJIIHJJJJJJHHKJJI-&333%" ,:EC()?4,[;6%*16"",'#*$%.0.(-''%.PQSSSRPTSQNLHIJKLKJIJKKJIIJKKKKMPOOPOOONNMLKMKKLKLMMLKLJKKHIIHGJIIJIJJIIIIIJIIIHGKJJH%-%-"%9>+;@=7'3/2"-/1.(322/*%,61#'('/1MRSRRSRTRPMKHJJKKKJIKLLLJHHKKKMMNNOPNNOONMMMMLKLLLMMKKKKKJIHGHFIGFHJJJIIIIJIIIIHHJKJI.4=9&+@25=@'"1/!",242621.:;C&*&82&&314KRRSRQRRSROMIHHKJJIHIJLMMJGGHIKMNNPPPMNOONLMNMMMMLLMMLKKLKIGGGGGFEFIJJIIGIHIIIIHHHIJJI )4@8>6C?C78"! %%",/2.2:K685@W6)$,7+2057PRRQQQQRRPOKJHGIJIIKJKMMMKHFGIMONOPOKMMNNNMMMMMMLLLMMMKKKJIGGGGGFEEIJIIFFFGHHGGHHIIHIJ,?;=&9EF=+!  ),2(,3>D31690-(043197HRRQQQQQRRPNKIHGHIILLLLLNNMIGFKNMNOONMNMONMMMMNMLKKLMNMLKJKIJIIGFEEHIIHGABEGHHHHIIIIHJK?3@>.8?<<>:8"" (,""#8?B?B69:\4,*)89:@?GRQQQRQQQQPMKJHGHIJJKMMMNOMJFJKLMONNNNNNONLNNNLLLKKLMNNMKKKKKJIIFEFGHIGEABCFHIGJIIIIIIJ;B8)<:65+,3E-;<<>5).1U28:@96:QQPRQQPPPNMKIHIHHJMMMNNMNLIIJLLMMNNNNMNONNNMMNMMNMMMNOMMLKKLKIIF?FGFGFDBEEEHIKKJHHIJJK<14-0>*($!#70'"#!"('+.@%&::37,551HPN58BQPPQQPPPONKJHFGJKNNMNMMMMMKJKLLMMNNNNNONOONNNMMLLLNNNPNNMMKAJKJDGDHGGEDDEFEHJKKIIIIKKK;?:5>2-(3&;/ ##"+,84*/+,..4-033>54PaMRQQPPQPPONLIGFGKONMNMLMMMLKJMMMMNONOOOOOPPOONONMKKLLLOONNMLKJIIHFHHFEDEFFEFGJKKJIIKLLL@98*4C<33=!+)57% 1>*.FK?-(37+2;>B/66%/1;RRRQPQPPOMKJHINOONMKJJKMMLKIMNNNOONOOOOPPOPONNNNMLLKLLMNMLKIJHJIHHHFDDDDFGHIJKKKKKLLLL8%3?36"2AB?+!-,,%-+((271/'# :36A49-C5(./89SSRRPPPONNLKIINNMJKKJIINNMKIMNNNPOOOPOPPPPPOOOONMLKLLKKJIKIGIGIHJIHFDCCCFHIJKLJKKLMLKK(.1?*:+;EHF65/.93&-;0, 0,,2#1-:1A01,-&.0:)/@1//316QNTSSQPPQPONNMKNMKKKLLJJIIMMKMNOOONOPPPOPPPPPPPOOMKKJJJHHGFGFGEEHIHHFEDCCEHIJKKKLLLMKKK"166898$(.4"%#+3)"/@4%<67(9;8/,@,/;96#4/;V@TSTTSSRRROONNNNKKKKKJIHIJNMMNMMONPPPPPPPPPPOPONMJJJKJHIHGFFEDEIHGFEEDDFGGIJJKKKMMMLJK.1864?42!(*"%#1!0C*#%,+85G@5V63=71,28:2=NUUWUUZYXUSPONONLLJJHGHGGINOMMMMONOPPOPPPPPPNOONKKJIIJIHHGFFFEHHEFFEFFFGHHHJJKKLLMLKKL,296$-&7)+'#" )298'(#*'-*10163:?7*+%-:@@9NXYWSPVVVVQPOOMLLIGHFGIJJLMLLNNOONNOOOPPQPNMNNMKKJJJIJIHGEFFGGGFEFFFGGGHIIKJJKKLLLMKM63??3+$17&#&(%$3.+$.$#74,(4151*(,1-*035).JP\\6APTTURPONMKJIHGGIILJKNLNNOOONMNPPPPQPLMNNMLJIJJJJJIHHHHGHFEFEEEGFIHHIJIIJKKMLLLMB=@@<6".38&"(/-,&7);@?(/;A*16<8*))*930%$'&L98E:AHRSUSPPNMKJIIGGJJJLLMMMNNONMNOPPPPQPEFONLLJJJKKKKIIHIIIIGFFFGHGGHHIIIIKJKKLLNNN78>A@=*",%(0*%(--3+7289&-$*'%44,$".(2A*..*2,.0A96*27,) ",2),.*23)-0,0+%#+-1.;0%095?52=-06L-&91,3&!,$&)('24/)-'()!.1861;5;;:BEMPPQPPPPPPPRPPOMKILLLHIIIJLNMNNNNNOOOPPPPPPQPPOPMLKLMLKLKKJJIJJIKLNNONLKMMMMMKLMNONNN+55=99>3+3)/,6&-(#)%'*2A0*.)(,$+3B:::9FJLMLQRRTSRQPPPPRPOPMMKLMIHHJKKLLLMMMNNOOOPPPPPQPPPPPPNLLLLJKKKKJIHKJKKNNONLLMMMMLMLLOONMM8+AG4?D8#(+(@01/;(-.-%.*0.1)6I/?@B9:@NUQQRTUUTRRRQPPPPPOOMNKMMHEHKKLMMLMMMMNNOOPPPPPPPPPPPONMMLKJKLKKJIIIKKKMMONKMMMLLLLLMMNMMK70;B90$""',3;9(,;)*%0- "..2:/586,HHBPRTVUTTRRRQPPPONNNMNMMLJFFKKMNMMNNNNMNONPOPQPPPPPPPPNNMLJKMMMKKKIIJJKKLONKMMLLLLLLLMNMML=;D@<,N:13&+.)#&.-*/5::65<@<:NJJIDRUVVUTTSRQQQQPPONONOMLMMIGFGJLMMNMNNNMNNNOOPPPPPPPPPPNNMLKMMMNMLKJJIIIKKOMKLLLLLLMMLMNNML2&=>26..5?8%7+-!*+0(+316=5G@E<8@IMTQVUVUUTTSQQPPPPONMOOONLNMIHHGGJKNNNNONNMMMOOPOPPPPQPPPOONKLMNNNONKKKJIIIKOMLLLMMONMMMMMNML:%71.+852=8,).+#(1=,.<95CFELBCA=HRVVUUUUTUTSQPQPPOONNNOPNNNLJHHGGIKMLLNNNNMNMOOOOPPPPPPPPPONLMMNNNONMMKKJJIIMMMLNNNNMMMMMMNMM7/"16*%%1+2:#+'6.,*3(H0>99?KI@HG@CJTRRVVVUTUUSRPPPPPOONONNMNMMMKIIIIILMMNONLLMNOOOOOPPPPPPPPPONMMMLNNPPNMMLKJIJLONNNNONNMMMMMMMM66 @K@A*6.92(**1/%3")'^<6@NEECDHJRVWVVWVUUSSRRPPPOPNNONMLKNMMLKJIGJHHMPOPOMMNNNOOOPPOPPPPPOPPONMMNNOPPONMMMLKKKNOONNONNMMMNNNNO++. =;>DFKLJMOIUYXWWWUTSRSRRQPPPNNNONMLMMMMKKKJJFEJMNPONNNMOONPPPPPQPPPOOOONMNPPPPOONMMMMLKJLOOOOONNNMMNOOOP"%?X^572.:/CC53#.=%*%5>H;@@GNGPRYVVXYXWXVSQSTRRQPPNNNOPPOONMMMLJLJJIGEGOPNOONNOOPPPPPQQPPPOOPONNPPPPPPOOMMMLLLKLLOOOOOMNMMNOPPO*&6H@4@87,4:@7*,D@]::>1.4;.@;9:>PIPPMX_\\\YX[\\VTTSQPPPNONOLNOPNMKMMLKLKKKMMGJPPPPPPPPPPOPPPQPPPPPOOOOPPPPPPPOOOOONNMMMMLMMMNNNNNOPON;8@?:7B>MKM__`]_\\^]\WRTTRQPNOOPONMMPOMLLKKKKKMLMLKKPOOOOPPPPPPPPQQQPPPPPNONPPPPONMMMNNNOONNNNMNNNNONMOOPPNBW@6(???-;*35M8N998=4C578>43>C:M[Ufa\`]^\\WTSPRQPONPPPNNNONOLKKKKJLLKJKMLPOPOPPOPPPPPPPQPPPPPPONNPONMMMLLLLMOOOOOOOOOOOOONMOPPONED@@5;?A"$/.138:CD0K12/(31*:B=AGJ^jlcc[\`\ZWSPNQPPMNPONONNPNKMMMLJMMKKJNMKKMMOOOPPPPPPPPPPPPPONMNNMLLKLKLLMMMMMNOOOPOOOONMLOPPONFCC<66:BP)"#+=454/'$$*"'#+595@:8CGJQfPfL[X_\XQPPPONMONMOPONONNLMOMJKIKILMKKJJOOOOPPPPQPPPPQPPOMMNMLMLKJJLLMMMMLLMOPPOOONNMNPPPPPE<==R7"(17<5507H;,90'2",@4;>;612CIIWGE@4#<344+. $)41?=87#:7>GKECB4%-,>>A_XVPPPNMNOPPPRWWWWVTOPNKIKKJJJKKKJMPOPPPPPPPPQQQPONMMMNNLKLMNNNOOMNNMMMNONNONNOPPPPP9,+52&/1)#CFFH==O353:;=@H_WRPNOPPPPPQUXYYZXUQPOOJJIKKJJKLLLOOOPPPPPPPPPPPPONNNNMMMMNNOONOOPNNMMMNMMNNNOOPPPP;010#(0,(%13I1/2+'"#)#=8-.453"%2=/8&"2 %""');=/5-;5;.3858)"-,,3"*0)!''""#??93039?6=;:1%)6*/.5BB^\ZXVVWXVZ[ZZX\\XWXUUVTSPOOOOMMOLLMMLNPPPPPPPOONOPPPPPPPPPPPPPOOPPPPQQQPPOPOPPPPP-3:>&.50*#@&)&".4++%0850J8902@@:>:/.-%-&!/45/#\]\XXWWWYZZYY\[YVVVVWVUVTNONNNNMMMONMPPPPPPPPPOOPOOPOPPPOOPPPOOOPPPPQQQQPPPPPQPP++3;4($3) 2:#$ 1/11? 73;3.1;74?C>7*8)-&G',%6;:W]\ZYXWYYYYXZ\\YM;39TVUVUTPONNNMLMOONMPPPPPQPPPOPPPOOOPPPOOPPPPOPPPPPQQQQQPPPQPP0//52/1,2%&86%+*#$=?G3:?:2%2<71745?5)/053)1.+%%&2@5/39X5;B6.'+%&*&"(*$B1-_!1',Ni`WX\[Z\[ZWX[\\\^^^^dea]M.,URPPNKJIJINONMLORQQRQPPPPPPPPPPOPPPPPPPONNPQQQQQQQQQPOO"$.):@!"-)035C2B2@A5-)22"."$+(.($"&02=fb`[Z[Y\[YX\\\\\]]]^ccaac,*PSPONLIHJIOMLKKOPRRRQPPPPPPPPPPPPQRQPPPPPOOPQRRQQQQPPOO27'0-'%%)##-1+11;21>@2"%$9):%)0O,3+"" #,7<;Ehd]][[\\\\\\\]]]]\_ab^fZ+ORPONMHIKIKMLKLNPQRRRPPQQPPPPPPPPQQQPPPPPOOPPQQQQQPPOPO%(,6=K7;')7/3:0183/4XB*5,%()O.&00)  '*,,?OFW\V__\]\^\\\\[Z^]^afgjT,,A6PMLKIILKJMLKMNPPSRRQPRQQPPPPPPPPQRQPOPPPOPPPPQQPPOOON"K:M6,0-22.6;;8?88@88/)% #(0-*#/'$! #"&4.86@:$IN_^\]\\\[\\\\^^afilndZ6%QNJJIHLKKLKKMNNPRTSRPPPPPPQPPPPNPRQPOPPPPOPPPPPPONONN,-+43,177?A6;C<:@<)-0-(##*/7+%'"%"#//32-#2?@P]^]\\\[Z\]^^]_`cdopgqe+MMKIIFKKLKJJJMMPQSTTRPPPPOPPPPONPRQPPPONPPPPNPPPOOMMM!$'+4>A:70?@F<7@GGG@5(( #(<)'3:+%##1/4/++),+.,03"(@R^\\\\Y[\]]_^_abaktrvY1DOLKIFHJJHJJIKOPPRSTTRQQPPPPPPMMORPPPOONMPOONNPOONMLK"'"0@:88:3?866;K?FKC4+1!%"<+/*"#*#B/4%$-%++.(+ 070\\Z\\[\\]_`_acadltopH5HPPKHFFJJIIIIINPPQQSSRSRQQPPPNMMOQPPPOMMMMNONMPPONMLM-70/8:8@7127*.=2PMKGGFIIIKKKPPOPPOPPRRRQQPONLKLNPPPOOMNONOMONNNONMML/+84'.=A9F:G7;@BBOMZE31( "").>P-+3 7g\^6"/1%".D5\\\ZXX\^`abffffhjnpqJQIPMKLIHGJIOOOONJDFKNORRPPPNMLJJMONNNNNMNPPPNONMLKKKKK&.+().#3PQ2-7ADAEUQA73.%% -?V)*) &396V)+''()(0583b`ZY[[]``cbfhinkko@@JFFNMKIIGINPNONJGHGLOPPONONNMKKLNNNONMNNOPQPPPONLLKKJK#1!"017"Bk036CC>@K\?XD&,-!1QD2/.'&+,+J7/231?548Q+01,2@\[\]]`aeffhUZ97NfILK0*810Y;,# #"%16(%&""13\5M=6%+85-3VSI`bcXH@<;H98'4XqZNKIHHGJMONMJHFJMMMKIJKNMKJILMKNOPNMNMMMNNPPPNNOMKKP""##).#!)2596A@CFAflOP@0c:8K).1 .*-ENctom='3 390-,;9:6<8C+,/.(.8GHYQPKJNJKIICJJLJJDCFEEHHHIFIKLJJKOONNNNNOPPQPPPONMMPP/$ "9439*4?=CFlKDhllO?NsZLPN2:.#5.7'.)$)->@CVolkkfW@^t@?\f,3)=6/.':5WrrpiW+0(""W(+J,0R8;)09F:7;X@fWOQROOKJIHHHIDBHGHIJHEHHGHHHIJLJIJJLKNOOPPPQPPPPPPNPQRR)("-33+')8=FA@Lld]ng_n_6OME9!<.-8?F668Tbaopqo9)-#0*+.//+2::@94BgofmnnneaPQNMJHHHGHIFBDGHIJGFIIGHHJIJKKIKJLKNPPOPQQPPPPPPPQRRQ%!'*$"%.+"805@7:@kjbhmKCU/ED;3"&4%5G`jXVIqoopqoQ/3B&$'W8bwMtnqnmmqooon\TRPNLKJIHGGGEBDHGJMHIIJHGJIKLKKJKKKKOOPPPPPPPPQOOPRRRQ!#(*#)0" 46>B>9[kieIk9cj;(]@9+1()9QUpIppoooqqj483." /\c\xwwwmrnjkmoqpmgQQPMLKKJHGFFCBDIHJNIJJJHGEJMNNMKLMLKOOPPQQQQPQPOPQRQQQ(,-$-8($<5B:94TjkNCQ9ld1))-:733#CBmo`Woonoqpo@;>))"^qvusutusrplknoqolfPOOMKKKJIGFECCCJHMMJKIIIFHNOOONMKMMNONPQQQRRRQPPPQQRRQ /[2#,42.&7;A9fkjZhfI4HU52".>(+*%T.3F?ejlkklmnooj]hekmoopqroqpppoljhffjjfcaUTQQPOJJIHHGFDDDBADCFKLMKGEHJQRQPNOOMOOPQPQSTTQQPPPQQQQgri/doc/examples/example6.gri0000644000175000017500000000320513147557614014627 0ustar psgpsg# Example 6 -- Plot IR image of Gulf of Maine # Define characteristics of norda images # Note that the pixel to temperature conversion formula is # # Temperature = 5C + pixel_value / 10 # # where pixel_value ranges from 0 to 255. Thus, a pixel # value of 0 corresponds to a temperatuer of 5C, and # 255 corresponds to 30.5C; this is why the limits # \0val and \255val, for use by the `set image # range' command, take on these values. \0val = "5" # 0 in image \255val = "30.5" # 255 in image .rows. = 128 .cols. = 128 .pixel_width. = 2 .km. = {rpn .cols. .pixel_width. *} # get filenames query \filename "Name image file" ("example6image.dat") query \maskname "Name mask file" ("example6mask.dat") # get data open \filename binary uchar set image range \0val \255val read image .rows. .cols. box 0 0 .km. .km. close open \maskname binary uchar read image mask .rows. .cols. close # find out what grayscale method to use query \histo "Do histogram enhancement? (yes|no)" ("no") query \minT "T/deg for white on page? " ("10") query \maxT "T/deg for black on page? " ("15") \incT = "1" # set up scales. set x size 12.8 set y size 12.8 set x name "km" set y name "km" set x axis 0 .km. 32 set y axis 0 .km. 32 # plot image, grayscale, and histogram if {"\histo" == "yes"} set image grayscale using histogram black \maxT white \minT else set image grayscale black \maxT white \minT end if draw image draw image palette left \minT right \maxT increment \incT draw image histogram if {"\histo" == "yes"} draw title "Example 6: grayscale histogram enhanced" else draw title "Example 6: grayscale linear \minT to \maxT" end if gri/doc/examples/example3.txt0000644000175000017500000000001513147557614014656 0ustar psgpsgexample3.gri gri/doc/examples/example12.ps0000644000175000017500000005070013147557614014547 0ustar psgpsg%!PS-Adobe-2.0 EPSF-1.2 %%Creator: Gri2.2.4 (released 1999-Oct-20). User=kelley, commandfile=example12.gri %%Title: example12.ps %%CreationDate: Thu Oct 21 11:30:30 1999 %%Pages: (atend) %%BoundingBox: (atend) %%TemplateBox: 0 0 612 792 %%DocumentFonts: (atend) %%Endcomments % NOTE: The Gri postscript dictionary is being converted to the Adobe % Illustrator 3.0 dialect of PostScript, as described in the Adobe % documents stored at URL % http://www.adobe.com/Support/TechNotes.html % (as of Jan 1996, this doc is number 5007). When the conversion % is complete, the Adobe Illustrator drawing program -- and any % program compatible with AI -- will be able to edit Gri output. % % The IslandDraw (TM) program is able to read Gri output % at this time; remarkably, it can read/edit arbitrary PostScript. % % The definitions below are presented in the same order as the Adobe % manual. The stack configuration before and after is shown in curly % brackets. All the operators are listed, but only some are defined % here. Most things are faithful, except that no distinction is made % between colors for stroking and filling paths. The string 'WRONGLY' % appears with commands that are approximations. % % PDF-style abbreviations: /rg {setrgbcolor} def % {red green blue} {-} set RGB color /RG {setrgbcolor} def % {red green blue} {-} set RGB color /q {gsave} def /Q {grestore} def /W {clip} def /W* {eoclip} def % % Gri-specific abbreviations: /hsb {sethsbcolor} def % {hue saturation brightness} {-} set HSB color % % Following all try to mimic Adobe Illustrator % % Mimicking section 5.1 of Adobe manual: %A % {flag A} {-} Determine whether % following object can % be selected. Flag=1 % prevents selection; % flag=0 allows it. % Mimicking section 5.2 of Adobe manual: %u % {u} {-} start group %U % end group %q % as 'u' but first item is a clip path %Q % as 'U' but first item is a clip path % Mimicking section 5.3 of Adobe manual: /g {setgray} def % {gray g} {-} Set gray for fill % path, WRONGLY used % for stroking also. /G {setgray} def % As 'g', but for filling path. %k % Set cmyk color for filling path. %K % As 'k', but for stroking path. %x % Set cmyk custom color for filling path. %X % As 'x' but for stroking path. %p % Define pattern for filling path. %P % As 'p' but for stroking path. %O % Specify whether overprinting for fill paths %R % As 'O' but for stroking path. % Mimicking section 5.4 of Adobe manual: /d {setdash} def % {[array] phase d} {-} Set dash. /i {setflat} def % {flatness i} {-} Set flatness. /j {setlinejoin} def % {linejoin j} {-} Set line join. /J {setlinecap} def % {linecap J} {-} Set line cap. /M {setmiterlimit} def % {miterlimit M} {-} Set miter limit. /w {setlinewidth} def % {linewidth w} {-} Set line width. % Mimicking section 5.5 of Adobe manual: /m {moveto} def % {x y m} {-} Move to locn /l {lineto} def % {x y l} {-} Draw line to locn % not a smooth point. % WRONGLY, no % distinction is made % between smooth and % corner. %L % {x y L} {-} As 'l' but a corner %c % Bezier curve to smooth point. %C % As 'c' but to corner point. %v % Something else to do with Bezier. %V % %y % %Y % % Mimicking section 5.6 of Adobe manual: %N % {N} {-} As 'n' for nondrawn stuff /n {newpath} def % {n} {-} WRONGLY interpreted % as path constructor /F {fill} def % {F} {-} Fill current path. %f % {f} {-} 'F' but close first /S {stroke} def % {S} {-} Stroke current path. %s % {s} {-} 'S' but close first %B % {B} {-} As 's' but don't empty path. %b % {b} {-} As 'f' but don't empty path. %H % no-op (weird huh?) /h {closepath} def % {h} {-} Close current path %W % Used to create masks. % Mimicking section 5.7 of Adobe manual: %a % Begin text block ... %e % Similar to 'a' but ... %I % Similar to 'a' but ... %o % Similar to 'a' but ... %r % Similar to 'a' but ... %t % {len (string) t} {-} Render string. %T % End block of text % That's the end of the Illustrator stuff. Following are some Gri % definitions which provide a temporary way of handling fonts. /sf {setfont} def % {fontname sf} {-} Set font name. /sh {show} def % {(text) sh} {-} Show text. /sc {scalefont} def % {size sc} {-} Scale font. % Gri items which should be translated to Illustrator format: /rl {rlineto} def /rm {rmoveto} def % Procedures /cimdict 7 dict def /cim { cimdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def q xll yll translate xur xll sub yur yll sub scale /do cl 3 mul string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop} false 3 colorimage Q end } def /imdict 14 dict def /im { imdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def /imagemap exch def q % Add the mapping to the transfer function (ref: white book, p 743. [{255 mul cvi imagemap exch get} /exec load currenttransfer /exec load] cvx settransfer xll yll translate xur xll sub yur yll sub scale /do cl string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop}image Q end } def /frdict 5 dict def /fr { frdict begin /yt exch def /xr exch def /yb exch def /xl exch def n xl yb m xl yt l xr yt l xr yb l h F n end } def /plusdict 3 dict def /_plus { plusdict begin dup 0.5 mul /t0 exch def /t1 exch def 0 t0 rm 0 t1 neg rl t0 neg t0 rm t1 0 rl t0 neg 0 rm end } def /timesdict 3 dict def /_times { timesdict begin dup 0.353553 mul /t0 exch def 0.707106 mul /t1 exch def t0 neg t0 rm t1 dup neg rl t1 neg 0 rm t1 dup rl t0 neg dup rm end } def /boxdict 3 dict def /_box { boxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm end } def /filledboxdict 3 dict def /_filledbox { filledboxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm F end } def /diamonddict 2 dict def /_diamond { diamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm end } def /filleddiamonddict 2 dict def /_filleddiamond { filleddiamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm F end } def /triangleupdict 5 dict def /_triangleup { triangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm end } def /filledtriangleupdict 5 dict def /_filledtriangleup { filledtriangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm F end } def /trianglerightdict 5 dict def /_triangleright { trianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm end } def /filledtrianglerightdict 5 dict def /_filledtriangleright { filledtrianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm F end } def /triangledowndict 5 dict def /_triangledown { triangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm end } def /filledtriangledowndict 5 dict def /_filledtriangledown { filledtriangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm F end } def /triangleleftdict 5 dict def /_triangleleft { triangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm end } def /filledtriangleleftdict 5 dict def /_filledtriangleleft { filledtriangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm F end } def /circdict 5 dict def /_circ { circdict begin 0.5 mul /t0 exch def currentpoint /t2 exch def /t1 exch def S n t1 t2 t0 0 360 arc t1 t2 m end } def /bulldict 3 dict def /_bull { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 360 arc h F S end } def /filledhalfmoonupdict 3 dict def /_filledhalfmoonup { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 180 arc h F S end } def /filledhalfmoondowndict 3 dict def /_filledhalfmoondown { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 180 360 arc h F S end } def 1 1 scale 10.0 M 1 j /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-ISOLatin1 exch definefont pop /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Bold-ISOLatin1 exch definefont pop /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-ISOLatin1 exch definefont pop /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Bold-ISOLatin1 exch definefont pop /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Roman-ISOLatin1 exch definefont pop /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Bold-ISOLatin1 exch definefont pop /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Italic-ISOLatin1 exch definefont pop /Symbol findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Symbol-ISOLatin1 exch definefont pop /Times findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-ISOLatin1 exch definefont pop /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Bold-ISOLatin1 exch definefont pop /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Roman-ISOLatin1 exch definefont pop %%EndProlog %%Page: 1 1 /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:# Example 12 -- Linegraph with key inside plot %gri:# $Id: example12.ps,v 1.1 2000/05/11 15:07:55 dankelley Exp $ %gri: %gri:set font size 10 # points (1in = 72pt) /Helvetica-ISOLatin1 findfont 10.00 sc sf %gri:set x size 10 # cm %gri:set y size 10 # cm %gri:set x name "Height" %gri:set y name "Total Energy" %gri: %gri:# Following axis setups not necessary; will autoscale if you %gri:# remove these. %gri:set x margin 3 %gri:set x axis 800 960 20 %gri:set y margin 3 %gri:set y axis -0.4 1 0.2 %gri: %gri:# Read data. Format is columns (x, y1, y2, y3, y4) %gri:open example12.dat %gri:read columns x y %gri:draw curve %^ scale 1 85.35 800 1.77812 1 85.35 -0.4 203.214 0.709 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 85.35 166.64 m 174.26 207.28 l 263.16 211.34 l 352.07 288.56 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 77.0 67.0 m (800) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 112.5 67.0 m (820) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 148.1 67.0 m (840) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 183.7 67.0 m (860) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 219.2 67.0 m (880) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 254.8 67.0 m (900) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 290.4 67.0 m (920) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 325.9 67.0 m (940) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 361.5 67.0 m (960) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 85.35 85.35 m 85.35 85.35 l 85.35 79.66 l 85.35 85.35 l 120.91 85.35 l 120.91 79.66 l 120.91 85.35 l 156.47 85.35 l 156.47 79.66 l 156.47 85.35 l 192.04 85.35 l 192.04 79.66 l 192.04 85.35 l 227.60 85.35 l 227.60 79.66 l 227.60 85.35 l 263.16 85.35 l 263.16 79.66 l 263.16 85.35 l 298.72 85.35 l 298.72 79.66 l 298.72 85.35 l 334.29 85.35 l 334.29 79.66 l 334.29 85.35 l 369.85 85.35 l 369.85 79.66 l 369.85 85.35 l 369.89 85.35 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 213.1 54.4 m (Height) sh % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 85.35 369.85 m 85.35 369.85 l 85.35 375.54 l 85.35 369.85 l 120.91 369.85 l 120.91 375.54 l 120.91 369.85 l 156.47 369.85 l 156.47 375.54 l 156.47 369.85 l 192.04 369.85 l 192.04 375.54 l 192.04 369.85 l 227.60 369.85 l 227.60 375.54 l 227.60 369.85 l 263.16 369.85 l 263.16 375.54 l 263.16 369.85 l 298.72 369.85 l 298.72 375.54 l 298.72 369.85 l 334.29 369.85 l 334.29 375.54 l 334.29 369.85 l 369.85 369.85 l 369.85 375.54 l 369.85 369.85 l 369.89 369.85 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 10.00 sc sf % gr_show_at() BEGIN 0 g 0 G 57.5 81.7 m (-0.4) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 57.5 122.4 m (-0.2) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 69.2 163.0 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 60.8 203.7 m (0.2) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 60.8 244.3 m (0.4) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 60.8 285.0 m (0.6) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 60.8 325.6 m (0.8) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 69.2 366.2 m (1) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 85.35 85.35 m 85.35 85.35 l 79.66 85.35 l 85.35 85.35 l 85.35 125.99 l 79.66 125.99 l 85.35 125.99 l 85.35 166.64 l 79.66 166.64 l 85.35 166.64 l 85.35 207.28 l 79.66 207.28 l 85.35 207.28 l 85.35 247.92 l 79.66 247.92 l 85.35 247.92 l 85.35 288.56 l 79.66 288.56 l 85.35 288.56 l 85.35 329.21 l 79.66 329.21 l 85.35 329.21 l 85.35 369.85 l 79.66 369.85 l 85.35 369.85 l 85.35 369.85 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 52.6 199.2 m 90.00 rotate (Total Energy) sh -90.00 rotate % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 369.85 85.35 m 369.85 85.35 l 375.54 85.35 l 369.85 85.35 l 369.85 125.99 l 375.54 125.99 l 369.85 125.99 l 369.85 166.64 l 375.54 166.64 l 369.85 166.64 l 369.85 207.28 l 375.54 207.28 l 369.85 207.28 l 369.85 247.92 l 375.54 247.92 l 369.85 247.92 l 369.85 288.56 l 375.54 288.56 l 369.85 288.56 l 369.85 329.21 l 375.54 329.21 l 369.85 329.21 l 369.85 369.85 l 375.54 369.85 l 369.85 369.85 l 369.85 369.85 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 10.00 sc sf %gri:draw label for last curve "1" %^ scale 1 85.35 800 1.77812 1 85.35 -0.4 203.214 % gr_show_at() BEGIN 0 g 0 G S n 356.2 285.0 m (1) sh % gr_show_at() END %gri: %gri:rewind %gri:set line width {rpn ..linewidth.. 1.5 *} %gri:read columns x * y %gri:draw curve %^ scale 1 85.35 800 1.77812 1 85.35 -0.4 203.214 1.063 w 0 g 0 G 1.0 i 0 J 1 j 1.063 w 10.0 M [] 0 d 85.35 207.28 m 174.26 227.60 l 263.16 233.70 l 352.07 308.89 l S % END GriPath stroke/fill %gri:draw label for last curve "2" %^ scale 1 85.35 800 1.77812 1 85.35 -0.4 203.214 % gr_show_at() BEGIN 0 g 0 G S n 356.2 305.3 m (2) sh % gr_show_at() END %gri: %gri:rewind %gri:set line width {rpn ..linewidth.. 1.5 *} %gri:read columns x * * y %gri:draw curve %^ scale 1 85.35 800 1.77812 1 85.35 -0.4 203.214 1.595 w 0 g 0 G 1.0 i 0 J 1 j 1.595 w 10.0 M [] 0 d 85.35 227.60 m 174.26 247.92 l 263.16 256.05 l 352.07 329.21 l S % END GriPath stroke/fill %gri:draw label for last curve "3" %^ scale 1 85.35 800 1.77812 1 85.35 -0.4 203.214 % gr_show_at() BEGIN 0 g 0 G S n 356.2 325.6 m (3) sh % gr_show_at() END %gri: %gri:rewind %gri:set line width {rpn ..linewidth.. 1.5 *} %gri:read columns x * * * y %gri:draw curve %^ scale 1 85.35 800 1.77812 1 85.35 -0.4 203.214 2.393 w 0 g 0 G 1.0 i 0 J 1 j 2.393 w 10.0 M [] 0 d 85.35 247.92 m 174.26 268.24 l 263.16 278.40 l 352.07 349.53 l S % END GriPath stroke/fill %gri:draw label for last curve "4" %^ scale 1 85.35 800 1.77812 1 85.35 -0.4 203.214 % gr_show_at() BEGIN 0 g 0 G S n 356.2 345.9 m (4) sh % gr_show_at() END %gri: %gri:# Draw the key. %gri:# NOTES: %gri:# (1) This key is inside the plot; it's location was chosen %gri:# after looking at the data. To put the key in a different %gri:# location, alter the .key_topleft_x. and .key_topleft_y. %gri:# variables. For example, you could put the key to the %gri:# right of the plot by changing the next line to: %gri:# `.key_topleft_x. = {rpn ..xsize.. 0.5 +}' %gri:# (2) The variable .dy_inc. is the spacing between lines in %gri:# the key. It should be OK even if you change the %gri:# font size above. %gri:.key_topleft_x. = 0.5 # cm right of left axis %gri:.key_topleft_y. = 0.5 # cm below top axis %gri:.dy_inc. = {rpn ..fontsize.. pttocm 1.5 *} %gri: %gri:draw label "1 = Model 1A" at {rpn ..xleft.. xusertocm .key_topleft_x. +} {rpn ..ytop.. yusertocm .key_topleft_y. -} cm %^ scale 1 85.35 800 1.77812 1 85.35 -0.4 203.214 % gr_show_at() BEGIN 0 g 0 G S n 99.6 355.6 m (1 = Model 1A) sh % gr_show_at() END %gri: %gri:.key_topleft_y. += .dy_inc. %gri:draw label "2 = Model 2A" at {rpn ..xleft.. xusertocm .key_topleft_x. +} {rpn ..ytop.. yusertocm .key_topleft_y. -} cm %^ scale 1 85.35 800 1.77812 1 85.35 -0.4 203.214 % gr_show_at() BEGIN 0 g 0 G S n 99.6 340.6 m (2 = Model 2A) sh % gr_show_at() END %gri: %gri:.key_topleft_y. += .dy_inc. %gri:draw label "3 = Model 1B" at {rpn ..xleft.. xusertocm .key_topleft_x. +} {rpn ..ytop.. yusertocm .key_topleft_y. -} cm %^ scale 1 85.35 800 1.77812 1 85.35 -0.4 203.214 % gr_show_at() BEGIN 0 g 0 G S n 99.6 325.6 m (3 = Model 1B) sh % gr_show_at() END %gri: %gri:.key_topleft_y. += .dy_inc. %gri:draw label "4 = Model 2B" at {rpn ..xleft.. xusertocm .key_topleft_x. +} {rpn ..ytop.. yusertocm .key_topleft_y. -} cm %^ scale 1 85.35 800 1.77812 1 85.35 -0.4 203.214 % gr_show_at() BEGIN 0 g 0 G S n 99.6 310.6 m (4 = Model 2B) sh % gr_show_at() END %gri: %gri:draw title "Example 12 -- Total heating vs height of boundary layer" %^ scale 1 85.35 800 1.77812 1 85.35 -0.4 203.214 % gr_show_at() BEGIN 0 g 0 G 104.3 398.3 m (Example 12 -- Total heating vs height of boundary layer) sh % gr_show_at() END %gri:quit showpage %%Trailer %%BoundingBox: 43 50 380 408 %%DocumentFonts: Courier Helvetica Palatino-Roman Palatino-Italic Symbol Times-Roman %%Pages: 1 gri/doc/examples/example7d.dat0000644000175000017500000000601713147557614014767 0ustar psgpsg 0.216 -0.666 0.284 -0.547 0.244 -0.613 0.292 -0.535 0.093 -1.032 0.201 -0.697 0.221 -0.656 0.152 -0.818 0.036 -1.444 0.070 -1.155 0.199 -0.701 0.287 -0.542 0.853 -0.069 0.193 -0.714 0.089 -1.051 0.273 -0.564 0.358 -0.446 0.232 -0.635 0.252 -0.599 0.066 -1.180 0.149 -0.827 0.170 -0.770 0.308 -0.511 0.154 -0.812 0.309 -0.510 0.402 -0.396 0.219 -0.660 0.226 -0.646 0.307 -0.513 0.188 -0.726 0.255 -0.593 0.082 -1.086 0.275 -0.561 0.187 -0.728 0.218 -0.662 0.688 -0.162 0.513 -0.290 0.206 -0.686 0.053 -1.276 0.516 -0.287 0.130 -0.886 0.158 -0.801 0.218 -0.662 0.139 -0.857 0.214 -0.670 0.326 -0.487 0.314 -0.503 0.205 -0.688 0.425 -0.372 0.183 -0.738 0.314 -0.503 0.164 -0.785 0.288 -0.541 0.187 -0.728 0.145 -0.839 0.132 -0.879 0.256 -0.592 0.347 -0.460 0.175 -0.757 0.080 -1.097 1.794 0.254 3.077 0.488 1.256 0.099 0.222 -0.654 0.108 -0.967 0.125 -0.903 0.100 -1.000 0.203 -0.693 0.261 -0.583 0.517 -0.287 0.333 -0.478 0.483 -0.316 0.294 -0.532 0.103 -0.987 0.246 -0.609 0.256 -0.592 0.401 -0.397 0.194 -0.712 1.045 0.019 0.179 -0.747 0.141 -0.851 0.814 -0.089 0.204 -0.690 0.230 -0.638 0.535 -0.272 0.155 -0.810 0.344 -0.463 0.837 -0.077 0.420 -0.377 0.255 -0.593 0.223 -0.652 0.149 -0.827 0.433 -0.364 0.347 -0.460 0.153 -0.815 0.236 -0.627 0.140 -0.854 0.176 -0.754 0.065 -1.187 0.131 -0.883 0.090 -1.046 0.144 -0.842 0.533 -0.273 0.153 -0.815 0.236 -0.627 0.337 -0.472 0.512 -0.291 0.225 -0.648 0.578 -0.238 0.355 -0.450 1.375 0.138 0.140 -0.854 0.715 -0.146 0.510 -0.292 0.314 -0.503 0.309 -0.510 0.313 -0.504 0.304 -0.517 0.164 -0.785 0.281 -0.551 0.125 -0.903 0.141 -0.851 0.183 -0.738 0.120 -0.921 0.471 -0.327 0.219 -0.660 0.210 -0.678 0.389 -0.410 0.469 -0.329 0.386 -0.413 0.406 -0.391 0.170 -0.770 0.195 -0.710 0.194 -0.712 0.279 -0.554 0.771 -0.113 0.284 -0.547 0.544 -0.264 0.161 -0.793 0.183 -0.738 0.091 -1.041 0.276 -0.559 0.239 -0.622 0.347 -0.460 0.938 -0.028 0.409 -0.388 0.176 -0.754 gri/doc/examples/example13.gri0000644000175000017500000000236113147557614014707 0ustar psgpsg# Example 13 -- TS diagram, with isopycnals # Draw Axes set line width axis 0.25 set line width 0.75 .tic_size. = 0.1 # cm set symbol size 0.03 .isopycnal_fontsize. = 8 # for isopycnal labels .axes_fontsize. = 10 # for axes set font size .axes_fontsize. set x margin 2 set x size 10 set y margin 2 set y size 10 set tic size .tic_size. set x name "Salinity / PSU" set y name "Potential Temperature / $\circ$C" set x axis 34 35 0.5 0.1 set y axis 2 10 1 set axes style offset draw axes 1 set clip on .old. = ..fontsize.. set font size .isopycnal_fontsize. set line width rapidograph 1 draw isopycnal 26.00 draw isopycnal 27.00 draw isopycnal 28.00 draw isopycnal 29.00 set line width rapidograph 3x0 draw isopycnal unlabelled 26.75 draw isopycnal unlabelled 26.50 draw isopycnal unlabelled 26.25 draw isopycnal unlabelled 27.75 draw isopycnal unlabelled 27.50 draw isopycnal unlabelled 27.25 draw isopycnal unlabelled 28.75 draw isopycnal unlabelled 28.50 draw isopycnal unlabelled 28.25 set clip off set font size .old. # # Draw the data. open example13.dat read columns x y set color blue set symbol size 0.1 draw symbol bullet set font size 14 set color black draw title "Example 13 -- TS diagram, with isopycnals" gri/doc/examples/example4.ps0000644000175000017500000005177213147557614014502 0ustar psgpsg%!PS-Adobe-2.0 EPSF-1.2 %%Creator: Gri2.7.0 (released 2001-mmm-dd). User=kelley, commandfile=example4.gri %%Title: example4.ps %%CreationDate: Mon Jul 23 11:14:48 2001 %%Pages: (atend) %%BoundingBox: (atend) %%TemplateBox: 0 0 612 792 %%DocumentFonts: (atend) %%Endcomments % NOTE: The Gri postscript dictionary is being converted to the Adobe % Illustrator 3.0 dialect of PostScript, as described in the Adobe % documents stored at URL % http://www.adobe.com/Support/TechNotes.html % (as of Jan 1996, this doc is number 5007). When the conversion % is complete, the Adobe Illustrator drawing program -- and any % program compatible with AI -- will be able to edit Gri output. % % The IslandDraw (TM) program is able to read Gri output % at this time; remarkably, it can read/edit arbitrary PostScript. % % The definitions below are presented in the same order as the Adobe % manual. The stack configuration before and after is shown in curly % brackets. All the operators are listed, but only some are defined % here. Most things are faithful, except that no distinction is made % between colors for stroking and filling paths. The string 'WRONGLY' % appears with commands that are approximations. % % PDF-style abbreviations: /rg {setrgbcolor} def % {red green blue} {-} set RGB color /RG {setrgbcolor} def % {red green blue} {-} set RGB color /q {gsave} def /Q {grestore} def /W {clip} def /W* {eoclip} def % % Gri-specific abbreviations: /hsb {sethsbcolor} def % {hue saturation brightness} {-} set HSB color % % Following all try to mimic Adobe Illustrator % % Mimicking section 5.1 of Adobe manual: %A % {flag A} {-} Determine whether % following object can % be selected. Flag=1 % prevents selection; % flag=0 allows it. % Mimicking section 5.2 of Adobe manual: %u % {u} {-} start group %U % end group %q % as 'u' but first item is a clip path %Q % as 'U' but first item is a clip path % Mimicking section 5.3 of Adobe manual: /g {setgray} def % {gray g} {-} Set gray for fill % path, WRONGLY used % for stroking also. /G {setgray} def % As 'g', but for filling path. %k % Set cmyk color for filling path. %K % As 'k', but for stroking path. %x % Set cmyk custom color for filling path. %X % As 'x' but for stroking path. %p % Define pattern for filling path. %P % As 'p' but for stroking path. %O % Specify whether overprinting for fill paths %R % As 'O' but for stroking path. % Mimicking section 5.4 of Adobe manual: /d {setdash} def % {[array] phase d} {-} Set dash. /i {setflat} def % {flatness i} {-} Set flatness. /j {setlinejoin} def % {linejoin j} {-} Set line join. /J {setlinecap} def % {linecap J} {-} Set line cap. /M {setmiterlimit} def % {miterlimit M} {-} Set miter limit. /w {setlinewidth} def % {linewidth w} {-} Set line width. % Mimicking section 5.5 of Adobe manual: /m {moveto} def % {x y m} {-} Move to locn /l {lineto} def % {x y l} {-} Draw line to locn % not a smooth point. % WRONGLY, no % distinction is made % between smooth and % corner. %L % {x y L} {-} As 'l' but a corner %c % Bezier curve to smooth point. %C % As 'c' but to corner point. %v % Something else to do with Bezier. %V % %y % %Y % % Mimicking section 5.6 of Adobe manual: %N % {N} {-} As 'n' for nondrawn stuff /n {newpath} def % {n} {-} WRONGLY interpreted % as path constructor /F {fill} def % {F} {-} Fill current path. %f % {f} {-} 'F' but close first /S {stroke} def % {S} {-} Stroke current path. %s % {s} {-} 'S' but close first %B % {B} {-} As 's' but don't empty path. %b % {b} {-} As 'f' but don't empty path. %H % no-op (weird huh?) /h {closepath} def % {h} {-} Close current path %W % Used to create masks. % Mimicking section 5.7 of Adobe manual: %a % Begin text block ... %e % Similar to 'a' but ... %I % Similar to 'a' but ... %o % Similar to 'a' but ... %r % Similar to 'a' but ... %t % {len (string) t} {-} Render string. %T % End block of text % That's the end of the Illustrator stuff. Following are some Gri % definitions which provide a temporary way of handling fonts. /sf {setfont} def % {fontname sf} {-} Set font name. /sh {show} def % {(text) sh} {-} Show text. /sc {scalefont} def % {size sc} {-} Scale font. % Gri items which should be translated to Illustrator format: /rl {rlineto} def /rm {rmoveto} def % Procedures /cimdict 7 dict def /cim { cimdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def q xll yll translate xur xll sub yur yll sub scale /do cl 3 mul string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop} false 3 colorimage Q end } def /imdict 14 dict def /im { imdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def /imagemap exch def q % Until version 2.6.0 used a 'settransfer' here, but that % triggers a bug in ps2pdf xll yll translate xur xll sub yur yll sub scale /do cl string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop dup length 1 sub 0 1 3 -1 roll { 1 index exch 2 copy get imagemap exch get 255 mul cvi put } for }image Q end } bind def /frdict 5 dict def /fr { frdict begin /yt exch def /xr exch def /yb exch def /xl exch def n xl yb m xl yt l xr yt l xr yb l h F n end } def /plusdict 3 dict def /_plus { plusdict begin dup 0.5 mul /t0 exch def /t1 exch def 0 t0 rm 0 t1 neg rl t0 neg t0 rm t1 0 rl t0 neg 0 rm end } def /timesdict 3 dict def /_times { timesdict begin dup 0.353553 mul /t0 exch def 0.707106 mul /t1 exch def t0 neg t0 rm t1 dup neg rl t1 neg 0 rm t1 dup rl t0 neg dup rm end } def /boxdict 3 dict def /_box { boxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm end } def /filledboxdict 3 dict def /_filledbox { filledboxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm F end } def /diamonddict 2 dict def /_diamond { diamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm end } def /filleddiamonddict 2 dict def /_filleddiamond { filleddiamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm F end } def /triangleupdict 5 dict def /_triangleup { triangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm end } def /filledtriangleupdict 5 dict def /_filledtriangleup { filledtriangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm F end } def /trianglerightdict 5 dict def /_triangleright { trianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm end } def /filledtrianglerightdict 5 dict def /_filledtriangleright { filledtrianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm F end } def /triangledowndict 5 dict def /_triangledown { triangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm end } def /filledtriangledowndict 5 dict def /_filledtriangledown { filledtriangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm F end } def /triangleleftdict 5 dict def /_triangleleft { triangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm end } def /filledtriangleleftdict 5 dict def /_filledtriangleleft { filledtriangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm F end } def /circdict 5 dict def /_circ { circdict begin 0.5 mul /t0 exch def currentpoint /t2 exch def /t1 exch def S n t1 t2 t0 0 360 arc t1 t2 m end } def /bulldict 3 dict def /_bull { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 360 arc h F S end } def /filledhalfmoonupdict 3 dict def /_filledhalfmoonup { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 180 arc h F S end } def /filledhalfmoondowndict 3 dict def /_filledhalfmoondown { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 180 360 arc h F S end } def 1 1 scale 10.0 M 1 j /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-ISOLatin1 exch definefont pop /Courier-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Oblique-ISOLatin1 exch definefont pop /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Bold-ISOLatin1 exch definefont pop /Courier-BoldOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-BoldOblique-ISOLatin1 exch definefont pop /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-ISOLatin1 exch definefont pop /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Bold-ISOLatin1 exch definefont pop /Helvetica-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Oblique-ISOLatin1 exch definefont pop /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Roman-ISOLatin1 exch definefont pop /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Italic-ISOLatin1 exch definefont pop /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Bold-ISOLatin1 exch definefont pop /Palatino-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-BoldItalic-ISOLatin1 exch definefont pop /Symbol findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Symbol-ISOLatin1 exch definefont pop /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Roman-ISOLatin1 exch definefont pop /Times-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Italic-ISOLatin1 exch definefont pop /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Bold-ISOLatin1 exch definefont pop /Times-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-BoldItalic-ISOLatin1 exch definefont pop %%EndProlog %%Page: 1 1 /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:# Gri was invoked by user named %gri:# kelley %gri:# on host named %gri:# Intrusion.phys.ocean.dal.ca %gri:# using the command %gri:# gri -y -p example4.gri %gri:# at time Mon Jul 23 11:14:48 2001. %gri:# %gri:# The user's ~/.grirc file ... %gri:assert {rpn 1 2 >} "Must have a > here" %gri:# ... end of users ~/.grirc file. %gri: %gri:# Example 4 -- Simple contour graph %gri: %gri:# %gri:# Read x-grid; blank-line means stop reading. %gri:read grid x %gri:0 %gri:.2 %gri:1 %gri: %gri:# Note that the x-grid was irregular. The y-grid %gri:# in this example is regular, so we can just set %gri:# it to range from 10 to 20, incrementing by 2.5. %gri:set y grid 10 20 2.5 %gri:# Thus we now have a grid 3 wide and 5 high. Let's %gri:# read the actual data now. %gri:read grid data %gri:1 2 3 %gri:2 3 4 %gri:3 4 5 %gri:4 5 6 %gri:5 6 7 %gri:# Now draw contours (automatically set; we could %gri:# have done `draw contour 2' to draw contour fro %gri:# value 2 or `draw contour 1 10 2' to draw contours %gri:# ranging from 1 to 10 with an increment of 2.) %gri:draw contour %^ scale 1 170.7 0 284.5 1 170.7 10 28.45 0.709 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 227.60 170.70 m 341.40 206.26 l 455.20 241.82 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 336.38 199.43 m 346.42 199.43 l 346.42 211.42 l 336.38 211.42 l 336.38 211.42 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 338.1 201.1 m (6) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 170.70 m 199.15 206.26 l 227.60 241.82 l 341.40 277.39 l 455.20 312.95 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 194.13 199.43 m 204.17 199.43 l 204.17 211.42 l 194.13 211.42 l 194.13 211.42 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 195.8 201.1 m (5) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 241.82 m 199.15 277.39 l 227.60 312.95 l 341.40 348.51 l 455.20 384.07 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 194.13 270.56 m 204.17 270.56 l 204.17 282.55 l 194.13 282.55 l 194.13 282.55 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 195.8 272.2 m (4) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 312.95 m 199.15 348.51 l 227.60 384.07 l 341.40 419.64 l 455.20 455.20 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 194.13 341.68 m 204.17 341.68 l 204.17 353.67 l 194.13 353.67 l 194.13 353.67 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 195.8 343.4 m (3) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 384.07 m 199.15 419.64 l 227.60 455.20 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 194.13 412.81 m 204.17 412.81 l 204.17 424.80 l 194.13 424.80 l 194.13 424.80 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 195.8 414.5 m (2) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 167.4 149.9 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 190.8 149.9 m (0.1) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 219.2 149.9 m (0.2) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 247.7 149.9 m (0.3) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 276.1 149.9 m (0.4) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 304.6 149.9 m (0.5) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 333.0 149.9 m (0.6) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 361.5 149.9 m (0.7) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 389.9 149.9 m (0.8) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 418.4 149.9 m (0.9) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 451.9 149.9 m (1) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 170.70 165.01 l 170.70 170.70 l 199.15 170.70 l 199.15 165.01 l 199.15 170.70 l 227.60 170.70 l 227.60 165.01 l 227.60 170.70 l 256.05 170.70 l 256.05 165.01 l 256.05 170.70 l 284.50 170.70 l 284.50 165.01 l 284.50 170.70 l 312.95 170.70 l 312.95 165.01 l 312.95 170.70 l 341.40 170.70 l 341.40 165.01 l 341.40 170.70 l 369.85 170.70 l 369.85 165.01 l 369.85 170.70 l 398.30 170.70 l 398.30 165.01 l 398.30 170.70 l 426.75 170.70 l 426.75 165.01 l 426.75 170.70 l 455.20 170.70 l 455.20 165.01 l 455.20 170.70 l 455.23 170.70 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 310.0 134.7 m (x) sh % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 455.20 m 170.70 455.20 l 170.70 460.89 l 170.70 455.20 l 199.15 455.20 l 199.15 460.89 l 199.15 455.20 l 227.60 455.20 l 227.60 460.89 l 227.60 455.20 l 256.05 455.20 l 256.05 460.89 l 256.05 455.20 l 284.50 455.20 l 284.50 460.89 l 284.50 455.20 l 312.95 455.20 l 312.95 460.89 l 312.95 455.20 l 341.40 455.20 l 341.40 460.89 l 341.40 455.20 l 369.85 455.20 l 369.85 460.89 l 369.85 455.20 l 398.30 455.20 l 398.30 460.89 l 398.30 455.20 l 426.75 455.20 l 426.75 460.89 l 426.75 455.20 l 455.20 455.20 l 455.20 460.89 l 455.20 455.20 l 455.23 455.20 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf % gr_show_at() BEGIN 0 g 0 G 145.8 166.4 m (10) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 194.8 m (11) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 223.3 m (12) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 251.7 m (13) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 280.2 m (14) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 308.6 m (15) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 337.1 m (16) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 365.5 m (17) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 394.0 m (18) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 422.4 m (19) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 450.9 m (20) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 165.01 170.70 l 170.70 170.70 l 170.70 199.15 l 165.01 199.15 l 170.70 199.15 l 170.70 227.60 l 165.01 227.60 l 170.70 227.60 l 170.70 256.05 l 165.01 256.05 l 170.70 256.05 l 170.70 284.50 l 165.01 284.50 l 170.70 284.50 l 170.70 312.95 l 165.01 312.95 l 170.70 312.95 l 170.70 341.40 l 165.01 341.40 l 170.70 341.40 l 170.70 369.85 l 165.01 369.85 l 170.70 369.85 l 170.70 398.30 l 165.01 398.30 l 170.70 398.30 l 170.70 426.75 l 165.01 426.75 l 170.70 426.75 l 170.70 455.20 l 165.01 455.20 l 170.70 455.20 l 170.70 455.20 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 139.9 309.9 m 90.00 rotate (y) sh -90.00 rotate % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 455.20 170.70 m 455.20 170.70 l 460.89 170.70 l 455.20 170.70 l 455.20 199.15 l 460.89 199.15 l 455.20 199.15 l 455.20 227.60 l 460.89 227.60 l 455.20 227.60 l 455.20 256.05 l 460.89 256.05 l 455.20 256.05 l 455.20 284.50 l 460.89 284.50 l 455.20 284.50 l 455.20 312.95 l 460.89 312.95 l 455.20 312.95 l 455.20 341.40 l 460.89 341.40 l 455.20 341.40 l 455.20 369.85 l 460.89 369.85 l 455.20 369.85 l 455.20 398.30 l 460.89 398.30 l 455.20 398.30 l 455.20 426.75 l 460.89 426.75 l 455.20 426.75 l 455.20 455.20 l 460.89 455.20 l 455.20 455.20 l 455.20 455.20 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:draw title "Example 4" %^ scale 1 170.7 0 284.5 1 170.7 10 28.45 % gr_show_at() BEGIN 0 g 0 G 284.5 483.6 m (Example 4) sh % gr_show_at() END %gri: showpage %%Trailer %%BoundingBox: 129 130 463 494 %%DocumentFonts: Courier Helvetica Palatino-Roman Palatino-Italic Symbol Times-Roman %%Pages: 1 gri/doc/examples/model.elements0000644000175000017500000000004013147557614015233 0ustar psgpsg1 1 2 3 2 2 5 3 3 2 4 5 4 3 5 6 gri/doc/examples/example3.ps0000644000175000017500000005205013147557614014467 0ustar psgpsg%!PS-Adobe-2.0 EPSF-1.2 %%Creator: Gri2.4.2 (released 2000-Mar-25). User=rhogee, commandfile=example3.gri %%Title: example3.ps %%CreationDate: Wed May 31 09:54:20 2000 %%Pages: (atend) %%BoundingBox: (atend) %%TemplateBox: 0 0 612 792 %%DocumentFonts: (atend) %%Endcomments % NOTE: The Gri postscript dictionary is being converted to the Adobe % Illustrator 3.0 dialect of PostScript, as described in the Adobe % documents stored at URL % http://www.adobe.com/Support/TechNotes.html % (as of Jan 1996, this doc is number 5007). When the conversion % is complete, the Adobe Illustrator drawing program -- and any % program compatible with AI -- will be able to edit Gri output. % % The IslandDraw (TM) program is able to read Gri output % at this time; remarkably, it can read/edit arbitrary PostScript. % % The definitions below are presented in the same order as the Adobe % manual. The stack configuration before and after is shown in curly % brackets. All the operators are listed, but only some are defined % here. Most things are faithful, except that no distinction is made % between colors for stroking and filling paths. The string 'WRONGLY' % appears with commands that are approximations. % % PDF-style abbreviations: /rg {setrgbcolor} def % {red green blue} {-} set RGB color /RG {setrgbcolor} def % {red green blue} {-} set RGB color /q {gsave} def /Q {grestore} def /W {clip} def /W* {eoclip} def % % Gri-specific abbreviations: /hsb {sethsbcolor} def % {hue saturation brightness} {-} set HSB color % % Following all try to mimic Adobe Illustrator % % Mimicking section 5.1 of Adobe manual: %A % {flag A} {-} Determine whether % following object can % be selected. Flag=1 % prevents selection; % flag=0 allows it. % Mimicking section 5.2 of Adobe manual: %u % {u} {-} start group %U % end group %q % as 'u' but first item is a clip path %Q % as 'U' but first item is a clip path % Mimicking section 5.3 of Adobe manual: /g {setgray} def % {gray g} {-} Set gray for fill % path, WRONGLY used % for stroking also. /G {setgray} def % As 'g', but for filling path. %k % Set cmyk color for filling path. %K % As 'k', but for stroking path. %x % Set cmyk custom color for filling path. %X % As 'x' but for stroking path. %p % Define pattern for filling path. %P % As 'p' but for stroking path. %O % Specify whether overprinting for fill paths %R % As 'O' but for stroking path. % Mimicking section 5.4 of Adobe manual: /d {setdash} def % {[array] phase d} {-} Set dash. /i {setflat} def % {flatness i} {-} Set flatness. /j {setlinejoin} def % {linejoin j} {-} Set line join. /J {setlinecap} def % {linecap J} {-} Set line cap. /M {setmiterlimit} def % {miterlimit M} {-} Set miter limit. /w {setlinewidth} def % {linewidth w} {-} Set line width. % Mimicking section 5.5 of Adobe manual: /m {moveto} def % {x y m} {-} Move to locn /l {lineto} def % {x y l} {-} Draw line to locn % not a smooth point. % WRONGLY, no % distinction is made % between smooth and % corner. %L % {x y L} {-} As 'l' but a corner %c % Bezier curve to smooth point. %C % As 'c' but to corner point. %v % Something else to do with Bezier. %V % %y % %Y % % Mimicking section 5.6 of Adobe manual: %N % {N} {-} As 'n' for nondrawn stuff /n {newpath} def % {n} {-} WRONGLY interpreted % as path constructor /F {fill} def % {F} {-} Fill current path. %f % {f} {-} 'F' but close first /S {stroke} def % {S} {-} Stroke current path. %s % {s} {-} 'S' but close first %B % {B} {-} As 's' but don't empty path. %b % {b} {-} As 'f' but don't empty path. %H % no-op (weird huh?) /h {closepath} def % {h} {-} Close current path %W % Used to create masks. % Mimicking section 5.7 of Adobe manual: %a % Begin text block ... %e % Similar to 'a' but ... %I % Similar to 'a' but ... %o % Similar to 'a' but ... %r % Similar to 'a' but ... %t % {len (string) t} {-} Render string. %T % End block of text % That's the end of the Illustrator stuff. Following are some Gri % definitions which provide a temporary way of handling fonts. /sf {setfont} def % {fontname sf} {-} Set font name. /sh {show} def % {(text) sh} {-} Show text. /sc {scalefont} def % {size sc} {-} Scale font. % Gri items which should be translated to Illustrator format: /rl {rlineto} def /rm {rmoveto} def % Procedures /cimdict 7 dict def /cim { cimdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def q xll yll translate xur xll sub yur yll sub scale /do cl 3 mul string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop} false 3 colorimage Q end } def /imdict 14 dict def /im { imdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def /imagemap exch def q % Add the mapping to the transfer function (ref: white book, p 743. [{255 mul cvi imagemap exch get} /exec load currenttransfer /exec load] cvx settransfer xll yll translate xur xll sub yur yll sub scale /do cl string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop}image Q end } def /frdict 5 dict def /fr { frdict begin /yt exch def /xr exch def /yb exch def /xl exch def n xl yb m xl yt l xr yt l xr yb l h F n end } def /plusdict 3 dict def /_plus { plusdict begin dup 0.5 mul /t0 exch def /t1 exch def 0 t0 rm 0 t1 neg rl t0 neg t0 rm t1 0 rl t0 neg 0 rm end } def /timesdict 3 dict def /_times { timesdict begin dup 0.353553 mul /t0 exch def 0.707106 mul /t1 exch def t0 neg t0 rm t1 dup neg rl t1 neg 0 rm t1 dup rl t0 neg dup rm end } def /boxdict 3 dict def /_box { boxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm end } def /filledboxdict 3 dict def /_filledbox { filledboxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm F end } def /diamonddict 2 dict def /_diamond { diamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm end } def /filleddiamonddict 2 dict def /_filleddiamond { filleddiamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm F end } def /triangleupdict 5 dict def /_triangleup { triangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm end } def /filledtriangleupdict 5 dict def /_filledtriangleup { filledtriangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm F end } def /trianglerightdict 5 dict def /_triangleright { trianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm end } def /filledtrianglerightdict 5 dict def /_filledtriangleright { filledtrianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm F end } def /triangledowndict 5 dict def /_triangledown { triangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm end } def /filledtriangledowndict 5 dict def /_filledtriangledown { filledtriangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm F end } def /triangleleftdict 5 dict def /_triangleleft { triangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm end } def /filledtriangleleftdict 5 dict def /_filledtriangleleft { filledtriangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm F end } def /circdict 5 dict def /_circ { circdict begin 0.5 mul /t0 exch def currentpoint /t2 exch def /t1 exch def S n t1 t2 t0 0 360 arc t1 t2 m end } def /bulldict 3 dict def /_bull { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 360 arc h F S end } def /filledhalfmoonupdict 3 dict def /_filledhalfmoonup { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 180 arc h F S end } def /filledhalfmoondowndict 3 dict def /_filledhalfmoondown { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 180 360 arc h F S end } def 1 1 scale 10.0 M 1 j /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-ISOLatin1 exch definefont pop /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Bold-ISOLatin1 exch definefont pop /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-ISOLatin1 exch definefont pop /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Bold-ISOLatin1 exch definefont pop /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Roman-ISOLatin1 exch definefont pop /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Bold-ISOLatin1 exch definefont pop /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Italic-ISOLatin1 exch definefont pop /Symbol findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Symbol-ISOLatin1 exch definefont pop /Times findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-ISOLatin1 exch definefont pop /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Bold-ISOLatin1 exch definefont pop /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Roman-ISOLatin1 exch definefont pop %%EndProlog %%Page: 1 1 /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:# Example 3 -- Controlling scales, etc %gri: %gri:# %gri:# Example of how to control axis scales, etc. This example makes %gri:# two panels, plotting the same data in different ways. %gri:# %gri:# %gri:# ----- PANEL 2 ------------------------------------------------ %gri:# %gri:# Set up the x axis. %gri:# %gri:# Make the x axis run from 0 to 1, with labelled tics each 0.25. %gri:set x axis 0 1 .25 %gri:# Make the plot 5 cm wide. %gri:set x size 5 %gri:# 2 cm of space between the left edge of the plot %gri:# and the left edge of the paper. %gri:set x margin 2 %gri:# Give the x-axis the name "t" with subscript 0. %gri:set x name "$t_0$" %gri:# %gri:# Set up the y axis. %gri:# %gri:# Make the y axis run from 10 to 20, with labelled tics at intervals %gri:# of 5 and smaller, unlabelled, tics, at intervals of 1. Other %gri:# commands are similar to those for the x-axis. %gri:set y axis 10 20 5 1 %gri:set y size 10 %gri:set y margin 2 %gri:set y name "F" %gri:# %gri:# Now, read our simple data set. %gri:open example1.dat %gri:read columns x y %gri:close %gri:# %gri:# Draw a curve connecting these (x,y) data. Note that the axes, as %gri:# defined above, will be drawn automatically along with the curve. %gri:draw curve %^ scale 1 56.9 0 142.25 1 56.9 10 28.45 0.709 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 64.01 128.03 m 92.46 312.95 l 128.03 199.15 l 163.59 199.15 l 192.04 142.25 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 53.6 36.1 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 80.7 36.1 m (0.25) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 119.7 36.1 m (0.5) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 151.9 36.1 m (0.75) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 195.8 36.1 m (1) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 56.90 56.90 m 56.90 56.90 l 56.90 51.21 l 56.90 56.90 l 92.46 56.90 l 92.46 51.21 l 92.46 56.90 l 128.03 56.90 l 128.03 51.21 l 128.03 56.90 l 163.59 56.90 l 163.59 51.21 l 163.59 56.90 l 199.15 56.90 l 199.15 51.21 l 199.15 56.90 l 199.19 56.90 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 123.0 20.9 m () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf (t) sh 0.0 -3.2 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-ISOLatin1 findfont 9.00 sc sf (0) sh /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 3.2 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 56.90 341.40 m 56.90 341.40 l 56.90 347.09 l 56.90 341.40 l 92.46 341.40 l 92.46 347.09 l 92.46 341.40 l 128.03 341.40 l 128.03 347.09 l 128.03 341.40 l 163.59 341.40 l 163.59 347.09 l 163.59 341.40 l 199.15 341.40 l 199.15 347.09 l 199.15 341.40 l 199.19 341.40 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf % gr_show_at() BEGIN 0 g 0 G 32.0 52.6 m (10) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 32.0 194.8 m (15) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 32.0 337.1 m (20) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 56.90 56.90 m 56.90 56.90 l 51.21 56.90 l 56.90 56.90 l 56.90 85.35 l 54.05 85.35 l 56.90 85.35 l 56.90 113.80 l 54.05 113.80 l 56.90 113.80 l 56.90 142.25 l 54.05 142.25 l 56.90 142.25 l 56.90 170.70 l 54.05 170.70 l 56.90 170.70 l 56.90 199.15 l 51.21 199.15 l 56.90 199.15 l 56.90 227.60 l 54.05 227.60 l 56.90 227.60 l 56.90 256.05 l 54.05 256.05 l 56.90 256.05 l 56.90 284.50 l 54.05 284.50 l 56.90 284.50 l 56.90 312.95 l 54.05 312.95 l 56.90 312.95 l 56.90 341.40 l 51.21 341.40 l 56.90 341.40 l 56.90 341.40 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 26.1 195.5 m 90.00 rotate (F) sh -90.00 rotate % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 199.15 56.90 m 199.15 56.90 l 204.84 56.90 l 199.15 56.90 l 199.15 85.35 l 201.99 85.35 l 199.15 85.35 l 199.15 113.80 l 201.99 113.80 l 199.15 113.80 l 199.15 142.25 l 201.99 142.25 l 199.15 142.25 l 199.15 170.70 l 201.99 170.70 l 199.15 170.70 l 199.15 199.15 l 204.84 199.15 l 199.15 199.15 l 199.15 227.60 l 201.99 227.60 l 199.15 227.60 l 199.15 256.05 l 201.99 256.05 l 199.15 256.05 l 199.15 284.50 l 201.99 284.50 l 199.15 284.50 l 199.15 312.95 l 201.99 312.95 l 199.15 312.95 l 199.15 341.40 l 204.84 341.40 l 199.15 341.40 l 199.15 341.40 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri: %gri: %gri:# %gri:# ----- PANEL 2 ----------------------------------------- %gri:# %gri:# OK, now for a more complicated version. We'll keep the %gri:# same data, but redraw it in a new panel, to the right of %gri:# the first graph. So, the first step is to increase the %gri:# x margin. The rpn command creates a number which is %gri:# the sum of the old x margin (stored in the variable %gri:# ..xmargin..) and the old plot width (stored in %gri:# the variable ..xsize..), plus an extra 1 cm %gri:set x margin bigger {rpn ..xsize.. ..xmargin.. + 1 +} %gri:# %gri:# Set the line thickness for the curve to 1 point (0.3 mm) and the %gri:# axis line thickness to 0.2 points (0.1 mm). %gri:set line width 1.0 # points %gri:set line width axis 0.2 # points %gri:# Set the tics to be 1.5 mm. %gri:set tic size 0.15 # centimetres %gri:# Draw axes and frame, with axes offset from frame. Some %gri:# people find this more attractive. %gri:set axes style offset %gri:draw axes 1 % gr_show_at() BEGIN 0 g 0 G 281.2 33.2 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 308.3 33.2 m (0.25) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 347.3 33.2 m (0.5) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 379.5 33.2 m (0.75) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 423.4 33.2 m (1) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.200 w 10.0 M [] 0 d 284.50 52.63 m 284.50 52.63 l 284.50 48.36 l 284.50 52.63 l 320.06 52.63 l 320.06 48.36 l 320.06 52.63 l 355.62 52.63 l 355.62 48.36 l 355.62 52.63 l 391.19 52.63 l 391.19 48.36 l 391.19 52.63 l 426.75 52.63 l 426.75 48.36 l 426.75 52.63 l 426.79 52.63 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 350.6 18.1 m () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf (t) sh 0.0 -3.2 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-ISOLatin1 findfont 9.00 sc sf (0) sh /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 3.2 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 256.7 52.6 m (10) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 256.7 194.8 m (15) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 256.7 337.1 m (20) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.200 w 10.0 M [] 0 d 280.23 56.90 m 280.23 56.90 l 275.96 56.90 l 280.23 56.90 l 280.23 85.35 l 278.10 85.35 l 280.23 85.35 l 280.23 113.80 l 278.10 113.80 l 280.23 113.80 l 280.23 142.25 l 278.10 142.25 l 280.23 142.25 l 280.23 170.70 l 278.10 170.70 l 280.23 170.70 l 280.23 199.15 l 275.96 199.15 l 280.23 199.15 l 280.23 227.60 l 278.10 227.60 l 280.23 227.60 l 280.23 256.05 l 278.10 256.05 l 280.23 256.05 l 280.23 284.50 l 278.10 284.50 l 280.23 284.50 l 280.23 312.95 l 278.10 312.95 l 280.23 312.95 l 280.23 341.40 l 275.96 341.40 l 280.23 341.40 l 280.23 341.40 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 250.9 195.5 m 90.00 rotate (F) sh -90.00 rotate % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.200 w 10.0 M [] 0 d 284.50 341.40 m 426.75 341.40 l 426.75 56.90 l 284.50 56.90 l 284.50 341.40 l S % END GriPath stroke/fill %gri:# Now draw the actual curve. %gri:draw curve %^ scale 1 284.5 0 142.25 1 56.9 10 28.45 1.000 w 0 g 0 G 1.0 i 0 J 1 j 1.000 w 10.0 M [] 0 d 291.61 128.03 m 320.06 312.95 l 355.62 199.15 l 391.19 199.15 l 419.64 142.25 l S % END GriPath stroke/fill %gri:# Superimpose dots (radius 1.5 mm) at the data. %gri:set symbol size 0.15 %gri:draw symbol bullet %^ scale 1 284.5 0 142.25 1 56.9 10 28.45 0 g 0 G 0.369 w 0.369 w n 291.6 128.0 m 4.3 _bull S n 320.1 312.9 m 4.3 _bull S n 355.6 199.1 m 4.3 _bull S n 391.2 199.1 m 4.3 _bull S n 419.6 142.2 m 4.3 _bull S %gri:# %gri:# All done. %gri:# Draw a title above the plot. %gri:set font size 20 /Helvetica-ISOLatin1 findfont 20.00 sc sf %gri:\label = "Example 3 -- scales, axes, etc" %gri:draw label "\label" centered at {rpn 2 5 + .5 + } {rpn ..ytop.. yusertocm 2 +} cm %^ scale 1 284.5 0 142.25 1 56.9 10 28.45 % gr_show_at() BEGIN 0 g 0 G 79.5 398.3 m (Example 3 -- scales, axes, etc) sh % gr_show_at() END %gri:quit showpage %%Trailer %%BoundingBox: 15 13 432 415 %%DocumentFonts: Courier Helvetica Palatino-Roman Palatino-Italic Symbol Times-Roman %%Pages: 1 gri/doc/examples/example6.ps0000644000175000017500000020716613147557614014504 0ustar psgpsg%!PS-Adobe-2.0 EPSF-1.2 %%Creator: Gri2.7.0 (released 2001-mmm-dd). User=kelley, commandfile=example6.gri %%Title: example6.ps %%CreationDate: Sat May 19 11:54:52 2001 %%Pages: (atend) %%BoundingBox: (atend) %%TemplateBox: 0 0 612 792 %%DocumentFonts: (atend) %%Endcomments % NOTE: The Gri postscript dictionary is being converted to the Adobe % Illustrator 3.0 dialect of PostScript, as described in the Adobe % documents stored at URL % http://www.adobe.com/Support/TechNotes.html % (as of Jan 1996, this doc is number 5007). When the conversion % is complete, the Adobe Illustrator drawing program -- and any % program compatible with AI -- will be able to edit Gri output. % % The IslandDraw (TM) program is able to read Gri output % at this time; remarkably, it can read/edit arbitrary PostScript. % % The definitions below are presented in the same order as the Adobe % manual. The stack configuration before and after is shown in curly % brackets. All the operators are listed, but only some are defined % here. Most things are faithful, except that no distinction is made % between colors for stroking and filling paths. The string 'WRONGLY' % appears with commands that are approximations. % % PDF-style abbreviations: /rg {setrgbcolor} def % {red green blue} {-} set RGB color /RG {setrgbcolor} def % {red green blue} {-} set RGB color /q {gsave} def /Q {grestore} def /W {clip} def /W* {eoclip} def % % Gri-specific abbreviations: /hsb {sethsbcolor} def % {hue saturation brightness} {-} set HSB color % % Following all try to mimic Adobe Illustrator % % Mimicking section 5.1 of Adobe manual: %A % {flag A} {-} Determine whether % following object can % be selected. Flag=1 % prevents selection; % flag=0 allows it. % Mimicking section 5.2 of Adobe manual: %u % {u} {-} start group %U % end group %q % as 'u' but first item is a clip path %Q % as 'U' but first item is a clip path % Mimicking section 5.3 of Adobe manual: /g {setgray} def % {gray g} {-} Set gray for fill % path, WRONGLY used % for stroking also. /G {setgray} def % As 'g', but for filling path. %k % Set cmyk color for filling path. %K % As 'k', but for stroking path. %x % Set cmyk custom color for filling path. %X % As 'x' but for stroking path. %p % Define pattern for filling path. %P % As 'p' but for stroking path. %O % Specify whether overprinting for fill paths %R % As 'O' but for stroking path. % Mimicking section 5.4 of Adobe manual: /d {setdash} def % {[array] phase d} {-} Set dash. /i {setflat} def % {flatness i} {-} Set flatness. /j {setlinejoin} def % {linejoin j} {-} Set line join. /J {setlinecap} def % {linecap J} {-} Set line cap. /M {setmiterlimit} def % {miterlimit M} {-} Set miter limit. /w {setlinewidth} def % {linewidth w} {-} Set line width. % Mimicking section 5.5 of Adobe manual: /m {moveto} def % {x y m} {-} Move to locn /l {lineto} def % {x y l} {-} Draw line to locn % not a smooth point. % WRONGLY, no % distinction is made % between smooth and % corner. %L % {x y L} {-} As 'l' but a corner %c % Bezier curve to smooth point. %C % As 'c' but to corner point. %v % Something else to do with Bezier. %V % %y % %Y % % Mimicking section 5.6 of Adobe manual: %N % {N} {-} As 'n' for nondrawn stuff /n {newpath} def % {n} {-} WRONGLY interpreted % as path constructor /F {fill} def % {F} {-} Fill current path. %f % {f} {-} 'F' but close first /S {stroke} def % {S} {-} Stroke current path. %s % {s} {-} 'S' but close first %B % {B} {-} As 's' but don't empty path. %b % {b} {-} As 'f' but don't empty path. %H % no-op (weird huh?) /h {closepath} def % {h} {-} Close current path %W % Used to create masks. % Mimicking section 5.7 of Adobe manual: %a % Begin text block ... %e % Similar to 'a' but ... %I % Similar to 'a' but ... %o % Similar to 'a' but ... %r % Similar to 'a' but ... %t % {len (string) t} {-} Render string. %T % End block of text % That's the end of the Illustrator stuff. Following are some Gri % definitions which provide a temporary way of handling fonts. /sf {setfont} def % {fontname sf} {-} Set font name. /sh {show} def % {(text) sh} {-} Show text. /sc {scalefont} def % {size sc} {-} Scale font. % Gri items which should be translated to Illustrator format: /rl {rlineto} def /rm {rmoveto} def % Procedures /cimdict 7 dict def /cim { cimdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def q xll yll translate xur xll sub yur yll sub scale /do cl 3 mul string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop} false 3 colorimage Q end } def /imdict 14 dict def /im { imdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def /imagemap exch def q % Until version 2.6.0 used a 'settransfer' here, but that % triggers a bug in ps2pdf xll yll translate xur xll sub yur yll sub scale /do cl string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop dup length 1 sub 0 1 3 -1 roll { 1 index exch 2 copy get imagemap exch get 255 mul cvi put } for }image Q end } bind def /frdict 5 dict def /fr { frdict begin /yt exch def /xr exch def /yb exch def /xl exch def n xl yb m xl yt l xr yt l xr yb l h F n end } def /plusdict 3 dict def /_plus { plusdict begin dup 0.5 mul /t0 exch def /t1 exch def 0 t0 rm 0 t1 neg rl t0 neg t0 rm t1 0 rl t0 neg 0 rm end } def /timesdict 3 dict def /_times { timesdict begin dup 0.353553 mul /t0 exch def 0.707106 mul /t1 exch def t0 neg t0 rm t1 dup neg rl t1 neg 0 rm t1 dup rl t0 neg dup rm end } def /boxdict 3 dict def /_box { boxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm end } def /filledboxdict 3 dict def /_filledbox { filledboxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm F end } def /diamonddict 2 dict def /_diamond { diamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm end } def /filleddiamonddict 2 dict def /_filleddiamond { filleddiamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm F end } def /triangleupdict 5 dict def /_triangleup { triangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm end } def /filledtriangleupdict 5 dict def /_filledtriangleup { filledtriangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm F end } def /trianglerightdict 5 dict def /_triangleright { trianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm end } def /filledtrianglerightdict 5 dict def /_filledtriangleright { filledtrianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm F end } def /triangledowndict 5 dict def /_triangledown { triangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm end } def /filledtriangledowndict 5 dict def /_filledtriangledown { filledtriangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm F end } def /triangleleftdict 5 dict def /_triangleleft { triangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm end } def /filledtriangleleftdict 5 dict def /_filledtriangleleft { filledtriangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm F end } def /circdict 5 dict def /_circ { circdict begin 0.5 mul /t0 exch def currentpoint /t2 exch def /t1 exch def S n t1 t2 t0 0 360 arc t1 t2 m end } def /bulldict 3 dict def /_bull { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 360 arc h F S end } def /filledhalfmoonupdict 3 dict def /_filledhalfmoonup { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 180 arc h F S end } def /filledhalfmoondowndict 3 dict def /_filledhalfmoondown { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 180 360 arc h F S end } def 1 1 scale 10.0 M 1 j /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-ISOLatin1 exch definefont pop /Courier-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Oblique-ISOLatin1 exch definefont pop /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Bold-ISOLatin1 exch definefont pop /Courier-BoldOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-BoldOblique-ISOLatin1 exch definefont pop /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-ISOLatin1 exch definefont pop /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Bold-ISOLatin1 exch definefont pop /Helvetica-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Oblique-ISOLatin1 exch definefont pop /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Roman-ISOLatin1 exch definefont pop /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Italic-ISOLatin1 exch definefont pop /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Bold-ISOLatin1 exch definefont pop /Palatino-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-BoldItalic-ISOLatin1 exch definefont pop /Symbol findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Symbol-ISOLatin1 exch definefont pop /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Roman-ISOLatin1 exch definefont pop /Times-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Italic-ISOLatin1 exch definefont pop /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Bold-ISOLatin1 exch definefont pop /Times-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-BoldItalic-ISOLatin1 exch definefont pop %%EndProlog %%Page: 1 1 /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:# Gri was invoked by user named %gri:# kelley %gri:# on host named %gri:# Intrusion.phys.ocean.dal.ca %gri:# using the command %gri:# gri -y -p example6.gri %gri:# at time Sat May 19 11:54:52 2001. %gri:# %gri:# The user's ~/.grirc file ... %gri:# ... end of users ~/.grirc file. %gri: %gri:# Example 6 -- Plot IR image of Gulf of Maine %gri: %gri:# Define characteristics of norda images %gri:# Note that the pixel to temperature conversion formula is %gri:# %gri:# Temperature = 5C + pixel_value / 10 %gri:# %gri:# where pixel_value ranges from 0 to 255. Thus, a pixel %gri:# value of 0 corresponds to a temperatuer of 5C, and %gri:# 255 corresponds to 30.5C; this is why the limits %gri:# \0val and \255val, for use by the `set image %gri:# range' command, take on these values. %gri:\0val = "5" # 0 in image %gri:\255val = "30.5" # 255 in image %gri:.rows. = 128 %gri:.cols. = 128 %gri:.pixel_width. = 2 %gri:.km. = {rpn .cols. .pixel_width. *} %gri: %gri:# get filenames %gri:query \filename "Name image file" ("example6image.dat") %gri:query \maskname "Name mask file" ("example6mask.dat") %gri: %gri:# get data %gri:open \filename binary uchar %gri:set image range \0val \255val %gri:read image .rows. .cols. box 0 0 .km. .km. %gri:close %gri:open \maskname binary uchar %gri:read image mask .rows. .cols. %gri:close %gri: %gri:# find out what grayscale method to use %gri:query \histo "Do histogram enhancement? (yes|no)" ("no") %gri:query \minT "T/deg for white on page? " ("10") %gri:query \maxT "T/deg for black on page? " ("15") %gri:\incT = "1" %gri: %gri:# set up scales. %gri:set x size 12.8 %gri:set y size 12.8 %gri:set x name "km" %gri:set y name "km" %gri:set x axis 0 .km. 32 %gri:set y axis 0 .km. 32 %gri: %gri:# plot image, grayscale, and histogram %gri:if {"\histo" == "yes"} %gri: set image grayscale using histogram black \maxT white \minT %gri:else %gri: set image grayscale black \maxT white \minT %gri:end if %gri:draw image %^ scale 1 170.7 0 1.4225 1 170.7 0 1.4225 % Push map onto stack, then image stuff. [ 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.9961 0.9765 0.9569 0.9373 0.9176 0.8980 0.8784 0.8588 0.8392 0.8196 0.8000 0.7765 0.7569 0.7373 0.7176 0.6980 0.6784 0.6588 0.6392 0.6196 0.6000 0.5765 0.5569 0.5373 0.5176 0.4980 0.4784 0.4588 0.4392 0.4196 0.4000 0.3765 0.3569 0.3373 0.3176 0.2980 0.2784 0.2588 0.2392 0.2196 0.2000 0.1765 0.1569 0.1373 0.1176 0.0980 0.0784 0.0588 0.0392 0.0196 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 ] %BEGIN_IMAGE 169.266299 169.266299 536.293701 536.293701 128 128 im 1A253A251D1A0B0A0B1915161B19191D27221822191C2E142B291C4F2531221C22333A2C25262F 312E341C29242E3E3136525455503955253066271C190B25150F11180B161206180F1A13152235 3B1E2C322C353E333829202938363D27414646464343423A4243424040403D403E3E3D3A3B3832 23061E192C211A1A040404211C1F25282D150F121522221B09172C233213081C171B131117051F 222D1319282B333B312120333A251C1E2A33371F345553535240594A3438171A0404261C1D1018 110B1C22143B4740453D303F2822293D2336343C34313F3838412C464747464343424243424040 4040403F3D3D3C3C3B37332823312A2C2C351C20040825222A2A221314140919111506222E2F15 100709050B221C121805041119132525283438202D2F15332918211F3C2212232A57575448514E 261C121D270824271B1109131C2C36224F4551393E2F3937264635283733372B42433940404246 46474643414040424141404141403F3D3D3C3A383735281F2E27123936232A3023250F1C290B07 10100B06111F2E2B31251619152F27282E34233715123C0C12121B233D260C271B1C1714161C23 2829231C17222D5C5D46291D141230352C2A2E20101A190543434B51412A2D38433333263C422D 30393722404241414244464646454441403F404040404040403F3E3E3C3A38373536372B2B2634 180D302A2D12151C1821111A08141F222B33202024102222223536312E39323137641C342A1F22 240C0C131C1D24221419152329250A14262A5850312E1C171A2C2F20201E14191B0704374B4D4B 33204337373E292527483026373A30424044454645464645444242403F404140404040403F3E3A 3A3A3A2F232B322715252D0F042E2C0B10271C0C0509121315250D363740612F1D120D1C2A2B33 31332D261966341220381A0B0816041F181F2929210F262B1210222D294A6031201B0B18402422 2C1904081E0A1B2C474D4D092C383D3D401D2A284535303B3A4043404346454646454543424140 3E42414140403F3E3C3C3B3E3D3B383234361E2B372C2C2C33302E1E212528091116101A1D1B33 57634F32390F1A1C2C262F34333D271A13042735391D11091F0F1F411C1F362F2832231811181B 1B2A3D231B20131F35223330181F1D3842234247443F232B404243412B2A26403C403D3F434340 454546464545444343423C39413F3E403E3F3D3C3C3D3C3A3820323735303C30162B242B262625 2926240F0F171117102240646139383B28331A2D292C2C3037311819151015130D11212D242E31 2723343B363411101C481324272214111D101A1C2939222813214744422F48373A213043444441 402F2C3D4142404345474748484747444443434342414140403F3E3F3E3D3E3C3D3D3B38343638 28223522182B241E2A22212D2C172F19130C1C304031344C2A2C3F363F25122E33373147302625 12090A0A161B1D26322723201127222E2F1D20180A0C26272117101C0D1524302F2A312A3B462C 04042E203840464744434241344646454242424546474849474745434344424140403E403F3C3F 3E3C3D3B3C3C3B38303A3C1418381B153035322422171A2715262F1513181A272B1F302331393D 1F2942150D23132522292E260D11261C122A28241823181E33142E262E1F2612111D201C1B0C19 18182523252D2C334649311C042D45474747474432404041454440454345464848494947444343 4443414040403F403F3D3E3E3F3E3E403E3F3F363F3D2335333637262A30242627222B3727262C 211A111B30212228344E43232B5B4E290A172C292D321C11122A4065213D3310210F202615221E 231E1E2222201D1813221F19132B26222E382D48462F403540464A4A4948443145454244424545 444647494A49484645444343414140403F3E3E403F3E3F3F40404040403F3F4037363F112F3E25 282E3A20312E2958261F2B1F1A1C24383E3D222F384F4432414633131F2E302A2E300A1E291827 200C0F1C0F0A0A0B1C361A2615141C192313221A28302213201B271F2F264442483B3F2C3F4048 3F444344494543424344464547494A49494745454342414240403F404040404040404140414041 4140404040393D2D333A1627362E14152531571F272E1C1B282623263C44332E4F4A4A37575416 1E30371B1F28281D1929351F150C29231112071C4022282619222522151A1A221F1C18171D2634 1C3A494548454638361922324045454945434346484746484A4A49474645434241404040404040 414241424141414141414141414040403E3C33371819041A16042F161C22452435181616292614 2B2F554B4C434F4D4E4B411525301E1F272C1C3E39261D182F161D290414263027222D2E21221B 141D1B1C1523231B2D29303236474945333D424A484A44494B4B47454548494948484949494848 45434341404040404141424243454542424241403F3E3F3F403F3F3E3F17261804040404042F29 091B2C1B232519203C253228273C57454F5253594F4A222F2C401A292C3131424B4B241A290726 1613142C402331361719202020231A1324221D1D251D2B2E46493104042D4B4B4B494349454545 38484A494848494747474745444343414141404142434343444544424141403C3E3E3D3C3A3D39 3236381404040F0A0F2D2A11231C2120241B292F312222223D2B4F5853595D48563B2F45606039 271D26393E34271C2013281515233040202923221F2119251F15141D1F2822211F27273B463704 414F4D4C4B3B40424446494A474B49494746474846464645434442414142424245434344454642 4240403F3E3E3C3B393A321F393207183323151C3132151D231F1B262F1D22362E321B552F272E 50595F605B5952343C263128212C2B5F5F483E30041B2F1B12372B19212E20172B172022171A25 2222262120202C3B4A4F4F504F4E3F283741474A494A4A4B4A4A46464849484747474544414241 42434346494544444646424140403F403F3E3D3B392D2F32202F2B1B3615201A231A191F1D2523 3921222C27472234292A263A406059626663474028314F3129253C5052375C4C0F23242F2E2E11 15261A241C201B1B1613232A2F342724313C3B4B5051504F4D411D3F464B4A494A4A48473A1A35 4747474746464443414242434344454A4745434545414245444142413F3B2E381D34382F363609 362C220F1329312F1D25232F181C2A224B313D27212E3635363C6666272F2E2E323E25173B4217 312F29381A1D35262C221C21422928181D1C18142226282F3D4147483C4A4F4F504F4E4A383C4B 4B4C4B4A4A4B47474947474746474645444546464746474648494B494645474542434544454441 3D3D36343A3D37223A2A04293015091D29342A18142823131A262B2D5C241D22303532383A5631 271E212B31394043242B2B333833412212333732231B37382A302A1615131620192E494D434B4A 43474F50504F4F474B4C4B4B4B4942494B4B4A49484647464545444545454748494A4A4A4A4A4B 48464748444345464645443D3D3B393C3B3A37363317042204161926282C2E15110C152535171D 2423282225353D393E4030222F312E243F41262D26202F3725342C2933312D323411352B2C1919 21192D2A25394F4D4A4C4B4D505050504F4F4E4C4B4B4B483F474A4B4A49484745454545444444 4446494A4B4C4B4A494A4B49464649484846474746423834373B3D40403C332C23040407131F24 21392A20181B21252F2252161F1417273635362B333E2D3243392636372F17141019302C202C26 3233262E2A3128202F181F301A2D423A2F504E4C4C4C5050505050504F4D4D4B4A4B4A4A4A4A4B 4A48474745444444454447494B4B4C4C4B4B4B4B4A4B4A494A4A4949484947473E373D3F3E3E34 3E3B25041C14040C3339283022244935232D191C221F22140C1B2A2D223E2A22322C1B302B353B 2A1E27142D1A2D302B2A222935291F1B1B2916271924191522283E42514F4E4D4D515050505050 4E4D4C4C4B4C4A4A494949484745454545444545484A4C4E4E4D4B4A4A4A494948494A4A4B4949 4949484745403F3F3F3F3F39391B252B0D0404302C22242231351C20151222181712171F27272F 292622312C251C1E222933462F36244822322C11172B2E2C28252D21191C1614142311212E232A 504B504F5051505150504F4E4C4B4A4B4B4A494848474646474545474748494A4C4F504F4F4C48 4B4B494A4B4B4B4B4A4A49494949474540403E3E3D3E3E3A2E0F0404040418212017222D301C23 261418261D20201B27312A282E2328171E1D11262920242D3D3A332D21170B1A222C2528173226 22200D0D0C191A28241B244B4B4F50515050504F504F4D4B4B4B4B4B4A46454545464849494948 4B4A4C4D4F4F4F4F4F4B47494A4A4A4B4B4A4A4949494A4A484745403F3E3E3E3C33371F242304 04042C2E36222E242513202922203135271F28202C3D241420291F1D301B1C2B221D2E3530312B 3228071320342225161E192E1A191B122018171E22394C4D4F5051504F504F504D4B4A4A4B4A4A 48474545464748484A4A4C4C4D4E4F5050504E4F4B474849494A4C4B49484749484A4948464440 403C3C3D3916150404060404043836342A28332D2B1F1B2D2F363F3E222424252F301D2F1A1C21 2031363B191D2A3624302931100411173033221B11100B10212B2B1B191826474C4D4E4F505050 4F4F4F504C4B4B4A4B4A494846454547494A4A4C4C4E4F4F4F50504F4D4C4D4C484749494A4A48 484746464748494746453F3F3B3635222E28152E22040F1B3A42313C3B2A30171318252C323832 191F14253239221F412A25252E333122261C222F31241B0B040A1A36401B20130B141E2522301F 222336504F4E4F4F504F4E4E4F4F504B4C4B4A4A4A4A4847464647474A4B4D4E4E4F50504E4D4D 4A4B4B4C4B494948474948474747484648494946433E2E142C312F3C383632341F0C073B43261D 2B2B3926140B25353B37221B0F22242E282819281C21251F2C262C332822302C26100404081B2A 334A200A161815262A2230292E4450504F4E4E4D4E4E4E4E4F4D4B4C4B494A4B4A494746454747 464B4E4F4F50504E4B4B4A494B4B4A494948474647474747474748484847453E3A3C3C3E3D3D3C 3B3428090C040439483321171A14261814191F361B15151C15271A121413110F181620142C3440 3E1D1F161E0D05080414222F1F131011191B292F2D48434C5050504E4E4D4B4D4D4E4E4E4E4D4D 4B494A4B4A48464545464C4D4B5050504F4E4B4B4A494A4A494948494847474747474848484748 474544413F403E3E3D3C3D3B3A35231504041D45331C282A251612141A1B2F2815121C13141922 151711160409111A313B3C48222318220B0C0B09222A230F09161A1223263B4B474D4E5050504E 4E4C4B4B4E4E4E4D4E4D4C4B48494A4948464344464A4A4E5051504D4C4C4A4B49494949484848 48474848484848474747464544423F3F403D3E3D3C3C363C3B3A36251D1B2A3125422E2F20141F 1C11161B080D17122012161F28231C1F151C2B36302E2D2A221D2110091726221F0D121028221D 212F424D4F505050504F4E4E4D4B4B4D4E4E4D4E4D4B4948484846444543444748494F50504D4C 4C4B4B4A4948494847484848484848484748474646454343403F40403F3C3B3B363D3D3D3D3E40 38191E271C301F2B222E2422131623181014221C0D18212B3228302F343233382C3B262021271A 14232E1D1C090F15201820252D4D4E505151504F4D4D4D4C4C4B4D4E4E4D4D4C49484847474646 45434648494B4E50504D4D4D4C4C4B4847474747484848484848494847474545434242403E3E3E 3F3D3B3A3B3A3E3F3F3F402E36331F222D2E191525201F221A2B1D0D0D1F160C232E3337231F39 39362D282A34331E212B1B26251B1B11130C0D19141A2B3B4F50515150504F4E4E4D4D4C4B4E4F 4E4E4D4C4746464747464545444747494D4F50504D4E4D4C4D4A48474847474848494948484847 474645434143433F3F3F3F3F3D3D3D3D3B3F40403E40223D43403A20321D0C1722191F1C302314 0D2019161C232E303720554D37312934302821281F1C1B2722150C150625212E25314C50515252 51504F4E4E4D4D4A4C4D4F4D4D4D4D48464747484746454546484A4C50504F4D4E4D4C4D4B494A 4A484748484A49494948474544444442414242403E3F3D3C3D3F3F3C3E40414242323740402213 1D1F14212B4D2D19221F1F272E170D131F2326222831403336322D312D2B29222F2C2B222C1811 1922323C3635435151535251504F4E4D4D4B4A4D4E4E4D4B4D4B49474747494848484748484A4D 4F504F4E4E4E4D4D4C4A4A494949494A4A4A494948474644454643424241403F3E3D3E3E403F3F 40403E43424137282738141B2A182B3238282E2C121A32311516272A2B411F30222C39393A373A 2A2E2D2A2A302216241D212623363937324052525352504F4E4E4D4B4A4B4D4D4D4B4949484746 474849494A4948494B4B4E4F504F4E4E4D4C4B4B4C4B4A4A494949494A4A484744444648474541 4242403F3E3D3D4040414140424343424435252E301B1D242529202C24281F0B20231910193733 3456331F26323A403D3D473B282F302C2D30252C2A29262F403C3C334F52525351504E4D4E4D4B 4B4B4D4C4A4A47474846464749494B4C4B4C4B4C4D4E50504F4D4E4D4D4C4C4D4C4B4B4A4A4A4B 494A4A48464546464949434242413F404040404040414242434646472127242723302A2C261C33 1F182A15241A0B1315223B414932333F4639413E3F333A292026222F271D1D2F2017293F3D3A3E 5052525452504D494C4D4C4B4D4B4B4A494747494746494A4B4D4D4D4D4D4F5050504F4F4E4F4D 4D4B4D4D4D4B4B4B4A4B4A4A4B4B4948474847494A494341404040414342424241424344464849 2A3434232F2625251F18161B233125281D10141426243D402B353D3A3326363B2F33242028232A 28342321181B22342931505252525352504E4A4A4D4B4B4C4B4B4A49484748474649494C4D4D4B 4C4E50505050504F504E4D4C4C4D4D4D4D4B4B4A4B4B4D4D4C4A49494A494A4A4A454142384444 4544454344464546484949322B3A382E19232517192A2C2E2B212A18171E1F101D342F2C2E2E30 2F2635343830301E292C252939212122191D3133384F52535353524F4E4A4B4D4B494B4B494A4A 484749484748494C4D4C4C4E4F50505050504E4F4D4B4B4C4D4D4D4D4C4D4C4D4D4D4E4E4D4B4B 4A4A494A4B4947424345474846474647474748494A4B242C2E3B272C171125332438322C25271A 2322231329382C202D473937272E3034332E252527305951492320191B222C485253535353504E 4D4A4C4D4C4A4A494A4A4A4846484949484C4D4C4B4C4F50505051504E4D4C4B4B4A4B4D4D4D4C 4D4D4D4E4D4D4E4F4E4D4C4A4A4A4A4A4B49464443464949484849494A494A4C4B27223E322E2B 1F302332242F362A272F1929212B2B28342C1F314A4E4F33383E3229292C2824285B262A3C3A30 2222324F5352525352504E4C4B4B4C4C4B494A4B4A4A484747494B4C4D4C4B4B4F505050505250 4F4E4D4C4B4B4B4C4C4C4B4C4D4D4E4E4D4E4E4F4E4C4B4A4A4B4A4A4A48454646484A4A494A4B 4B4B4B4B4B33312C393733373A232C2C2B1F3A2F2A2525232F2F35252F1C2C3A4C503933362D2B 221F29274E5936362C4336412D3A535352535350504D4C4B4B4B4A494A4B4B4A4B4746454B4B4C 4B4B4A4C505051505050504E4D4E4B4B4B4C4C4C4B4B4C4D4D4D4D4D4D4D4D4B4C4B4B4A4B4C4B 4A4A47464647494A4A4A4B4A4B4B4B4B37261A2E3640272822282E162030292B2623221B2A3439 292226323A383935353B2D1C1D2D39676A5F37343D4F413E505454535352504E4C4C4B4B4A4949 4B4C4C4B4B4A47474A4A4A4A4B4B4F5050505150504E4D4D4D4A4B4C4C4C4D4C4C4C4C4C4D4D4D 4B4B4A4B4B4B4B4B4C4C4B4A4B494948474949494B4B4B4B4B4A4A3A2E2F3538361F1F1B262120 1F27272222242B36263339322F253A31342C352D2A22221B2033383247333037374F5052525454 5351504D4D4C4B4B4A4A494B4C4D4B4B4A4A4A4A49494A4C4D505050505050504F4D4D4D4B4B4B 4B4B4D4D4D4E4D4D4E4D4C4B4A4B4B4B4B4C4B4B4B4B4B4B4B4A49494A4A494A4B4A4B49494927 252F34362C18231928261D2E2928322E2C233D26122134333F313031282E292922182A2621352A 2C3036303451505353535452514F4E4C4B4B4B4C4B4C4E4E4D4B4B4A49494B4B4B4C4D4F504F50 505050504E4D4D4C4D4A4A4B4B4C4C4C4D4D4D4D4C4C4A4A4A4B4B4B4C4C4A4B4B494A4A4B494A 4A4A494A4A4949484848242B33402A23221F1C1F282E242E2B392F30262527172830333029282B 27222828311F2A272221181F2A282F4051525353535352504F4C4A4A4A4C4C4D4D4D4D4D4C4B4B 49494A4D4B4D4E4F50505050504F4E4E4D4C4C4E4A4A4B4C4C4C4C4C4D4D4C4B4B494A4A4B4A4A 4B4B4B4A4A4A4B4A4A4A494A4A494A494849494948412C352A2C282C22292C3C373B3233403736 4E4D3923153134382C27282C262F2428252F32262A22252B303A5152535453525453514F494949 494B4C4B4C4B4A4C4C4B494A49494B4B4B4F50504E504F4F4F4D4E4C4C4C4C4A4B4C4C4D4D4D4D 4D4D4C4B4A494948484A4A4B4B4B4A494A4949484A4A4A4A4A4A48484B4A4A492D261F33333325 22202C3A454328293F342C5B3B361C252A313622222C27232A24252E302E282D2727252E505153 535352505453514E4C48494A4B4C4B4A494A4B4B4A49494A4B4B4B4B4D504F4F504F4F4F4E4E4D 4C4B4D4B4B4C4B4C4D4D4C4B4C4A4B4B48494948474A49494A494A4A49494949494A4949494847 4B4A4A481C252D252D2225393E2B3B403D3727332F1F3222181C2D2F312E283332322F2A252C36 311D232728272F314D5253525253525452504D4B484A4A4B4B4B4A494B4C4C4C4A48484B4B4B4D 4D4E4E4F504E4E4F4F4E4D4D4D4D4C4B4C4C4C4D4D4B4B4B4B4B4A4948474846494746484A4A4A 494949494A4949494948484A4B4A492E343D391D261F2B4032353D402722312F1D211E222C3234 323632312E3A3B43262A26383226263331344B5252535251525253524F4D4948484B4A4A494849 4A4C4D4D4A474748494B4D4E4E5050504D4E4F4F4E4C4D4E4D4D4D4D4C4C4D4D4C4B4B4C4B4947 47474747464546494A4A494947494849494949484848494A4A4920293440381B3E36433F433738 22212025251D222C2F322E323A4B36383540573629242C372B3230353750525251515151525250 4F4B4A4847494A49494B4A4B4D4D4D4B484647494D4F4E4F504F4B4D4D4E4E4E4D4D4D4D4D4D4C 4C4C4D4D4D4B4B4B4A494747474747464545494A494946464647484847474848494948494A1C2C 3F3B3D1F263945463D2B1B172120191F20291D2C32282C333E4433313639302D28303433313937 48525251515151515252504E4B4948474849494C4C4C4C4C4E4E4D4947464B4E4D4E4F4F4E4D4E 4D4F4E4D4D4D4D4E4D4C4B4B4C4D4E4D4C4B4A4B494A4949474645454849494847414245474848 484849494949484A4B3F33403E2E383F3C3C3E3A38221C1C221920282C222223383F423F423639 3A5C342C2A2938393A403F47525151515251515151504D4B4A484748494A4A4B4D4D4D4E4F4D4A 464A4B4C4D4F4E4E4E4E4E4E4F4E4C4E4E4E4C4C4C4B4B4C4D4E4E4D4B4B4B4B4B4A4949464546 4748494745414243464849474A4949494949494A3B4238293C3A363C2F28212E2124281F1D2423 2326252B3237553333343E352B2C33452D3B3C3C3E3C4D5251525252515151504F4D4B4A474948 49484B4D4D4D4E4E4E4B49484B4B4D4D4D4D4F4E4E4E4E4F4E4E4E4D4D4C4C4D4D4D4C4D4D4E4D 4C4C4C4C484A4A4949474747474847444042444548484A4A4A49484948494B3A363A3032312B20 372B1D141F232D1D1C2520212526302B37342934393E35292E315532383A4039363A5151505251 515050504E4D4B49484948484A4D4D4D4E4E4D4E4C49494A4C4C4D4D4E4E4E4E4D4E4F4E4E4E4D 4D4E4D4D4E4D4D4D4E4F4D4D4C4B4B4C4B4949463F4647464746444245454548494B4B4A484849 4A4A4B3C31342D303E2A2824211F233730271B192223212228272B2E4025263A3A33372C353531 48504E35384251505051515050504F4E4B4A4846474A4B4E4E4D4E4D4D4D4D4D4B4A4B4C4C4D4D 4E4E4E4E4E4F4E4F4F4E4E4E4D4D4C4C4C4E4E4E504E4E4D4D4B414A4B4A444744484747454444 454645484A4B4B494949494B4B4B3B3F3A1D353E322D28331E263B2F201E1D2323221F2B2C3834 2A2F2B2C2E2E342D3033333E353450614D52515150505150504F4E4C494746474B4F4E4D4E4D4C 4D4D4D4C4B4A4D4D4D4D4E4F4E4F4F4F4F4F50504F4F4E4F4E4D4B4B4C4C4C4F4F4E4E4D4C4B4A 4949484648484645444546464546474A4B4B4A49494B4C4C4C4039382A34433C33333D212B2935 372520313E1C2A2E464B3F2D2833372B323B3E422F3636251D2F313B52525251505150504F4D4B 4A48494E4F4F4E4D4B4A4A4B4D4D4C4B494D4E4E4E4F4F4E4F4F4F4F50504F504F4E4E4E4E4D4C 4C4B4C4C4D4E4D4C4B494A484A494848484644444444464748494A4B4B4B4B4B4C4C4C4C382533 3F3336223241423F2B212D2C2C252D2B28283237312F2723203A33364134392D4335282E2F3839 535352525050504F4E4E4C4B49494E4E4D4A4B4B4A49494E4E4D4B494D4E4E4E504F4F4F504F50 505050504F4F4F4F4E4D4C4B4C4C4B4B4A494B4947494749484A494846444343434648494A4B4C 4A4B4B4C4D4C4B4B282E313F2A3A2B3B45484636352F2E3933262D3B302C20302C2C3223312D3A 314130312C2D262E303C5049535351505050504F4E4D4C4B494D4D4A4A4B4B4B4A4A4A4D4D4D4B 4D4D4F4F504E4F50504F50505050505050504F4E4E4C4C4C4B4A4A494849484748464648494949 46444342434648494B4B4B4B4C4C4C4D4D4B4B2934323B353C2C323642312F252B292A2E2B393A 2E232940322C303330363E3A292F40312F2F333136514E54535351505051504F4E4E4D4B4E4D4B 4B4B4C4C4A4A49494D4D4B4D4E4F4F4F4E4F5050504F505050505050504F4F4D4B4B4A4A4A4848 474647464745454849484846454443434548494A4B4B4B4C4C4C4D4B4B4B223136363839382428 2E342225232B3329222F4034253C363728393B382F2C402C2F3B393623342F3B56405453545453 535252524F4F4E4E4E4E4B4B4B4B4B4A4948494A4E4D4D4E4D4D4F4E505050505050505050504F 504F4E4D4A4A4A4B4A4849484746464544454948474645454444464747494A4A4B4B4B4D4D4D4C 4A4B2E313836343F3432211D282A22251F23312130432A23252C2B38354740355636333D37312C 32383A323D4E55555755555A59585553504F4E4F4E4C4C4A4A4847484747494E4F4D4D4D4D4F4E 4F50504F5050505050504E4F4F4E4B4B4A49494A49484847464646454848454646454646464748 48484A4A4B4B4C4C4D4C4B4B4C2C323936242D2637292B1B2723221920293239382728232A272D 2A31303136333A3F372A2B252D3A4040394E58595753505656565651504F4F4D4C4C4947484647 494A4A4C4D4C4C4E4E4F4F4E4E4F4F4F505051504E4D4E4E4D4B4B4A4A4A494A49484745464647 474746454646464747474849494B4A4A4B4B4C4C4C4D4B4D36333F3F332B2431372623261A1D28 2524332E2B242E242337342C28343135312A282C312D2A303335292E4A505C5C36415054545552 504F4E4D4B4A4948474749494C4A4B4E4C4E4E4F4F4F4E4D4E5050505051504C4D4E4E4D4C4A49 4A4A4A4A4A494848484847484645464545454746494848494A49494A4B4B4D4C4C4C4D423D4040 3C36221F2E33382622282F2D2C2637293B403F282F3B412A31363C382A29292A39333025242726 4C3938453A41485253555350504E4D4B4A494947474A4A4A4C4C4D4D4D4E4E4F4E4D4E4F505050 50515045464F4E4C4C4A4A4A4B4B4B4B4949484949494947464646474847474848494949494B4A 4B4B4C4C4E4E4E37383E41403D2A222C2528302A25282D2D332B37323839262D242A272534342C 24222E2832412A2E2E2A322C2E3041393C4C4F51545350504F4D4C49494949494B4A494947494A 4D4E4E4E4D4E4E4F504F505151514F4E4F4E4C4B4B4A4A4B4B4B4B4A4949494949494746474748 494747484949494A4A4B4C4D4D4D4D4E4E4E363D393D384B362C25231C212C202C2C2D2F2F362C 2E2A2C29242223323A283541312731362C312D304A322E3F4146464150505051525050504D4D49 494A4A4A4C4B48474748484D4C4E4E4E4E4F4F4F5050505151504E4E4E4D4C4C4B4B4B4B4C4B4B 49494949494948484849494948484849494A4B4B4D4D4E4E4E4D4D4D4E2B3E362A32372C1F291F 20222C32292C2E2A3233292D302C302B25232B2D312E3B30253039353F35323D2D30363C484F4E 50505050525050504E4B4B494A4C4B4A4949474648494B4D4E4F4E4E4F4F4F505051515151504D 4D4C4D4D4B4B4B4C4C4B4C4C4B4A4A494A49494949494A4A4B48494B4C4C4D4E4E4D4C4E4D4D4D 4E26303C34392E2D282B221729272B41242F292229252E2D32322A2B28312B2F26262C34383932 383C2F313C3747464E505050505050515150504F4D4B494B4B4C49494848484A4D4D4E4E4E4E4F 4F504F50505151515050504F4D4E4D4C4B4B4D4C4C4C4C4B4B49494A4A4A4B4B4A4A4B4B4A4A4D 4D4D4D4E4D4D4D4E4E4E4D4E242E3736393E4C2D261839312C3326212C242629282732342F292D 272829212E313836313B353B3B3A42454D505051505050505050505250504F4D4B494C4C4C4849 49494A4C4E4D4E4E4E4E4E4F4F4F5050505050505150504F504D4C4B4C4D4C4B4C4B4B4A4A494A 4A494B4C4E4E4F4E4C4B4D4D4D4D4D4B4C4D4E4F4E4E4E2B35353D39393E332B33292F2C36262D 28232925272A3241302A2E29282C242B33423A3A3A39464A4C4D4C515252545352515050505052 504F504D4D4B4C4D4948484A4B4B4C4C4C4D4D4D4E4E4F4F4F5050505050515050505050504E4C 4C4C4C4A4B4B4B4B4A49484B4A4B4B4E4E4F4E4C4C4D4D4D4D4C4D4C4C4F4F4E4D4D382B414734 3F443823282B284030312F3B282D2E2D251F2E2A302E312936492F3F4042393A404E5551515254 5555545252525150505050504F4F4D4E4B4D4D4845484B4B4C4D4D4C4D4D4D4D4E4E4F4F505050 50505050505050504F4E4D4D4C4B4A4B4C4B4B4A4949494B4B4B4D4D4F4E4B4D4D4D4C4C4C4C4C 4D4D4E4D4D4B37303B423930242222272C333B39282C3B292A25302D20222E2E323A2F3538362C 483C423B3E484250525456555454525252515050504F4E4E4E4D4E4D4D4C4A46464B4B4D4E4D4D 4E4E4E4E4D4E4F4E504F505150505050505050504E4E4D4C4A4B4D4D4D4B4B4B49494A4A4B4B4C 4F4E4B4D4D4C4C4C4C4C4C4C4D4E4D4D4C3D3B44403C1F1F1F182C4E3A3133262B2E2923262E2D 1F2A2F353A3A36353C403C3A4E4A4A49445255565655545453525151515150504F4E4F4E4F4D4C 4D4D494746474A4C4D4D4E4D4E4E4E4D4E4E4E4F4F505050505050505050504E4E4D4C4B4D4D4D 4E4D4C4B4A4A4949494B4B4F4D4B4C4C4C4C4C4C4D4D4C4D4E4E4D4C32263D3E32362E1A192E35 3F3825372B2D212A2B301C282B3331363D354740453C3840494D54515655565555545453515150 5050504F4E4D4F4F4F4E4C4E4D49484847474A4B4E4E4E4E4F4E4E4D4D4D4F4F504F5050505051 5050504F4F4E4B4C4D4E4E4E4F4E4B4B4B4A4949494B4F4D4C4C4C4D4D4F4E4D4D4D4D4D4E4D4C 3A1B2537312E1C1C2B3835323D382C292E2B2328313D2C2E3C39354346454C4243413D48525656 555555555455545351505150504F4F4E4E4E4F504E4E4E4C4A48484747494B4D4C4C4E4E4E4E4D 4E4D4F4F4F4F5050505050505050504F4E4C4D4D4E4E4E4F4E4D4D4B4B4A4A49494D4D4D4C4E4E 4E4E4D4D4D4D4D4D4E4D4D372F2231362A2525312B323A232B27362E2C2A332848303E39393F4B 4940484740434A54525256565655545555535250505050504F4F4E4F4E4E4D4E4D4D4D4B494949 49494C4D4D4E4F4E4C4C4D4E4F4F4F4F4F5050505050505050504F4E4D4D4D4C4E4E50504E4D4D 4C4B4A494A4C4F4E4E4E4E4F4E4E4D4D4D4D4D4D4D4D363620404B40412A362E3932282A2A312F 251E332229275E3C36404E45454344484A525657565657565555535352525050504F504E4E4F4E 4D4C4B4E4D4D4C4B4A49474A48484D504F504F4D4D4E4E4E4F4F4F50504F50505050504F50504F 4E4D4D4E4E4F50504F4E4D4D4D4C4B4B4B4E4F4F4E4E4F4E4E4D4D4D4E4E4E4E4F2B2B2E203C6D 4E2E31363538322E38322E2B22382F232B3E3D3B3E44464B4C4A4D4F4955595857575755545352 535252515050504E4E4E4F4E4D4C4D4D4D4D4B4B4B4A4A46454A4D4E504F4E4E4E4D4F4F4E5050 505050515050504F4F4F4F4E4D4E505050504F4F4E4D4D4D4D4C4B4A4C4F4F4F4F4F4E4E4E4D4D 4E4F4F4F5022253F585E3537322E3A2F434335331A232E3D252A25353E483B4040474E47505259 56565859585758565351535452525150504E4E4E4F50504F4F4E4D4D4D4C4A4C4A4A494745474F 504E4F4F4E4E4F4F505050505051515050504F4F504F4E4E5050505050504F4F4D4D4D4C4C4C4B 4C4C4F4F4F4F4F4D4E4D4D4E4F50504F2A26364840344038372C343A3C3F403B422733322C4038 493B3B41494953645960545C56595A59585B5A53525454525150504F4D4D4D4D5050504E4D4D4C 4D4B494B4B494C4947474F505050504F4F4F5050504F4F50505150505050504F4F4F5050505050 50504F4F4E4E4D4D4D4D4D4D4C4C4D4E4F4E4E4E4D4E4E4F50504E3F35353832313E40372A2C44 405D3A3A3E312E343B2E403B393A3E504950504D585F5C5C5C59585B5C5C56545453515050504E 4F4E4F4C4E4F504E4D4B4D4D4C4B4C4B4B4B4D4D474A505050505050505050504F505050515050 5050504F4F4F4F505050505050504F4F4F4F4F4E4E4D4D4D4D4C4D4D4D4E4E4E4E4E4F504F4E3B 38403F3A373C3F372625303342362D313A32302B30403D393A3E423E4D4B4D5F5F605D5F5C5C5E 5D5C575254545251504E4F4F504F4E4D4D504F4D4C4C4B4B4B4B4B4D4C4D4C4B4B504F4F4F4F50 5050505050505051515150505050504E4F4E505050504F4E4D4D4D4E4E4E4F4F4E4E4E4E4D4E4E 4E4E4F4E4D4F4F50504E42574036283F3F3F2D3B2A33354D384E3939383D34433537383E34333E 433A4D5B5566615C605D5E5C5C575453505251504F4E5050504E4E4E4F4E4F4C4B4B4B4B4A4C4C 4B4A4B4D4C504F504F50504F50505050505050515050505050504F4E4E504F4E4D4D4D4C4C4C4C 4D4F4F4F4F4F4F4F4F4F4F4F4F4F4E4D4F50504F4E45444040353B3F4122242F2E3133383A4344 304B31322F2833312A3A423D41474A5E6A6C63635B5C605C5A5753504E5150504D4E504F4E4F4E 4E504E4B4D4D4D4C4A4D4D4B4B4A4E4D4B4B4D4D4F4F4F505050505050505050505050504F4E4D 4E4E4D4C4C4B4C4B4C4C4D4D4D4D4D4E4F4F4F504F4F4F4F4E4D4C4F50504F4E4643433C36363A 42502922232B3D3435342F2724242A2227232B353935403A3843474A516650664C5B585F5C5851 5050504F4E4D4F4E4D4F504F4E4F4E4E4C4D4F4D4A4B494B494C4D4B4B4A4A4F4F4F4F50505050 51505050505150504F4D4D4E4D4C4D4C4B4A4A4C4C4D4D4D4D4C4C4D4F50504F4F4F4E4E4D4E50 50505050453C3D3D5237222831373C35353037483B2C39302732222C40343B3E3B363132434949 57474540343C3F5C555B55525050504F4E4F4D4F4F50505054535352504F4F4D4A4A48494A4A4B 4B494B4B4D4F505050515050505150515151514F4D4D4D4D4D4E4C4B4B4B4D4D4D4D4E4D4C4D4D 4D4F50504F4E4E4E4E4E5050504F5040392B3A2C2B28212237353E233C3334342B2E2024293431 3F3D3837233A373E474B45434234252D2C3E3E415F58565050504E4D4E4F505050525757575756 544F504E4B494B4B4A4A4A4B4B4B4A4D504F5050505050505050515151504F4E4D4D4D4E4E4C4B 4C4D4E4E4E4F4F4D4E4E4D4D4D4E4F4E4E4F4E4E4F5050505050392C2B3532262F1F3129233C2F 3B2F25392C22231D222F333C332F30293E434646483D3D4F3335333A3B3D40485F5752504E4F50 5050505051555859595A585551504F4F4A4A494B4B4A4A4B4C4C4C4F4F4F505050505050505050 5050504F4E4E4E4E4D4D4D4D4E4E4F4F4E4F4F504E4E4D4D4D4E4D4D4E4E4E4F4F505050503B30 3130231A28302C2825313349312F322B27221D2329233D382D182E343C45553D403C3C3C362C31 3D3D45405C5F5C52505251515050505154595A59595856534E5150504E4B4A4A4A4A4B4C4C4B4B 4F4F4F4F5050515050505050504F4E4E4E4E4E4E4E4E4E4E4E4F4F4F505050504F4F4F4E4E4D4D 4E4E4F4E4E4F50505030303736303030342B1D292C36313826212F1B221C1A272C2C302B243B30 2F3638393552353347334035333A3A585E5E5A585554535151515454575A595A59575550515152 50504F4F504F4C4D4B4B4A4D4D4F505051505150505050504F4F4F4D4E4E4F4F4F4F4F4F4F4F50 4F505050505050504F4E4D4E4E4E4F4E4F505050292D372B2F291C2F2B1C26293F413728232E21 2222221C302F373032322C36353734364330322F3739313331404B5F5D5A585553525252555557 5B5A5A59595956525050504F4E4D4E4D50504F4E4C4B4B4D4E4F4F505050505050504F4F4F4F4E 4E4E4F4F4F4F4F50504F505050505050515150504F4F4E4E4F4F4F4F4F505025263131383E3533 221C25323D2F3826221F322025222227293B3D2F352D3B353B2E3338353829222D2C2C333C4A4D 5D5C5957545356585656595B5A58595A575855555250504F4E4D4E4C4D4F4F4F4D4C4D4C4E4E50 5050505050504F4F4F4F4F4F4F4F4F4F4F505050505050505050505050505050504F4E4E4F4F4F 505050293C2E3B36314432211928352F2C3E222A30292127272222233F3F39333033393F363D3B 3A312529362A2F2E3542425E5C5A5856565758565A5B5A5A585C5C5857585555565453504F4F4F 4F4D4D4F4C4C4D4D4C4E505050505050504F4F4E4F505050505050505050505050504F4F505050 5051515150504F504F50505050502D333A3E262E35302A1F2340261B2926222E342B2B25303835 304A3839303240403A3E3A2F2E2D252D26212F34352F235C5D5C5858575757595A5A59595C5B59 5656565657565556544E4F4E4E4E4E4D4D4D4F4E4D5050505050505050504F4F504F4F504F5050 504F4F5050504F4F4F505050505151515150505050505150502B2B333B34282433291E20323A23 2420312F31313F2037333B332E313B37343F433E372A38292D26471F272C25363B3A575D5C5A59 585759595959585A5C5C594D3B3339545655565554504F4E4E4E4D4C4D4F4F4E4D505050505051 5050504F5050504F4F4F5050504F4F505050504F50505050505151515151505050515050302F2F 35322F312C3225263836252B2A23243D3F47333A3F3A3225323C373137343C2F2C23292E3B4736 302E3337385A5F5E5C5B5958595959595756595C5C595236464C603652545454544F4D4E4D4D4B 4C4E4E4E4E5050515051515050504F505050504F505050505050505050504F4F50505151515151 51505150515150506F33363038353F3135223831302227252C22373838373E353F35292F303533 29312E2B25251F263240352F333C484066615F5C59585759595A5856595A5C5D5C5C445E5E613F 2538545453504E4D4D4C4A4C4C4E4E4F505051505051515050504F4F5050505050505050505050 504F4F4E50505152515251515151515150504F342B19412E212A3A3B2B2A2D2B3B272A272D1D37 394641352E31222A312B2827232623242A1B442D3A4B2D2A3544496D685D5D5957595A5A59585A 5A5C5C5D5F5F605D63625C392C4F555351504D4C4C4A4A494D4E4F4E4E50505051525050505050 5050505050504F50505050504F4F4F50505052515151515151515150504F1F152B45363C25332E 252C2C36402F2A3E3958353B42362E272B25262A261D1F221F282A2442312D5F2131272C4E6960 57585C5B5A5C5B5A57585B5C5C5C5E5E5E5E6465615D4D2E2C555250504E4B4A494A494E4F4E4D 4C4F5251515251505050505050505050504F505050505050504F4E4E5051515151515151515150 4F4F221F242E293A1A4021221E2D29303335433242324041352D293232222E221C242B1D282E28 24221F1A1C2630323D6662605B5A5B595C5B59585C5C5C5C5C5D5D5D5E63636161632C2A505350 4F4E4C49484A494F4D4C4B4B4F505252525150505050505050505050505051525150505050504F 4F505152525151515150504F4F1F323727302D2725252923232D312B31313B32313E4032222524 39293A2529304F2C332B2222201B1F232C373C3B4568645D5D5B5B5C5C5C5C5C5C5C5D5D5D5D5C 5F61625E665A1C2B4F52504F4E4D48494B494B4D4C4B4C4E505152525250505151505050505050 505051515150505050504F4F5050515151515150504F504F25282C363D4B373B271B29372F333A 303138332F3458422A352C2528294F2E26303029201E20121D1D272A2C2C3F4F46575C565F5F5C 5D5C5E5C5C5C5C5B5A5E5D5E6166676A542C2C4136504D4C4B49494C4B4A4D4C4B4D4E50505352 5251505251515050505050505050515251504F5050504F50505050515150504F4F4F4E1F1D224B 3A4D362C302D32322E363B3B383F38384038382F2925202328302D2A232F27241F212023222634 2E3836403A241F494E5F5E5C5D5C5C5C5B5C5C5C5C5E5E6166696C6E645A3625514E4A4A49484C 4B4B4C4B4B4D4E4E505254535250505050505051505050504E505251504F505050504F50505050 50504F4E4F4E4E1E1C2C2D2B34332C3137373F41363B433C3A403C292D302D281C23232A2F372B 2527221F2522232F2F33322D23321B3F1D1340505D5E5D5C5C5C5B5A5C5D5E5E5D5F6063646F70 6771652B4D4D4B4949464B4B4C4B4A4A4A4D4D505153545452505050504F505050504F4E505251 5050504F4E505050504E5050504F4F4D4D4D2124272B343E413A37303F40463C37404747474035 28282023283C2927333A2B252323312F342F2B2B292C2B2E2C303322152840525E5C5C5C5C595B 5C5D5D5F5E5F6162616B7472765931444F4C4B4946484A4A484A4A494B4F505052535454525151 5050505050504D4D4F525050504F4F4E4D504F4F4E4E504F4F4E4D4C4B22272230403A38383A33 3F3836363B4B3F464B43342B312125223C2B2F2A22232A23422F3425242D252B2B2E282B0A1707 301F37305C5C5A5C5C5B5C5C5D5F605F616361646C746F7048354850504B4846464A4A49494949 494E50505151535352535251515050504E4D4D4F515050504F4D4D4D4D4E4F4E4D50504F4E4D4C 4D2D37302F383A3840373132372A2E3D3C45464F4337222F211B21282423302522252230453552 262822222E45310F0912044B402A395C5C5A585A5B5C5C5C5F6060636361646C736C706E3E3250 4D4B4747464949494B4B4B50504F50504F50505252525151504F4E4C4B4C4E5050504F4F4D4E4F 4E4F4D4F4E4E4E4F4E4D4D4C1F2F2B3834272E3D4139463A47373B3C454D4D414A2F251D20312C 2B212C291C2221322C777657232E23292D2D20200B06131C2C595D5B59585C5B5A5C6061616165 636266676A6F716F5C46504D4B49494849494B4C4D504F4F4E4F4F4E4D4F5052525150504E4D4B 4B4C4D504F4E4E4E4D4E4F4F4F4D4D4D4D4B4D4B4B4B4C212D26353225333D433D562D423D3841 494F52443133282022222124324522212A2526405D4955222B28232E2C1704041B4C2B355D5C5C 5A5A59585C5D6161636466626567686A6F736A4551504F4C4A4A4848494B4D4F4E4F4F4D4E4D4C 4D5052535150504F4E4B4A4A4D4F4E4E4E4E4D4D4D4F504F4D4E4D4D4D4B4B4A4A492030232D33 23342E314240223E4042424F4D5A4533312820221F22292E3E502D2B332037675C5E36221A2F31 252210172E131044355C5C5C5A58585C5E60616266666666686A6E70714A5149504D4B4C494847 4A494F4F4F4F4E4A44464B4E4F52525050504E4D4C4A4A4D4F4E4E4E4E4E4D4E5050504E4F4E4D 4C4B4B4B4B4B262E2B28292E23335051322D374144414555514137332E2525201F2D3F56292A29 20182633393656292B272728292830151F1935383362605A595B5B5D606063626668696E6B6B6F 40404A46464E4D4B494947494E504E4F4E4A4748474C4F50504F4E4F4E4E4D4B4B4C4E4E4E4F4E 4D4E4E4F50515050504F4E4C4C4B4B4A4B23311C212230313722426B30333643433E404B5C3F58 44262C2D21315144322F1E2E27262B2C2B4A372F3233313F353438512B30312C32405C5B5C5D5D 606165666668555A39373C41413D6448504B4A494948494E4F4F504D4B47464C50504E4E4D4D4E 4D4D4B4A4B4D4E4E4F4F4E4D4E4D4D4F4F505050504F4E4D4D4C4C4D222C1A1E152C2C362F2B2B 26373839403F3E4E66494C4B302A383130593B2C230B2322253136282526222231335C354D3D36 25171E2B38352D335653496062635848403C3B483938273458715A4E4B494848474A4D4F4E4D4A 48464A4D4D4D4B494A4B4E4D4B4A494C4D4B4E4F504E4D4E4D4D4D4E4E5050504E4E4F4D4B4B50 2222231D23292E232129323539364140434641666C4F504030633A3C45462E3F432C2D20292622 28221B172A3671684963332B1D070D19342A2F233654606066382C3532462B5F59373455636452 4E49484C49484A49494B4A494C4B4B4B47454749474A4A494A4B4D4B4B4D4F504E4E4E4E4E4E4E 50505050504F4D4D4C4D4F231B181E222C2F2F404130373A373B4B414137506C6A4B405C676D51 4A743E384B292E1A31202E1A1E2A2D454E63746F6D3D2733060A1A3339302D2C3B393A363C3843 2B2C2F2E282E3847485951504B4A4E4A4B4949434A4A4C4A4A44434645454848484946494B4C4A 4A4B4F4F4E4E4E4E4E4F5050515050504F4E4D4D50502F240C181F22393433392A343F3D43466C 4B44686C6C4F3F4E735A4C504E323A2E23352E37272E2924292D3C726A70685638301E1229482D 232335393A3B372731322E4041342E292D3C47464D504E4B4B4C4A4B4B4742424B4B4846494747 474647484948494B4C4A4A494B4D4F4E4E4E4F4F50505050505050504E4E505051312F11133124 34372A381F2F3E3E4043566F6C6B6B6657405E74403F5C662C331A1D291D3D362F2E273A355772 727069572B3028222257282B4A2C3052383B293039463A373B584066574F51524F4F4B4A494848 48494442484748494A4845484847484848494A4C4A494A4A4C4B4E4F4F50505051505050505050 4E5051525229281B1D222D33332B271D29383D4641404C6C645D6E675F6E5F364F4D4539213C2E 2D383F463636385462616F70716F39292D23302A2B2E2F2F2B323A3A40393442676F666D6E6E6E 656150514E4D4A4848484748494642444748494A474649494748484A494A4B4B494B4A4C4B4E50 504F50515150505050505050515252512521272A2422252E2B1F2238303540373A406B6A62686D 4B43552F45443B33222634253547606A585649716F6F70716F512F331C4226142427573862774D 746E716E6D6D716F6F6F6E5C5452504E4C4B4A494847474745424448474A4D4849494A48474A49 4B4C4B4B4A4B4B4B4B4F4F5050505050505050514F4F5052525251211723281B2A232930222034 363E423E395B6B6965496B39636A3B285D40392B312829395155704970706F6F6F71716A343833 2E1D22202F5C635C787777776D726E6A6B6D6F71706D675151504D4C4B4B4A4847464643424449 484A4E494A4A4A4847454A4D4E4E4D4B4C4D4C4B4F4F5050515151515051504F50515251515117 282C2D191D242D3828243C35423A3934546A6B4E4351396C643129292D3A3733332343426D6F60 576F6F6E6F71706F403B3E29291E225E717675737574757372706C6B6E6F716F6C66504F4F4D4B 4B4B4A494746454343434A484D4D4A4B49494946484E4F4F4F4E4D4B4D4D4E4F4E505151515252 52515050505151525251202F5B321B12232C34322E26373B4139666B6A5A686649344855353222 2E3E282B2A253C696D6F6E6D6C6F6D6F6F717051412934375A3A6A7372717272717170706F6B6B 6D6F6F6C6B6253524F4D4B4B4A4949474645434343474B4E4D4C4A494748454A494B50504F4F4B 4C4D4F4D4F51515152535452515050505152525252232D312C1C10293A2938341F29333D333769 5E50685136494D5A3126363C3A5933313A29586D6D6B6D6D6D6E6F706F604543505F5C61507272 716F6F70706F6F6F6A68686A6E6867645E545352514D4A4949484746454343444448484D4B4B4C 4C464944464C4F524F4D4B4D4E4E4D4F5051515252535251505050505150505023332E33291B22 3A293A272B282F332F30614C5064592A375D6536382F5D3E542E33463F656A6C6B6B6C6D6E6F6F 6A5D68656B6D6F6F7071726F717070706F6C6A6866666A6A66636155545151504F4A4A49484847 4644444442414443464B4C4D4B4745484A515251504E4F4F4D4F4F505150515354545151505050 51515151 %END_IMAGE % gr_show_at() BEGIN 0 g 0 G 167.4 149.9 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 209.5 149.9 m (32) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 255.0 149.9 m (64) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 300.6 149.9 m (96) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 342.7 149.9 m (128) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 388.3 149.9 m (160) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 433.8 149.9 m (192) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 479.3 149.9 m (224) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 524.8 149.9 m (256) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 170.70 165.01 l 170.70 170.70 l 216.22 170.70 l 216.22 165.01 l 216.22 170.70 l 261.74 170.70 l 261.74 165.01 l 261.74 170.70 l 307.26 170.70 l 307.26 165.01 l 307.26 170.70 l 352.78 170.70 l 352.78 165.01 l 352.78 170.70 l 398.30 170.70 l 398.30 165.01 l 398.30 170.70 l 443.82 170.70 l 443.82 165.01 l 443.82 170.70 l 489.34 170.70 l 489.34 165.01 l 489.34 170.70 l 534.86 170.70 l 534.86 165.01 l 534.86 170.70 l 534.91 170.70 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 344.8 134.7 m (km) sh % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 534.86 m 170.70 534.86 l 170.70 540.55 l 170.70 534.86 l 216.22 534.86 l 216.22 540.55 l 216.22 534.86 l 261.74 534.86 l 261.74 540.55 l 261.74 534.86 l 307.26 534.86 l 307.26 540.55 l 307.26 534.86 l 352.78 534.86 l 352.78 540.55 l 352.78 534.86 l 398.30 534.86 l 398.30 540.55 l 398.30 534.86 l 443.82 534.86 l 443.82 540.55 l 443.82 534.86 l 489.34 534.86 l 489.34 540.55 l 489.34 534.86 l 534.86 534.86 l 534.86 540.55 l 534.86 534.86 l 534.91 534.86 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf % gr_show_at() BEGIN 0 g 0 G 152.5 166.4 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 211.9 m (32) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 257.4 m (64) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 302.9 m (96) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 139.1 348.5 m (128) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 139.1 394.0 m (160) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 139.1 439.5 m (192) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 139.1 485.0 m (224) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 139.1 530.5 m (256) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 165.01 170.70 l 170.70 170.70 l 170.70 216.22 l 165.01 216.22 l 170.70 216.22 l 170.70 261.74 l 165.01 261.74 l 170.70 261.74 l 170.70 307.26 l 165.01 307.26 l 170.70 307.26 l 170.70 352.78 l 165.01 352.78 l 170.70 352.78 l 170.70 398.30 l 165.01 398.30 l 170.70 398.30 l 170.70 443.82 l 165.01 443.82 l 170.70 443.82 l 170.70 489.34 l 165.01 489.34 l 170.70 489.34 l 170.70 534.86 l 165.01 534.86 l 170.70 534.86 l 170.70 534.86 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 133.2 344.8 m 90.00 rotate (km) sh -90.00 rotate % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 534.86 170.70 m 534.86 170.70 l 540.55 170.70 l 534.86 170.70 l 534.86 216.22 l 540.55 216.22 l 534.86 216.22 l 534.86 261.74 l 540.55 261.74 l 534.86 261.74 l 534.86 307.26 l 540.55 307.26 l 534.86 307.26 l 534.86 352.78 l 540.55 352.78 l 534.86 352.78 l 534.86 398.30 l 540.55 398.30 l 534.86 398.30 l 534.86 443.82 l 540.55 443.82 l 534.86 443.82 l 534.86 489.34 l 540.55 489.34 l 534.86 489.34 l 534.86 534.86 l 540.55 534.86 l 534.86 534.86 l 534.86 534.86 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:draw image palette left \minT right \maxT increment \incT %^ scale 1 170.7 0 1.4225 1 170.7 0 1.4225 0 g 0 G q n % turn clipping on for image palette 170.700000 591.760000 moveto 534.860000 591.760000 lineto 534.860000 620.210000 lineto 170.700000 620.210000 lineto 170.700000 591.760000 lineto closepath W % Push map onto stack, then image stuff. [ 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.9961 0.9765 0.9569 0.9373 0.9176 0.8980 0.8784 0.8588 0.8392 0.8196 0.8000 0.7765 0.7569 0.7373 0.7176 0.6980 0.6784 0.6588 0.6392 0.6196 0.6000 0.5765 0.5569 0.5373 0.5176 0.4980 0.4784 0.4588 0.4392 0.4196 0.4000 0.3765 0.3569 0.3373 0.3176 0.2980 0.2784 0.2588 0.2392 0.2196 0.2000 0.1765 0.1569 0.1373 0.1176 0.0980 0.0784 0.0588 0.0392 0.0196 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 ] 170.343679 591.760000 535.216321 620.210000 1 512 im 323232323232333333333333333333333434343434343434343435353535353535353535363636 36363636363636373737373737373737373738383838383838383838393939393939393939393A 3A3A3A3A3A3A3A3A3A3B3B3B3B3B3B3B3B3B3B3B3C3C3C3C3C3C3C3C3C3C3D3D3D3D3D3D3D3D3D 3D3E3E3E3E3E3E3E3E3E3E3F3F3F3F3F3F3F3F3F3F404040404040404040404041414141414141 414141424242424242424242424343434343434343434344444444444444444444444545454545 454545454546464646464646464646474747474747474747474848484848484848484849494949 494949494949494A4A4A4A4A4A4A4A4A4A4B4B4B4B4B4B4B4B4B4B4C4C4C4C4C4C4C4C4C4C4D4D 4D4D4D4D4D4D4D4D4D4E4E4E4E4E4E4E4E4E4E4F4F4F4F4F4F4F4F4F4F50505050505050505050 515151515151515151515252525252525252525252535353535353535353535454545454545454 545455555555555555555555565656565656565656565657575757575757575757585858585858 58585858595959595959595959595A5A5A5A5A5A5A5A5A5A5B5B5B5B5B5B5B5B5B5B5B5C5C5C5C 5C5C5C5C5C5C5D5D5D5D5D5D5D5D5D5D5E5E5E5E5E5E5E5E5E5E5F5F5F5F5F5F5F5F5F5F5F6060 606060606060606061616161616161616161626262626262626262626363636363636363636364 6464646464 Q % turn clipping off for image palette % gr_show_at() BEGIN 0 g 0 G 164.0 570.9 m (10) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 236.8 570.9 m (11) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 309.7 570.9 m (12) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 382.5 570.9 m (13) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 455.3 570.9 m (14) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 528.2 570.9 m (15) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 591.76 m 170.70 591.76 l 170.70 586.07 l 170.70 591.76 l 243.53 591.76 l 243.53 586.07 l 243.53 591.76 l 316.36 591.76 l 316.36 586.07 l 316.36 591.76 l 389.20 591.76 l 389.20 586.07 l 389.20 591.76 l 462.03 591.76 l 462.03 586.07 l 462.03 591.76 l 534.86 591.76 l 534.86 586.07 l 534.86 591.76 l 534.93 591.76 l S % END GriPath stroke/fill 0.369 w % test 0 g 0 G 1.0 i 0 J 1 j 0.369 w 10.0 M [] 0 d 170.70 591.76 m 170.70 620.21 l 534.86 620.21 l 534.86 591.76 l 170.70 591.76 l S % END GriPath stroke/fill %gri:draw image histogram %^ scale 1 170.7 0 1.4225 1 170.7 0 1.4225 % gr_show_at() BEGIN 0 g 0 G 167.4 642.1 m (5) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 224.7 642.1 m (10) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 285.4 642.1 m (15) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 346.1 642.1 m (20) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 406.8 642.1 m (25) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 467.5 642.1 m (30) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 528.2 642.1 m (35) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 662.88 m 170.70 662.88 l 170.70 657.20 l 170.70 662.88 l 231.39 662.88 l 231.39 657.20 l 231.39 662.88 l 292.09 662.88 l 292.09 657.20 l 292.09 662.88 l 352.78 662.88 l 352.78 657.20 l 352.78 662.88 l 413.47 662.88 l 413.47 657.20 l 413.47 662.88 l 474.17 662.88 l 474.17 657.20 l 474.17 662.88 l 534.86 662.88 l 534.86 657.20 l 534.86 662.88 l 534.92 662.88 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 135.1 658.6 m () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (1) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (0) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh 0.0 5.4 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh (\255) sh () sh /Helvetica-ISOLatin1 findfont 9.00 sc sf (4) sh /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 -5.4 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 135.1 676.3 m () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (1) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (0) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh 0.0 5.4 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh (\255) sh () sh /Helvetica-ISOLatin1 findfont 9.00 sc sf (3) sh /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 -5.4 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 135.1 694.1 m () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (1) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (0) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh 0.0 5.4 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh (\255) sh () sh /Helvetica-ISOLatin1 findfont 9.00 sc sf (2) sh /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 -5.4 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 135.1 711.9 m () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (1) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf (0) sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf () sh 0.0 5.4 rm /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh (\255) sh () sh /Helvetica-ISOLatin1 findfont 9.00 sc sf (1) sh /Helvetica-Oblique-ISOLatin1 findfont 9.00 sc sf () sh /Helvetica-Oblique-ISOLatin1 findfont 12.00 sc sf 0.0 -5.4 rm () sh /Helvetica-ISOLatin1 findfont 12.00 sc sf () sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 152.5 729.7 m (1) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 662.74 m 170.70 662.88 l 165.01 662.88 l 170.70 662.88 l 170.70 668.24 l 167.86 668.24 l 170.70 668.24 l 170.70 671.37 l 167.86 671.37 l 170.70 671.37 l 170.70 673.59 l 167.86 673.59 l 170.70 673.59 l 170.70 675.31 l 167.86 675.31 l 170.70 675.31 l 170.70 676.72 l 167.86 676.72 l 170.70 676.72 l 170.70 677.91 l 167.86 677.91 l 170.70 677.91 l 170.70 678.94 l 167.86 678.94 l 170.70 678.94 l 170.70 679.85 l 167.86 679.85 l 170.70 679.85 l 170.70 680.67 l 165.01 680.67 l 170.70 680.67 l 170.70 686.02 l 167.86 686.02 l 170.70 686.02 l 170.70 689.15 l 167.86 689.15 l 170.70 689.15 l 170.70 691.37 l 167.86 691.37 l 170.70 691.37 l 170.70 693.09 l 167.86 693.09 l 170.70 693.09 l 170.70 694.50 l 167.86 694.50 l 170.70 694.50 l 170.70 695.69 l 167.86 695.69 l 170.70 695.69 l 170.70 696.72 l 167.86 696.72 l 170.70 696.72 l 170.70 697.63 l 167.86 697.63 l 170.70 697.63 l 170.70 698.45 l 165.01 698.45 l 170.70 698.45 l 170.70 703.80 l 167.86 703.80 l 170.70 703.80 l 170.70 706.93 l 167.86 706.93 l 170.70 706.93 l 170.70 709.15 l 167.86 709.15 l 170.70 709.15 l 170.70 710.88 l 167.86 710.88 l 170.70 710.88 l 170.70 712.28 l 167.86 712.28 l 170.70 712.28 l 170.70 713.47 l 167.86 713.47 l 170.70 713.47 l 170.70 714.51 l 167.86 714.51 l 170.70 714.51 l 170.70 715.42 l 167.86 715.42 l 170.70 715.42 l 170.70 716.23 l 165.01 716.23 l 170.70 716.23 l 170.70 721.58 l 167.86 721.58 l 170.70 721.58 l 170.70 724.71 l 167.86 724.71 l 170.70 724.71 l 170.70 726.93 l 167.86 726.93 l 170.70 726.93 l 170.70 728.66 l 167.86 728.66 l 170.70 728.66 l 170.70 730.07 l 167.86 730.07 l 170.70 730.07 l 170.70 731.26 l 167.86 731.26 l 170.70 731.26 l 170.70 732.29 l 167.86 732.29 l 170.70 732.29 l 170.70 733.20 l 167.86 733.20 l 170.70 733.20 l 170.70 734.01 l 165.01 734.01 l 170.70 734.01 l 170.70 734.01 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 662.88 m 170.70 734.01 l 534.86 734.01 l 534.86 662.88 l 170.70 662.88 m 170.70 662.88 l 171.91 662.88 l 173.13 662.88 l 174.34 662.88 l 175.56 692.95 l 176.77 662.88 l 177.98 671.49 l 179.20 675.46 l 180.41 668.33 l 181.62 671.49 l 182.84 671.49 l 184.05 668.33 l 185.27 673.72 l 186.48 671.49 l 187.69 662.88 l 188.91 676.87 l 190.12 662.88 l 191.34 668.33 l 192.55 668.33 l 193.76 662.88 l 194.98 676.87 l 196.19 680.01 l 197.41 675.46 l 198.62 671.49 l 199.83 678.06 l 201.05 673.72 l 202.26 675.46 l 203.47 676.87 l 204.69 675.46 l 205.90 673.72 l 207.12 675.46 l 208.33 675.46 l 209.54 678.06 l 210.76 671.49 l 211.97 682.86 l 213.19 682.24 l 214.40 678.06 l 215.61 676.87 l 216.83 680.01 l 218.04 673.72 l 219.25 679.10 l 220.47 668.33 l 221.68 679.10 l 222.90 682.24 l 224.11 684.93 l 225.32 680.83 l 226.54 683.43 l 227.75 680.01 l 228.97 684.46 l 230.18 680.01 l 231.39 683.96 l 232.61 682.86 l 233.82 683.96 l 235.03 682.24 l 236.25 687.91 l 237.46 688.79 l 238.68 688.51 l 239.89 685.79 l 241.10 690.06 l 242.32 690.29 l 243.53 692.10 l 244.75 693.86 l 245.96 695.30 l 247.17 696.80 l 248.39 702.01 l 249.60 697.55 l 250.82 698.93 l 252.03 699.07 l 253.24 699.22 l 254.46 702.81 l 255.67 704.89 l 256.88 707.58 l 258.10 708.81 l 259.31 712.05 l 260.53 712.08 l 261.74 714.19 l 262.95 711.16 l 264.17 715.13 l 265.38 714.52 l 266.60 714.01 l 267.81 718.19 l 269.02 707.29 l 270.24 703.33 l 271.45 697.81 l 272.66 695.64 l 273.88 693.11 l 275.09 691.74 l 276.31 690.51 l 277.52 692.10 l 278.73 693.42 l 279.95 692.28 l 281.16 689.06 l 282.38 698.47 l 283.59 691.35 l 284.80 689.32 l 286.02 686.56 l 287.23 683.96 l 288.45 687.27 l 289.66 682.24 l 290.87 682.86 l 292.09 681.56 l 293.30 679.10 l 294.51 685.79 l 295.73 679.10 l 296.94 682.24 l 298.16 676.87 l 299.37 684.46 l 300.58 684.46 l 301.80 683.43 l 303.01 686.19 l 304.23 684.93 l 305.44 691.35 l 306.65 684.46 l 307.87 683.96 l 309.08 682.24 l 310.29 675.46 l 311.51 671.49 l 312.72 673.72 l 313.94 668.33 l 315.15 671.49 l 316.36 662.88 l 317.58 662.88 l 318.79 662.88 l 320.01 662.88 l 321.22 662.88 l 322.43 662.88 l 323.65 662.88 l 324.86 662.88 l 326.07 662.88 l 327.29 662.88 l 328.50 662.88 l 329.72 662.88 l 330.93 662.88 l 332.14 662.88 l 333.36 662.88 l 334.57 662.88 l 335.79 662.88 l 337.00 662.88 l 338.21 662.88 l 339.43 662.88 l 340.64 662.88 l 341.86 662.88 l 343.07 662.88 l 344.28 662.88 l 345.50 662.88 l 346.71 662.88 l 347.92 662.88 l 349.14 662.88 l 350.35 662.88 l 351.57 662.88 l 352.78 662.88 l 353.99 662.88 l 355.21 662.88 l 356.42 662.88 l 357.64 662.88 l 358.85 662.88 l 360.06 662.88 l 361.28 662.88 l 362.49 662.88 l 363.70 662.88 l 364.92 662.88 l 366.13 662.88 l 367.35 662.88 l 368.56 662.88 l 369.77 662.88 l 370.99 662.88 l 372.20 662.88 l 373.42 662.88 l 374.63 662.88 l 375.84 662.88 l 377.06 662.88 l 378.27 662.88 l 379.49 662.88 l 380.70 662.88 l 381.91 662.88 l 383.13 662.88 l 384.34 662.88 l 385.55 662.88 l 386.77 662.88 l 387.98 662.88 l 389.20 662.88 l 390.41 662.88 l 391.62 662.88 l 392.84 662.88 l 394.05 662.88 l 395.27 662.88 l 396.48 662.88 l 397.69 662.88 l 398.91 662.88 l 400.12 662.88 l 401.33 662.88 l 402.55 662.88 l 403.76 662.88 l 404.98 662.88 l 406.19 662.88 l 407.40 662.88 l 408.62 662.88 l 409.83 662.88 l 411.05 662.88 l 412.26 662.88 l 413.47 662.88 l 414.69 662.88 l 415.90 662.88 l 417.11 662.88 l 418.33 662.88 l 419.54 662.88 l 420.76 662.88 l 421.97 662.88 l 423.18 662.88 l 424.40 662.88 l 425.61 662.88 l 426.83 662.88 l 428.04 662.88 l 429.25 662.88 l 430.47 662.88 l 431.68 662.88 l 432.90 662.88 l 434.11 662.88 l 435.32 662.88 l 436.54 662.88 l 437.75 662.88 l 438.96 662.88 l 440.18 662.88 l 441.39 662.88 l 442.61 662.88 l 443.82 662.88 l 445.03 662.88 l 446.25 662.88 l 447.46 662.88 l 448.68 662.88 l 449.89 662.88 l 451.10 662.88 l 452.32 662.88 l 453.53 662.88 l 454.74 662.88 l 455.96 662.88 l 457.17 662.88 l 458.39 662.88 l 459.60 662.88 l 460.81 662.88 l 462.03 662.88 l 463.24 662.88 l 464.46 662.88 l 465.67 662.88 l 466.88 662.88 l 468.10 662.88 l 469.31 662.88 l 470.53 662.88 l 471.74 662.88 l 472.95 662.88 l 474.17 662.88 l 475.38 662.88 l 476.59 662.88 l 477.81 662.88 l 479.02 662.88 l 480.24 662.88 l S % END GriPath stroke/fill %gri:if {"\histo" == "yes"} %gri: draw title "Example 6: grayscale histogram enhanced" %gri:else %gri: draw title "Example 6: grayscale linear \minT to \maxT" %^ scale 1 170.7 0 1.4225 1 170.7 0 1.4225 % gr_show_at() BEGIN 0 g 0 G 255.4 762.5 m (Example 6: grayscale linear 10 to 15) sh % gr_show_at() END %gri:end if %gri:quit showpage %%Trailer %%BoundingBox: 123 130 547 773 %%DocumentFonts: Courier Helvetica Palatino-Roman Palatino-Italic Symbol Times-Roman %%Pages: 1 gri/doc/examples/example7.txt0000644000175000017500000000001513147557614014662 0ustar psgpsgexample7.gri gri/doc/examples/example13.ps0000644000175000017500000007056713147557614014565 0ustar psgpsg%!PS-Adobe-2.0 EPSF-1.2 %%Creator: Gri2.6.0 (released 2000-Jun-23). User=kelley, commandfile=/home/kelley/GRI-work/gri/doc/examples/example13.gri %%Title: example13.ps %%CreationDate: Fri Jun 23 12:28:49 2000 %%Pages: (atend) %%BoundingBox: (atend) %%TemplateBox: 0 0 612 792 %%DocumentFonts: (atend) %%Endcomments % NOTE: The Gri postscript dictionary is being converted to the Adobe % Illustrator 3.0 dialect of PostScript, as described in the Adobe % documents stored at URL % http://www.adobe.com/Support/TechNotes.html % (as of Jan 1996, this doc is number 5007). When the conversion % is complete, the Adobe Illustrator drawing program -- and any % program compatible with AI -- will be able to edit Gri output. % % The IslandDraw (TM) program is able to read Gri output % at this time; remarkably, it can read/edit arbitrary PostScript. % % The definitions below are presented in the same order as the Adobe % manual. The stack configuration before and after is shown in curly % brackets. All the operators are listed, but only some are defined % here. Most things are faithful, except that no distinction is made % between colors for stroking and filling paths. The string 'WRONGLY' % appears with commands that are approximations. % % PDF-style abbreviations: /rg {setrgbcolor} def % {red green blue} {-} set RGB color /RG {setrgbcolor} def % {red green blue} {-} set RGB color /q {gsave} def /Q {grestore} def /W {clip} def /W* {eoclip} def % % Gri-specific abbreviations: /hsb {sethsbcolor} def % {hue saturation brightness} {-} set HSB color % % Following all try to mimic Adobe Illustrator % % Mimicking section 5.1 of Adobe manual: %A % {flag A} {-} Determine whether % following object can % be selected. Flag=1 % prevents selection; % flag=0 allows it. % Mimicking section 5.2 of Adobe manual: %u % {u} {-} start group %U % end group %q % as 'u' but first item is a clip path %Q % as 'U' but first item is a clip path % Mimicking section 5.3 of Adobe manual: /g {setgray} def % {gray g} {-} Set gray for fill % path, WRONGLY used % for stroking also. /G {setgray} def % As 'g', but for filling path. %k % Set cmyk color for filling path. %K % As 'k', but for stroking path. %x % Set cmyk custom color for filling path. %X % As 'x' but for stroking path. %p % Define pattern for filling path. %P % As 'p' but for stroking path. %O % Specify whether overprinting for fill paths %R % As 'O' but for stroking path. % Mimicking section 5.4 of Adobe manual: /d {setdash} def % {[array] phase d} {-} Set dash. /i {setflat} def % {flatness i} {-} Set flatness. /j {setlinejoin} def % {linejoin j} {-} Set line join. /J {setlinecap} def % {linecap J} {-} Set line cap. /M {setmiterlimit} def % {miterlimit M} {-} Set miter limit. /w {setlinewidth} def % {linewidth w} {-} Set line width. % Mimicking section 5.5 of Adobe manual: /m {moveto} def % {x y m} {-} Move to locn /l {lineto} def % {x y l} {-} Draw line to locn % not a smooth point. % WRONGLY, no % distinction is made % between smooth and % corner. %L % {x y L} {-} As 'l' but a corner %c % Bezier curve to smooth point. %C % As 'c' but to corner point. %v % Something else to do with Bezier. %V % %y % %Y % % Mimicking section 5.6 of Adobe manual: %N % {N} {-} As 'n' for nondrawn stuff /n {newpath} def % {n} {-} WRONGLY interpreted % as path constructor /F {fill} def % {F} {-} Fill current path. %f % {f} {-} 'F' but close first /S {stroke} def % {S} {-} Stroke current path. %s % {s} {-} 'S' but close first %B % {B} {-} As 's' but don't empty path. %b % {b} {-} As 'f' but don't empty path. %H % no-op (weird huh?) /h {closepath} def % {h} {-} Close current path %W % Used to create masks. % Mimicking section 5.7 of Adobe manual: %a % Begin text block ... %e % Similar to 'a' but ... %I % Similar to 'a' but ... %o % Similar to 'a' but ... %r % Similar to 'a' but ... %t % {len (string) t} {-} Render string. %T % End block of text % That's the end of the Illustrator stuff. Following are some Gri % definitions which provide a temporary way of handling fonts. /sf {setfont} def % {fontname sf} {-} Set font name. /sh {show} def % {(text) sh} {-} Show text. /sc {scalefont} def % {size sc} {-} Scale font. % Gri items which should be translated to Illustrator format: /rl {rlineto} def /rm {rmoveto} def % Procedures /cimdict 7 dict def /cim { cimdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def q xll yll translate xur xll sub yur yll sub scale /do cl 3 mul string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop} false 3 colorimage Q end } def /imdict 14 dict def /im { imdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def /imagemap exch def q % Add the mapping to the transfer function (ref: white book, p 743. [{255 mul cvi imagemap exch get} /exec load currenttransfer /exec load] cvx settransfer xll yll translate xur xll sub yur yll sub scale /do cl string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop}image Q end } def /frdict 5 dict def /fr { frdict begin /yt exch def /xr exch def /yb exch def /xl exch def n xl yb m xl yt l xr yt l xr yb l h F n end } def /plusdict 3 dict def /_plus { plusdict begin dup 0.5 mul /t0 exch def /t1 exch def 0 t0 rm 0 t1 neg rl t0 neg t0 rm t1 0 rl t0 neg 0 rm end } def /timesdict 3 dict def /_times { timesdict begin dup 0.353553 mul /t0 exch def 0.707106 mul /t1 exch def t0 neg t0 rm t1 dup neg rl t1 neg 0 rm t1 dup rl t0 neg dup rm end } def /boxdict 3 dict def /_box { boxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm end } def /filledboxdict 3 dict def /_filledbox { filledboxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm F end } def /diamonddict 2 dict def /_diamond { diamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm end } def /filleddiamonddict 2 dict def /_filleddiamond { filleddiamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm F end } def /triangleupdict 5 dict def /_triangleup { triangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm end } def /filledtriangleupdict 5 dict def /_filledtriangleup { filledtriangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm F end } def /trianglerightdict 5 dict def /_triangleright { trianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm end } def /filledtrianglerightdict 5 dict def /_filledtriangleright { filledtrianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm F end } def /triangledowndict 5 dict def /_triangledown { triangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm end } def /filledtriangledowndict 5 dict def /_filledtriangledown { filledtriangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm F end } def /triangleleftdict 5 dict def /_triangleleft { triangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm end } def /filledtriangleleftdict 5 dict def /_filledtriangleleft { filledtriangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm F end } def /circdict 5 dict def /_circ { circdict begin 0.5 mul /t0 exch def currentpoint /t2 exch def /t1 exch def S n t1 t2 t0 0 360 arc t1 t2 m end } def /bulldict 3 dict def /_bull { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 360 arc h F S end } def /filledhalfmoonupdict 3 dict def /_filledhalfmoonup { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 180 arc h F S end } def /filledhalfmoondowndict 3 dict def /_filledhalfmoondown { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 180 360 arc h F S end } def 1 1 scale 10.0 M 1 j /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-ISOLatin1 exch definefont pop /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Bold-ISOLatin1 exch definefont pop /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-ISOLatin1 exch definefont pop /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Bold-ISOLatin1 exch definefont pop /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Roman-ISOLatin1 exch definefont pop /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Bold-ISOLatin1 exch definefont pop /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Italic-ISOLatin1 exch definefont pop /Symbol findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Symbol-ISOLatin1 exch definefont pop /Times findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-ISOLatin1 exch definefont pop /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Bold-ISOLatin1 exch definefont pop /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Roman-ISOLatin1 exch definefont pop %%EndProlog %%Page: 1 1 /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:# Example 13 -- TS diagram, with isopycnals %gri: %gri:# Draw Axes %gri:set line width axis 0.25 %gri:set line width 0.75 %gri:.tic_size. = 0.1 # cm %gri:set symbol size 0.03 %gri:.isopycnal_fontsize. = 8 # for isopycnal labels %gri:.axes_fontsize. = 10 # for axes %gri:set font size .axes_fontsize. /Helvetica-ISOLatin1 findfont 10.00 sc sf %gri:set x margin 2 %gri:set x size 10 %gri:set y margin 2 %gri:set y size 10 %gri:set tic size .tic_size. %gri:set x name "Salinity / PSU" %gri:set y name "Potential Temperature / $\circ$C" %gri:set x axis 34 35 0.5 0.1 %gri:set y axis 2 10 1 %gri:set axes style offset %gri:draw axes 1 % gr_show_at() BEGIN 0 g 0 G 51.3 38.6 m (34) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 189.4 38.6 m (34.5) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 335.8 38.6 m (35) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.250 w 10.0 M [] 0 d 56.90 54.05 m 56.90 54.05 l 56.90 51.21 l 56.90 54.05 l 85.35 54.05 l 85.35 52.63 l 85.35 54.05 l 113.80 54.05 l 113.80 52.63 l 113.80 54.05 l 142.25 54.05 l 142.25 52.63 l 142.25 54.05 l 170.70 54.05 l 170.70 52.63 l 170.70 54.05 l 199.15 54.05 l 199.15 51.21 l 199.15 54.05 l 227.60 54.05 l 227.60 52.63 l 227.60 54.05 l 256.05 54.05 l 256.05 52.63 l 256.05 54.05 l 284.50 54.05 l 284.50 52.63 l 284.50 54.05 l 312.95 54.05 l 312.95 52.63 l 312.95 54.05 l 341.40 54.05 l 341.40 51.21 l 341.40 54.05 l 341.54 54.05 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 168.5 26.0 m (Salinity / PSU) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 40.8 53.3 m (2) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 40.8 88.9 m (3) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 40.8 124.4 m (4) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 40.8 160.0 m (5) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 40.8 195.5 m (6) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 40.8 231.1 m (7) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 40.8 266.7 m (8) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 40.8 302.2 m (9) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 35.2 337.8 m (10) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.250 w 10.0 M [] 0 d 54.06 56.90 m 54.06 56.90 l 51.21 56.90 l 54.06 56.90 l 54.06 92.46 l 51.21 92.46 l 54.06 92.46 l 54.06 128.03 l 51.21 128.03 l 54.06 128.03 l 54.06 163.59 l 51.21 163.59 l 54.06 163.59 l 54.06 199.15 l 51.21 199.15 l 54.06 199.15 l 54.06 234.71 l 51.21 234.71 l 54.06 234.71 l 54.06 270.27 l 51.21 270.27 l 54.06 270.27 l 54.06 305.84 l 51.21 305.84 l 54.06 305.84 l 54.06 341.40 l 51.21 341.40 l 54.06 341.40 l 54.06 341.40 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 30.3 140.4 m 90.00 rotate (Potential Temperature / ) sh /Helvetica-Oblique-ISOLatin1 findfont 10.00 sc sf () sh /Symbol findfont 10.00 sc sf (\260) sh /Helvetica-Oblique-ISOLatin1 findfont 10.00 sc sf () sh /Helvetica-ISOLatin1 findfont 10.00 sc sf (C) sh -90.00 rotate % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.250 w 10.0 M [] 0 d 56.90 341.40 m 341.40 341.40 l 341.40 56.90 l 56.90 56.90 l 56.90 341.40 l S % END GriPath stroke/fill %gri:set clip on %gri:.old. = ..fontsize.. %gri:set font size .isopycnal_fontsize. /Helvetica-ISOLatin1 findfont 8.00 sc sf %gri:set line width rapidograph 1 %gri:draw isopycnal 26.00 %^ scale 1 56.9 34 284.5 1 56.9 2 35.5625 %gri:draw isopycnal 27.00 %^ scale 1 56.9 34 284.5 1 56.9 2 35.5625 1.417 w 0 g 0 G 1.0 i 0 J 1 j 1.417 w 10.0 M [] 0 d 56.90 124.80 m 56.90 124.80 l 59.74 127.58 l 62.59 130.33 l 65.43 133.07 l 68.28 135.78 l 71.12 138.45 l 73.97 141.11 l 76.81 143.75 l 79.66 146.36 l 82.50 148.95 l 85.35 151.51 l 88.19 154.06 l 91.04 156.59 l 93.88 159.09 l 96.73 161.58 l 99.57 164.05 l 102.42 166.50 l 105.26 168.93 l 108.11 171.34 l 110.95 173.74 l 113.80 176.12 l 116.64 178.48 l 119.49 180.83 l 122.33 183.16 l 125.18 185.48 l 128.02 187.77 l 130.87 190.06 l 133.71 192.33 l 136.56 194.59 l 139.40 196.83 l 142.25 199.06 l 145.09 201.28 l 147.94 203.48 l 150.78 205.67 l 153.63 207.85 l 156.47 210.01 l 159.32 212.17 l 162.16 214.31 l 165.01 216.43 l 167.85 218.55 l 170.70 220.66 l 173.54 222.75 l 176.39 224.84 l 179.23 226.91 l 182.08 228.97 l 184.92 231.02 l 187.77 233.06 l 190.61 235.10 l 193.46 237.12 l 196.30 239.13 l 199.15 241.13 l 201.99 243.12 l 204.84 245.11 l 207.68 247.08 l 210.53 249.05 l 213.37 251.00 l 216.22 252.95 l 219.06 254.89 l 221.91 256.82 l 224.75 258.74 l 227.60 260.65 l 230.44 262.56 l 233.29 264.45 l 236.13 266.34 l 238.98 268.23 l 241.82 270.09 l 244.67 271.96 l 247.51 273.82 l 250.36 275.67 l 253.20 277.51 l 256.05 279.35 l 258.89 281.18 l 261.74 283.00 l 264.58 284.81 l 267.43 286.62 l 270.27 288.42 l 273.12 290.21 l 275.96 292.00 l 278.81 293.79 l 281.65 295.56 l 284.50 297.32 l 287.34 299.08 l 290.19 300.84 l 293.03 302.59 l 295.88 304.33 l 298.72 306.07 l 301.57 307.80 l 304.41 309.53 l 307.26 311.24 l 310.10 312.96 l 312.95 314.67 l 315.79 316.37 l 318.64 318.06 l 321.48 319.76 l 324.33 321.44 l 327.17 323.12 l 330.02 324.79 l 332.86 326.46 l 335.71 328.13 l 338.55 329.78 l 341.40 331.44 l S % END GriPath stroke/fill 0 g 0 G 1 g 1 G 1.0 i 0 J 1 j 1.417 w 10.0 M [] 0 d 74.08 145.24 m 85.24 145.24 l 85.24 153.24 l 74.08 153.24 l 74.08 153.24 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 75.2 146.4 m (27) sh % gr_show_at() END 1 g 1 G 1.0 i 0 J 1 j 1.417 w 10.0 M [] 0 d 304.53 311.84 m 315.68 311.84 l 315.68 319.84 l 304.53 319.84 l 304.53 319.84 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 305.6 313.0 m (27) sh % gr_show_at() END %gri:draw isopycnal 28.00 %^ scale 1 56.9 34 284.5 1 56.9 2 35.5625 %gri:draw isopycnal 29.00 %^ scale 1 56.9 34 284.5 1 56.9 2 35.5625 %gri:set line width rapidograph 3x0 %gri:draw isopycnal unlabelled 26.75 %^ scale 1 56.9 34 284.5 1 56.9 2 35.5625 0.709 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 56.90 202.71 m 56.90 202.71 l 59.74 204.91 l 62.59 207.11 l 65.43 209.29 l 68.28 211.46 l 71.12 213.62 l 73.97 215.76 l 76.81 217.90 l 79.66 220.02 l 82.50 222.12 l 85.35 224.23 l 88.19 226.31 l 91.04 228.39 l 93.88 230.46 l 96.73 232.51 l 99.57 234.56 l 102.42 236.59 l 105.26 238.62 l 108.11 240.63 l 110.95 242.64 l 113.80 244.64 l 116.64 246.62 l 119.49 248.60 l 122.33 250.57 l 125.18 252.53 l 128.02 254.48 l 130.87 256.42 l 133.71 258.35 l 136.56 260.28 l 139.40 262.19 l 142.25 264.10 l 145.09 266.00 l 147.94 267.89 l 150.78 269.78 l 153.63 271.65 l 156.47 273.52 l 159.32 275.38 l 162.16 277.23 l 165.01 279.08 l 167.85 280.91 l 170.70 282.75 l 173.54 284.57 l 176.39 286.39 l 179.23 288.20 l 182.08 290.00 l 184.92 291.80 l 187.77 293.59 l 190.61 295.37 l 193.46 297.15 l 196.30 298.91 l 199.15 300.68 l 201.99 302.43 l 204.84 304.19 l 207.68 305.93 l 210.53 307.67 l 213.37 309.40 l 216.22 311.13 l 219.06 312.85 l 221.91 314.56 l 224.75 316.27 l 227.60 317.98 l 230.44 319.68 l 233.29 321.37 l 236.13 323.05 l 238.98 324.74 l 241.82 326.41 l 244.67 328.09 l 247.51 329.75 l 250.36 331.41 l 253.20 333.07 l 256.05 334.71 l 258.89 336.36 l 261.74 338.00 l 264.58 339.63 l 267.43 341.26 l 267.67 341.40 l S % END GriPath stroke/fill %gri:draw isopycnal unlabelled 26.50 %^ scale 1 56.9 34 284.5 1 56.9 2 35.5625 0.709 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 56.90 267.56 m 56.90 267.56 l 59.74 269.46 l 62.59 271.34 l 65.43 273.22 l 68.28 275.09 l 71.12 276.95 l 73.97 278.81 l 76.81 280.66 l 79.66 282.50 l 82.50 284.33 l 85.35 286.16 l 88.19 287.98 l 91.04 289.79 l 93.88 291.60 l 96.73 293.40 l 99.57 295.19 l 102.42 296.97 l 105.26 298.75 l 108.11 300.53 l 110.95 302.29 l 113.80 304.05 l 116.64 305.80 l 119.49 307.55 l 122.33 309.29 l 125.18 311.02 l 128.02 312.75 l 130.87 314.47 l 133.71 316.19 l 136.56 317.90 l 139.40 319.61 l 142.25 321.31 l 145.09 323.00 l 147.94 324.69 l 150.78 326.37 l 153.63 328.05 l 156.47 329.72 l 159.32 331.39 l 162.16 333.05 l 165.01 334.71 l 167.85 336.36 l 170.70 338.01 l 173.54 339.65 l 176.39 341.28 l 176.60 341.40 l S % END GriPath stroke/fill %gri:draw isopycnal unlabelled 26.25 %^ scale 1 56.9 34 284.5 1 56.9 2 35.5625 0.709 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 56.90 324.65 m 56.90 324.65 l 59.74 326.34 l 62.59 328.02 l 65.43 329.70 l 68.28 331.38 l 71.12 333.04 l 73.97 334.71 l 76.81 336.36 l 79.66 338.02 l 82.50 339.67 l 85.35 341.31 l 85.51 341.40 l S % END GriPath stroke/fill %gri:draw isopycnal unlabelled 27.75 %^ scale 1 56.9 34 284.5 1 56.9 2 35.5625 0.709 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 262.67 56.90 m 262.67 56.90 l 265.51 60.46 l 268.36 63.96 l 271.20 67.41 l 274.05 70.80 l 276.89 74.14 l 279.74 77.44 l 282.58 80.69 l 285.43 83.89 l 288.27 87.06 l 291.12 90.18 l 293.96 93.27 l 296.81 96.31 l 299.65 99.33 l 302.50 102.31 l 305.34 105.25 l 308.19 108.16 l 311.03 111.05 l 313.88 113.90 l 316.72 116.72 l 319.57 119.51 l 322.41 122.28 l 325.26 125.02 l 328.10 127.74 l 330.95 130.43 l 333.79 133.09 l 336.64 135.74 l 339.48 138.36 l S % END GriPath stroke/fill %gri:draw isopycnal unlabelled 27.50 %^ scale 1 56.9 34 284.5 1 56.9 2 35.5625 0.709 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 173.90 56.90 m 173.90 56.90 l 176.75 60.50 l 179.59 64.04 l 182.44 67.52 l 185.28 70.95 l 188.13 74.33 l 190.97 77.65 l 193.82 80.93 l 196.66 84.17 l 199.51 87.36 l 202.35 90.51 l 205.20 93.62 l 208.04 96.70 l 210.89 99.73 l 213.73 102.73 l 216.58 105.70 l 219.42 108.63 l 222.27 111.53 l 225.11 114.40 l 227.96 117.25 l 230.80 120.06 l 233.65 122.84 l 236.49 125.60 l 239.34 128.33 l 242.18 131.04 l 245.03 133.72 l 247.87 136.38 l 250.72 139.01 l 253.56 141.62 l 256.41 144.21 l 259.25 146.78 l 262.10 149.33 l 264.94 151.85 l 267.79 154.36 l 270.63 156.85 l 273.48 159.32 l 276.32 161.77 l 279.17 164.20 l 282.01 166.61 l 284.86 169.01 l 287.70 171.39 l 290.55 173.76 l 293.39 176.10 l 296.24 178.43 l 299.08 180.75 l 301.93 183.05 l 304.77 185.34 l 307.62 187.61 l 310.46 189.87 l 313.31 192.11 l 316.15 194.34 l 319.00 196.56 l 321.84 198.76 l 324.69 200.95 l 327.53 203.13 l 330.38 205.29 l 333.22 207.45 l 336.07 209.59 l 338.91 211.72 l S % END GriPath stroke/fill %gri:draw isopycnal unlabelled 27.25 %^ scale 1 56.9 34 284.5 1 56.9 2 35.5625 0.709 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 85.13 56.90 m 85.13 56.90 l 87.97 60.54 l 90.82 64.12 l 93.66 67.64 l 96.51 71.10 l 99.35 74.51 l 102.20 77.87 l 105.04 81.18 l 107.89 84.45 l 110.73 87.66 l 113.58 90.84 l 116.42 93.98 l 119.27 97.08 l 122.11 100.14 l 124.96 103.16 l 127.80 106.15 l 130.65 109.10 l 133.49 112.03 l 136.34 114.92 l 139.18 117.78 l 142.03 120.61 l 144.87 123.41 l 147.72 126.19 l 150.56 128.93 l 153.41 131.66 l 156.25 134.36 l 159.10 137.03 l 161.94 139.68 l 164.79 142.31 l 167.63 144.91 l 170.48 147.49 l 173.32 150.05 l 176.17 152.59 l 179.01 155.11 l 181.86 157.61 l 184.70 160.09 l 187.55 162.55 l 190.39 164.99 l 193.24 167.42 l 196.08 169.83 l 198.93 172.22 l 201.77 174.59 l 204.62 176.95 l 207.46 179.29 l 210.31 181.61 l 213.15 183.93 l 216.00 186.22 l 218.84 188.50 l 221.69 190.77 l 224.53 193.02 l 227.38 195.26 l 230.22 197.49 l 233.07 199.70 l 235.91 201.90 l 238.76 204.08 l 241.60 206.26 l 244.45 208.42 l 247.29 210.56 l 250.14 212.70 l 252.98 214.83 l 255.83 216.94 l 258.67 219.04 l 261.52 221.13 l 264.36 223.21 l 267.21 225.28 l 270.05 227.34 l 272.90 229.39 l 275.74 231.43 l 278.59 233.46 l 281.43 235.47 l 284.28 237.49 l 287.12 239.49 l 289.97 241.47 l 292.81 243.46 l 295.66 245.42 l 298.50 247.39 l 301.35 249.34 l 304.19 251.29 l 307.04 253.22 l 309.88 255.15 l 312.73 257.07 l 315.57 258.98 l 318.42 260.88 l 321.26 262.78 l 324.11 264.66 l 326.95 266.54 l 329.80 268.41 l 332.64 270.28 l 335.49 272.13 l 338.33 273.98 l 341.18 275.82 l S % END GriPath stroke/fill %gri:draw isopycnal unlabelled 28.75 %^ scale 1 56.9 34 284.5 1 56.9 2 35.5625 %gri:draw isopycnal unlabelled 28.50 %^ scale 1 56.9 34 284.5 1 56.9 2 35.5625 %gri:draw isopycnal unlabelled 28.25 %^ scale 1 56.9 34 284.5 1 56.9 2 35.5625 %gri:set clip off %gri:set font size .old. /Helvetica-ISOLatin1 findfont 10.00 sc sf %gri:# %gri:# Draw the data. %gri:open example13.dat %gri:read columns x y %gri:set color blue %gri:set symbol size 0.1 %gri:draw symbol bullet %^ scale 1 56.9 34 284.5 1 56.9 2 35.5625 0 0 1 rg 0 0 1 RG 0.369 w 0.369 w n 192.3 295.2 m 2.8 _bull S n 196.3 293.0 m 2.8 _bull S n 245.2 130.9 m 2.8 _bull S n 315.2 142.2 m 2.8 _bull S n 318.9 139.8 m 2.8 _bull S n 320.1 139.0 m 2.8 _bull S n 316.6 130.2 m 2.8 _bull S n 310.7 125.2 m 2.8 _bull S n 307.8 118.8 m 2.8 _bull S n 306.1 115.9 m 2.8 _bull S n 307.8 115.9 m 2.8 _bull S n 307.8 113.1 m 2.8 _bull S n 307.5 112.4 m 2.8 _bull S n 314.1 113.1 m 2.8 _bull S n 202.3 295.2 m 2.8 _bull S n 200.0 295.5 m 2.8 _bull S n 244.1 191.0 m 2.8 _bull S n 301.0 127.7 m 2.8 _bull S n 301.9 124.5 m 2.8 _bull S n 302.1 121.3 m 2.8 _bull S n 302.4 118.8 m 2.8 _bull S n 303.8 117.7 m 2.8 _bull S n 304.4 115.6 m 2.8 _bull S n 304.4 114.2 m 2.8 _bull S n 304.4 113.8 m 2.8 _bull S n 306.4 112.4 m 2.8 _bull S n 305.8 111.0 m 2.8 _bull S n 309.5 112.7 m 2.8 _bull S n 223.3 292.7 m 2.8 _bull S n 224.8 292.7 m 2.8 _bull S n 264.3 174.6 m 2.8 _bull S n 292.5 121.6 m 2.8 _bull S n 296.2 119.8 m 2.8 _bull S n 297.6 119.5 m 2.8 _bull S n 294.7 116.6 m 2.8 _bull S n 296.2 115.9 m 2.8 _bull S n 296.4 115.9 m 2.8 _bull S n 302.4 115.6 m 2.8 _bull S n 302.7 115.2 m 2.8 _bull S n 306.4 114.9 m 2.8 _bull S n 307.8 113.8 m 2.8 _bull S n 310.7 112.0 m 2.8 _bull S n 223.3 288.4 m 2.8 _bull S n 224.8 279.5 m 2.8 _bull S n 228.7 267.1 m 2.8 _bull S n 293.6 127.7 m 2.8 _bull S n 294.5 119.1 m 2.8 _bull S n 306.1 121.6 m 2.8 _bull S n 304.1 118.1 m 2.8 _bull S n 304.7 118.8 m 2.8 _bull S n 307.5 117.0 m 2.8 _bull S n 311.0 114.9 m 2.8 _bull S n 307.3 112.4 m 2.8 _bull S n 311.0 113.8 m 2.8 _bull S n 312.1 111.3 m 2.8 _bull S n 316.9 112.4 m 2.8 _bull S n 224.5 287.7 m 2.8 _bull S n 223.6 286.6 m 2.8 _bull S n 258.9 185.3 m 2.8 _bull S n 283.6 122.3 m 2.8 _bull S n 285.1 120.2 m 2.8 _bull S n 292.8 118.4 m 2.8 _bull S n 292.8 115.2 m 2.8 _bull S n 300.7 115.9 m 2.8 _bull S n 304.1 115.2 m 2.8 _bull S n 304.1 114.9 m 2.8 _bull S n 304.1 113.8 m 2.8 _bull S n 305.8 113.4 m 2.8 _bull S n 310.7 111.7 m 2.8 _bull S n 218.5 245.4 m 2.8 _bull S n 217.4 246.1 m 2.8 _bull S n 266.9 144.4 m 2.8 _bull S n 291.9 133.4 m 2.8 _bull S n 294.7 126.6 m 2.8 _bull S n 295.0 120.6 m 2.8 _bull S n 301.0 118.1 m 2.8 _bull S n 297.9 115.9 m 2.8 _bull S n 223.6 264.6 m 2.8 _bull S n 233.3 256.4 m 2.8 _bull S n 279.4 131.6 m 2.8 _bull S n 294.5 120.9 m 2.8 _bull S n 296.2 118.8 m 2.8 _bull S n 297.3 118.1 m 2.8 _bull S n 300.4 115.6 m 2.8 _bull S n 301.6 115.6 m 2.8 _bull S n 303.3 114.2 m 2.8 _bull S n 310.7 114.5 m 2.8 _bull S n 312.7 113.8 m 2.8 _bull S n 224.5 265.7 m 2.8 _bull S n 224.2 263.2 m 2.8 _bull S n 269.7 162.2 m 2.8 _bull S n 288.5 128.0 m 2.8 _bull S n 285.4 122.0 m 2.8 _bull S n 299.0 122.0 m 2.8 _bull S n 301.6 121.3 m 2.8 _bull S n 306.4 121.3 m 2.8 _bull S n 307.8 117.7 m 2.8 _bull S n 303.0 116.3 m 2.8 _bull S n 305.8 115.9 m 2.8 _bull S n 311.0 117.0 m 2.8 _bull S n 311.0 114.2 m 2.8 _bull S n 222.5 236.8 m 2.8 _bull S n 222.5 237.6 m 2.8 _bull S n 223.6 237.9 m 2.8 _bull S n 278.2 130.2 m 2.8 _bull S n 276.0 120.6 m 2.8 _bull S n 290.5 122.0 m 2.8 _bull S n 298.2 118.1 m 2.8 _bull S n 298.2 116.6 m 2.8 _bull S n 299.3 115.2 m 2.8 _bull S n 301.6 115.9 m 2.8 _bull S n 302.7 115.6 m 2.8 _bull S n 305.0 113.8 m 2.8 _bull S n 309.5 113.8 m 2.8 _bull S n 311.8 111.0 m 2.8 _bull S n 232.2 234.4 m 2.8 _bull S n 232.2 234.0 m 2.8 _bull S n 233.3 234.0 m 2.8 _bull S n 285.9 135.8 m 2.8 _bull S n 292.8 122.7 m 2.8 _bull S n 297.9 119.8 m 2.8 _bull S n 298.2 117.0 m 2.8 _bull S n 300.4 118.4 m 2.8 _bull S n 302.7 116.3 m 2.8 _bull S n 305.0 116.6 m 2.8 _bull S n 308.4 117.0 m 2.8 _bull S n 308.4 115.9 m 2.8 _bull S n 311.8 113.4 m 2.8 _bull S n 317.2 112.7 m 2.8 _bull S %gri:set font size 14 /Helvetica-ISOLatin1 findfont 14.00 sc sf %gri:set color black %gri:draw title "Example 13 -- TS diagram, with isopycnals" %^ scale 1 56.9 34 284.5 1 56.9 2 35.5625 % gr_show_at() BEGIN 0 g 0 G 66.0 369.8 m (Example 13 -- TS diagram, with isopycnals) sh % gr_show_at() END %gri:quit showpage %%Trailer %%BoundingBox: 21 22 349 382 %%DocumentFonts: Courier Helvetica Palatino-Roman Palatino-Italic Symbol Times-Roman %%Pages: 1 gri/doc/examples/example1.gri0000644000175000017500000000031113147557614014615 0ustar psgpsg# Example 1 -- Linegraph using data in a separate file open example1.dat # Open the data file read columns x y # Read (x,y) draw curve # Draw data curve draw title "Example 1" # A title for plot gri/doc/examples/example6.txt0000644000175000017500000000001513147557614014661 0ustar psgpsgexample6.gri gri/doc/examples/example8.gri0000644000175000017500000000546313147557614014641 0ustar psgpsg# Example 8 -- Plot T=T(x,rho) section of eubex data `Initialize Parameters' { \FILE_DATA = "example8a.dat" # T vs rho \FILE_LOCN = "example8b.dat" # section distances set missing value -99.0 # # Following values from ~/eubex/processing/to_rho_bins/do_rho_inter \RHO_MIN = "28.1" \RHO_MAX = "27.5" \RHO_INC = "-0.002" \NY = "301" \xmin = "350" \xmax = "0" \xinc = "-100" \ymin = "28.1" \ymax = "27.8" \yinc = "-0.1" \zmin = "0" \zmax = "2.5" } `Initialize Axes' /* Set up axes */ { set x name "km" set x size 10 set x axis \xmin \xmax \xinc set y name "$\sigma_T$" set y size 5 set y axis name horizontal set y axis \ymin \ymax \yinc set y format "%.1f" } `Initialize Files' { query \data "Data file? " ("\FILE_DATA") query \locn "Station locn?" ("\FILE_LOCN") } `Read Data' { # Read x-locations system awk '{print $2}' < \locn > TMP system wc TMP | awk '{print $1}' > NUM open NUM read .gridx_number. close system rm NUM open TMP read grid x .gridx_number. close system rm TMP # Create y-locations set y grid \RHO_MIN \RHO_MAX \RHO_INC # # Read data open \data read grid data \NY .gridx_number. close } `Plot Contours' { set graylevel .contour_graylevel. set clip on set line width 0.5 draw contour -3 3 0.25 unlabelled # # wide line at 0 degrees set line width 2 draw contour 0 unlabelled } `Plot Image And Maybe Contours' { \imagefile = "image" set image range \zmin \zmax convert grid to image box \xmin \ymin \xmax \ymax query \dohisto "Do histogram scaling? (yes|no)" ("yes") \incs = "no" if {"\dohisto" == "yes"} set image grayscale using histogram else \zinc = "0.25" query \incs "In linear scaling, band at an increment of \zinc?" ("yes") if {"\incs" == "yes"} set image grayscale black \zmin white \zmax increment \zinc else set image grayscale black \zmin white \zmax end if end if write image rasterfile to \imagefile show "wrote image rasterfile `\imagefile '" draw image draw image palette query \do_contours "Do contours as well (yes|no)" ("yes") if {"\do_contours" == "yes"} Plot Contours end if draw title "Example 8 -- \data black=\zmin white=\zmax" if {"\dohisto" == "yes"} draw title "Histogram enhanced grayscales" else if {"\incs" == "yes"} draw title "Grayscale banded at intervals of \zinc" end if end if } Initialize Parameters Initialize Axes Initialize Files Read Data query \doimage "Draw image (yes|no)" ("no") if {"\doimage" == "yes"} .contour_graylevel. = 1 # white contours Plot Image And Maybe Contours else .contour_graylevel. = 0 # black contours Plot Contours draw title "Example 8" end if gri/doc/examples/example2.gri0000644000175000017500000000027613147557614014630 0ustar psgpsg# Example 2 -- Storing data within command file read columns x y 0.05 12.5 0.25 19 0.5 15 0.75 15 0.95 13 # Note that a blank line ended the data set draw curve draw title "Example 2" gri/doc/examples/example9a.dat0000644000175000017500000003557213147557614014776 0ustar psgpsg-99.000000 -99.000000 3.500000 -0.500000 8.500000 -99.000000 -99.000000 4.000000 0.000000 5.000000 -99.000000 -99.000000 3.500000 0.500000 -1.000000 -99.000000 -99.000000 4.000000 0.000000 -1.000000 -99.000000 -99.000000 4.000000 0.500000 -1.000000 -99.000000 -0.500000 3.000000 0.000000 -1.000000 -99.000000 0.000000 2.500000 0.500000 -2.000000 -99.000000 -0.500000 2.500000 0.000000 -2.500000 -99.000000 -0.500000 2.500000 1.000000 -2.500000 -99.000000 0.000000 2.500000 1.000000 -2.000000 -99.000000 0.000000 2.000000 1.000000 -1.500000 -99.000000 -0.500000 2.500000 1.000000 1.000000 -99.000000 0.000000 3.000000 1.000000 -2.500000 -99.000000 0.500000 3.000000 1.500000 -2.500000 -99.000000 0.000000 3.000000 2.500000 0.000000 -99.000000 0.000000 3.000000 2.500000 1.000000 -99.000000 0.000000 3.000000 -1.500000 0.500000 -99.000000 0.000000 3.000000 -1.500000 8.000000 -99.000000 0.000000 3.000000 -1.500000 -1.500000 -99.000000 0.500000 3.000000 -2.000000 -1.000000 -99.000000 0.500000 3.000000 0.000000 0.000000 -99.000000 0.000000 3.000000 0.000000 0.000000 -99.000000 0.500000 2.500000 0.500000 -0.500000 -99.000000 0.000000 3.000000 0.000000 -0.500000 -99.000000 0.000000 3.000000 -1.000000 0.500000 2.000000 0.500000 3.000000 -1.000000 0.500000 2.000000 0.000000 1.000000 -1.500000 -0.500000 1.500000 0.000000 1.500000 -1.000000 3.500000 2.000000 0.000000 1.500000 -1.500000 2.000000 1.500000 0.000000 1.500000 -1.000000 2.000000 1.500000 0.000000 1.500000 -1.000000 -0.500000 1.000000 1.500000 0.500000 -1.500000 0.000000 1.000000 0.000000 0.500000 -1.500000 1.500000 1.500000 -0.500000 0.000000 -1.000000 3.000000 1.000000 -0.500000 0.500000 0.000000 -2.500000 1.000000 0.500000 0.500000 -0.500000 -2.500000 1.000000 6.500000 0.000000 -0.500000 -0.500000 1.000000 1.000000 0.500000 0.500000 4.000000 0.500000 1.000000 0.000000 -1.000000 2.500000 1.000000 0.500000 0.500000 -1.500000 1.500000 0.500000 0.000000 -0.500000 -2.000000 1.500000 0.500000 0.500000 -1.000000 -1.000000 3.000000 0.500000 2.500000 -1.000000 -0.500000 4.500000 0.500000 2.000000 -0.500000 0.000000 1.500000 0.500000 1.500000 -1.000000 0.000000 1.000000 0.500000 0.500000 -1.000000 -1.000000 3.000000 0.500000 0.500000 -0.500000 0.500000 3.000000 1.000000 2.000000 -1.500000 1.500000 2.500000 1.000000 3.500000 -7.500000 0.000000 3.000000 1.500000 2.500000 -8.000000 -1.000000 3.500000 2.000000 2.000000 -7.500000 0.000000 1.000000 2.500000 0.500000 -8.000000 2.500000 1.500000 2.000000 1.500000 -7.500000 1.500000 5.500000 1.500000 1.500000 -7.500000 2.000000 2.500000 1.500000 -0.500000 -8.000000 4.000000 8.000000 3.000000 4.500000 -9.500000 0.500000 3.000000 3.500000 4.000000 -10.500000 9.000000 10.000000 3.500000 5.500000 -10.000000 2.000000 5.500000 3.000000 7.500000 -10.500000 -0.500000 7.000000 1.500000 -2.500000 -10.500000 -0.500000 3.500000 2.500000 0.500000 -10.500000 0.500000 11.500000 3.000000 -1.500000 -10.500000 0.500000 6.500000 3.000000 27.000000 50.500000 4.500000 21.000000 4.500000 2.500000 -9.500000 4.000000 12.000000 3.000000 21.500000 -10.500000 14.500000 7.000000 16.000000 6.000000 -11.000000 8.000000 14.500000 8.000000 2.000000 -12.000000 59.000000 39.000000 19.000000 22.500000 -18.500000 13.500000 12.000000 2.000000 15.500000 -19.000000 87.000000 10.000000 24.500000 6.000000 -7.000000 26.000000 22.000000 21.500000 6.000000 29.500000 43.500000 26.500000 23.000000 5.500000 -12.500000 34.000000 8.500000 14.500000 8.500000 265.500000 26.500000 11.500000 3.000000 27.500000 11.000000 20.500000 38.500000 3.000000 66.500000 9.000000 4.500000 1.500000 5.000000 15.500000 20.000000 4.500000 3.500000 9.000000 14.000000 57.000000 4.500000 5.500000 8.500000 15.000000 8.500000 8.500000 6.500000 13.000000 25.500000 9.000000 10.000000 12.000000 16.000000 112.500000 8.500000 9.500000 14.000000 17.500000 8.000000 9.000000 5.000000 13.500000 22.000000 8.000000 75.500000 5.000000 15.000000 18.500000 8.000000 12.500000 9.000000 38.500000 16.500000 7.000000 11.000000 31.500000 16.000000 6.000000 6.000000 9.000000 55.500000 14.000000 6.500000 6.500000 8.500000 23.500000 11.000000 6.500000 10.000000 3.000000 17.000000 21.500000 8.500000 10.500000 3.500000 10.000000 17.000000 9.000000 22.500000 3.000000 7.500000 8.000000 7.000000 22.500000 7.000000 8.000000 9.000000 6.500000 11.000000 26.000000 9.500000 12.500000 15.500000 5.000000 27.000000 10.000000 11.500000 2.500000 7.500000 20.500000 7.500000 10.500000 3.500000 9.000000 57.500000 10.000000 13.000000 23.000000 9.000000 29.000000 15.000000 20.500000 80.000000 25.000000 21.500000 14.000000 20.500000 9.000000 10.500000 7.000000 13.500000 16.000000 10.000000 33.000000 7.000000 14.000000 13.000000 9.500000 49.500000 7.000000 23.500000 11.500000 8.000000 4.000000 8.500000 2.500000 12.500000 7.000000 4.000000 16.500000 2.000000 19.000000 10.000000 4.000000 140.500000 2.500000 11.000000 3.500000 2.500000 6.500000 3.000000 6.000000 1.000000 2.500000 6.500000 16.500000 13.500000 0.500000 2.000000 6.500000 17.500000 17.000000 1.000000 2.000000 13.000000 36.000000 13.500000 53.500000 0.500000 16.000000 17.500000 11.500000 5.500000 1.000000 4.000000 14.000000 9.000000 5.500000 0.000000 4.000000 29.000000 8.500000 9.000000 1.500000 4.000000 13.000000 7.000000 13.500000 3.000000 3.500000 8.000000 6.000000 13.500000 55.500000 42.500000 8.500000 15.500000 33.000000 28.500000 20.000000 16.000000 14.500000 15.500000 5.500000 17.000000 15.500000 13.500000 14.000000 10.000000 12.500000 7.500000 9.500000 67.500000 11.500000 12.500000 8.000000 7.500000 22.500000 8.500000 14.000000 8.500000 11.500000 17.000000 7.000000 12.000000 11.000000 12.000000 5.500000 8.000000 9.000000 11.500000 14.000000 6.000000 22.000000 9.000000 14.000000 14.000000 5.500000 106.500000 10.500000 13.500000 14.000000 4.000000 19.500000 10.500000 9.500000 10.500000 1.000000 19.500000 29.500000 13.500000 8.500000 1.000000 14.000000 15.500000 24.500000 9.500000 1.000000 13.500000 7.500000 15.000000 9.500000 3.500000 2.000000 4.500000 9.000000 12.000000 4.000000 2.000000 3.000000 9.500000 13.000000 6.000000 43.500000 10.000000 42.500000 10.000000 12.500000 69.500000 42.000000 7.000000 8.500000 79.500000 57.000000 14.500000 7.000000 10.000000 11.500000 39.500000 14.500000 4.500000 26.000000 -2.000000 9.500000 9.000000 3.500000 5.500000 -3.500000 9.500000 8.000000 4.500000 4.000000 -4.500000 4.500000 9.000000 5.000000 10.000000 63.500000 2.000000 28.000000 6.000000 8.000000 11.500000 1.500000 13.000000 6.500000 6.000000 28.500000 20.000000 9.000000 11.000000 10.500000 0.500000 160.500000 23.000000 9.000000 10.000000 8.500000 23.500000 12.000000 17.500000 6.000000 18.500000 29.500000 12.500000 17.500000 6.000000 21.000000 41.500000 18.000000 12.500000 6.000000 14.500000 6.500000 9.000000 12.500000 8.000000 23.000000 6.500000 4.000000 14.500000 9.000000 11.500000 6.000000 13.000000 20.500000 6.000000 4.500000 6.500000 13.000000 19.500000 7.500000 4.000000 6.500000 38.500000 17.500000 10.500000 2.000000 11.500000 7.000000 6.500000 5.500000 42.500000 13.000000 7.000000 6.500000 13.500000 20.500000 4.500000 7.500000 8.000000 15.000000 19.500000 2.000000 5.500000 12.500000 7.000000 17.000000 2.500000 7.500000 13.000000 9.000000 15.500000 7.000000 9.000000 2.000000 14.500000 13.000000 8.500000 20.000000 4.000000 9.500000 8.500000 22.000000 15.000000 22.000000 11.500000 20.500000 4.500000 5.000000 9.500000 4.500000 108.500000 1.000000 0.500000 18.500000 6.000000 7.500000 6.500000 -3.000000 11.500000 15.000000 5.500000 -2.000000 15.500000 9.000000 21.000000 8.500000 5.500000 17.500000 8.000000 7.000000 19.000000 5.000000 12.000000 23.000000 12.500000 14.000000 99.000000 15.000000 19.500000 13.000000 34.000000 8.000000 23.000000 8.000000 10.000000 68.500000 1.500000 16.500000 14.000000 7.000000 -2.000000 0.000000 9.000000 7.000000 6.000000 -2.000000 1.500000 2.500000 5.000000 -0.500000 -4.000000 2.500000 -0.500000 14.000000 9.000000 -3.500000 10.000000 -5.000000 17.500000 8.500000 -3.500000 5.000000 -6.000000 11.000000 6.000000 -3.000000 2.500000 -6.500000 40.000000 12.500000 -3.000000 46.500000 -16.000000 11.500000 11.500000 133.000000 19.500000 46.000000 4.000000 0.000000 2.500000 13.000000 16.000000 4.000000 -4.000000 -2.000000 -5.000000 1.500000 14.500000 -0.500000 14.500000 2.000000 -3.500000 4.500000 4.000000 19.500000 37.500000 -2.500000 6.000000 12.500000 95.000000 -0.500000 -5.500000 8.000000 24.000000 14.000000 3.000000 28.000000 5.500000 13.000000 8.500000 2.500000 4.500000 9.500000 16.500000 -4.500000 5.500000 8.500000 8.500000 15.000000 5.500000 9.500000 -1.500000 7.000000 3.000000 28.500000 3.500000 -7.500000 15.000000 0.500000 15.500000 -5.000000 13.000000 11.000000 24.000000 -2.500000 -16.000000 29.000000 9.000000 1.000000 -2.000000 30.000000 10.500000 4.000000 11.000000 -2.500000 1.000000 3.500000 13.000000 11.000000 -5.000000 -10.500000 -2.500000 4.000000 9.500000 78.000000 -7.000000 -7.500000 17.000000 12.500000 -1.000000 8.000000 12.500000 6.000000 12.500000 16.000000 -14.500000 -12.000000 8.500000 11.000000 6.500000 34.500000 -16.500000 2.000000 3.500000 19.000000 -8.000000 18.500000 -2.500000 -1.500000 -6.500000 -1.000000 11.500000 12.000000 -9.500000 23.500000 -1.000000 -1.500000 13.500000 36.500000 -2.500000 -4.500000 -3.500000 2.000000 6.500000 -9.000000 -8.000000 16.000000 0.000000 0.000000 1.500000 -17.500000 -7.500000 -9.000000 -6.000000 0.000000 -16.000000 -17.500000 -8.000000 -16.500000 -4.500000 4.500000 -9.000000 -7.500000 -6.000000 1.500000 27.500000 7.000000 9.000000 -16.500000 -1.000000 4.000000 1.000000 8.500000 -40.000000 -6.000000 1.500000 -5.000000 4.500000 8.000000 -17.000000 14.500000 12.000000 1.500000 3.000000 -27.000000 -4.500000 -9.000000 6.000000 35.000000 -8.000000 0.000000 -5.500000 6.000000 19.000000 -9.000000 -8.500000 -4.000000 1.000000 14.000000 -10.000000 -21.500000 -5.000000 0.500000 9.000000 -2.000000 -5.500000 -13.500000 -3.500000 2.000000 -8.000000 -40.000000 2.500000 0.500000 7.500000 -12.000000 -4.500000 -5.500000 -14.000000 7.500000 -10.500000 -25.000000 -10.500000 1.500000 0.000000 -7.500000 -17.000000 -3.000000 4.000000 -5.000000 -6.500000 -15.500000 -0.500000 2.000000 -8.000000 -30.500000 -8.000000 -2.500000 -0.500000 -0.500000 -2.500000 -10.000000 -6.000000 -1.000000 12.500000 -75.500000 -55.500000 -5.500000 -10.500000 2.500000 -24.500000 -11.000000 -9.000000 -16.000000 3.000000 -17.000000 -8.500000 -14.000000 -23.500000 -8.000000 -6.000000 -4.500000 -11.000000 -20.000000 -4.000000 -10.500000 -11.000000 -22.500000 -22.000000 -25.000000 -12.500000 -16.500000 -22.000000 -23.000000 -30.000000 -21.500000 -13.000000 -14.500000 -17.500000 -33.500000 -14.500000 -11.000000 -14.500000 -14.000000 -35.500000 11.500000 -8.000000 -14.500000 6.500000 -22.000000 -8.000000 -15.000000 -11.000000 2.000000 4.500000 -13.500000 -12.500000 -8.500000 0.000000 15.000000 -27.500000 -7.000000 0.500000 -3.000000 8.500000 -19.000000 -11.000000 -1.500000 -3.000000 8.000000 -14.500000 -5.500000 -6.000000 -5.500000 13.500000 -17.500000 -2.000000 -2.000000 -3.500000 -4.500000 -27.500000 -9.500000 -2.000000 -1.000000 -3.500000 -12.500000 -13.500000 -21.500000 -9.500000 13.500000 -17.500000 -17.000000 -12.000000 -13.000000 -6.500000 -20.500000 -47.000000 -11.000000 -12.500000 -19.000000 -16.500000 -20.000000 -14.000000 -32.000000 -31.500000 -12.500000 -11.000000 -9.000000 -30.500000 -27.000000 -21.500000 -16.000000 -7.000000 -36.500000 -26.000000 -12.000000 -14.500000 -28.500000 -25.500000 -20.500000 -14.500000 -0.500000 -38.500000 -4.500000 8.000000 -36.500000 -20.000000 -10.500000 3.500000 0.000000 -23.000000 -3.000000 -2.000000 13.500000 4.500000 -10.500000 -7.500000 -7.500000 3.000000 -1.000000 -12.500000 -18.500000 -10.000000 1.000000 5.000000 -10.500000 -9.000000 -13.500000 2.000000 6.500000 -23.000000 -9.000000 6.500000 0.500000 4.500000 -9.000000 -8.000000 5.000000 -8.000000 -8.500000 -16.500000 -5.000000 1.000000 -14.000000 -17.000000 -6.000000 -2.500000 -10.000000 -29.500000 -27.000000 -15.500000 -41.000000 -20.500000 -30.500000 -44.000000 -8.000000 -6.500000 -43.500000 -15.000000 -20.000000 -51.500000 -22.000000 -15.500000 -28.000000 -17.500000 -14.500000 -10.500000 -10.000000 -21.500000 -17.000000 -13.500000 -15.500000 -22.500000 -12.000000 -13.000000 -6.500000 -17.000000 -25.000000 -14.500000 -7.000000 -28.000000 -20.500000 -11.000000 -22.500000 -22.000000 -17.000000 -15.500000 -11.000000 -20.500000 -27.000000 -9.500000 -32.500000 -17.000000 -24.000000 -14.500000 -11.000000 -33.000000 -24.000000 -14.000000 -22.000000 -21.000000 -6.000000 -10.000000 -32.000000 -13.500000 -15.000000 -7.000000 -20.500000 -13.000000 -28.000000 -17.500000 -14.500000 -9.500000 -17.500000 -17.500000 -12.500000 -10.000000 -24.000000 -17.500000 -13.000000 -9.500000 -12.500000 -28.000000 -28.500000 -13.500000 -24.000000 -20.000000 -21.000000 -29.500000 -13.500000 -9.000000 -11.500000 -14.500000 -11.000000 -21.500000 -13.000000 -1.500000 -12.500000 -19.000000 -13.500000 -18.000000 -26.500000 -18.500000 -28.500000 -24.000000 -9.500000 -12.500000 -6.500000 -17.000000 -25.000000 -15.000000 -22.000000 -42.500000 -13.000000 -29.500000 -14.500000 -18.000000 -26.500000 -38.500000 -29.000000 -18.500000 -4.000000 -16.500000 -8.500000 -25.000000 -11.000000 -51.500000 -22.500000 -1.500000 -6.000000 -19.500000 -10.500000 -18.000000 -14.000000 -1.000000 -28.000000 -27.000000 -10.500000 -56.500000 -23.000000 -19.500000 -17.500000 -25.500000 -12.000000 -39.500000 -16.500000 -18.500000 -13.500000 -9.000000 2.000000 -14.500000 -18.500000 -32.500000 -9.000000 -9.500000 -99.000000 -18.000000 -27.500000 -99.000000 -18.000000 -99.000000 -13.500000 -2.000000 -99.000000 -99.000000 -99.000000 -32.500000 -7.000000 -99.000000 -99.000000 -99.000000 -20.500000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 -99.000000 gri/doc/examples/example12.txt0000644000175000017500000000001613147557614014737 0ustar psgpsgexample12.gri gri/doc/examples/example7.gri0000644000175000017500000000163313147557614014633 0ustar psgpsg# Example 7 -- Box plots of mixing efficiency vs density ratio (meddy) `Draw y boxplot from \file at .x.' /* Draw a y boxplot for data in given file, at given value of x. */ { open \.word4. read columns * y close draw y box plot at \.word6. } if !..publication.. draw time stamp end if set x axis 1 3 1 0.1 set x name "Density Ratio, $R_\rho$" set x margin 4 set y axis -2 1 1 # # Must fool gri into not drawing the axes, because the y data # are already in logspace. draw axes none Draw y boxplot from example7a.dat at 1.3 Draw y boxplot from example7b.dat at 1.4 Draw y boxplot from example7c.dat at 1.5 Draw y boxplot from example7d.dat at 1.6 Draw y boxplot from example7e.dat at 1.7 Draw y boxplot from example7f.dat at 1.8 Draw y boxplot from example7g.dat at 1.9 delete y scale set y name "Efficiency, $\Gamma$" set y type log set y axis 0.01 10 1 draw axes draw title "Example 7 -- Box plot" gri/doc/examples/example13.txt0000644000175000017500000000001613147557614014740 0ustar psgpsgexample13.gri gri/doc/examples/example12.dat0000644000175000017500000000010413147557614014666 0ustar psgpsg800 .0 .2 .3 .4 850 .2 .3 .4 .5 900 .22 .33 .44 .55 950 .6 .7 .8 .9 gri/doc/examples/example6mask.dat0000644000175000017500000004000013147557614015464 0ustar psgpsggri/doc/examples/FEM.ps0000644000175000017500000004306113147557614013362 0ustar psgpsg%!PS-Adobe-2.0 EPSF-1.2 %%Creator: Gri2.2.4 (released 1999-Oct-20). User=kelley, commandfile=FEM.gri %%Title: FEM.ps %%CreationDate: Thu Oct 21 11:30:26 1999 %%Pages: (atend) %%BoundingBox: (atend) %%TemplateBox: 0 0 612 792 %%DocumentFonts: (atend) %%Endcomments % NOTE: The Gri postscript dictionary is being converted to the Adobe % Illustrator 3.0 dialect of PostScript, as described in the Adobe % documents stored at URL % http://www.adobe.com/Support/TechNotes.html % (as of Jan 1996, this doc is number 5007). When the conversion % is complete, the Adobe Illustrator drawing program -- and any % program compatible with AI -- will be able to edit Gri output. % % The IslandDraw (TM) program is able to read Gri output % at this time; remarkably, it can read/edit arbitrary PostScript. % % The definitions below are presented in the same order as the Adobe % manual. The stack configuration before and after is shown in curly % brackets. All the operators are listed, but only some are defined % here. Most things are faithful, except that no distinction is made % between colors for stroking and filling paths. The string 'WRONGLY' % appears with commands that are approximations. % % PDF-style abbreviations: /rg {setrgbcolor} def % {red green blue} {-} set RGB color /RG {setrgbcolor} def % {red green blue} {-} set RGB color /q {gsave} def /Q {grestore} def /W {clip} def /W* {eoclip} def % % Gri-specific abbreviations: /hsb {sethsbcolor} def % {hue saturation brightness} {-} set HSB color % % Following all try to mimic Adobe Illustrator % % Mimicking section 5.1 of Adobe manual: %A % {flag A} {-} Determine whether % following object can % be selected. Flag=1 % prevents selection; % flag=0 allows it. % Mimicking section 5.2 of Adobe manual: %u % {u} {-} start group %U % end group %q % as 'u' but first item is a clip path %Q % as 'U' but first item is a clip path % Mimicking section 5.3 of Adobe manual: /g {setgray} def % {gray g} {-} Set gray for fill % path, WRONGLY used % for stroking also. /G {setgray} def % As 'g', but for filling path. %k % Set cmyk color for filling path. %K % As 'k', but for stroking path. %x % Set cmyk custom color for filling path. %X % As 'x' but for stroking path. %p % Define pattern for filling path. %P % As 'p' but for stroking path. %O % Specify whether overprinting for fill paths %R % As 'O' but for stroking path. % Mimicking section 5.4 of Adobe manual: /d {setdash} def % {[array] phase d} {-} Set dash. /i {setflat} def % {flatness i} {-} Set flatness. /j {setlinejoin} def % {linejoin j} {-} Set line join. /J {setlinecap} def % {linecap J} {-} Set line cap. /M {setmiterlimit} def % {miterlimit M} {-} Set miter limit. /w {setlinewidth} def % {linewidth w} {-} Set line width. % Mimicking section 5.5 of Adobe manual: /m {moveto} def % {x y m} {-} Move to locn /l {lineto} def % {x y l} {-} Draw line to locn % not a smooth point. % WRONGLY, no % distinction is made % between smooth and % corner. %L % {x y L} {-} As 'l' but a corner %c % Bezier curve to smooth point. %C % As 'c' but to corner point. %v % Something else to do with Bezier. %V % %y % %Y % % Mimicking section 5.6 of Adobe manual: %N % {N} {-} As 'n' for nondrawn stuff /n {newpath} def % {n} {-} WRONGLY interpreted % as path constructor /F {fill} def % {F} {-} Fill current path. %f % {f} {-} 'F' but close first /S {stroke} def % {S} {-} Stroke current path. %s % {s} {-} 'S' but close first %B % {B} {-} As 's' but don't empty path. %b % {b} {-} As 'f' but don't empty path. %H % no-op (weird huh?) /h {closepath} def % {h} {-} Close current path %W % Used to create masks. % Mimicking section 5.7 of Adobe manual: %a % Begin text block ... %e % Similar to 'a' but ... %I % Similar to 'a' but ... %o % Similar to 'a' but ... %r % Similar to 'a' but ... %t % {len (string) t} {-} Render string. %T % End block of text % That's the end of the Illustrator stuff. Following are some Gri % definitions which provide a temporary way of handling fonts. /sf {setfont} def % {fontname sf} {-} Set font name. /sh {show} def % {(text) sh} {-} Show text. /sc {scalefont} def % {size sc} {-} Scale font. % Gri items which should be translated to Illustrator format: /rl {rlineto} def /rm {rmoveto} def % Procedures /cimdict 7 dict def /cim { cimdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def q xll yll translate xur xll sub yur yll sub scale /do cl 3 mul string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop} false 3 colorimage Q end } def /imdict 14 dict def /im { imdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def /imagemap exch def q % Add the mapping to the transfer function (ref: white book, p 743. [{255 mul cvi imagemap exch get} /exec load currenttransfer /exec load] cvx settransfer xll yll translate xur xll sub yur yll sub scale /do cl string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop}image Q end } def /frdict 5 dict def /fr { frdict begin /yt exch def /xr exch def /yb exch def /xl exch def n xl yb m xl yt l xr yt l xr yb l h F n end } def /plusdict 3 dict def /_plus { plusdict begin dup 0.5 mul /t0 exch def /t1 exch def 0 t0 rm 0 t1 neg rl t0 neg t0 rm t1 0 rl t0 neg 0 rm end } def /timesdict 3 dict def /_times { timesdict begin dup 0.353553 mul /t0 exch def 0.707106 mul /t1 exch def t0 neg t0 rm t1 dup neg rl t1 neg 0 rm t1 dup rl t0 neg dup rm end } def /boxdict 3 dict def /_box { boxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm end } def /filledboxdict 3 dict def /_filledbox { filledboxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm F end } def /diamonddict 2 dict def /_diamond { diamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm end } def /filleddiamonddict 2 dict def /_filleddiamond { filleddiamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm F end } def /triangleupdict 5 dict def /_triangleup { triangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm end } def /filledtriangleupdict 5 dict def /_filledtriangleup { filledtriangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm F end } def /trianglerightdict 5 dict def /_triangleright { trianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm end } def /filledtrianglerightdict 5 dict def /_filledtriangleright { filledtrianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm F end } def /triangledowndict 5 dict def /_triangledown { triangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm end } def /filledtriangledowndict 5 dict def /_filledtriangledown { filledtriangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm F end } def /triangleleftdict 5 dict def /_triangleleft { triangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm end } def /filledtriangleleftdict 5 dict def /_filledtriangleleft { filledtriangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm F end } def /circdict 5 dict def /_circ { circdict begin 0.5 mul /t0 exch def currentpoint /t2 exch def /t1 exch def S n t1 t2 t0 0 360 arc t1 t2 m end } def /bulldict 3 dict def /_bull { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 360 arc h F S end } def /filledhalfmoonupdict 3 dict def /_filledhalfmoonup { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 180 arc h F S end } def /filledhalfmoondowndict 3 dict def /_filledhalfmoondown { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 180 360 arc h F S end } def 1 1 scale 10.0 M 1 j /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-ISOLatin1 exch definefont pop /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Bold-ISOLatin1 exch definefont pop /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-ISOLatin1 exch definefont pop /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Bold-ISOLatin1 exch definefont pop /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Roman-ISOLatin1 exch definefont pop /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Bold-ISOLatin1 exch definefont pop /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Italic-ISOLatin1 exch definefont pop /Symbol findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Symbol-ISOLatin1 exch definefont pop /Times findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-ISOLatin1 exch definefont pop /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Bold-ISOLatin1 exch definefont pop /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Roman-ISOLatin1 exch definefont pop %%EndProlog %%Page: 1 1 /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:set missing value -99.99 %gri: %gri:# Create data using perl-script %gri:system perl FEM.pl model.nodes model.elements > tmp %gri: %gri:open tmp %gri:read columns x y %gri:close %gri:draw curve %^ scale 1 170.7 1 142.25 1 170.7 1 142.25 0.709 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 170.70 m 312.95 170.70 l 170.70 312.95 l 170.70 170.70 l 312.95 170.70 m 312.95 312.95 l 170.70 312.95 l 312.95 170.70 l 312.95 170.70 m 455.20 241.82 l 312.95 312.95 l 312.95 170.70 l 170.70 312.95 m 312.95 312.95 l 241.82 455.20 l 170.70 312.95 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 167.4 149.9 m (1) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 190.8 149.9 m (1.2) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 219.2 149.9 m (1.4) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 247.7 149.9 m (1.6) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 276.1 149.9 m (1.8) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 309.6 149.9 m (2) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 333.0 149.9 m (2.2) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 361.5 149.9 m (2.4) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 389.9 149.9 m (2.6) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 418.4 149.9 m (2.8) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 451.9 149.9 m (3) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 170.70 165.01 l 170.70 170.70 l 199.15 170.70 l 199.15 165.01 l 199.15 170.70 l 227.60 170.70 l 227.60 165.01 l 227.60 170.70 l 256.05 170.70 l 256.05 165.01 l 256.05 170.70 l 284.50 170.70 l 284.50 165.01 l 284.50 170.70 l 312.95 170.70 l 312.95 165.01 l 312.95 170.70 l 341.40 170.70 l 341.40 165.01 l 341.40 170.70 l 369.85 170.70 l 369.85 165.01 l 369.85 170.70 l 398.30 170.70 l 398.30 165.01 l 398.30 170.70 l 426.75 170.70 l 426.75 165.01 l 426.75 170.70 l 455.20 170.70 l 455.20 165.01 l 455.20 170.70 l 455.23 170.70 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 310.0 134.7 m (x) sh % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 455.20 m 170.70 455.20 l 170.70 460.89 l 170.70 455.20 l 199.15 455.20 l 199.15 460.89 l 199.15 455.20 l 227.60 455.20 l 227.60 460.89 l 227.60 455.20 l 256.05 455.20 l 256.05 460.89 l 256.05 455.20 l 284.50 455.20 l 284.50 460.89 l 284.50 455.20 l 312.95 455.20 l 312.95 460.89 l 312.95 455.20 l 341.40 455.20 l 341.40 460.89 l 341.40 455.20 l 369.85 455.20 l 369.85 460.89 l 369.85 455.20 l 398.30 455.20 l 398.30 460.89 l 398.30 455.20 l 426.75 455.20 l 426.75 460.89 l 426.75 455.20 l 455.20 455.20 l 455.20 460.89 l 455.20 455.20 l 455.23 455.20 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf % gr_show_at() BEGIN 0 g 0 G 152.5 166.4 m (1) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 142.4 194.8 m (1.2) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 142.4 223.3 m (1.4) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 142.4 251.7 m (1.6) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 142.4 280.2 m (1.8) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 152.5 308.6 m (2) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 142.4 337.1 m (2.2) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 142.4 365.5 m (2.4) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 142.4 394.0 m (2.6) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 142.4 422.4 m (2.8) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 152.5 450.9 m (3) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 165.01 170.70 l 170.70 170.70 l 170.70 199.15 l 165.01 199.15 l 170.70 199.15 l 170.70 227.60 l 165.01 227.60 l 170.70 227.60 l 170.70 256.05 l 165.01 256.05 l 170.70 256.05 l 170.70 284.50 l 165.01 284.50 l 170.70 284.50 l 170.70 312.95 l 165.01 312.95 l 170.70 312.95 l 170.70 341.40 l 165.01 341.40 l 170.70 341.40 l 170.70 369.85 l 165.01 369.85 l 170.70 369.85 l 170.70 398.30 l 165.01 398.30 l 170.70 398.30 l 170.70 426.75 l 165.01 426.75 l 170.70 426.75 l 170.70 455.20 l 165.01 455.20 l 170.70 455.20 l 170.70 455.20 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 136.6 309.9 m 90.00 rotate (y) sh -90.00 rotate % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 455.20 170.70 m 455.20 170.70 l 460.89 170.70 l 455.20 170.70 l 455.20 199.15 l 460.89 199.15 l 455.20 199.15 l 455.20 227.60 l 460.89 227.60 l 455.20 227.60 l 455.20 256.05 l 460.89 256.05 l 455.20 256.05 l 455.20 284.50 l 460.89 284.50 l 455.20 284.50 l 455.20 312.95 l 460.89 312.95 l 455.20 312.95 l 455.20 341.40 l 460.89 341.40 l 455.20 341.40 l 455.20 369.85 l 460.89 369.85 l 455.20 369.85 l 455.20 398.30 l 460.89 398.30 l 455.20 398.30 l 455.20 426.75 l 460.89 426.75 l 455.20 426.75 l 455.20 455.20 l 460.89 455.20 l 455.20 455.20 l 455.20 455.20 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri: %gri:# Comment-out the next line if you want to inspect %gri:# the temporary output. %gri:system rm tmp showpage %%Trailer %%BoundingBox: 126 130 463 463 %%DocumentFonts: Courier Helvetica Palatino-Roman Palatino-Italic Symbol Times-Roman %%Pages: 1 gri/doc/examples/example5.ps0000644000175000017500000017613213147557614014501 0ustar psgpsg%!PS-Adobe-2.0 EPSF-1.2 %%Creator: Gri2.7.0 (released 2001-mmm-dd). User=kelley, commandfile=example5.gri %%Title: example5.ps %%CreationDate: Mon Jul 23 11:14:57 2001 %%Pages: (atend) %%BoundingBox: (atend) %%TemplateBox: 0 0 612 792 %%DocumentFonts: (atend) %%Endcomments % NOTE: The Gri postscript dictionary is being converted to the Adobe % Illustrator 3.0 dialect of PostScript, as described in the Adobe % documents stored at URL % http://www.adobe.com/Support/TechNotes.html % (as of Jan 1996, this doc is number 5007). When the conversion % is complete, the Adobe Illustrator drawing program -- and any % program compatible with AI -- will be able to edit Gri output. % % The IslandDraw (TM) program is able to read Gri output % at this time; remarkably, it can read/edit arbitrary PostScript. % % The definitions below are presented in the same order as the Adobe % manual. The stack configuration before and after is shown in curly % brackets. All the operators are listed, but only some are defined % here. Most things are faithful, except that no distinction is made % between colors for stroking and filling paths. The string 'WRONGLY' % appears with commands that are approximations. % % PDF-style abbreviations: /rg {setrgbcolor} def % {red green blue} {-} set RGB color /RG {setrgbcolor} def % {red green blue} {-} set RGB color /q {gsave} def /Q {grestore} def /W {clip} def /W* {eoclip} def % % Gri-specific abbreviations: /hsb {sethsbcolor} def % {hue saturation brightness} {-} set HSB color % % Following all try to mimic Adobe Illustrator % % Mimicking section 5.1 of Adobe manual: %A % {flag A} {-} Determine whether % following object can % be selected. Flag=1 % prevents selection; % flag=0 allows it. % Mimicking section 5.2 of Adobe manual: %u % {u} {-} start group %U % end group %q % as 'u' but first item is a clip path %Q % as 'U' but first item is a clip path % Mimicking section 5.3 of Adobe manual: /g {setgray} def % {gray g} {-} Set gray for fill % path, WRONGLY used % for stroking also. /G {setgray} def % As 'g', but for filling path. %k % Set cmyk color for filling path. %K % As 'k', but for stroking path. %x % Set cmyk custom color for filling path. %X % As 'x' but for stroking path. %p % Define pattern for filling path. %P % As 'p' but for stroking path. %O % Specify whether overprinting for fill paths %R % As 'O' but for stroking path. % Mimicking section 5.4 of Adobe manual: /d {setdash} def % {[array] phase d} {-} Set dash. /i {setflat} def % {flatness i} {-} Set flatness. /j {setlinejoin} def % {linejoin j} {-} Set line join. /J {setlinecap} def % {linecap J} {-} Set line cap. /M {setmiterlimit} def % {miterlimit M} {-} Set miter limit. /w {setlinewidth} def % {linewidth w} {-} Set line width. % Mimicking section 5.5 of Adobe manual: /m {moveto} def % {x y m} {-} Move to locn /l {lineto} def % {x y l} {-} Draw line to locn % not a smooth point. % WRONGLY, no % distinction is made % between smooth and % corner. %L % {x y L} {-} As 'l' but a corner %c % Bezier curve to smooth point. %C % As 'c' but to corner point. %v % Something else to do with Bezier. %V % %y % %Y % % Mimicking section 5.6 of Adobe manual: %N % {N} {-} As 'n' for nondrawn stuff /n {newpath} def % {n} {-} WRONGLY interpreted % as path constructor /F {fill} def % {F} {-} Fill current path. %f % {f} {-} 'F' but close first /S {stroke} def % {S} {-} Stroke current path. %s % {s} {-} 'S' but close first %B % {B} {-} As 's' but don't empty path. %b % {b} {-} As 'f' but don't empty path. %H % no-op (weird huh?) /h {closepath} def % {h} {-} Close current path %W % Used to create masks. % Mimicking section 5.7 of Adobe manual: %a % Begin text block ... %e % Similar to 'a' but ... %I % Similar to 'a' but ... %o % Similar to 'a' but ... %r % Similar to 'a' but ... %t % {len (string) t} {-} Render string. %T % End block of text % That's the end of the Illustrator stuff. Following are some Gri % definitions which provide a temporary way of handling fonts. /sf {setfont} def % {fontname sf} {-} Set font name. /sh {show} def % {(text) sh} {-} Show text. /sc {scalefont} def % {size sc} {-} Scale font. % Gri items which should be translated to Illustrator format: /rl {rlineto} def /rm {rmoveto} def % Procedures /cimdict 7 dict def /cim { cimdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def q xll yll translate xur xll sub yur yll sub scale /do cl 3 mul string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop} false 3 colorimage Q end } def /imdict 14 dict def /im { imdict begin /cl exch def /rw exch def /yur exch def /xur exch def /yll exch def /xll exch def /imagemap exch def q % Until version 2.6.0 used a 'settransfer' here, but that % triggers a bug in ps2pdf xll yll translate xur xll sub yur yll sub scale /do cl string def cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop dup length 1 sub 0 1 3 -1 roll { 1 index exch 2 copy get imagemap exch get 255 mul cvi put } for }image Q end } bind def /frdict 5 dict def /fr { frdict begin /yt exch def /xr exch def /yb exch def /xl exch def n xl yb m xl yt l xr yt l xr yb l h F n end } def /plusdict 3 dict def /_plus { plusdict begin dup 0.5 mul /t0 exch def /t1 exch def 0 t0 rm 0 t1 neg rl t0 neg t0 rm t1 0 rl t0 neg 0 rm end } def /timesdict 3 dict def /_times { timesdict begin dup 0.353553 mul /t0 exch def 0.707106 mul /t1 exch def t0 neg t0 rm t1 dup neg rl t1 neg 0 rm t1 dup rl t0 neg dup rm end } def /boxdict 3 dict def /_box { boxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm end } def /filledboxdict 3 dict def /_filledbox { filledboxdict begin dup 0.5 mul /t0 exch def 1 mul /t1 exch def t0 neg t0 rm t1 0 rl 0 t1 neg rl t1 neg 0 rl h t0 dup neg rm F end } def /diamonddict 2 dict def /_diamond { diamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm end } def /filleddiamonddict 2 dict def /_filleddiamond { filleddiamonddict begin 0.5 mul /t0 exch def t0 neg 0 rm t0 dup rl t0 dup neg rl t0 neg dup rl h t0 0 rm F end } def /triangleupdict 5 dict def /_triangleup { triangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm end } def /filledtriangleupdict 5 dict def /_filledtriangleup { filledtriangleupdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 neg rm t1 t2 rl t1 t2 neg rl h t1 t0 rm F end } def /trianglerightdict 5 dict def /_triangleright { trianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm end } def /filledtrianglerightdict 5 dict def /_filledtriangleright { filledtrianglerightdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 neg t1 rm t2 t1 neg rl t2 neg t1 neg rl h t0 t1 neg rm F end } def /triangledowndict 5 dict def /_triangledown { triangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm end } def /filledtriangledowndict 5 dict def /_filledtriangledown { filledtriangledowndict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t1 neg t0 rm t3 0 rl t1 neg t2 neg rl h t1 t0 neg rm F end } def /triangleleftdict 5 dict def /_triangleleft { triangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm end } def /filledtriangleleftdict 5 dict def /_filledtriangleleft { filledtriangleleftdict begin dup 0.25 mul /t0 exch def dup 0.433013 mul /t1 exch def dup 0.75 mul /t2 exch def 0.866026 mul /t3 exch def t0 t1 rm 0 t3 neg rl t2 neg t1 rl h t0 neg t1 neg rm F end } def /circdict 5 dict def /_circ { circdict begin 0.5 mul /t0 exch def currentpoint /t2 exch def /t1 exch def S n t1 t2 t0 0 360 arc t1 t2 m end } def /bulldict 3 dict def /_bull { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 360 arc h F S end } def /filledhalfmoonupdict 3 dict def /_filledhalfmoonup { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 0 180 arc h F S end } def /filledhalfmoondowndict 3 dict def /_filledhalfmoondown { bulldict begin 0.5 mul /r exch def currentpoint /y exch def /x exch def S n x y r 180 360 arc h F S end } def 1 1 scale 10.0 M 1 j /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-ISOLatin1 exch definefont pop /Courier-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Oblique-ISOLatin1 exch definefont pop /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-Bold-ISOLatin1 exch definefont pop /Courier-BoldOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Courier-BoldOblique-ISOLatin1 exch definefont pop /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-ISOLatin1 exch definefont pop /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Bold-ISOLatin1 exch definefont pop /Helvetica-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-Oblique-ISOLatin1 exch definefont pop /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Roman-ISOLatin1 exch definefont pop /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Italic-ISOLatin1 exch definefont pop /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-Bold-ISOLatin1 exch definefont pop /Palatino-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Palatino-BoldItalic-ISOLatin1 exch definefont pop /Symbol findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Symbol-ISOLatin1 exch definefont pop /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Roman-ISOLatin1 exch definefont pop /Times-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Italic-ISOLatin1 exch definefont pop /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-Bold-ISOLatin1 exch definefont pop /Times-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse } forall /Encoding ISOLatin1Encoding def currentdict end /Times-BoldItalic-ISOLatin1 exch definefont pop %%EndProlog %%Page: 1 1 /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:# Gri was invoked by user named %gri:# kelley %gri:# on host named %gri:# Intrusion.phys.ocean.dal.ca %gri:# using the command %gri:# gri -y -p example5.gri %gri:# at time Mon Jul 23 11:14:57 2001. %gri:# %gri:# The user's ~/.grirc file ... %gri:assert {rpn 1 2 >} "Must have a > here" %gri:# ... end of users ~/.grirc file. %gri: %gri:# Example 5 - Contouring ungridded data %gri: %gri:# Data from figure %gri:# 5 of Koch et al., 1983, J. Climate Appl. Met., %gri:# volume 22, pages 1487-1503. %gri:open example5.dat %gri:read columns x y z %gri:close %gri:set x size 12 %gri:set x axis 0 12 2 %gri:set y size 10 %gri:set y axis 0 10 2 %gri:draw axes % gr_show_at() BEGIN 0 g 0 G 167.4 149.9 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 224.3 149.9 m (2) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 281.2 149.9 m (4) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 338.1 149.9 m (6) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 395.0 149.9 m (8) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 448.5 149.9 m (10) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 505.4 149.9 m (12) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 170.70 165.01 l 170.70 170.70 l 227.60 170.70 l 227.60 165.01 l 227.60 170.70 l 284.50 170.70 l 284.50 165.01 l 284.50 170.70 l 341.40 170.70 l 341.40 165.01 l 341.40 170.70 l 398.30 170.70 l 398.30 165.01 l 398.30 170.70 l 455.20 170.70 l 455.20 165.01 l 455.20 170.70 l 512.10 170.70 l 512.10 165.01 l 512.10 170.70 l 512.16 170.70 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 338.4 134.7 m (x) sh % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 455.20 m 170.70 455.20 l 170.70 460.89 l 170.70 455.20 l 227.60 455.20 l 227.60 460.89 l 227.60 455.20 l 284.50 455.20 l 284.50 460.89 l 284.50 455.20 l 341.40 455.20 l 341.40 460.89 l 341.40 455.20 l 398.30 455.20 l 398.30 460.89 l 398.30 455.20 l 455.20 455.20 l 455.20 460.89 l 455.20 455.20 l 512.10 455.20 l 512.10 460.89 l 512.10 455.20 l 512.16 455.20 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf % gr_show_at() BEGIN 0 g 0 G 152.5 166.4 m (0) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 152.5 223.3 m (2) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 152.5 280.2 m (4) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 152.5 337.1 m (6) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 152.5 394.0 m (8) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G 145.8 450.9 m (10) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 170.70 170.70 m 170.70 170.70 l 165.01 170.70 l 170.70 170.70 l 170.70 227.60 l 165.01 227.60 l 170.70 227.60 l 170.70 284.50 l 165.01 284.50 l 170.70 284.50 l 170.70 341.40 l 165.01 341.40 l 170.70 341.40 l 170.70 398.30 l 165.01 398.30 l 170.70 398.30 l 170.70 455.20 l 165.01 455.20 l 170.70 455.20 l 170.70 455.20 l S % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G 139.9 309.9 m 90.00 rotate (y) sh -90.00 rotate % gr_show_at() END /Helvetica-ISOLatin1 findfont 0.00 sc sf 0 g 0 G 1.0 i 0 J 0 j 0.369 w 10.0 M [] 0 d 512.10 170.70 m 512.10 170.70 l 517.79 170.70 l 512.10 170.70 l 512.10 227.60 l 517.79 227.60 l 512.10 227.60 l 512.10 284.50 l 517.79 284.50 l 512.10 284.50 l 512.10 341.40 l 517.79 341.40 l 512.10 341.40 l 512.10 398.30 l 517.79 398.30 l 512.10 398.30 l 512.10 455.20 l 517.79 455.20 l 512.10 455.20 l 512.10 455.20 l S % END GriPath stroke/fill /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:set line width symbol 0.2 %gri:set symbol size 0.2 %gri:draw symbol bullet %^ scale 1 170.7 0 28.45 1 170.7 0 28.45 0 g 0 G 0.200 w 0.200 w n 257.5 186.3 m 5.7 _bull S n 320.1 179.2 m 5.7 _bull S n 436.1 189.2 m 5.7 _bull S n 280.2 204.8 m 5.7 _bull S n 331.4 206.3 m 5.7 _bull S n 377.0 200.6 m 5.7 _bull S n 173.5 224.8 m 5.7 _bull S n 236.1 234.7 m 5.7 _bull S n 280.2 240.4 m 5.7 _bull S n 299.3 239.0 m 5.7 _bull S n 357.0 240.4 m 5.7 _bull S n 394.0 242.4 m 5.7 _bull S n 423.9 242.4 m 5.7 _bull S n 470.8 247.5 m 5.7 _bull S n 231.9 260.9 m 5.7 _bull S n 267.4 275.1 m 5.7 _bull S n 170.7 290.2 m 5.7 _bull S n 243.2 293.0 m 5.7 _bull S n 312.1 294.5 m 5.7 _bull S n 389.8 285.1 m 5.7 _bull S n 364.2 325.8 m 5.7 _bull S n 478.0 314.4 m 5.7 _bull S n 269.4 340.0 m 5.7 _bull S n 391.2 354.2 m 5.7 _bull S n 441.0 357.0 m 5.7 _bull S n 197.7 369.8 m 5.7 _bull S n 247.5 367.0 m 5.7 _bull S n 338.0 364.2 m 5.7 _bull S n 258.9 401.1 m 5.7 _bull S n 330.6 406.8 m 5.7 _bull S n 428.2 394.0 m 5.7 _bull S %gri:set font size 8 /Helvetica-ISOLatin1 findfont 8.00 sc sf %gri:draw values %^ scale 1 170.7 0 28.45 1 170.7 0 28.45 % gr_show_at() BEGIN 0 g 0 G S n 260.8 183.5 m (11) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 323.4 176.4 m (14) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 439.5 186.3 m (12) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 283.6 202.0 m (17) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 334.8 203.4 m (17) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 380.3 197.7 m (16) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 176.9 221.9 m (34) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 239.5 231.8 m (27) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 283.6 237.5 m (24) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 302.6 236.1 m (25) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 360.4 237.5 m (24) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 397.4 239.5 m (21) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 427.2 239.5 m (16) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 474.2 244.6 m (17) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 235.2 258.0 m (27) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 270.8 272.2 m (25) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 174.0 287.3 m (9) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 246.6 290.2 m (28) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 315.4 291.6 m (27) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 393.1 282.2 m (19) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 367.5 322.9 m (23) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 481.3 311.5 m (29) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 272.8 337.1 m (28) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 394.5 351.3 m (18) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 444.3 354.2 m (22) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 201.1 367.0 m (7) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 250.9 364.1 m (16) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 341.3 361.3 m (22) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 262.2 398.3 m (17) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 333.9 404.0 m (18) sh % gr_show_at() END % gr_show_at() BEGIN 0 g 0 G S n 431.5 391.2 m (19) sh % gr_show_at() END %gri:set x grid 0 12 0.25 %gri:set y grid 0 10 0.25 %gri: %gri:# Use default method (Barnes) %gri:convert columns to grid %gri: %gri:set font size 10 /Helvetica-ISOLatin1 findfont 10.00 sc sf %gri:draw contour 0 40 2 %^ scale 1 170.7 0 28.45 1 170.7 0 28.45 0.709 w 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 214.18 m 170.90 213.57 l 170.94 213.38 l 170.91 213.16 l 170.70 208.69 l S % END GriPath stroke/fill 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 234.62 m 170.88 234.53 l 175.69 232.59 l 177.81 231.39 l 180.12 229.91 l 182.74 227.60 l 183.54 226.21 l 184.92 222.47 l 185.43 220.99 l 185.53 220.49 l 185.43 219.98 l 184.96 213.41 l 184.96 213.38 l 184.95 213.35 l 184.92 213.28 l 183.07 208.12 l 182.59 206.26 l 180.97 203.11 l 180.42 201.76 l 179.27 199.15 l 178.69 198.27 l 177.81 196.68 l 176.07 193.78 l 175.20 192.04 l 173.36 189.38 l 170.87 185.10 l 170.77 184.92 l 170.74 184.89 l 170.70 184.83 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 177.99 207.72 m 191.94 207.72 l 191.94 217.71 l 177.99 217.71 l 177.99 217.71 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 179.4 209.1 m (30) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 512.10 300.10 m 509.97 300.86 l 507.86 301.60 l 504.99 302.62 l 502.68 303.53 l 498.50 305.22 l 497.88 305.46 l 497.62 305.58 l 497.04 305.84 l 493.56 308.63 l 490.76 310.97 l 489.74 311.93 l 488.69 312.95 l 488.05 315.66 l 487.71 317.01 l 487.03 320.06 l 488.17 322.66 l 489.36 325.78 l 489.93 327.18 l 490.33 327.61 l 490.76 328.12 l 493.73 331.32 l 496.26 334.29 l 497.17 335.00 l 497.88 335.58 l 501.17 338.11 l 504.09 340.50 l 504.99 341.23 l 505.08 341.30 l 505.20 341.40 l 509.48 344.02 l 512.10 345.72 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 481.08 309.97 m 495.03 309.97 l 495.03 319.96 l 481.08 319.96 l 481.08 319.96 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 482.5 311.4 m (28) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 243.50 m 172.36 243.48 l 176.51 243.12 l 177.81 243.11 l 179.06 243.07 l 184.39 242.36 l 184.92 242.34 l 185.41 242.31 l 187.81 241.82 l 191.13 240.92 l 192.04 240.47 l 194.96 238.91 l 195.84 238.51 l 199.15 235.82 l 199.74 235.31 l 200.15 234.71 l 200.32 233.54 l 201.39 229.84 l 201.62 227.60 l 201.03 225.72 l 200.42 221.75 l 200.10 220.49 l 199.75 219.88 l 199.15 218.51 l 197.58 214.94 l 197.09 213.38 l 195.20 210.22 l 194.47 208.69 l 193.22 206.26 l 192.71 205.59 l 192.04 204.53 l 189.91 201.27 l 188.75 199.15 l 187.11 196.96 l 184.92 193.58 l 184.30 192.66 l 183.94 192.04 l 181.30 188.55 l 181.01 188.12 l 178.84 184.92 l 178.38 184.36 l 177.81 183.60 l 175.27 180.35 l 173.53 177.81 l 172.26 176.25 l 170.70 174.12 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 192.18 230.12 m 206.12 230.12 l 206.12 240.12 l 192.18 240.12 l 192.18 240.12 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 193.6 231.5 m (28) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 512.10 289.29 m 510.16 289.67 l 506.14 290.46 l 504.99 290.68 l 504.22 290.85 l 500.72 291.61 l 498.48 292.22 l 497.88 292.39 l 496.76 292.73 l 493.01 293.86 l 490.76 294.55 l 487.64 295.61 l 486.30 296.07 l 483.65 296.98 l 482.39 297.46 l 479.18 298.72 l 477.49 299.68 l 476.54 300.23 l 473.13 302.43 l 472.26 303.01 l 469.43 304.88 l 468.87 305.28 l 468.14 305.84 l 465.80 309.32 l 465.53 309.73 l 463.44 312.95 l 463.38 314.02 l 463.17 319.20 l 463.13 320.06 l 463.76 321.51 l 465.05 324.44 l 466.23 327.18 l 467.64 328.96 l 469.43 331.19 l 470.84 332.87 l 472.02 334.29 l 474.39 336.43 l 476.54 338.33 l 478.19 339.75 l 480.12 341.40 l 482.16 342.89 l 483.65 343.96 l 486.34 345.82 l 490.24 348.51 l 490.56 348.71 l 490.76 348.84 l 491.57 349.32 l 495.00 351.39 l 497.88 353.08 l 499.49 354.01 l 502.30 355.62 l 504.04 356.57 l 504.99 357.07 l 508.00 358.64 l 508.71 359.01 l 512.10 360.75 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 476.68 291.29 m 490.62 291.29 l 490.62 301.28 l 476.68 301.28 l 476.68 301.28 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 478.1 292.7 m (26) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 250.52 m 172.50 250.74 l 175.81 250.94 l 177.81 251.22 l 180.44 251.57 l 182.21 251.66 l 184.92 252.08 l 188.44 252.54 l 188.56 252.57 l 192.04 253.14 l 194.63 253.46 l 197.29 254.19 l 199.15 254.49 l 200.56 254.64 l 205.46 256.05 l 206.10 256.21 l 206.26 256.28 l 206.62 256.41 l 211.80 257.63 l 213.38 258.43 l 216.87 259.67 l 217.23 259.91 l 220.49 261.76 l 221.53 262.12 l 222.84 263.16 l 225.82 264.94 l 227.60 266.97 l 229.48 268.40 l 230.77 270.27 l 232.65 272.34 l 234.71 276.40 l 235.13 276.97 l 235.30 277.39 l 235.97 278.65 l 237.71 281.50 l 238.88 284.50 l 239.83 286.49 l 241.26 291.05 l 241.48 291.61 l 241.59 291.85 l 241.82 292.51 l 243.83 296.72 l 244.52 298.72 l 246.06 301.61 l 247.01 303.91 l 247.89 305.84 l 248.32 306.45 l 248.94 307.47 l 251.36 310.53 l 252.96 312.95 l 254.57 314.43 l 256.05 315.99 l 258.33 317.79 l 260.79 320.06 l 262.27 320.95 l 263.16 321.56 l 266.17 323.07 l 266.91 323.42 l 270.27 325.31 l 271.65 325.80 l 274.82 327.18 l 276.78 327.78 l 277.39 328.01 l 278.43 328.22 l 282.74 328.94 l 284.50 329.33 l 286.73 329.41 l 289.39 329.40 l 291.61 329.48 l 293.60 329.16 l 297.55 328.35 l 298.73 328.14 l 299.43 327.88 l 301.09 327.18 l 304.07 325.41 l 305.84 324.31 l 308.11 322.33 l 310.64 320.06 l 311.60 318.71 l 312.95 316.85 l 314.40 314.40 l 315.29 312.95 l 316.38 309.52 l 316.44 309.33 l 317.60 305.84 l 317.73 303.50 l 317.97 300.82 l 318.09 298.72 l 317.60 296.26 l 317.28 294.39 l 316.68 291.61 l 315.52 289.04 l 313.47 285.02 l 313.22 284.50 l 313.11 284.34 l 312.95 284.15 l 309.61 280.72 l 306.16 277.39 l 305.97 277.25 l 305.84 277.15 l 305.27 276.82 l 301.51 274.60 l 298.73 272.98 l 296.90 272.10 l 293.24 270.27 l 292.08 269.81 l 291.61 269.61 l 290.55 269.21 l 286.87 267.90 l 284.50 266.98 l 281.66 266.00 l 279.28 265.06 l 277.39 264.35 l 276.48 264.07 l 274.17 263.16 l 271.19 262.25 l 270.27 261.90 l 268.37 261.26 l 265.81 260.51 l 263.16 259.48 l 260.59 258.62 l 256.87 256.87 l 256.05 256.53 l 255.68 256.42 l 255.00 256.05 l 250.54 254.45 l 248.94 253.61 l 245.77 252.11 l 242.78 249.89 l 241.82 249.24 l 241.64 249.13 l 241.47 248.94 l 237.23 246.42 l 234.71 244.05 l 233.56 242.98 l 232.85 241.82 l 229.94 239.48 l 227.60 236.70 l 226.71 235.60 l 226.26 234.71 l 223.37 231.83 l 220.49 227.87 l 220.38 227.71 l 220.32 227.60 l 219.24 226.35 l 217.07 223.90 l 214.68 220.49 l 214.02 219.84 l 213.38 219.11 l 210.80 215.95 l 209.08 213.38 l 207.71 211.93 l 206.26 210.15 l 204.56 207.96 l 203.44 206.26 l 201.43 203.98 l 199.15 201.06 l 198.32 199.98 l 197.78 199.15 l 195.15 196.04 l 192.39 192.39 l 192.12 192.04 l 192.08 191.99 l 192.04 191.94 l 188.84 188.12 l 186.42 184.92 l 185.72 184.13 l 184.92 183.16 l 182.50 180.24 l 180.68 177.81 l 179.36 176.27 l 177.81 174.33 l 176.17 172.34 l 174.95 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 192.18 248.80 m 206.12 248.80 l 206.12 258.79 l 192.18 258.79 l 192.18 258.79 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 193.6 250.2 m (26) sh % gr_show_at() END 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 203.83 210.25 m 217.78 210.25 l 217.78 220.25 l 203.83 220.25 l 203.83 220.25 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 205.2 211.6 m (26) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 512.10 280.84 m 508.97 281.37 l 507.93 281.55 l 504.99 282.06 l 502.93 282.44 l 499.22 283.16 l 497.88 283.41 l 496.97 283.59 l 492.73 284.50 l 491.13 284.87 l 490.76 284.96 l 490.14 285.12 l 485.46 286.31 l 483.65 286.80 l 480.42 287.73 l 479.91 287.87 l 476.54 288.88 l 474.46 289.54 l 469.91 291.13 l 469.43 291.29 l 469.19 291.37 l 468.57 291.61 l 464.29 293.59 l 462.31 294.58 l 459.59 296.00 l 455.67 298.25 l 455.20 298.52 l 455.07 298.59 l 454.86 298.72 l 451.28 301.91 l 448.09 304.97 l 447.65 305.40 l 447.22 305.84 l 446.36 307.56 l 445.13 309.99 l 443.70 312.95 l 443.62 315.59 l 443.54 317.49 l 443.46 320.06 l 444.63 323.52 l 444.75 323.84 l 445.94 327.18 l 446.76 328.50 l 448.09 330.46 l 449.61 332.76 l 450.70 334.29 l 452.81 336.67 l 455.20 339.13 l 456.31 340.29 l 457.45 341.40 l 460.02 343.69 l 462.31 345.56 l 463.93 346.89 l 466.05 348.51 l 467.97 349.97 l 469.43 350.96 l 472.17 352.88 l 476.47 355.62 l 476.51 355.65 l 476.54 355.67 l 476.65 355.74 l 480.88 358.40 l 483.65 359.98 l 485.39 361.00 l 488.61 362.74 l 489.98 363.52 l 490.76 363.92 l 493.27 365.25 l 494.63 365.99 l 497.88 367.59 l 499.37 368.36 l 502.56 369.85 l 504.18 370.66 l 504.99 371.02 l 507.19 372.05 l 509.02 372.93 l 512.10 374.29 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 476.68 281.10 m 490.62 281.10 l 490.62 291.10 l 476.68 291.10 l 476.68 291.10 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 478.1 282.5 m (24) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 256.69 m 171.55 256.90 l 176.09 257.78 l 177.81 258.26 l 180.85 259.09 l 181.71 259.27 l 184.92 260.31 l 187.12 260.96 l 191.88 263.00 l 192.04 263.06 l 192.11 263.09 l 192.27 263.16 l 196.97 265.34 l 199.15 266.73 l 201.43 268.00 l 204.43 270.27 l 205.47 271.06 l 206.26 271.84 l 209.28 274.37 l 212.04 277.39 l 212.67 278.09 l 213.38 279.07 l 215.87 282.00 l 217.55 284.50 l 218.72 286.27 l 220.49 289.63 l 221.27 290.83 l 221.67 291.61 l 223.03 294.16 l 223.76 295.45 l 225.31 298.72 l 226.10 300.23 l 227.60 303.56 l 228.41 305.02 l 228.80 305.84 l 230.71 308.95 l 231.06 309.49 l 233.01 312.95 l 233.75 313.92 l 234.71 315.28 l 236.92 317.85 l 238.65 320.06 l 240.29 321.60 l 241.82 323.13 l 244.04 324.96 l 246.49 327.18 l 247.92 328.19 l 248.94 328.96 l 252.20 331.02 l 254.07 332.31 l 256.05 333.65 l 256.46 333.88 l 257.14 334.29 l 261.11 336.34 l 263.16 337.49 l 265.87 338.70 l 269.25 340.37 l 270.27 340.86 l 270.67 341.00 l 271.66 341.40 l 275.87 342.92 l 277.39 343.53 l 280.33 344.34 l 281.31 344.59 l 284.50 345.53 l 287.08 345.93 l 289.52 346.42 l 291.61 346.77 l 293.32 346.81 l 297.25 347.04 l 298.73 347.07 l 300.38 346.85 l 303.85 346.53 l 305.84 346.24 l 309.01 345.34 l 309.63 345.19 l 312.95 344.15 l 314.88 343.33 l 318.72 341.40 l 319.58 340.92 l 320.06 340.62 l 322.81 338.65 l 323.76 337.99 l 327.18 335.30 l 327.73 334.84 l 328.34 334.29 l 331.25 331.25 l 334.29 327.82 l 334.59 327.48 l 334.84 327.18 l 335.99 325.47 l 337.50 323.27 l 339.56 320.06 l 340.16 318.82 l 341.40 316.09 l 342.39 313.94 l 342.82 312.95 l 343.33 311.02 l 344.05 308.48 l 344.73 305.84 l 345.11 302.44 l 345.15 302.09 l 345.52 298.72 l 345.49 295.71 l 345.48 294.64 l 345.45 291.61 l 345.08 288.18 l 345.06 287.96 l 344.67 284.50 l 344.11 281.79 l 343.59 279.58 l 343.12 277.39 l 342.69 276.10 l 341.40 272.74 l 340.67 271.00 l 340.32 270.27 l 338.04 266.91 l 337.88 266.68 l 335.22 263.16 l 334.75 262.70 l 334.29 262.30 l 330.75 259.59 l 330.63 259.50 l 327.18 257.08 l 326.54 256.69 l 325.41 256.05 l 321.74 254.38 l 320.06 253.67 l 316.63 252.37 l 316.23 252.22 l 312.95 251.01 l 311.41 250.48 l 306.76 248.94 l 306.04 248.73 l 305.84 248.68 l 305.49 248.59 l 300.43 247.23 l 298.73 246.78 l 295.77 245.98 l 294.82 245.73 l 291.61 244.86 l 289.24 244.20 l 285.90 243.22 l 284.50 242.82 l 283.73 242.59 l 281.31 241.82 l 278.21 241.01 l 277.39 240.78 l 275.90 240.34 l 272.69 239.41 l 270.27 238.67 l 267.31 237.68 l 265.45 237.00 l 263.16 236.20 l 262.08 235.79 l 259.55 234.71 l 256.95 233.82 l 256.05 233.49 l 253.95 232.61 l 251.87 231.78 l 248.94 230.49 l 247.01 229.53 l 243.57 227.60 l 242.36 227.06 l 241.82 226.80 l 240.01 225.78 l 237.75 224.56 l 234.71 222.72 l 233.39 221.81 l 231.72 220.49 l 229.18 218.91 l 227.60 217.82 l 225.10 215.87 l 222.28 213.38 l 221.24 212.63 l 220.49 212.05 l 217.40 209.35 l 214.22 206.26 l 213.76 205.88 l 213.38 205.55 l 210.11 202.41 l 207.01 199.15 l 206.62 198.79 l 206.26 198.46 l 203.12 195.18 l 200.31 192.04 l 199.73 191.46 l 199.15 190.86 l 196.32 187.75 l 193.91 184.92 l 193.00 183.96 l 192.04 182.92 l 189.65 180.20 l 187.67 177.81 l 186.37 176.37 l 184.92 174.73 l 183.06 172.56 l 181.56 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 192.18 261.04 m 206.12 261.04 l 206.12 271.03 l 192.18 271.03 l 192.18 271.03 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 193.6 262.4 m (24) sh % gr_show_at() END 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 265.72 233.72 m 279.66 233.72 l 279.66 243.71 l 265.72 243.71 l 265.72 243.71 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 267.1 235.1 m (24) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 512.10 272.72 m 509.20 273.17 l 508.06 273.34 l 504.99 273.84 l 501.95 274.35 l 500.68 274.58 l 497.88 275.07 l 495.91 275.42 l 491.93 276.22 l 490.76 276.44 l 489.96 276.59 l 486.31 277.39 l 484.10 277.84 l 483.65 277.94 l 482.92 278.11 l 478.28 279.13 l 476.54 279.57 l 473.61 280.32 l 472.59 280.56 l 469.43 281.42 l 467.01 282.09 l 463.62 283.19 l 462.31 283.58 l 461.60 283.79 l 459.60 284.50 l 456.35 285.65 l 455.20 286.13 l 452.46 287.24 l 451.27 287.68 l 448.09 289.13 l 446.34 289.87 l 443.01 291.61 l 441.72 292.36 l 440.98 292.87 l 437.70 294.89 l 437.35 295.10 l 433.86 297.60 l 433.16 298.02 l 432.21 298.72 l 429.41 301.38 l 426.75 304.37 l 425.96 305.05 l 425.21 305.84 l 423.26 309.33 l 423.21 309.41 l 421.40 312.95 l 421.25 314.56 l 420.86 318.84 l 420.75 320.06 l 421.19 321.62 l 422.02 324.80 l 422.73 327.18 l 424.19 329.74 l 426.75 333.68 l 426.96 334.08 l 427.09 334.29 l 428.14 335.68 l 429.98 338.17 l 432.76 341.40 l 433.29 341.98 l 433.86 342.52 l 436.72 345.65 l 439.77 348.51 l 440.38 349.10 l 440.98 349.59 l 444.12 352.48 l 448.01 355.55 l 448.09 355.61 l 448.10 355.62 l 448.11 355.62 l 452.04 358.78 l 455.20 360.97 l 456.22 361.72 l 457.81 362.74 l 460.45 364.60 l 462.31 365.73 l 464.81 367.35 l 469.31 369.85 l 469.38 369.90 l 469.43 369.92 l 469.59 370.01 l 473.84 372.54 l 476.54 373.93 l 478.50 375.00 l 482.66 376.96 l 483.31 377.31 l 483.65 377.47 l 484.64 377.95 l 488.03 379.69 l 490.76 380.91 l 492.91 381.92 l 497.64 383.84 l 497.88 383.94 l 497.97 383.98 l 498.19 384.07 l 502.85 386.22 l 504.99 387.08 l 507.87 388.31 l 510.02 389.11 l 512.10 389.93 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 477.13 272.15 m 491.08 272.15 l 491.08 282.14 l 477.13 282.14 l 477.13 282.14 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 478.5 273.5 m (22) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 262.52 m 171.22 262.64 l 172.79 263.16 l 176.55 264.42 l 177.81 264.95 l 180.90 266.25 l 181.58 266.51 l 184.92 268.14 l 186.38 268.82 l 188.80 270.27 l 190.79 271.52 l 192.04 272.48 l 194.89 274.54 l 198.10 277.39 l 198.64 277.90 l 199.15 278.47 l 202.13 281.52 l 204.54 284.50 l 205.28 285.48 l 206.26 287.01 l 208.20 289.67 l 209.38 291.61 l 210.85 294.14 l 212.92 298.27 l 213.16 298.72 l 213.23 298.87 l 213.38 299.17 l 215.69 303.52 l 216.79 305.84 l 218.07 308.25 l 220.30 312.76 l 220.39 312.95 l 220.43 313.01 l 220.49 313.11 l 223.31 317.24 l 225.15 320.06 l 226.26 321.40 l 227.60 323.04 l 229.61 325.17 l 231.42 327.18 l 233.14 328.74 l 234.71 330.21 l 236.97 332.03 l 239.64 334.29 l 240.88 335.23 l 241.82 335.97 l 245.06 338.17 l 247.31 339.78 l 248.94 340.93 l 249.23 341.10 l 249.69 341.40 l 253.63 343.82 l 256.05 345.38 l 258.07 346.49 l 261.57 348.51 l 262.57 349.10 l 263.16 349.46 l 265.09 350.44 l 267.26 351.53 l 270.27 353.11 l 272.04 353.86 l 275.96 355.62 l 276.93 356.08 l 277.39 356.31 l 278.49 356.73 l 282.07 358.05 l 284.50 359.01 l 287.43 359.81 l 289.24 360.36 l 291.61 361.05 l 293.07 361.28 l 298.29 362.30 l 298.73 362.37 l 299.08 362.39 l 303.55 362.74 l 305.66 362.91 l 305.84 362.93 l 306.03 362.93 l 310.90 362.74 l 312.87 362.66 l 312.95 362.65 l 313.05 362.63 l 319.05 361.72 l 320.06 361.50 l 321.84 360.96 l 324.66 360.22 l 327.18 359.36 l 329.83 358.28 l 333.43 356.49 l 334.29 356.09 l 334.59 355.93 l 335.10 355.62 l 339.03 353.25 l 341.40 351.57 l 343.19 350.30 l 345.41 348.51 l 347.12 347.12 l 348.51 345.83 l 350.88 343.77 l 353.34 341.40 l 354.48 340.25 l 355.62 338.97 l 357.96 336.62 l 360.09 334.29 l 361.28 332.83 l 362.74 330.85 l 364.43 328.86 l 365.74 327.18 l 367.29 324.61 l 369.60 320.31 l 369.74 320.06 l 369.77 319.98 l 369.85 319.71 l 371.64 314.74 l 372.18 312.95 l 372.36 310.44 l 372.57 308.56 l 372.75 305.84 l 372.50 303.19 l 372.41 301.28 l 372.19 298.72 l 371.85 296.72 l 371.40 293.16 l 371.16 291.61 l 370.97 290.50 l 370.15 284.80 l 370.10 284.50 l 370.06 284.29 l 369.85 282.81 l 369.21 278.02 l 369.13 277.39 l 368.97 276.51 l 368.19 271.94 l 367.88 270.27 l 367.08 267.50 l 366.74 266.27 l 365.80 263.16 l 364.83 261.07 l 362.74 256.99 l 362.42 256.37 l 362.22 256.05 l 359.74 253.06 l 359.24 252.44 l 355.99 248.94 l 355.79 248.77 l 355.62 248.66 l 354.77 248.08 l 351.57 245.88 l 348.51 244.03 l 347.09 243.25 l 344.14 241.82 l 342.19 241.03 l 341.40 240.75 l 339.81 240.24 l 336.88 239.23 l 334.29 238.44 l 331.37 237.63 l 329.67 237.20 l 327.18 236.54 l 325.71 236.18 l 320.33 234.98 l 320.06 234.91 l 319.90 234.88 l 319.13 234.71 l 313.94 233.72 l 312.95 233.55 l 311.53 233.29 l 307.94 232.61 l 305.84 232.25 l 302.81 231.68 l 301.93 231.51 l 298.73 230.92 l 295.95 230.37 l 294.01 230.00 l 291.61 229.53 l 290.03 229.18 l 285.02 228.12 l 284.50 228.01 l 284.17 227.93 l 282.81 227.60 l 278.35 226.64 l 277.39 226.44 l 275.87 226.08 l 272.59 225.28 l 270.27 224.73 l 266.96 223.81 l 266.30 223.62 l 263.16 222.74 l 261.46 222.19 l 256.42 220.49 l 256.14 220.40 l 256.05 220.38 l 255.88 220.31 l 250.89 218.53 l 248.94 217.83 l 245.83 216.48 l 244.20 215.75 l 241.82 214.70 l 240.96 214.24 l 239.40 213.38 l 236.26 211.83 l 234.71 211.06 l 231.72 209.26 l 228.71 207.37 l 227.60 206.68 l 227.36 206.50 l 227.05 206.26 l 223.15 203.60 l 220.49 201.73 l 219.07 200.57 l 217.43 199.15 l 215.15 197.37 l 213.38 195.96 l 211.32 194.09 l 209.16 192.04 l 207.62 190.68 l 206.26 189.48 l 203.98 187.21 l 201.76 184.92 l 200.43 183.64 l 199.15 182.41 l 196.92 180.04 l 194.87 177.81 l 193.48 176.37 l 192.04 174.90 l 190.05 172.69 l 188.29 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 191.13 271.69 m 205.08 271.69 l 205.08 281.69 l 191.13 281.69 l 191.13 281.69 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 192.5 273.1 m (22) sh % gr_show_at() END 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 337.16 236.13 m 351.11 236.13 l 351.11 246.12 l 337.16 246.12 l 337.16 246.12 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 338.6 237.5 m (22) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 512.10 263.70 m 511.46 263.80 l 506.33 264.50 l 504.99 264.71 l 503.15 265.00 l 500.14 265.42 l 497.88 265.79 l 494.73 266.31 l 494.01 266.41 l 490.76 266.97 l 487.93 267.45 l 486.11 267.81 l 483.65 268.25 l 481.93 268.55 l 477.28 269.53 l 476.54 269.67 l 476.02 269.76 l 473.65 270.27 l 470.08 270.93 l 469.43 271.07 l 468.40 271.30 l 464.11 272.07 l 462.31 272.50 l 459.47 273.12 l 458.25 273.33 l 455.20 274.07 l 452.44 274.63 l 450.21 275.27 l 448.09 275.76 l 446.70 276.00 l 441.52 277.39 l 441.08 277.49 l 440.98 277.52 l 440.79 277.57 l 435.13 278.65 l 433.86 279.05 l 431.78 279.47 l 429.12 279.76 l 426.75 280.35 l 423.50 280.64 l 422.87 280.62 l 419.64 280.99 l 416.33 280.70 l 415.69 280.55 l 412.53 280.18 l 410.48 279.43 l 406.84 277.39 l 405.96 276.84 l 405.41 276.36 l 402.60 273.09 l 400.68 270.27 l 399.73 268.85 l 398.30 266.28 l 397.28 264.18 l 396.85 263.16 l 395.32 260.18 l 394.92 259.43 l 393.27 256.05 l 392.47 254.77 l 391.19 252.67 l 389.80 250.32 l 388.98 248.94 l 386.81 246.21 l 384.07 242.91 l 383.58 242.32 l 383.15 241.82 l 379.86 238.92 l 376.96 236.55 l 375.93 235.74 l 374.47 234.71 l 371.57 232.99 l 369.85 232.07 l 366.84 230.61 l 364.92 229.78 l 362.74 228.80 l 361.88 228.46 l 359.45 227.60 l 356.55 226.67 l 355.62 226.41 l 354.06 226.03 l 350.91 225.20 l 348.51 224.65 l 345.04 223.96 l 344.84 223.93 l 341.40 223.28 l 339.01 222.88 l 336.31 222.51 l 334.29 222.18 l 332.81 221.97 l 328.08 221.39 l 327.18 221.26 l 326.49 221.17 l 320.59 220.49 l 320.12 220.43 l 320.06 220.43 l 320.00 220.42 l 313.72 219.71 l 312.95 219.64 l 312.01 219.55 l 307.34 218.99 l 305.84 218.84 l 303.97 218.62 l 300.98 218.24 l 298.73 217.99 l 295.85 217.61 l 294.66 217.44 l 291.61 217.06 l 288.41 216.58 l 287.60 216.47 l 284.50 216.02 l 282.25 215.63 l 279.15 215.13 l 277.39 214.83 l 276.18 214.58 l 270.34 213.44 l 270.27 213.42 l 270.24 213.41 l 270.07 213.38 l 264.45 212.09 l 263.16 211.81 l 261.02 211.23 l 258.81 210.62 l 256.05 209.89 l 253.33 208.98 l 250.86 208.18 l 248.94 207.55 l 248.02 207.18 l 245.76 206.26 l 242.92 205.16 l 241.82 204.75 l 238.99 203.42 l 238.01 202.96 l 234.71 201.44 l 233.26 200.61 l 230.72 199.15 l 228.71 198.04 l 227.60 197.45 l 224.34 195.30 l 222.64 194.19 l 220.49 192.78 l 220.07 192.45 l 219.55 192.04 l 216.05 189.37 l 213.38 187.37 l 212.07 186.23 l 210.60 184.92 l 208.28 182.91 l 206.26 181.23 l 204.53 179.55 l 202.72 177.81 l 200.89 176.07 l 199.15 174.48 l 197.30 172.55 l 195.48 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 476.68 262.56 m 490.62 262.56 l 490.62 272.55 l 476.68 272.55 l 476.68 272.55 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 478.1 264.0 m (20) sh % gr_show_at() END 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 197.55 173.85 m 211.50 173.85 l 211.50 183.85 l 197.55 183.85 l 197.55 183.85 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 198.9 175.2 m (20) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 268.46 m 172.02 268.95 l 174.93 270.27 l 176.86 271.23 l 177.81 271.78 l 181.35 273.85 l 181.49 273.96 l 184.92 276.25 l 185.61 276.70 l 186.48 277.39 l 189.47 279.95 l 192.04 282.51 l 193.06 283.48 l 193.98 284.50 l 196.30 287.35 l 199.15 291.34 l 199.27 291.50 l 199.34 291.61 l 199.65 292.11 l 202.01 295.87 l 203.61 298.72 l 204.52 300.47 l 206.26 304.09 l 206.87 305.23 l 207.16 305.84 l 208.06 307.64 l 209.25 309.97 l 210.69 312.95 l 211.64 314.69 l 213.38 317.88 l 214.20 319.24 l 214.69 320.06 l 217.13 323.42 l 218.26 324.95 l 219.89 327.18 l 220.17 327.50 l 220.49 327.86 l 223.65 331.12 l 226.73 334.29 l 227.17 334.71 l 227.60 335.12 l 230.99 338.01 l 233.28 339.96 l 234.71 341.19 l 234.83 341.28 l 234.98 341.40 l 238.84 344.39 l 241.82 346.72 l 242.88 347.46 l 244.36 348.51 l 246.97 350.48 l 248.94 351.96 l 251.13 353.43 l 254.36 355.62 l 255.32 356.35 l 256.05 356.90 l 259.56 359.23 l 259.83 359.40 l 263.16 361.62 l 263.87 362.03 l 265.10 362.74 l 268.22 364.79 l 270.27 366.13 l 272.68 367.45 l 277.01 369.85 l 277.24 370.00 l 277.39 370.09 l 277.89 370.36 l 281.90 372.45 l 284.50 373.82 l 286.73 374.73 l 291.29 376.64 l 291.61 376.77 l 291.76 376.82 l 292.22 376.96 l 296.98 378.71 l 298.73 379.36 l 301.97 380.21 l 302.47 380.33 l 305.84 381.24 l 308.28 381.64 l 311.05 382.17 l 312.95 382.50 l 314.42 382.61 l 319.12 383.13 l 320.06 383.21 l 320.94 383.20 l 326.49 383.39 l 327.18 383.38 l 327.93 383.32 l 333.29 383.08 l 334.29 382.98 l 335.62 382.74 l 339.57 382.24 l 341.40 381.88 l 344.38 381.10 l 345.33 380.89 l 348.51 379.95 l 350.73 379.18 l 355.48 377.11 l 355.62 377.05 l 355.69 377.02 l 355.81 376.96 l 360.45 374.67 l 362.74 373.32 l 364.97 372.09 l 368.50 369.85 l 369.34 369.34 l 369.85 368.99 l 371.91 367.79 l 373.83 366.71 l 376.96 364.74 l 378.33 364.10 l 380.99 362.74 l 383.07 361.73 l 384.07 361.20 l 386.26 360.56 l 388.40 359.95 l 391.19 359.09 l 394.52 358.96 l 394.99 358.94 l 398.30 358.81 l 401.47 359.57 l 402.47 359.80 l 405.41 360.48 l 406.92 361.23 l 410.27 362.74 l 411.79 363.47 l 412.53 363.80 l 415.54 365.75 l 416.19 366.19 l 419.64 368.22 l 420.57 368.92 l 421.98 369.85 l 424.75 371.85 l 426.75 373.12 l 428.95 374.77 l 432.39 376.96 l 433.25 377.58 l 433.86 377.95 l 437.05 380.15 l 437.48 380.45 l 440.98 382.58 l 441.87 383.18 l 443.48 384.07 l 446.30 385.87 l 448.09 386.85 l 450.83 388.45 l 454.07 390.06 l 455.20 390.65 l 455.55 390.84 l 456.28 391.19 l 460.19 393.31 l 462.31 394.31 l 464.97 395.64 l 468.08 396.96 l 469.43 397.56 l 469.92 397.80 l 471.15 398.30 l 474.80 400.04 l 476.54 400.76 l 479.77 402.18 l 480.80 402.56 l 483.65 403.71 l 484.85 404.21 l 488.16 405.41 l 489.98 406.19 l 490.76 406.48 l 492.53 407.18 l 495.05 408.23 l 497.88 409.26 l 500.23 410.17 l 503.84 411.38 l 504.99 411.79 l 505.52 412.00 l 507.08 412.52 l 510.64 413.98 l 512.10 414.51 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 187.00 278.81 m 200.95 278.81 l 200.95 288.80 l 187.00 288.80 l 187.00 288.80 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 188.4 280.2 m (20) sh % gr_show_at() END 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 447.10 384.36 m 461.04 384.36 l 461.04 394.36 l 447.10 394.36 l 447.10 394.36 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 448.5 385.8 m (20) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 512.10 251.55 m 509.06 251.97 l 508.14 252.09 l 504.99 252.54 l 501.90 252.96 l 500.78 253.14 l 497.88 253.56 l 495.67 253.84 l 492.46 254.35 l 490.76 254.58 l 489.45 254.74 l 484.18 255.52 l 483.65 255.59 l 483.23 255.63 l 480.10 256.05 l 476.88 256.40 l 476.54 256.45 l 476.08 256.50 l 470.38 257.00 l 469.43 257.13 l 468.23 257.24 l 463.74 257.48 l 462.31 257.63 l 460.64 257.72 l 456.87 257.72 l 455.20 257.82 l 453.45 257.80 l 449.55 257.51 l 448.09 257.49 l 446.78 257.36 l 441.30 256.38 l 440.98 256.34 l 440.74 256.29 l 439.99 256.05 l 435.46 254.46 l 433.86 253.76 l 430.75 252.05 l 428.24 250.43 l 426.75 249.50 l 426.43 249.26 l 426.04 248.94 l 422.51 246.07 l 419.64 243.56 l 418.76 242.71 l 417.90 241.82 l 415.08 239.27 l 412.53 236.91 l 411.41 235.82 l 410.28 234.71 l 407.63 232.50 l 405.41 230.67 l 403.74 229.27 l 401.68 227.60 l 399.70 226.20 l 398.30 225.24 l 395.44 223.35 l 391.67 220.97 l 391.19 220.66 l 391.08 220.60 l 390.88 220.49 l 386.39 218.17 l 384.07 217.06 l 381.50 215.95 l 378.26 214.67 l 376.96 214.14 l 376.40 213.94 l 374.64 213.38 l 370.99 212.23 l 369.85 211.91 l 367.94 211.47 l 365.30 210.81 l 362.74 210.25 l 359.34 209.66 l 358.96 209.60 l 355.62 209.05 l 353.15 208.73 l 350.74 208.49 l 348.51 208.22 l 346.73 208.05 l 342.93 207.79 l 341.40 207.65 l 340.10 207.56 l 335.36 207.34 l 334.29 207.27 l 333.34 207.21 l 327.93 207.02 l 327.18 206.97 l 326.50 206.94 l 320.54 206.74 l 320.06 206.72 l 319.63 206.69 l 313.15 206.46 l 312.95 206.45 l 312.78 206.44 l 308.64 206.26 l 305.96 206.14 l 305.84 206.14 l 305.71 206.14 l 299.21 205.78 l 298.73 205.77 l 298.20 205.74 l 292.53 205.34 l 291.61 205.30 l 290.58 205.23 l 285.96 204.80 l 284.50 204.70 l 282.76 204.53 l 279.52 204.13 l 277.39 203.92 l 274.67 203.55 l 273.22 203.32 l 270.27 202.92 l 267.09 202.33 l 266.20 202.19 l 263.16 201.65 l 261.15 201.16 l 257.19 200.29 l 256.05 200.03 l 255.38 199.82 l 253.04 199.15 l 249.87 198.22 l 248.94 197.97 l 247.11 197.32 l 244.58 196.39 l 241.82 195.45 l 239.47 194.40 l 235.31 192.64 l 234.71 192.38 l 234.49 192.26 l 234.08 192.04 l 229.86 189.77 l 227.60 188.63 l 225.34 187.18 l 221.66 184.92 l 220.94 184.47 l 220.49 184.20 l 217.63 182.07 l 216.83 181.47 l 213.38 179.01 l 212.73 178.45 l 211.96 177.81 l 208.89 175.19 l 206.26 173.10 l 205.03 171.93 l 203.68 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 476.68 249.90 m 490.62 249.90 l 490.62 259.89 l 476.68 259.89 l 476.68 259.89 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 478.1 251.3 m (18) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 274.81 m 172.40 275.69 l 175.25 277.39 l 176.78 278.42 l 177.81 279.20 l 180.79 281.52 l 184.19 284.50 l 184.55 284.87 l 184.92 285.28 l 187.92 288.62 l 190.34 291.61 l 191.04 292.61 l 192.04 294.13 l 193.87 296.89 l 194.98 298.72 l 196.45 301.43 l 198.22 304.91 l 198.70 305.84 l 198.85 306.14 l 199.15 306.78 l 201.18 310.92 l 202.14 312.95 l 203.51 315.70 l 205.15 318.95 l 205.71 320.06 l 205.91 320.42 l 206.26 321.01 l 208.65 324.78 l 210.23 327.18 l 211.58 328.97 l 213.38 331.24 l 214.78 332.88 l 216.01 334.29 l 218.17 336.61 l 220.49 338.99 l 221.72 340.17 l 223.03 341.40 l 225.36 343.64 l 227.60 345.73 l 229.10 347.02 l 230.85 348.51 l 232.85 350.37 l 234.71 352.06 l 236.65 353.68 l 239.00 355.62 l 240.45 357.00 l 241.82 358.27 l 244.24 360.32 l 247.15 362.74 l 248.04 363.63 l 248.94 364.49 l 251.79 367.00 l 255.14 369.85 l 255.58 370.32 l 256.05 370.80 l 259.28 373.73 l 262.99 376.96 l 263.07 377.05 l 263.16 377.15 l 265.97 379.77 l 266.74 380.49 l 270.27 383.61 l 270.54 383.81 l 270.89 384.07 l 274.22 387.24 l 277.39 390.05 l 278.04 390.54 l 278.95 391.19 l 281.82 393.87 l 284.50 396.16 l 285.75 397.05 l 287.64 398.30 l 289.77 400.14 l 291.61 401.58 l 293.95 403.08 l 297.86 405.41 l 298.35 405.79 l 298.73 406.05 l 300.25 406.93 l 302.81 408.44 l 305.84 410.10 l 307.51 410.86 l 311.40 412.52 l 312.41 413.07 l 312.95 413.34 l 314.34 413.92 l 317.38 415.21 l 320.06 416.30 l 322.55 417.15 l 325.75 418.22 l 327.18 418.69 l 327.92 418.90 l 330.54 419.64 l 333.35 420.57 l 334.29 420.88 l 336.02 421.37 l 338.88 422.16 l 341.40 422.88 l 344.53 423.62 l 345.69 423.92 l 348.51 424.62 l 350.29 424.98 l 354.93 426.06 l 355.62 426.20 l 356.09 426.28 l 358.31 426.75 l 361.88 427.61 l 362.74 427.85 l 364.20 428.21 l 367.63 428.97 l 369.85 429.57 l 373.30 430.42 l 373.61 430.51 l 376.96 431.41 l 378.90 431.92 l 383.64 433.42 l 384.07 433.55 l 384.32 433.62 l 385.00 433.86 l 389.45 435.60 l 391.19 436.36 l 394.36 437.80 l 395.87 438.55 l 398.30 439.71 l 399.15 440.13 l 400.77 440.97 l 403.71 442.67 l 405.41 443.70 l 408.15 445.35 l 412.42 447.98 l 412.53 448.05 l 412.55 448.06 l 412.59 448.09 l 416.75 450.97 l 419.64 453.01 l 420.93 453.91 l 422.80 455.20 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 185.06 288.44 m 199.01 288.44 l 199.01 298.43 l 185.06 298.43 l 185.06 298.43 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 186.5 289.8 m (18) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 512.10 233.05 m 510.63 233.24 l 505.81 233.89 l 504.99 233.99 l 504.34 234.06 l 498.60 234.71 l 497.94 234.78 l 497.88 234.79 l 497.79 234.80 l 491.35 235.30 l 490.76 235.35 l 490.08 235.39 l 484.56 235.62 l 483.65 235.68 l 482.67 235.69 l 477.50 235.68 l 476.54 235.69 l 475.60 235.65 l 470.02 235.30 l 469.43 235.28 l 468.92 235.22 l 465.24 234.71 l 462.67 234.36 l 462.31 234.30 l 461.77 234.17 l 456.87 233.04 l 455.20 232.63 l 452.04 231.56 l 451.44 231.36 l 448.09 230.18 l 446.31 229.38 l 442.50 227.60 l 441.44 227.14 l 440.98 226.94 l 439.58 226.21 l 436.74 224.72 l 433.86 223.20 l 432.17 222.18 l 429.38 220.49 l 427.69 219.54 l 426.75 219.02 l 423.23 216.89 l 423.04 216.78 l 419.64 214.73 l 418.81 214.21 l 417.47 213.38 l 414.36 211.54 l 412.53 210.47 l 409.87 208.92 l 405.67 206.52 l 405.41 206.37 l 405.34 206.33 l 405.21 206.26 l 400.72 203.85 l 398.30 202.59 l 395.98 201.47 l 391.38 199.34 l 391.19 199.25 l 391.12 199.22 l 390.94 199.15 l 386.08 197.14 l 384.07 196.35 l 380.82 195.29 l 379.95 195.03 l 376.96 194.08 l 375.32 193.68 l 370.40 192.59 l 369.85 192.46 l 369.49 192.40 l 367.02 192.04 l 363.33 191.44 l 362.74 191.36 l 362.00 191.30 l 356.84 190.83 l 355.62 190.74 l 354.30 190.71 l 350.00 190.55 l 348.51 190.52 l 347.02 190.55 l 342.88 190.56 l 341.40 190.59 l 340.03 190.66 l 335.52 190.81 l 334.29 190.87 l 333.19 190.94 l 328.01 191.20 l 327.18 191.26 l 326.45 191.32 l 320.44 191.66 l 320.06 191.69 l 319.75 191.72 l 314.46 192.04 l 313.03 192.12 l 312.95 192.12 l 312.87 192.12 l 306.26 192.46 l 305.84 192.47 l 305.40 192.47 l 299.41 192.72 l 298.73 192.73 l 298.03 192.73 l 292.45 192.87 l 291.61 192.87 l 290.80 192.85 l 285.32 192.85 l 284.50 192.84 l 283.75 192.79 l 277.96 192.61 l 277.39 192.58 l 276.89 192.53 l 270.30 192.07 l 270.27 192.06 l 270.25 192.06 l 270.06 192.04 l 263.96 191.24 l 263.16 191.16 l 262.11 190.98 l 257.92 190.17 l 256.05 189.87 l 253.17 189.16 l 252.10 188.87 l 248.94 188.13 l 246.53 187.33 l 243.27 186.37 l 241.82 185.91 l 241.13 185.62 l 239.35 184.92 l 236.08 183.55 l 234.71 183.04 l 231.25 181.27 l 230.90 181.11 l 227.60 179.53 l 226.54 178.87 l 224.72 177.81 l 222.11 176.19 l 220.49 175.27 l 217.85 173.34 l 213.90 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 476.68 229.99 m 490.62 229.99 l 490.62 239.98 l 476.68 239.98 l 476.68 239.98 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 478.1 231.4 m (16) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 281.90 m 172.24 282.96 l 174.26 284.50 l 176.14 286.18 l 177.81 287.78 l 179.72 289.70 l 181.47 291.61 l 182.98 293.56 l 184.92 296.22 l 185.97 297.68 l 186.66 298.72 l 188.63 302.14 l 188.98 302.78 l 190.68 305.84 l 191.13 306.75 l 192.04 308.61 l 193.45 311.53 l 194.13 312.95 l 195.72 316.38 l 195.95 316.86 l 197.46 320.06 l 198.02 321.19 l 199.15 323.28 l 200.53 325.79 l 201.35 327.18 l 203.29 330.14 l 206.20 334.23 l 206.24 334.29 l 206.25 334.30 l 206.26 334.31 l 209.46 338.20 l 212.28 341.40 l 212.78 341.99 l 213.38 342.65 l 216.21 345.68 l 219.01 348.51 l 219.70 349.30 l 220.49 350.14 l 223.19 352.92 l 225.93 355.62 l 226.70 356.52 l 227.60 357.52 l 230.13 360.20 l 232.64 362.74 l 233.55 363.90 l 234.71 365.29 l 236.85 367.71 l 238.83 369.85 l 240.07 371.60 l 241.82 373.93 l 243.18 375.61 l 244.34 376.96 l 246.10 379.80 l 248.94 384.01 l 248.97 384.05 l 248.99 384.07 l 249.05 384.19 l 251.44 388.68 l 252.93 391.19 l 253.77 393.47 l 255.66 397.91 l 255.82 398.30 l 255.86 398.49 l 256.05 399.22 l 257.46 404.00 l 257.97 405.41 l 258.41 407.77 l 258.70 409.88 l 259.25 412.52 l 259.46 415.94 l 259.46 416.22 l 259.71 419.64 l 259.61 423.19 l 259.61 423.19 l 259.49 426.75 l 259.19 429.89 l 259.02 430.89 l 258.70 433.86 l 258.37 436.19 l 257.67 439.35 l 257.41 440.97 l 257.19 442.12 l 256.05 446.35 l 255.72 447.76 l 255.62 448.09 l 255.41 448.72 l 254.16 453.31 l 253.48 455.20 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 183.71 300.14 m 197.66 300.14 l 197.66 310.14 l 183.71 310.14 l 183.71 310.14 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 185.1 301.5 m (16) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 328.65 170.70 m 327.41 170.94 l 327.18 170.98 l 326.83 171.05 l 321.54 172.18 l 320.06 172.47 l 317.82 172.95 l 315.69 173.44 l 312.95 174.00 l 309.83 174.69 l 308.75 174.90 l 305.84 175.52 l 303.95 175.93 l 299.85 176.69 l 298.73 176.92 l 297.98 177.07 l 293.52 177.81 l 291.85 178.05 l 291.61 178.08 l 291.32 178.11 l 285.48 178.79 l 284.50 178.88 l 283.37 178.94 l 278.87 179.30 l 277.39 179.37 l 275.82 179.38 l 271.97 179.50 l 270.27 179.51 l 268.67 179.42 l 264.67 179.32 l 263.16 179.24 l 261.90 179.08 l 256.84 178.60 l 256.05 178.50 l 255.48 178.38 l 252.18 177.81 l 249.47 177.28 l 248.94 177.20 l 248.11 176.98 l 243.89 175.75 l 241.82 175.24 l 238.52 174.00 l 237.78 173.77 l 234.71 172.70 l 233.37 172.05 l 230.25 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 292.87 171.00 m 306.82 171.00 l 306.82 180.99 l 292.87 180.99 l 292.87 180.99 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 294.3 172.4 m (14) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 512.10 209.82 m 508.96 210.24 l 508.00 210.36 l 504.99 210.76 l 502.61 211.00 l 500.00 211.25 l 497.88 211.46 l 496.07 211.57 l 492.34 211.79 l 490.76 211.89 l 489.29 211.91 l 485.06 211.97 l 483.65 211.98 l 482.20 211.92 l 478.15 211.76 l 476.54 211.69 l 474.66 211.50 l 471.61 211.19 l 469.43 210.96 l 466.50 210.45 l 465.42 210.27 l 462.31 209.72 l 459.54 209.04 l 457.45 208.51 l 455.20 207.95 l 453.93 207.54 l 450.03 206.26 l 448.57 205.78 l 448.09 205.62 l 447.01 205.19 l 443.47 203.76 l 440.98 202.76 l 438.51 201.61 l 434.43 199.72 l 433.86 199.45 l 433.66 199.35 l 433.28 199.15 l 429.04 196.86 l 426.75 195.65 l 424.45 194.33 l 420.37 192.04 l 419.92 191.76 l 419.64 191.59 l 418.48 190.88 l 415.52 189.04 l 412.53 187.23 l 411.09 186.36 l 408.64 184.92 l 406.68 183.65 l 405.41 182.85 l 402.27 180.96 l 400.28 179.79 l 398.30 178.62 l 397.77 178.34 l 396.74 177.81 l 393.22 175.78 l 391.19 174.63 l 388.51 173.38 l 385.31 171.93 l 384.07 171.37 l 383.58 171.20 l 382.09 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 476.68 206.29 m 490.62 206.29 l 490.62 216.28 l 476.68 216.28 l 476.68 216.28 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 478.1 207.7 m (14) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 290.28 m 171.40 290.91 l 172.14 291.61 l 174.78 294.65 l 177.81 298.28 l 178.01 298.53 l 178.15 298.72 l 178.72 299.64 l 180.77 302.88 l 182.57 305.84 l 183.38 307.39 l 184.92 310.38 l 185.78 312.10 l 186.19 312.95 l 187.22 315.24 l 187.99 317.00 l 189.39 320.06 l 190.21 321.89 l 192.04 325.64 l 192.54 326.68 l 192.80 327.18 l 193.80 328.94 l 195.08 331.25 l 196.95 334.29 l 197.81 335.62 l 199.15 337.47 l 200.80 339.75 l 202.11 341.40 l 203.90 343.76 l 206.26 346.59 l 207.14 347.64 l 207.93 348.51 l 210.35 351.53 l 213.38 355.04 l 213.65 355.35 l 213.91 355.62 l 215.77 358.02 l 216.78 359.33 l 219.59 362.74 l 219.94 363.29 l 220.49 364.09 l 222.86 367.48 l 224.63 369.85 l 225.67 371.78 l 227.60 375.08 l 228.31 376.25 l 228.77 376.96 l 229.69 379.05 l 230.56 381.11 l 231.93 384.07 l 232.51 386.27 l 233.67 390.15 l 233.96 391.19 l 234.03 391.87 l 234.71 397.14 l 234.86 398.16 l 234.88 398.30 l 234.88 398.47 l 234.73 405.40 l 234.73 405.41 l 234.73 405.43 l 234.71 405.52 l 233.81 411.62 l 233.63 412.52 l 233.21 414.03 l 232.39 417.31 l 231.68 419.64 l 230.60 422.63 l 229.77 424.58 l 228.91 426.75 l 228.52 427.67 l 227.60 429.51 l 226.26 432.52 l 225.56 433.86 l 223.82 437.20 l 223.12 438.34 l 221.58 440.97 l 221.19 441.68 l 220.49 442.78 l 218.56 446.16 l 217.28 448.09 l 215.84 450.55 l 213.38 454.19 l 213.00 454.82 l 212.74 455.20 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 180.24 309.55 m 194.19 309.55 l 194.19 319.54 l 180.24 319.54 l 180.24 319.54 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 181.6 310.9 m (14) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 512.10 187.85 m 508.81 188.21 l 508.32 188.26 l 504.99 188.64 l 501.80 188.85 l 500.99 188.92 l 497.88 189.14 l 495.04 189.20 l 493.55 189.25 l 490.76 189.31 l 487.94 189.22 l 486.50 189.19 l 483.65 189.08 l 480.37 188.76 l 479.86 188.72 l 476.54 188.38 l 473.58 187.88 l 472.13 187.63 l 469.43 187.16 l 467.62 186.73 l 462.97 185.58 l 462.31 185.42 l 461.94 185.30 l 460.74 184.92 l 456.66 183.46 l 455.20 182.93 l 451.68 181.41 l 451.63 181.38 l 448.09 179.85 l 446.73 179.17 l 444.00 177.81 l 442.07 176.71 l 440.98 176.10 l 437.67 174.00 l 436.34 173.18 l 433.86 171.64 l 433.31 171.26 l 432.47 170.70 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 476.68 183.39 m 490.62 183.39 l 490.62 193.38 l 476.68 193.38 l 476.68 193.38 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 478.1 184.8 m (12) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 301.18 m 172.62 303.92 l 173.92 305.84 l 175.33 308.32 l 177.81 312.73 l 177.89 312.88 l 177.93 312.95 l 178.02 313.16 l 180.07 317.81 l 181.09 320.06 l 182.21 322.78 l 183.58 325.83 l 184.16 327.18 l 184.39 327.71 l 184.92 328.80 l 186.68 332.53 l 187.62 334.29 l 189.21 337.12 l 191.83 341.19 l 191.96 341.40 l 191.99 341.45 l 192.04 341.52 l 194.83 345.72 l 196.93 348.51 l 197.82 349.84 l 199.15 351.65 l 200.82 353.96 l 202.13 355.62 l 203.77 358.12 l 206.26 361.63 l 206.72 362.28 l 207.06 362.74 l 208.19 364.66 l 209.37 366.74 l 211.29 369.85 l 211.92 371.31 l 213.38 374.44 l 214.18 376.16 l 214.58 376.96 l 215.14 378.72 l 215.96 381.49 l 216.82 384.07 l 217.30 387.26 l 217.46 388.16 l 217.94 391.19 l 217.92 393.76 l 217.95 395.76 l 217.93 398.30 l 217.46 401.33 l 217.34 402.26 l 216.83 405.41 l 216.08 408.12 l 215.31 410.59 l 214.74 412.52 l 214.37 413.52 l 213.38 415.93 l 212.34 418.60 l 211.90 419.64 l 210.54 422.48 l 210.08 423.46 l 208.40 426.75 l 207.64 428.13 l 206.26 430.40 l 205.01 432.61 l 204.25 433.86 l 202.26 436.98 l 200.19 439.93 l 199.47 440.97 l 199.35 441.17 l 199.15 441.44 l 196.48 445.42 l 194.52 448.09 l 193.53 449.58 l 192.04 451.60 l 190.59 453.75 l 189.52 455.20 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 177.19 321.48 m 191.14 321.48 l 191.14 331.47 l 177.19 331.47 l 177.19 331.47 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 178.6 322.9 m (12) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 316.92 m 171.69 319.08 l 172.15 320.06 l 173.08 322.44 l 173.72 324.15 l 174.96 327.18 l 175.73 329.26 l 177.81 334.10 l 177.87 334.23 l 177.89 334.29 l 177.96 334.44 l 180.08 339.13 l 181.30 341.40 l 182.56 343.77 l 184.92 347.59 l 185.26 348.17 l 185.49 348.51 l 186.37 349.95 l 187.93 352.62 l 189.93 355.62 l 190.68 356.98 l 192.04 359.16 l 193.36 361.41 l 194.22 362.74 l 195.86 366.03 l 196.49 367.19 l 197.89 369.85 l 198.23 370.77 l 199.15 373.12 l 200.20 375.91 l 200.64 376.96 l 201.10 378.91 l 201.69 381.53 l 202.32 384.07 l 202.61 387.54 l 202.62 387.71 l 202.93 391.19 l 202.69 394.73 l 202.69 394.76 l 202.44 398.30 l 201.87 401.02 l 201.39 403.17 l 200.91 405.41 l 200.47 406.73 l 199.15 410.53 l 198.64 412.01 l 198.45 412.52 l 197.90 413.78 l 196.49 416.97 l 195.28 419.64 l 194.16 421.76 l 192.04 425.66 l 191.66 426.37 l 191.45 426.75 l 190.52 428.27 l 188.98 430.80 l 187.06 433.86 l 186.20 435.13 l 184.92 436.93 l 183.28 439.33 l 182.12 440.97 l 180.32 443.48 l 177.81 446.79 l 177.26 447.53 l 176.83 448.09 l 174.20 451.59 l 173.76 452.14 l 171.34 455.20 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 175.59 338.07 m 189.53 338.07 l 189.53 348.07 l 175.59 348.07 l 175.59 348.07 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 177.0 339.5 m (10) sh % gr_show_at() END 0 g 0 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 170.70 343.83 m 172.10 347.12 l 172.81 348.51 l 174.45 351.87 l 174.96 352.77 l 176.50 355.62 l 176.92 356.51 l 177.81 358.17 l 179.32 361.23 l 180.16 362.74 l 181.61 366.06 l 182.05 366.97 l 183.38 369.85 l 183.76 371.02 l 184.92 374.39 l 185.56 376.33 l 185.78 376.96 l 185.99 378.02 l 186.77 382.23 l 187.14 384.07 l 187.25 386.40 l 187.35 388.76 l 187.47 391.19 l 187.25 393.51 l 186.98 396.24 l 186.78 398.30 l 186.43 399.80 l 185.19 405.15 l 185.13 405.41 l 185.07 405.56 l 184.92 405.98 l 183.18 410.78 l 182.57 412.52 l 181.08 415.79 l 180.61 416.84 l 179.35 419.64 l 178.81 420.64 l 177.81 422.51 l 176.31 425.24 l 175.50 426.75 l 173.64 429.69 l 171.60 432.97 l 171.04 433.86 l 170.90 434.06 l 170.70 434.33 l S % END GriPath stroke/fill 1 g 1 G 1.0 i 0 J 1 j 0.709 w 10.0 M [] 0 d 179.20 364.16 m 187.56 364.16 l 187.56 374.15 l 179.20 374.15 l 179.20 374.15 l h F % END GriPath stroke/fill % gr_show_at() BEGIN 0 g 0 G S n 180.6 365.6 m (8) sh % gr_show_at() END %gri:set font size 12 /Helvetica-ISOLatin1 findfont 12.00 sc sf %gri:draw title "Example 5 -- wind (Fig5 Koch et al, 1983)" %^ scale 1 170.7 0 28.45 1 170.7 0 28.45 % gr_show_at() BEGIN 0 g 0 G 230.6 483.6 m (Example 5 ) sh (\255) sh () sh (\255) sh ( wind \(Fig5 Koch et al, 1983\)) sh % gr_show_at() END %gri: showpage %%Trailer %%BoundingBox: 129 130 521 494 %%DocumentFonts: Courier Helvetica Palatino-Roman Palatino-Italic Symbol Times-Roman %%Pages: 1 gri/doc/examples/example12.gri0000644000175000017500000000413113147557614014703 0ustar psgpsg# Example 12 -- Linegraph with key inside plot set font size 10 # points (1in = 72pt) set x size 10 # cm set y size 10 # cm set x name "Height" set y name "Total Energy" # Following axis setups not necessary; will autoscale if you # remove these. set x margin 3 set x axis 800 960 20 set y margin 3 set y axis -0.4 1 0.2 # Read data. Format is columns (x, y1, y2, y3, y4) open example12.dat read columns x y draw curve draw label for last curve "1" rewind set line width {rpn ..linewidth.. 1.5 *} read columns x * y draw curve draw label for last curve "2" rewind set line width {rpn ..linewidth.. 1.5 *} read columns x * * y draw curve draw label for last curve "3" rewind set line width {rpn ..linewidth.. 1.5 *} read columns x * * * y draw curve draw label for last curve "4" # Draw the key. # NOTES: # (1) This key is inside the plot; it's location was chosen # after looking at the data. To put the key in a different # location, alter the .key_topleft_x. and .key_topleft_y. # variables. For example, you could put the key to the # right of the plot by changing the next line to: # `.key_topleft_x. = {rpn ..xsize.. 0.5 +}' # (2) The variable .dy_inc. is the spacing between lines in # the key. It should be OK even if you change the # font size above. .key_topleft_x. = 0.5 # cm right of left axis .key_topleft_y. = 0.5 # cm below top axis .dy_inc. = {rpn ..fontsize.. pttocm 1.5 *} draw label "1 = Model 1A" at \ {rpn ..xleft.. xusertocm .key_topleft_x. +} \ {rpn ..ytop.. yusertocm .key_topleft_y. -} cm .key_topleft_y. += .dy_inc. draw label "2 = Model 2A" at \ {rpn ..xleft.. xusertocm .key_topleft_x. +} \ {rpn ..ytop.. yusertocm .key_topleft_y. -} cm .key_topleft_y. += .dy_inc. draw label "3 = Model 1B" at \ {rpn ..xleft.. xusertocm .key_topleft_x. +} \ {rpn ..ytop.. yusertocm .key_topleft_y. -} cm .key_topleft_y. += .dy_inc. draw label "4 = Model 2B" at \ {rpn ..xleft.. xusertocm .key_topleft_x. +} \ {rpn ..ytop.. yusertocm .key_topleft_y. -} cm draw title "Example 12 -- Total heating vs height of boundary layer" gri/doc/gri.texi0000644000175000017500000243351613147557614012257 0ustar psgpsg\input texinfo @c @comment *** Start of HTML stuff *** @comment # HTML support, via comments in texinfo: @comment # @comment # `@c HTML some-stuff' @comment # Pass "some-stuff", or in other words all the text following @comment # the HTML token on the same line, directly to the output file. @comment # @comment # For example, you might do one of the following: @comment # @comment # (1) Let user see gif image. @comment # @c HTML Click to see plot

    @comment # @comment # (2) Let user ftp to a location. @comment # @c HTML the Gri FTP site.

    @comment # @comment # (3) Ignore some texinfo stuff. @comment # @c HTML @comment # @comment # (4) Create new file, possibly named and titled. @comment # @c HTML @comment # if it occurs on a line all by itself, causes @comment # this perlscript to chop files here. The filename @comment # will be as specified. The other_words @comment # will be used as the title. If neither the @comment # filename nor the other_words are present, then @comment # this script makes up filenames using numbers, e.g., @comment # gri1.html, gri2.html. If the filename is ".", @comment # then this same naming scheme is used, but the titles @comment # are used. @comment # @comment # (5) Plant a comment to be stripped out as a latex command @comment # @c HTML @comment *** End of HTML stuff *** @c @comment OVERRIDE some defaults in texinfo.tex @iftex @message{} @message{gri.texi: overriding parskip, } @global@parskip=4pt @c space between paragraphs @message{overriding baselineskip, } @global@baselineskip=12pt @c line spacing @message{overriding lispnarrowing } @c @global@lispnarrowing=0.2cm @c left margin on examples @global@widowpenalty=10000 @c Prevent widows @global@clubpenalty=10000 @c Prevent orphans @message{} @end iftex @comment %**start of header @setfilename gri.info @settitle Gri @set GRI-VERSION 2.12.26 @set GRI-PREVIOUS-VERSION 2.12.25 @set AUTHOR-EMAIL dankelley@@users.sourceforge.net @include version.texi @c %**end of header @iftex @finalout @end iftex @setchapternewpage odd @titlepage @title Gri @ifnottex @image{./examples/logo} @end ifnottex @subtitle A Program to Make Science Graphs @subtitle Version @value{GRI-VERSION} @subtitle 2015 @author Dan E. Kelley @page @vskip 0pt plus 1filll Copyright @copyright{} 1991-2015 Dan Kelley @sp 2 @end titlepage @dircategory Scientific Applications @direntry * Gri: (gri). Programming language for scientific illustration @end direntry @summarycontents @contents @node Top, Introduction, (dir), (dir) @comment node-name, next, previous, up @top Gri @c HTML @c HTML @c HTML Introduction @c HTML @c HTML @c HTML Introduction @c HTML @c HTML @c HTML @c HTML Gri Logo @c HTML Gri is an extensible @c HTML plotting language for producing scientific graphs, such as @c HTML x-y plots, @c HTML contour plots, and @c HTML image plots. @c HTML

    @c HTML This document describes Gri @value{GRI-VERSION}, @c HTML
    (c) 1991-2008 Dan Kelley. @comment HTML Gri is distributed @comment HTML with a license that permits @comment HTML sharing in an OpenSource way. @c HTML


    @c HTML New users: @c HTML To see if Gri might be useful to you, spend a few minutes @c HTML reading the @c HTML introduction, the @c HTML simple example tutorial, the @c HTML FAQ and the @c HTML @c HTML cookbook. @c HTML It is also a good idea to check out the real-world @c HTML examples. @c HTML Then you should return here to scan the table of contents. @c HTML

    @c HTML Experienced users: @c HTML To check the syntax of a command, consult @c HTML the list @c HTML of Gri commands. See @c HTML the history @c HTML to learn how Gri has changed over time. @c HTML

    @c HTML Open-Source Development: @c HTML Gri is distributed under an OpenSource licence (GPL). @c HTML To monitor (or contribute to) the development @c HTML process, visit @c HTML @c HTML gri.sourceforge.net. @c HTML

    @c HTML See also: @c HTML The @c HTML Gre language combines Gri features with Perl features. @c HTML
    @c HTML @c HTML @node Introduction, Simple Example, Top, Top @comment node-name, next, previous, up @chapter Introduction @strong{Gri is a programming language for drawing science-style graphs}. It is not mouse-driven, and it does not draw business-style graphs (e.g. pie charts, three-dimensional graphs). Gri has substantial power in advanced applications. It has been proven to be easy to learn; for simple applications, the learning curve is less than an hour. Many users regard Gri as the plotting equivalent of the La@TeX{} document preparation system. @strong{Computers Gri works on:} unix computers of many types, plus Microsoft Windows, and Macintosh OSX. You'll find Gri pre-packaged for various unixes, e.g. linux/debian, linux/redhat, and freeBSD. @strong{Capabilities of Gri} are those scientists commonly want, since Gri was written by a scientist. It is not so useful for business people -- e.g., Gri draws xy graphs (@ref{X-y Plots}), contour plots (@ref{Contour Plots}), and image plots (@ref{Images}), but it will not draw pie-charts unless you teach it how. The list of capabilities of Gri is similar to many packages, but unlike many of the other packages, Gri gives you control over line widths, fonts, grayscales, etc. (@ref{Getting More Control}), and it is a programming language of moderate power. @strong{The Gri drawing metaphor} is that of pen on paper. The ink in the pen is opaque. An item drawn in white ink will erase a previously drawn underlying object drawn in black ink. For example, to draw a timeseries curve in which the region between positive data values and the y=0 axis is filled with black ink, you might use (@code{draw curve filled}) to draw the timeseries with black ink (the default color), blackening the area between the curve and the lower axis. Then you could load white ink into the pen (using the @code{set graylevel 1} or @code{set graylevel white} command) and white-out a box drawn between the zero line and the lower axis. Then you'd load black ink back into the pen (@code{set graylevel 0}) and draw the curve again, so that the negative part would appear again. @strong{Input/output} in Gri may be interactive or non-interactive. For interactive use, type @code{gri} at the system commandline prompt. For non-interactive use, with Gri commands in a command-file called @file{cmd.gri}, type @code{gri cmd.gri}. @strong{Gri output} is in the PostScript page description language. The output is therefore of high quality, device-independent, capable of being inserted into popular text processors (e.g. LaTeX), and easily displayed. @strong{Online help:} the Gri command @code{help} makes Gri list the first words of all known commands, along with a hint for getting further help. To get more information, type @code{help} followed by a command-name (e.g. @code{help read}). There is also a tiny bit of information stored online and categorized by topic. Get this by typing for example @code{help - strings} (@ref{Online Help}). @strong{Data analysis} in Gri is limited. It has rudimentary data analysis functions, such as regression, column manipulation, smoothing, etc, but it is not intended as an integrated analysis/graphics package. @strong{System calls} are an easy and important facet of Gri. It is easy to use operating system commands within Gri (@ref{System}; @ref{Operating System}; @ref{Get Env}). This allows you to use familiar, powerful tools, and keeps Gri simple. Particularly useful is the ability to read files through operating system filters (@ref{Open}). @strong{Programming Gri} is quite straightforward, and users familiar with other programming languages find it easy. If Gri lacks a drawing method, you can add it fairly easily, since Gri has programming elements such as @code{if} statements (@ref{If Statements}), @code{while} loops (@ref{While}), facilities for interacting with the user (@ref{Query}), and mechanisms for storing numbers in "variables" (@ref{Variables}), and text strings in "synonyms" (@ref{Synonyms}). The Gri syntax can be augmented easily (@ref{Adding New Commands}), and these augmentations can be stored in a startup file (@ref{Resource File}), creating personalized versions of Gri. @cindex FTP site, cookbook @strong{Manuals:} Gri has an online texinfo manual, a PostScript manual, a WWW manual, a @c HTML cookbook @c HTML @cindex Gri newsgroup @cindex newsgroup and several reference cards. It also has several discussion groups (@ref{Discussion Group}). @strong{Version Numbering Scheme} @cindex gri version @cindex version numbers When you launch Gri interactively (without naming a commandfile, i.e. by just typing @code{gri} at the unix prompt), you'll see something like @example gri - scientific graphic program (version @value{GRI-VERSION}) GPL Copyright 2015 by Dan E. Kelley. Type `help' for an overview of Gri commands, or see the full manual at /usr/share/doc/gri-@value{GRI-VERSION}/html/index.html and its text-only version in the 'gri' INFO node. Visit http://gri.sourceforge.net for updates and resources. gri: @end example @noindent The last line is a prompt, suggesting that you type in Gri commands. You may type @code{quit} to get out of gri. The first line gives the version number. You can also get this by running Gri with the command @code{gri -v}. Version numbers have three numbers separated by periods. The first number increments for major changes, the second for smaller changes, the third for still smaller changes. The second number also indicates whether a copy is an experimental version or a more reliable release version. Experimental versions have the second digit being an odd integer, while release versions have this digit being even. @c HTML @node Simple Example, Invoking Gri, Introduction, Top @comment node-name, next, previous, up @chapter Simple Gri Program and How to Run it @cindex first-time usage @cindex hint, first-time usage @cindex beginners, simple example @cindex drawing x-y graphs, simple This chapter introduces Gri with a common example: an x-y graph. The example is discussed in detail later (@ref{X-y Plots}). The data files and command files here and throughout the manual should be available to you in a directory @file{.../gri/examples} on unix machines. @section Gri Command file @cindex example 01, linegraph using data in a separate file Here is a Gri command file to plot a linegraph of a set of (x,y) data, stored as space-separated columns in a file called @file{example1.dat}: @example # Example 1 -- Linegraph of data in separate file open example1.dat # Open the data file read columns x y # Read (x,y) columns draw curve # Draw data curve draw title "Example 1"# Title above plot @end example @noindent The first line is a comment, as are all things following hash symbols (@code{#}). (An exception to this rule is made within strings contained within the double-quote character @code{"}. This allows @code{sed} system commands to work as expected; (@ref{System}).) The other lines are Gri command lines; (@ref{X-y Plots}) for more explanation. @section Data File The data file @file{example1.dat} looks like: @example 0.05 12.5 # first point 0.25 19 # second point 0.5 15 # third point 0.75 15 # ... you get the idea! 0.95 13 @end example @noindent Note that spaces (or tabs) separate numbers. Any data line may have a comment on it, just as any command line may. @section Running The Command File Type @file{gri example1.gri} at the system prompt. Gri will create a PostScript file called @file{example1.ps}. For details on running Gri see @ref{Invoking Gri}. @section Output Graph The output PostScript file is called @file{example1.ps}. @c HTML @c HTML Example 1 @c HTML @c HTML Click the plot to enlarge it.) @c HTML

    @c HTML It looks something like the miniature shown above. @c BUG: pdftex ignores the size. @image{./examples/example1, 300pt} @cindex example 01, linegraph using data in a separate file To view Gri output, use your favorite PostScript previewer. Note that in the above example, Gri automatically chose reasonable scales for the axes, based on the range of the data. The next chapter illustrates that Gri also gives you control over such things. @c HTML @node Invoking Gri, Getting More Control, Simple Example, Top @comment node-name, next, previous, up @chapter Invoking Gri @section Invoking Gri in a nutshell First, the short story. In 90 percent of cases, Gri is run as @example gri myscript @end example where the file @file{myscript.gri} holds a script (list of Gri commands), and Gri will create a PostScript file called @file{myscript.ps} with the output. Some folks like to give the @file{.gri} suffix explicitly, so they would invoke Gri as @example gri myscript.gri @end example @noindent instead. If you'd rather not have @file{myscript.ps} as the PostScript output file name (let's say you prefer @file{graph1.ps}) you'd do @example gri -output graph1.ps myscript.gri @end example Few readers will need to know more than this. But, for the rest, the table in the next section gives full details on all the optional arguments that Gri can handle. @section Using Gri to draw things To draw things, invoke Gri as @example gri [OPTIONS] [CmdFile [optional_arguments]] @end example @cindex @code{[]} syntax for optional words in commands @cindex optional words in commands, @code{[]} syntax @noindent where the square brackets indicate that the enclosed items are optional. The @code{OPTIONS} item may consist of one or more of the following (explained below): @example [-batch] [-b] [-chatty N] [-c N] [-debug] [-d] [-directory_default] [-directory pathname] [-help] [-h] [-no_bounding_box] [-no_cmd_in_ps] [-no_startup_message] [-output PS_file_name|SVG_file_name] [-private] [-no_private] [-publication] [-p] [-superuser N] [-trace] [-t] [-yes] [-y] [-version] [-v] [-warn_offpage] [-no_warn_offpage] @end example @noindent @cindex colon on commandline @cindex commandline flag colon @cindex arguments on commandline, accessing @cindex commandline arguments, accessing @cindex @code{argv}, RPN operator to access commandline arguments @cindex @code{argc}, RPN operator to access commandline arguments Here, the optional @code{optional_arguments} are a mechanism to customize the action of the given Gri script from the commandline. After Gri processes standard arguments (e.g. @code{-t} for tracing), it puts the remaining commandline arguments into a list. This behavior is borrowed from C and othe languages, so Gri borrows the name of the list as well: it's called the "arg" list, and its elements are available with the RPN operators named @file{argc} (@ref{Solitary Operators}) and @file{argv} (@ref{Unary Operators}). For a note on usage within the Emacs gri-mode, see @ref{Filename arguments when running gri}. @strong{Details of command-line options} @cindex options on Gri command-line @cindex command-line options @itemize @bullet @item @code{-batch} or @code{-b} @cindex batch processing @cindex @code{-batch} command-line option Stops Gri from printing out prompts and hints. @item @code{-chatty N} or @code{-c N} @cindex @code{-chatty} command-line option Make Gri print out various informative messages. The numerical value gives a level of chattiness. A value of 1, the default if the @code{-chatty} code is not supplied, tells Gri to keep you informed of some important things, like the success in gridding data for contouring. Higher values make Gri tell you more: Information printed at various chatty levels: @itemize @bullet @item @strong{0} The bare minimum is printed. Thus invoking Gri as @code{gri -c 0}@dots{} will make it as quiet as can be. @item @strong{1 or higher} (the default) The full filenames of the commandfiles are displayed at startup time. @code{convert columns to grid} prints percentage of grid filled, as well as a suite of diagnostics, if you've let it calculate the region of influence automatically. It also prints a warning of the time it expects to take, before starting the calculation. @code{convert grid to image} prints characteristics of image created, including amount of image clipped. @code{read grid data} reports number of data values it could not read (since they were nonnumeric). @code{draw symbol} reports number of data points not drawn because they were missing or outside clip region (if one exists). @item @strong{2 or higher} @code{draw contour} prints value of contour being drawn. @code{open "...|"} prints the command to be passed to the operating system as well as the name of the temporary file being created; also notifies user when the temporary file is destroyed. @code{show image} reports histograms in intensity bands of 8 units, instead of the default 16 units. @item @strong{3 or higher} @code{show image} reports histograms in intensity bands of 4 units, instead of the default 16 units. @end itemize @item @code{-debug} or @code{-d} @cindex @code{-debug} command-line option @vindex @code{..debug..}, for debugging (by normal users) Sets the built-in variable flag @code{..debug..} that you can use to isolate blocks of code. @item @code{-directory_default} @cindex @code{-directory_default} command-line option Reports directory where @file{gri.cmd} is expected to be found, either in the default location or the one specified by @code{-directory} commandline option. @item @code{-directory pathname} @cindex @code{-directory} command-line option Specifies the directory where Gri looks for the startup file @file{gri.cmd}. (This file teaches Gri the standard commands; Gri will report an error and die if it cannot find this file.) If this switch is not provided -- and it is normally not -- then Gri looks for @file{gri.cmd} in a standard system directory (sometimes, but not always, @file{/usr/local/share/gri/@value{GRI-VERSION}}) which was specified during the compilation of the Gri program itself. For more on how Gri looks for @file{gri.cmd}, see the subsection below. @item @code{-no_bounding_box} @cindex postscript bounding box @cindex bounding box @cindex @code{-no_bounding_box} command-line option Make the so-called ``bounding box'' in the PostScript file be the full page. The bounding box is used by some PostScript previewers to clip the image to just the drawn parts of the page, and is used by the @code{epsfbox} macro in @code{latex} to automatically determine the geometry of the graph for inclusion in text. Normally the bounding box is calculated automatically, to enclose all the items drawn on the page. But the box may also be set with the @code{set bounding box} command (@ref{Set Bounding Box}). @item @code{-no_cmd_in_ps} @cindex -no_cmd_in_ps Prevent Gri from inserting the lines of the commandfile into the PostScript file as comments. (These comments can be used by the @code{-creator} commandline option (see above), but they take up a little bit of space and users might sometimes want to get rid of them.) @item @code{-no_warn_offpage} @cindex postscript bounding box @cindex bounding box @cindex @code{-no_warn_offpage} command-line option Do not warn if items are offpage. (Contrast this with @code{-warn_offpage}.) @item @code{-output PS_file_name} @cindex specifying the PostScript file name @cindex PostScript file name, specifying @cindex commandline option @code{-output PS_file_name} @cindex -output PS_file_name commandline option Specify the PostScript filename. If this is not specified, the PostScript filename is derived from the name of the commandfile (e.g. @file{mygraph.gri} produces @file{mygraph.ps}), or, for interactive use, it will have a name like @file{gri-00.ps}, or @file{gri-01.ps} if the former file exists, etc. @item @code{-output SVG_file_name} @cindex specifying the SVG file name @cindex SVG file name, specifying @cindex commandline option @code{-output SVG_file_name} @cindex -output SVG_file_name commandline option Specify the SVG filename. This is a pre-feature, as of version 2.12.x, meaning that SVG output is not working properly yet. If you specify an SVG file name, you will see a long list of warnings. These are debugging messages, and are not specific to your actual Gri script. For example, you will see warnings about centring strings, even if you are not centering any strings. This manual does not contain a list of working features (or broken features) for SVG output; the idea is that a discussion of such things be done using the bug-reporting system of the Gri website @ref{Reporting Bugs}. In addition to bugs, the author is interested in users' opinions on the scheme of the SVG, especially the hieararchy of groupings of graphical elements. It is because such things are being altered that this is designated a pre-feature. @item @code{-no_startup_message} @cindex startup message @cindex @code{-no_startup_message} command-line option Stops Gri from printing the startup message. @item @code{-private} @cindex @code{-private} command-line option @cindex private, command-line flag Prevents inserting any information about the user into the PostScript file (see @code{-no_private}, next). As of version 2.12.10, this privacy option is assumed by default. @item @code{-no_private} @cindex @code{-no_private} command-line option @cindex no_private, command-line flag Instructs Gri to include comments in the PostScript file that identify the user, state the commandline arguments used in invoking Gri, and that list all the commands that were executed. This information can be recovered by calling Gri on the PostScript file, with the @code{-creator} commandline argument. Until version 2.12.10, the default was to include this information, but a change was made out of privacy concerns. @item @code{-publication} or @code{-p} @cindex @code{-publication} command-line option @cindex publication quality, command-line flag Sets the built-in variable @code{..publication..} to 1. You may use this to distinguish between working plots and publication plots, as in this example: @example if !..publication.. draw time stamp draw title "working version of plot" end if @end example @item @code{-superuser} @cindex @code{-superuser} command-line option @vindex @code{..superuser..}, for debugging (by developers) (This option is included here only for completeness. It should only be used by developers (who will alter the code to print debugging information if @code{-superuser} is set in addition to @code{-debug}). An optional value can be inserted (e.g. @code{-superuser 2}) to set the debugging level (retrievable by the function superuser()) to indicated integer value. Specifying the @code{-superuser} command-line option sets the built-in variable @code{..superuser..} to 1 or the specified value.) For flag meanings, see @code{superuser} command (@ref{Superuser}). Using the question-mark symbol @code{?} instead of a flag number makes Gri print out the list of flags. @item @code{-trace} or @code{-t} @cindex @code{-trace} command-line option @cindex tracing execution, command-line option Makes Gri print out command lines as they are executed; this has the same effect as the @code{set trace} command. @item @code{-version} or @code{-v} @cindex @code{-version} command-line option Display version information and exit successfully. @item @code{-warn_offpage} @cindex command-line option @code{-warn_offpage} @cindex @code{-warn_offpage} command-line option Causes warnings to be issued for all items drawn far off a 8.5x11 inch page. This is the default. (Contrast with @code{-no_warn_offpage}.) @item @code{-yes} or @code{-y} @cindex @code{-yes} command-line option @vindex @code{..use_default_for_query..}, simulate @code{-yes} commandline flag @cindex interaction with user, @code{-y} command-line option Bypasses all @code{query} commands, making Gri act as though the user typed a carriage-return (thus giving the default) for each @code{query}. @item @code{-help} or @code{-h} @cindex @code{-help} command-line option Prints explanation of options. @item @code{CommandFile} @cindex @code{\\.path_commands.} builtin synonym @cindex builtin synonym @code{\\.path_commands.} @cindex @code{CommandFile} command-line option @cindex command files @cindex files, Command-file @cindex command-line, specifying command file If a command file @code{CommandFile} is specified, then commands will be read from that file instead of the keyboard. If the @code{chatty} level is 1 or larger, Gri prints the names of the commandfiles at startup time. It is conventional but not necessary that the filename ends in @code{.gri}. If the filename does end in @code{.gri}, you may delete this suffix; Gri will assume it as implied. @end itemize @strong{Executable scripts.} If you don't need to supply commandline options, you can put the following line as the first line in your Gri program @example #!/usr/bin/gri @end example @noindent (or point to wherever Gri is located on your machine), and @code{chmod +x} the file. Then you can run Gri simply by naming the file. There is no particular advantage in this, except for saving the typing of a few characters, but some folks like this. @cindex @file{gri.cmd}, how it is located @strong{How Gri locates the} @file{gri.cmd} @strong{file}. In a normal installation, Gri finds the @file{gri.cmd} file all by itself. However, developers and some others may wish to control where Gri looks for this file. The rules below specify how Gri looks for @file{gri.cmd}. @table @emph @item Case 1 If @code{-directory} was given on the commandline used to invoke Gri (e.g. @code{gri -directory /some/place mycommand_file.gri}), then Gri will use the @file{gri.cmd} in the named directory. An error will result if @file{gri.cmd} is not found there. @item Case 2 If @code{-directory} was not given on the commandline, then Gri looks for @file{gri.cmd} in a location that was specified during compilation. If @file{gri.cmd} is found there, then it is used. If it is not found, then Gri checks to see if an environment variable named @code{GRI_DIRECTORY_LIBRARY} is defined. If so, then Gri takes this to be the name of a directory that contains the @file{gri.cmd} file. If @file{gri.cmd} is not found there, an error results. @end table @section Extracting commandfile from a PostScript file @cindex recovering commands from a PostScript file @cindex command-line option @code{-creator} @cindex @code{-creator} command-line option @example gri -creator PostScriptFile @end example @noindent @strong{See also} @code{-no_cmd_in_ps}. The @code{-creator} flag makes gri examine the indicate PostScript file, and produce a facsimile of the command file (or interactively-typed commands) that created this PostScript file. (This only works if the Gri command that created the PostScript file used the @code{-no_private} commandline argument.) @c REMOVED_AFTER_2_8_x @section Fixing a broken PostScript file @c REMOVED_AFTER_2_8_x To make Gri repair a PostScript file created by a Gri job that failed @c REMOVED_AFTER_2_8_x midway through: @c REMOVED_AFTER_2_8_x @c REMOVED_AFTER_2_8_x @example @c REMOVED_AFTER_2_8_x gri -repair bad.ps good.ps @c REMOVED_AFTER_2_8_x @end example @c REMOVED_AFTER_2_8_x @c REMOVED_AFTER_2_8_x This may very well not work, and the author only provides it in case it @c REMOVED_AFTER_2_8_x may help you. Essentially all it does it try to complete a so-called @c REMOVED_AFTER_2_8_x PostScript "path", if Gri died in the middle of drawing a path. Please @c REMOVED_AFTER_2_8_x don't expect too much from this command, and don't expect bug fixes to @c REMOVED_AFTER_2_8_x it. @c HTML @node Getting More Control, Simple Example Revisited, Invoking Gri, Top @comment node-name, next, previous, up @chapter Controlling Axes, Fonts, Colors, etc Gri provides a great many things that you can control, if you want to. An introduction to some of these things is presented in the sections below. @menu * Simple Example Revisited:: Adding more details * Axis Scaling:: Gri automatically scales and draws axes * Log And Linear:: Selecting log/linar axes * Length:: Adjusting axis length * Range:: Adjusting axis range * Labels:: Adjusting labels on axes * Position:: Positioning the axes * Fonts:: Setting fonts * Pen Color:: Controlling Pen color @end menu @c HTML @node Simple Example Revisited, Axis Scaling, Getting More Control, Getting More Control @section An example @cindex scales @cindex axes, scales @cindex font, selecting Below is a followup to the previous example, which names the x and the y axes. @example # Fancier version of Example 1 open example1.dat read columns x y set x name "Time, hours" set y name "U, m/s" draw curve @end example The difference is that the x and y axes are named with a @code{set} command. There are many @code{set} commands, and they are all pretty simple, e.g. @code{set x size 15} makes the x-axis be 15 centimeters long, instead of the default of 10 centimeters. Indeed, you can control anything you want in gri, e.g. graph size, line width, fonts, etc etc. Speaking of fonts, the @code{$\alpha$} type of latex formatting of Greek letters is supported in a limited way. Also, Gri handles ISO-Latin-1 encodings as well as the U.S. style. The example below illustrates a few more @code{set} commands. This example is intentionally complicated, being about a good example of the level of complexity of many plots made by Gri. Read the comments to see what is being done, and consult the plot as you read the commandfile. @cindex multiple panels @cindex example 03 (controlling scales, etc) @c HTML @c HTML Example 3 @c HTML @c HTML The command-file.

    @image{./examples/example3, 300pt} @cindex example 03, controlling scales, etc @c HTML @c HTML @node Axis Scaling, Log And Linear, Simple Example Revisited, Getting More Control @comment node-name, next, previous, up @section Axis scaling @cindex axes, and mathematical operations on columns @cindex axes, autoscaling of @vindex @code{..xlast..}, last drawn x value @vindex @code{..ylast..}, last drawn y value @vindex @code{..xmargin..}, left margin @vindex @code{..ymargin..}, bottom margin @vindex @code{..xsize..}, x-axis length @vindex @code{..ysize..}, y-axis length @vindex @code{..xleft..}, x value at left of plot @vindex @code{..xright..}, x value at right of plot @vindex @code{..xinc..}, x increment on axes @vindex @code{..ybottom..}, y value at bottom of plot @vindex @code{..ytop..}, y value at top of plot @vindex @code{..yinc..}, y increment on axes Gri normally assumes that you are plotting scientific graphs, and therefore whenever it sees a command like @code{draw curve} or @code{draw symbol}, it draws an appropriate axis first. You can turn this feature off, by using @code{draw axes none} before the other @code{draw} command. Furthermore, Gri picks axis scales by itself, by scanning the (@code{x}, @code{y}) columns. If you don't like the scales Gri picks, you can override them (@ref{Range}). Gri normally draws axes labelled at left and bottom, and with an axis frame with tics all around. If you don't like this default axis style you can specify other styles. For example, if the commands @code{draw x axis} and @code{draw y axis} are placed before the @code{draw curve} command, Gri will realize you've already specified axes, and just draw them on the left and bottom sides of the box, without completing the axis frame. For your general use, Gri stores the minimum and maximum x and y values of the @strong{axes} in the variables @code{..xleft..}, @code{..xright..}, @code{..ybottom..}, and @code{..ytop..}. It also stores the increments used in labelling these axes in the @code{..xinc..} and @code{..yinc..} variables. To determine the minimum and maximum values of column data, you may use the built-in RPN functions @code{min}, @code{max}, and @code{mean} (@ref{Manipulation of Columns etc}). Gri stores the last (x,y) pair on a curve (whether data or axis) in the @code{..xlast..} and @code{..ylast..} variables Gri stores the axis sizes in @code{..xsize..} and @code{..ysize..}. It stores the space to the left of the plot in @code{..xmargin..} and the space below the plot in @code{..ymargin..}. @c HTML @node Log And Linear, Length, Axis Scaling, Getting More Control @comment node-name, next, previous, up @section Logarithmic and linear axes @cindex logarithmic axes @cindex axes, logarithmic @cindex linear axes @cindex axes, linear Axes are linear by default; to make logarithmic axes, use commands @code{set x type log} and @code{set y type log}. @c HTML @node Length, Range, Log And Linear, Getting More Control @comment node-name, next, previous, up @section Axis Length @cindex axes, guide to choosing length of @cindex length of axes, guide on choosing @cindex data files, protecting against movement of The axes are normally 10 centimetres long. To set the axis lengths (in centimetres), use commands like @code{set x size 5} and @code{set y size 7}. Some people like the ratio of axes to be in the so-called golden ratio @code{(root(5)-1)/2}; to get that, you could do this: @cindex axis sizes, scaled with golden ratio @cindex golden ratio, used for axes sizes @example set x size 15 set y size @{rpn ..xsize.. 5 0.5 power 1 - 2 / *@} @end example @cindex scaling for maps @cindex maps, scaling For maps, you'll want the plot scaled so that shapes retain their aspect ratio. To do this, do @code{set x size .cm.} and then do @code{resize y for maps} (or vice versa). @c HTML @node Range, Labels, Length, Getting More Control @comment node-name, next, previous, up @section Axis Range @cindex axes, range of values on @cindex range of axes To override axis ranges set by Gri, use @code{set x axis} and @code{set y axis}. With these commands, you specify the range of the axes; you may also set the interval for numbered tics, and an interval for unnumbered tics. The unnumbered tics must be at an interval that divides evenly into the numbered tic interval, but the numbered tic interval need not divide into the min/max range. Thus, @code{set x axis 0 1.1 0.5} will create an axis that will range from 0 to 1.1, with labelled tics at the values 0, 0.5 and 1. @c HTML @node Labels, Position, Range, Getting More Control @comment node-name, next, previous, up @section Axis Name @cindex labels, on axes @cindex axes, labels for To set the name of the x axis, use @code{set x name "string"}, and similarly for the y-axis. The default names are @code{x} and @code{y}. @c HTML @node Position, Fonts, Labels, Getting More Control @comment node-name, next, previous, up @section Axis location @cindex axes, location of @cindex positioning axes If you don't like the default position of axes (at left and bottom), you may get Gri to draw axes anywhere you like, using commands like @code{draw y axis at right} (so the y axis is at the right-hand end of the x range) or @code{draw x axis at top} (so the x axis is at the top of the plot); you may even specify an exact location, such as @code{draw x axis at 22.2}. Normally, the x axis is placed at the bottom end of the y axis, and the y axis is placed at the left end of the x axis. Some people prefer a style in which the axes are positioned a small offset away from these locations. To get this effect, you may either position the axes yourself, or simply use the @code{set axes style offset} command (@ref{Set}). If you want this axis style for all their plots, put the line @code{set axes style offset} in your @file{~/.grirc} startup file (@ref{Resource File}). @c HTML @node Fonts, Pen Color, Position, Getting More Control @comment node-name, next, previous, up @section Fonts Fonts are selected with @code{set font to} (@ref{Set Font To}) and font sizes are selected with @code{set font size} (@ref{Set Font Size}). Much more about text, including how to draw mathematical symbols, how to use subscripts and superscipts, how to write non-English (accented) European text, etc, is discussed (@ref{Text}). @c HTML @node Pen Color, X-y Plots, Fonts, Getting More Control @comment node-name, next, previous, up @section Colour of ink in pen @cindex graylevel, explanation @cindex lines, gray, explanation The darkness of the ``pen'' used in drawing commands (for either lines or for text) is set by @code{set graylevel .brightness.}. A brightness value of 0 corresponds to black ink, and a brightness value of 1 corresponds to white ink. Values outside this range are clipped to the nearer endpoint. Values inside this range choose a proportional graylevel in between; for example, @code{set graylevel 0.5} gives a 50 percent gray tone. The graylevel applies to text as well as lines. Often you'll want to draw a gray line and a black label beside it, or you'll want to set a graylevel temporarily. Here's how to do it: @example # Save old graylevl, set, then reset to old .old_gray. = ..graylevel.. set graylevel 0.5 draw curve set graylevel 0 draw label for last curve "TEST" set graylevel .old_gray. @end example The color of the "pen" may be set to any value you can describe with an RGB (red, green, blue) or HSB (hue, saturation, brightness) specification, or a color name. This pen color applies to everything, even text. @noindent @b{The} @code{set color \name} @b{command} Set the pen color to the indicated name. There are two types of names: hexadecimal-triplet names and English names. @anchor{pen-color-hexadecimal} Hexadecimal-triplet names are of a form often used in web-pages. They consist of exactly 6 characters, which are divided by Gri into three sets of two characters, specifying the red component, the green component, and the blue component of the color, respectively. These components are in hexadecimal notation, i.e. ranging from 00 to FF, indicating values from 0 to 255. For example, @example set color ACD4EF @end example @noindent sets a pastel blue color, almost the color of a robin's egg. The English colors are written simply in the form @example set color blue @end example @noindent where the color is from the following list. (Gri requires that you use the exact form shown, including the capitilization.) The color mixes are identical to those used in X11. @cindex builtin colors, list of @cindex colors, list of @example NAME RED GREEN BLUE "white" 1.000 1.000 1.000 "LightGray" 0.827 0.827 0.827 "darkslategray" 0.184 0.310 0.310 "black" 0.000 0.000 0.000 "red" 1.000 0.000 0.000 "brown" 0.647 0.165 0.165 "tan" 0.824 0.706 0.549 "orange" 1.000 0.647 0.000 "yellow" 1.000 1.000 0.000 "green" 0.000 1.000 0.000 "ForestGreen" 0.133 0.545 0.133 "cyan" 0.000 1.000 1.000 "blue" 0.000 0.000 1.000 "skyblue" 0.529 0.808 0.922 "magenta" 1.000 0.000 1.000 @end example @noindent To get more colors than those provided in the above list, use the @code{read colornames} command. You should do a test case for your printer to see which colors you find most to your liking. You'll want to pick colors that look different from each other. In some cases you might want to avoid dithered colors, since they look too broken on really thin lines. For example, on my printer I like the following colors: @code{black}, @code{red}, @code{yellow}, @code{green}, @code{cyan}, and @code{magenta}. @noindent @b{The} @code{set color rgb .red. .green. .blue.} @b{command} This command sets the color using the red-green-blue color model. If you are familiar with how colors add (e.g. red plus green yields yellow), then you might like this, but most people find it easier to use the @code{set color hsb ...} style described below. Set the individual color components as follows. The numbers @code{.red.}, @code{.green.} and @code{.blue.} range from 0 (for no contribution of that color component to the final color) to 1 (for maximal contribution). Values less than 0 are clipped to 0; values greater than 1 are clipped to 1. EXAMPLES: @example set color rgb 0 0 0 # black set color rgb 1 1 1 # white set color rgb 1 0 0 # bright red set color rgb 0.5 0 0 # dark red set color rgb 0 1 0 # pure green set color rgb 1 1 0 # yellow: red + green @end example @noindent @b{The} @code{set color hsb .hue. .saturation. .brightness.} @b{command} In this color model, the color ("hue") is specified with a single parameter. Many people find this easier than using the corresponding @code{rgb} command. @cindex hint, color palette range Set the individual color components as follows. The numbers @code{.hue.}, @code{.saturation.} and @code{.brightness.} range from 0 to 1. The color, represented by @code{.hue.}, ranges from 0 for pure red, through 1/3 for pure green, and 2/3 for pure blue, and back to 1 again for pure red. (HINT: It is a good idea to limit the total range of hue you use to 2/3, instead of 1; otherwise you'll get confused by (nearly) repeated colors at the crossover. For example, limit the hue to range from 1/3 to 1, or 0 to 2/3.) The purity of the color, represented by @code{.saturation.}, ranges from 0 (none of the hue is visible) to 1 (the maximal amount is present). Less saturated colours are like those you would get from mixing black paint into colored paint. The brightness of the color, represented by @code{.brightness.}, ranges from 0 (black) to 1 (maximal brightness). Lowering brightness is like decreasing the intensity of the light you shine on a painting. Hue, saturation, and brightness values are all clipped to the range 0 to 1. EXAMPLES: @example set color hsb 0 1 1 # pure, bright red set color hsb 0 1 0.5 # half black, half red set color hsb .333 1 1 # pure, bright green @end example @c HTML @node X-y Plots, Linegraphs, Pen Color, Top @comment node-name, next, previous, up @chapter X-Y Plots @menu * Linegraphs:: x-y graphs with data connected by line segments * Scattergraphs:: x-y graphs with data indicated by symbols * Formula Plots:: @end menu @node Linegraphs, Scattergraphs, X-y Plots, X-y Plots @comment node-name, next, previous, up @section Linegraphs The following Gri commands will draw a linegraph. For the output graph (@ref{Getting More Control}). @cindex linegraphs @cindex x-y graphs @cindex drawing linegraphs @cindex example 01, linegraph using data in a separate file This plots a simple linegraph: @c HTML @c HTML Example 1 @c HTML @example # Example 1 -- Linegraph using data in a separate file open example1.dat # Open the data file read columns x y # Read (x,y) columns draw curve # Draw data curve draw title "Example 1" # Title above plot @end example Here's what the command lines mean: @itemize @bullet @item The first line is a comment. Anything to the right of a hash-mark @code{#} is considered to be a comment. (This symbol is also called a "pound".) @cindex comments, @code{#} style @item The second line is blank. Gri ignores blank lines between commands. @item @code{open example1.dat} tells Gri to open the indicated file (in the current directory) as an input data file. You can specify files outside the current directory by using conventional unix-shell pathnames (e.g., @code{open ~/data/TS/section1/T_S.dat} or @code{open ../data/file.dat}). You can even use "synonyms" (@ref{Synonyms}.) in filenames, as in @code{open \BASENAME.dat}. @item @code{read columns x y} tells Gri to start reading columnar data, the first column being @code{x}, the second @code{y}. @code{x} and @code{y} are predefined names for whatever ends up on the horizontal and vertical axes. @cindex reading columns of data @cindex format for columnar data @cindex data format @cindex multiple datasets in one file The number of data needn't be specified. Gri reads columns until a blank line or end-of-file is found. You can tell Gri how many lines to read with a command like @code{read columns 10 x y}. Multiple datasets can reside within one file; provided that they are separated by a single blank line, Gri can access them by multiple @code{read} commands. Like C, Gri expects numbers to be separated by one or more spaces or tabs. Commas are not allowed. If the columns were reversed, the command would be @code{read columns y x}. If there were an initial column of extraneous data, the command would be @code{read columns * x y}, or @code{read columns x=2 y=3} (@ref{Read Columns}). @item @code{draw curve} tells Gri to draw a curve connecting the points in the @code{x} and @code{y} columns. A nice scale will be selected automatically. (You can change this or any other plot characteristics easily, as you'll see later.) @cindex drawing data lines @item @code{draw title} tells Gri to write the indicated string centered above the plot. The title @strong{must} be enclosed in quotes. @cindex titles, drawing above plot @cindex drawing titles @item @code{quit} tells Gri to exit. @end itemize Gri will draw axes automatically, and pick its own scales. If you wish to draw several curves which cross each other, you should try using @code{draw curve overlying} instead of @code{draw curve}. This will make it easier to distinguish the different curves. @node Scattergraphs, Formula Plots, Linegraphs, X-y Plots @comment node-name, next, previous, up @section Scattergraphs @cindex scattergraphs This section contains two examples, the first being a fuller explanation of all the bells and whistles, the second being a simple explanation of how to get a very quick plot, given just a file containing a matrix of grid data. To get a scattergraph with symbols at the data points, substitute @code{draw symbol} for @code{draw curve}. Both symbols and a curve result if both @code{draw curve} and @code{draw symbols} are used. See @ref{Getting More Control} for an example. By default, the symbol used is an x. To get another symbol, use a command like @code{draw symbol 0} or @code{draw symbol plus}. To change the symbol size from the default of 0.2 cm use commands like @code{set symbol size 0.1} to set to 1 mm (@ref{Set Symbol Size}). @subsection Coding data with symbols @cindex symbols To get different symbols for different data points, insert symbol codes from the above list as a column along with the x-y data, and substitute the command @code{read columns x y z}, and then draw them with @code{draw symbol}. Gri will interpret the rounded-integer values of the @code{z} columns as symbol codes. Note that even if you've read in a z column which you intend to represent symbols, it will be overridden if you designate a specific symbol in your @code{draw symbols} command; thus @code{draw symbol 0} puts a @code{+} at the data points whether or not you've read in a symbol column. @subsection Drawing a symbol legend @cindex legend for symbol @cindex symbol legend The following example shows how you might write a symbol legend for a plot. The legend is drawn 1 cm to the right of the right-hand side of the axes, with the bottom of the legend one quarter of the way up the plot; @ref{Draw Symbol Legend}. The lines in the legend are double-spaced vertically. To change the location of the legend, alter the @code{.legend_x. =} and @code{.legend_y. =} lines. To change the spacing, alter the @code{.legend_y. +=} line. @example set x axis -1 5 1 set y axis -1 5 1 read columns x y z 0 0 0 1 1 1 2 2 2 3 3 3 draw symbol # Legend .leg_x. = @{rpn ..xmargin.. ..xsize.. + 1 +@} .leg_y. = @{rpn ..ymargin.. ..ysize.. 4 / +@} draw symbol legend 0 "Foo" at .leg_x. .leg_y. cm .leg_y. += @{rpn "M" ascent 2 *@} draw symbol legend 1 "Bar" at .leg_x. .leg_y. cm .leg_y. += @{rpn "M" ascent 2 *@} @end example @subsection Coding data with symbol colors @cindex color, symbols @cindex symbols in color To get different colors for different symbols, read a color code into the z column, and do for example @code{draw symbol bullet color hue z}. The numerical color code ranges from 0 (red) through to 1, passing through green at 1/3 and blue at 2/3. @node Formula Plots, Contour Plots, Scattergraphs, X-y Plots @comment node-name, next, previous, up @section Formula Plots @cindex functions, how to plot @cindex formulae, how to plot There are two methods for formula graphs. @enumerate @item @strong{Use the system yourself.} Do as in this example: @example open "awk 'BEGIN@{for(i=0;i<3.141;i+=0.05)\ @{print(i,cos(i))@}@}' |" read columns x y close draw curve @end example @noindent @item @strong{Let Gri calculate things for you} The simplest is to let Gri calculate things for you with the @code{create columns from function} command (@ref{Create}). The command assumes that you have defined the synonym called @code{\function} which defines @code{y} in terms of @code{x}. Gri uses the program @code{awk} to create the columns, and cannot work without it. Here is an example of using @code{create columns from function}: @example show "First 2 terms of perturbation expansion" set y axis name horizontal set y name "sea-level" set x name "$\omega$t" \b = "0.4" # perturbation parameter b=dH/H \xmin = "0" \xmax = "6.28" \xinc = "3.14 / 20" \function = "cos(x)" set x axis \xmin \xmax create columns from function draw curve draw title "SOLID LINE \function" \function = "(cos(x)+\b/2*(1-cos(2*x)))" create columns from function set dash 1 draw curve draw title "DASHED LINE \function" draw title "b = \b" @end example Here's another example, in which the curve @code{y = 1/(\int + \sl*x)} is drawn through some data. Note how @code{sprintf} is used to set @code{\xmin} and @code{\xmax} using the scales that Gri has determined in reading the data. @example open file.data read columns x y close draw symbol bullet \int = "-0.1235" \sl = "0.003685" sprintf \xmin "%f" ..xleft.. sprintf \xmax "%f" ..xright.. \function = "1/(\int + x * \sl)" create columns from function draw curve @end example @end enumerate @c HTML @node Contour Plots, Pre-gridded Data, Formula Plots, Top @comment node-name, next, previous, up @chapter Contour Plots @cindex contours Contour plots can be done with either pregridded data or randomly distributed (ie, ungridded) data. @menu * Pre-gridded Data:: Contouring f(x1, y1, x2, y2, ...) * Ungridded Data:: Contouring f(x, y) where (x,y) are not on a grid @end menu @node Pre-gridded Data, Ungridded Data, Contour Plots, Contour Plots @comment node-name, next, previous, up @section Pre-gridded Data @cindex contours, pre-gridded data This section presents two examples of contouring pre-gridded data, the first example illustrating a boilerplate program to contour data stored in a simple matrix form in a file, the second example illustrating a case with more control of the details (e.g., a nonuniform grid). @subsection Simple example This example was hardwired to know the size of the grid, etc. Here's an example which is more general, in that it determines the dimensions of the grid data from using unix system commands. Note that the grid is set to run from 0 to 1 in both x and y; you'll most likely want to change that after you see the initial plot, but this should get you started. @cindex grid data, determining geometry from file @cindex image data, determining geometry from file @example \file = "somefile.dat" \rows = system wc \file | awk '@{print $1@}' \cols = system head -1 \file | awk '@{print NF@}' set x grid 0 1 /\cols set y grid 0 1 /\rows open \file read grid data \rows \cols close draw contour @end example @subsection Complicated example To get a simple contour graph based on pre-gridded data, with full control of axes, etc, do something like this: @cindex drawing contours of pregridded data @cindex example 04 (contouring pregridded data) @c HTML @c HTML Example 4 @c HTML @c HTML The command-file.

    @image{./examples/example4, 300pt} @c HTML Here several new things have been introduced. First, you've got to define a grid in xy space. This example uses a non-uniform x-grid, and reads it in from the commandfile. In this form, the blank line is essential; it tells Gri that the end of data has been located; if you like, you can specify the number of lines to read, as in @code{read grid x 3}. The y-grid for this example is uniform, however, so it may be specified with the @code{set y grid} command. It obtains values (10, 12.5, 15, 17.5, 20). The @code{set x|y grid} commands accept negative increments. Furthermore, it is possible to specify the number of steps, rather than the increment size, by putting @code{/} before the third number; thus @code{set x grid 0 1 /5} and @code{set x grid 0 1 0.2} are equivalent. Having defined a grid, it is time to read in the gridded data. Here this is done with the @code{read grid data} command. Since Gri already knows the grid dimensions, it will read the data appropriately. You could also have told it (@code{read grid data 3 5}). The first dataline is the top of the y-grid. In other words, the data appear in the file just as they would on the graph, assuming that the x-grid and y-grid both increase. Sometimes you want to read in the transpose of a matrix. Gri lets you do that. If the @code{bycolumns} keyword is present at the end of the @code{read grid} command, the first dataline will contain the first @strong{column}, of the data. If you have an extraneous column of data to the left of your data matrix, do @code{read grid data * 2 3} Now Gri has the grid in its head. We tell it to draw some contours with the @code{draw contour} command. As the comments in the example show, the contour values will be selected automatically, but you can alter that. @node Ungridded Data, Images, Pre-gridded Data, Contour Plots @comment node-name, next, previous, up @section Ungridded data @cindex contours, ungridded data @cindex gridding data, advice on methods When you have f=f(x,y) points at random x and y, you must cast them onto a grid to contour them. This is a difficult problem. There are many ways to grid data, and all have both good and bad features. You should try various methods, and various settings of the parameters of the methods. If you have a favorite gridding method that you prefer, you should probably pre-grid the data yourself. If not, Gri can do it for you. Gri has two methods for doing this, the ``boxcar'' method and the ``objective analysis'' method. Each method puts holes in the grid wherever there are too few data to map to grid points, unless you specifically ask to fill in the whole grid. The next two sections show first an example, then a discussion of the methods and how to use them. @subsection Example @cindex drawing contours of ungridded data @cindex Barnes method for gridding data This example uses data taken from Figure 5 of S. E. Koch and M. DesJardins and P. J. Kocin, 1983. ``An interactive Barnes objective map anlaysis scheme for use with satellite and conventional data,'', J. Climate Appl. Met., vol 22, p. 1487-1503. Readers should compare Figures 5 and 6 of that paper to the results shown here. @c HTML @c HTML Example 5 @c HTML @c HTML The command-file.

    @image{./examples/example5} @cindex example 05 - Contouring ungridded data, from figure @c HTML @subsection Discussion of Methods The various commands for converting columns to a grid are given in (@ref{Convert Columns To Grid}). Generally, the Barnes method is best. @c HTML @node Images, Reading and Creating Image Data, Ungridded Data, Top @comment node-name, next, previous, up @chapter Image Plots @cindex image plots, general Gri can read in images stored in various formats. It can also create image data internally, by converting gridded data, which is quite handy in some contouring applications. @cindex American Geophysical Union, recommended image gray levels Note: if your diagram is to be reproduced by a journal, it is unlikely that the reproduction will be able to distinguish between any two graylevels which differ by less than 0.2. Also, graylevels less than 0.2 may appear as pure black, while those of 0.8 or more may appear as pure white. These guidelines are as specified by American Geophysical Union (publishers of J. Geophysical Res.), as of 1998. @menu * Reading and Creating Image Data:: Reading image, and creating from grid data * Image PostScript Output:: How the image is embedded in the PostScript * Example Image:: How to plot a satellite image @end menu @node Reading and Creating Image Data, Image PostScript Output, Images, Images @comment node-name, next, previous, up @section Reading and Creating Image Data @cindex converting grids to images @cindex grid, converting to image @cindex data, images @cindex image, data format Gri can do black and white image plots, such as satellite images. There are several ways to create image data in Gri @itemize @bullet @item Create images from gridded data using @code{convert grid to image}. For examples see @ref{Grayscale Images}), @ref{Combination}, and @ref{Contouring}. @item Read raw ascii image data files. Use @code{read grid}. @item Read PGM (portable graymap) ascii files. (That is, a file with magic characters @code{P1} or @code{P3} at the start.) Use the @code{read image pgm} command, for a file opened in ascii mode with @code{open filename}. @item Read raw binary data, with or without headers. Use @code{read image}, after skipping any header bytes using the @code{skip} command, for a file opened in binary mode with @code{open filename binary}. @item Read a Sun ``rasterfile'' file (but only in uncompressed form). Use @code{read image rasterfile} for a file opened in binary mode with @code{open filename binary}. @item Read a PGM (portable graymap) binary file. (A file with magic characters @code{P2} or @code{P4} at the start.) Use the @code{read image pgm} for a file opened in binary mode with @code{open filename binary}. @item Aside: Images can be converted to grids (for contouring) using @code{convert image to grid} (@ref{Convert}). @end itemize Once the image is created, its grayscale/colorscale may be manipulated with the commands @code{set image grayscale} and @code{set image colorscale}, which permit linear and histogram-equalized blendings over the grayscale or color range, or with @code{read image grayscale} and @code{read image colorscale}, which permit reading in the grayscale or color values individually, one for each of the 256 pixel values. It is important to understand the structure of image data. Gri works only with 8-bit image data. This means that a given pixel of the image may have only one of 256 possible values. The example below uses a satellite image of surface temperature. The suppliers of the data dictate that pixel value 0 corresponds to a temperature of 5C, and a pixel value of 255 corresponds to 30.5C, so the resolution is 0.1C per pixel value. This resolution will be apparent if the output of the example below is previewed on a grayscale/color monitor --- notice the quantization in the palette. This resolution issue is not very important with satellite images, since you have to use what you are given by the suppliers of the data. However, the issue is very important when you are converting grid data to images. When Gri converts grid data to image data, it neccessarily discards information, because the grid data have resolution to about 6 digits, whereas the image data have only 8-bit (2-3 digit) resolution. The @code{set image range} commands determines the range of this 8-bit resolution in terms of user units. All other things being equal, it would be preferable to use the smallest range consistent with the range of your data. If your grid data ranged from 0 to 1, say, you might @code{set image range 0 1}. This would give a resolution in the image of 1/255 in the user units. But, when Gri converts the grid into an image, it will @strong{clip} all data outside the indicated range. In this case, any data greater than 1 in the grid would translate to @strong{exactly} 1 in the image. Naturally there is a tradeoff between having a range large enough to encompass any data in the grid, and a range small enough to yield adequate resolution. In most cases, 8-bit resolution will be adequate, but it is good to be aware of the limitations. One should always @code{draw image palette}, and check it on a color monitor for bandedness, which is a sign of resolution problems. @node Image PostScript Output, Example Image, Reading and Creating Image Data, Images @comment node-name, next, previous, up @section About The PostScript Output @cindex image, PostScript output @cindex postscript output, embedded images Programmers Note: Gri inserts some special comments in the PostScript file, to help programmers extract the image data; to extract the information, you'll have to understand how PostScript handles images. Gri inserts a single comment line before a line ending in the token @code{im}: @example %BEGIN_IMAGE 170.70 170.70 534.86 534.86 128 128 im @end example @noindent The first four numbers are the (x,y) locations of the lower-left and upper-right corners of the image, in units of points on the page (72 points = 1 inch). The fifth and sixth numbers are the width of the image and the height of the image. The keyword @code{im} is always present on this line. Gri inserts the following comment line at the end of the image data @example %END_IMAGE @end example @node Example Image, Examples, Image PostScript Output, Images @comment node-name, next, previous, up @section Example (Satellite image) @cindex satellite images Here's an example that will plot different types of images, depending on your answers to @code{query} questions. The file called @file{\filename} is the data file, in binary format with one byte (@code{unsigned char} in C) for each pixel, stored with the northwest pixel first, and the pixel to the east of that next. The file called @code{\mask} is in the same format, and the numbers are 0 if the point is over the sea and 1 if over land. The mask file is used in computing the histograms, which is done if @code{\histo} is 1. The file in this example covers 128 * 128 pixels over the Gulf of Maine. The numbers in @code{\filename} correspond to surface temperatures according to the equation @example T = 5 + 0.1 * pixel_value @end example @noindent which explains the following lines in the command file: @example \0val = "5" # 0 in image \255val = "30.5" # 255 in image @end example @cindex images, histogram scaling @cindex images, linear scaling Depending on @code{\histo}, the graymap will be linear or histogram-enhanced. The histogram method consists of dividing the cumulative histogram for the values in the image up into 256 levels, and assigning a graylevel to each. This has the effect of creating maximal contrast in all ranges of graylevel. It points up features really well, but it is a nonlinear mapping, so it is not good for telling you where gradients are strong or weak. @c HTML @cindex histogram enhancement of image plots @cindex drawing image plots @cindex drawing satellite images @c HTML @c HTML Example 6 @c HTML @c HTML The command-file.

    @image{./examples/example6} @image{./examples/example6histogram} @cindex example 06, plot IR image of Gulf of Maine @c HTML @c HTML @node Examples, Box Plots, Example Image, Top @comment node-name, next, previous, up @chapter Real-world examples @cindex cookbook The example files in this manual should be available to you directly, having been installed with Gri; if not, ask your system manager to check the FTP site. Additionally, I've collected a few real life examples here. Other sources are the Gri cookbook, available at @url{http://gri.sourceforge.net/gri-cookbook/index.html}. @menu * Box Plots:: Tukey box plots, which show histograms * Contouring:: sample contour plot * Grayscale Images:: create and plot image, from gridded data * Combination:: image and contour combination plot * Fancy:: fancy plot with lots of tricks * Legend:: plot with annotated curves and legend * Polygons:: read geometry, then draw polygon * TS Diagram:: temperature-salinity diagrams * PDF Diagram:: probability-density function * Running Means:: skyline plot of running means * Finite Element Model Mesh:: plotting mesh of FEM-type model * Handling Data:: samples of handling data @end menu @c HTML @node Box Plots, Contouring, Examples, Examples @comment node-name, next, previous, up @section Box plots Box plots were invented by Tukey for eda (exploratory data analysis). They show nonparametric statistics. The centre of the box is the median. The box edges show the first quartile (q1) and the third quartile (q3). The distance from q3 to q1 is called the inter-quartile range. The whiskers (lines with crosses on them) extend to the furthest points still within 1.5 inter-quartile ranges of q1 and q3. Beyond the whiskers, all outliers are shown, in open circles up to a distance of 3 inter-quartile ranges beyond q1 and q3, and in closed circles beyond that. Below is an example that uses a "new command" to define each box plot (@ref{Adding New Commands}). @c HTML @c HTML Example 7 @c HTML @c HTML The command-file.

    @image{./examples/example7} @cindex example 07, box plots of mixing efficiency vs density ratio (meddy) @c HTML @c HTML @node Contouring, Grayscale Images, Box Plots, Examples @comment node-name, next, previous, up @section Contouring This example plots a section of dT/drho vs x and rho (actually, sigma-t, as the label indicates). The contours are unlabelled; I'm only interested in the zero crossings. There are some other useful tricks in this example, such as calling @code{awk} and @code{wc} from the unix system. (In the plot shown, all @code{query} questions were answered with carriage return, yielding the defaults; the @code{-p} flag was specified on execution, so the time stamp was not drawn.) @c HTML @c HTML Example 8 @c HTML @c HTML The command-file.

    @image{./examples/example8} @cindex example 08, plot T=T(x,rho) section of eubex data @c HTML @c HTML @node Grayscale Images, Combination, Contouring, Examples @comment node-name, next, previous, up @section Image created from coarsely gridded data This example reads gridded ascii station data (@code{Read Data}), creates an interpolated image (@code{convert grid ...}), and then plots the image. There are some other useful tricks in this example, such as calling @code{awk} and @code{wc} from the unix system. (In the plot shown, all @code{query} questions were answered with carriage return, yielding the defaults; the @code{-p} flag was specified on execution, so the time stamp was not drawn.) @cindex axes, automatic drawing of @c HTML @c HTML Example 9 @c HTML @c HTML The command-file.

    @image{./examples/example9} @cindex example 09, plot dTdrho-rho section @c HTML @c HTML @node Combination, Fancy, Grayscale Images, Examples @comment node-name, next, previous, up @section Combination of image and contour @cindex image plot, with contours @cindex contours on images The following example reads gridded data and creates an image as in the previous example, but also superimposes unlabelled white contour lines. (In the plot shown, all @code{query} questions were answered with carriage return, yielding the defaults; the @code{-p} flag was specified on execution, so the time stamp was not drawn.) @cindex example 10 (image plot with contours) @c HTML @c HTML Example 10 @c HTML @c HTML The command-file.

    @image{./examples/example10} @cindex example 10, draw image plot of flushing of dye out of cove @c HTML @ifhtml A color version of this is possible using @code{set image colorscale} as shown here: @cindex example 10color, draw color image plot @end ifhtml @c HTML @c HTML Example 10 in colour @c HTML @c HTML The command-file.

    @c HTML @c HTML @node Fancy, Legend, Combination, Examples @comment node-name, next, previous, up @section Fancy x-y linegraph @cindex fancy plot The following code shows a fancy plot with lots of bells and whistles. @cindex multiple panels, example @cindex labels, example @cindex graylevel for lines, example @c HTML @c HTML Example 11 @c HTML @c HTML The command-file.

    @image{./examples/example11, 400pt} @cindex example 11, fancy plot @c HTML @c HTML @node Legend, Polygons, Fancy, Examples @comment node-name, next, previous, up @section Legends and annotated lines @cindex drawing legends @cindex legends @cindex annotating lines The following example shows how to handle annotated curves and legends. @c HTML @c HTML Example 12 @c HTML @c HTML The command-file.

    @image{./examples/example12} @cindex example 12, linegraph with key inside plot @c HTML @c HTML @node Polygons, TS Diagram, Legend, Examples @comment node-name, next, previous, up @section Drawing gray polygons @cindex polygons, filled @cindex gray level, example for polygons The following example shows how to draw polygons of a graylevel that is read in. It also draws a bullet (within the polygon). See the help lines at the start. @example `Draw Polygon And Bullet' Draw a polygon of a given graylevel, with a bullet (black dot) at an indicated location. The polygon coordinates are read in by this command, as are the graylevel and the location of the bullet. Variables used: .black. .white. Input data read: line 1: A code (which is ignored) and a graylevel to draw the polygon with. The value for this graylevel ranges from .black. (which codes to black ink on the paper) to .white. (which codes to blank paper). line 2: An (x,y) location for the bullet. line 3: Skipped. line 4-n: Locations of vertices of polygon, ended with a blank line. @{ read .code. .graylevel. # Read line 1 read .x. .y. # Read line 2 skip # Skip line 3 read columns x y # Read a polygon # Adjust .graylevel. to range between 0 # (for black ink) and 1 (for white paper), # then set graylevel and draw polygon. .graylevel. = @{rpn .graylevel. \ .black. - .white. .black. - /@} set graylevel .graylevel. draw curve filled # Draw black bullet set graylevel 0 draw symbol bullet at .x. .y. # Clean up local storage. delete .code. delete .graylevel. delete .x. delete .y. @} @end example @c HTML @node TS Diagram, PDF Diagram, Polygons, Examples @comment node-name, next, previous, up @section Temperature-Salinity Diagram @cindex oceanographic plots @cindex oceanographic plots, isopycnals on TS diagrams @cindex T-S diagram, example of drawing @cindex temperature-salinity diagram @cindex isopycnals Here is how you might draw an oceanographic "TS" (temperature salinity) diagram: @cindex example 13, TS diagram, with isopycnals @c HTML @c HTML Example 13 @c HTML @c HTML The command-file. @image{./examples/example13} @c HTML @c HTML @node PDF Diagram, Running Means, TS Diagram, Examples @comment node-name, next, previous, up @section Probability Density Function Diagram @cindex probability density function diagram @cindex perl, use to create probability density function A common application is to draw the probability density function for (x,y) data. Gri has no builtin facility to do this, but the following example shows how to create the gridded PDF data using a call to the @code{perl} system command. The gridded data thus generated are contoured, creating a PDF diagram. As the comments in the program state, the first call to Perl is specific to a particular dataset, and can be ignored on first reading; it just creates the file @file{tmp-xy.\.pid.}. @example # Draw prob-density-function TS diagram for Bravo data # This first call to perl is specific to the # particular (weird) dataset. All that matters # is that a file of (x,y) data is created, and # stored in the file called `tmp-xy.\.pid.' system perl <<"EOF" # # Slurp in x[], y[] data $dir = "/users/dek/kelley/Labrador/bravo/data"; $Sfile = "$dir/S_25db_1day"; $Tfile = "$dir/T_25db_1day"; open(S, "$Sfile") || die "Can't open input $Sfile"; open(T, "$Tfile") || die "Can't open input $Tfile"; open(ST, ">tmp-xy.\.pid.") || die "Can't open tmp-xy.\.pid."; $day = 5; $year = 1964; while() @{ @@S = split; $_ = ; @@T = split; if (240 < $day && $day < 360) @{ for ($i = 0; $i < $#S; $i++) @{ #all depths print ST "$S[$i] $T[$i]\n"; @} @} $day += 1; if ($day > 365) @{ $year++; $day = 0; @} if ($year > 1967) @{ last; @} @} EOF # # Create 2D PDF for (x,y) data in file \infile # storing the results in \outfile. X ranges # between the indicated limits, with the indicated # binsize, as does y. The synonyms defined # on the next 4 lines are the only input this # perlscript needs; the perlscript itself is # quite general. For details of what it does, # particularly the scaling of the PDF, see # the perl comments. \xmin = "33.5"; \xmax = "35.5"; \xinc = "0.05"; \ymin = "-2.0"; \ymax = "11.0"; \yinc = "0.25"; \infile = "tmp-xy.\.pid." \outfile = "tmp-grid.\.pid." system perl <<"EOF" # # Prepare 2 dimensional probability-density-function # dataset for contouring by Gri. This reads (x,y) # data from a file called $infile (defined below) # and creates an output file called $outfile # (also defined below) containing the # x-grid, the y-grid, and then the grid data, # suitable for reading/contouring by the Gri # commands # open tmp-grid.\.pid. # read .number_of_data. # read grid x # read grid y # read grid data # draw contour # # The values in the output grid are defined so # that they sum to the reciprocal of the # product of the x binsize and y binsize (see # definition of $factor below). # $xmin = \xmin; $xmax = \xmax; $xinc = \xinc; $ymin = \ymin; $ymax = \ymax; $yinc = \yinc; $infile = "\infile"; $outfile = "\outfile"; # # Slurp in the x[], y[] data, storing # the total number of data in $n. open(IN, "$infile") || die "Can't open infile"; open(OUT, ">$outfile") || die "Can't open outfile"; $n = 0; while() @{ ($x[$n], $y[$n]) = split; $n++; @} # # Zero out matrix (stored in a linear array scanned # as one reads a book). $cols = int(1 + ($xmax - $xmin) / $xinc); $rows = int(1 + ($ymax - $ymin) / $yinc); for ($y = $ymax; $y > $ymin; $y -= $yinc) @{ for ($x = $xmin; $x < $xmax; $x += $xinc) @{ $l = int(($x - $xmin) / $xinc + $cols * int(($y - $ymin) / $yinc)); $sum[$l] = 0; @} @} # # Cumulate (x,y) data into the matrix $inside = 0; for ($i = 0; $i < $n; $i++) @{ if ($ymin <= $y[$i] && $y[$i] <= $ymax && $xmin <= $x[$i] && $x[$i] <= $xmax) @{ $l = int(($x[$i] - $xmin) / $xinc + $cols * int(($y[$i] - $ymin) / $yinc)); $sum[$l]++; $inside++; @} else @{ print STDERR "($y[$i], $x[$i]) clipped\n"; @} @} # # Print number of points (to allow renormalization # if the user wishes) print OUT "$inside\n"; # # Print x grid, y grid, then grid itself for ($x = $xmin; $x < $xmax; $x += $xinc) @{ printf OUT "%lg\n", $x; @} print OUT "\n"; for ($y = $ymax; $y > $ymin; $y -= $yinc) @{ printf OUT "%lg\n", $y; @} print OUT "\n"; # # The $factor variable scales the PDF. $factor = 1 / $xinc / $yinc / $inside; for ($y = $ymax; $y > $ymin; $y -= $yinc) @{ for ($x = $xmin; $x < $xmax; $x += $xinc) @{ $l = int(($x - $xmin) / $xinc + $cols * int(($y - $ymin) / $yinc)); printf OUT "%lg ", $factor * $sum[$l]; @} print OUT "\n"; @} EOF # Axes set x margin 3 set x margin 6 set x name "Salinity [PSU]" set y name "Potential Temperature [$\circ$C]" set x axis 34.5 34.8 0.1 set y axis 5 9 1 draw axes # PDF open tmp-grid.\.pid. read .number_of_data. read grid x read grid y read grid data .smooth. = 0 # Contours. Use clipping, since the axes are # zooming in on part of the PDF. set font size 8 set contour label position centered set clip postscript on set line width rapidograph 4x0 draw contour 0.2 2.2 0.4 unlabelled set line width rapidograph 0 draw contour 0.4 2.4 0.4 set clip postscript off end if @end example @c HTML @node Running Means, Finite Element Model Mesh, PDF Diagram, Examples @comment node-name, next, previous, up @section Running-Mean Skyline Diagram @cindex Running-Mean Skyline Diagram Timeseries data are often cast into running means; e.g. a temperature record might be cast into monthly mean values. The following example shows how to use a perl script to accomplish this easily, producing a graph with both the raw data (bullets) and the running mean (a skyline plot). @example `Bin with x .min. .max. .inc. \in_file \out_file' Creates \out_file from \in_file. In each of these files, column 1 represents x and column 2 represents y. The \out_file file contains the average values of y in x bands of width .inc., centred at .min., (.min.+.inc.), up to .max, and with missing values inserted in bands with no x-data in \in_file. Each x-band is represented in \out_file by a plateau in y, and adjacent bands with non-missing data are connnected by vertical lines; the effect is a skyline plot of the banded means. Sample application: plot monthly means of a variable. @{ if @{rpn \.words. 8 !=@} show "ERROR: `\.proper_usage.' called without" show " giving all parameters" quit 1 end if system perl <<"EOF" $min = \.word3.; $max = \.word4.; $inc = \.word5.; open(IN, "\.word6.") || die "`\.proper_usage': no \\in_file"; open(OUT, ">\.word7.") || die "`\.proper_usage': no \\out_file"; $n = ($max - $min) / $inc; # # Set up bins. for($i = 0; $i <= $n; $i++) @{ $xx[$i] = 0; $yy[$i] = 0; $nn[$i] = 0; @} while() @{ ($x, $y) = split(' '); $i = int(0.5 + ($x - $min) / $inc); $i = 0 if $i < 0; $i = $n - 1 if $i > $n - 1; $xx[$i] += $x; $yy[$i] += $y; $nn[$i]++; @} for($i = 0; $i <= $n; $i++) @{ if ($nn[$i] > 0) @{ $xx[$i] /= $nn[$i]; $yy[$i] /= $nn[$i]; $xleft = $min + $inc * ($i - 0.5); $xright = $min + $inc * ($i + 0.5); # # If datum to left non-missing, # just draw vertical line # down to the last yy value. if ($i > 0 && $nn[$i - 1] > 0) @{ print OUT "$xleft $yy[$i - 1]\n"; @} else @{ print OUT "$xleft \.missingvalue.\n" @} print OUT "$xleft $yy[$i]\n"; print OUT "$xright $yy[$i]\n"; @} @} EOF @} # Bin into months Bin with x 1964 1974 @{rpn 1 12 /@} \ timeseries.dat tmp.dat open tmp.dat read columns x y close draw curve # skyline of means open timeseries.dat read columns x y close draw symbol bullet # data system rm -f tmp.dat # clean up @end example @c HTML @node Finite Element Model Mesh, Handling Data, Running Means, Examples @comment node-name, next, previous, up @section Finite Element Model mesh @cindex Finite Element Model mesh @cindex FEM mesh plot @cindex mesh plot for FEM Finite Element Models (used in fluid mechanics) employ non-rectangular meshes, and plotting these meshes requires a few intermediate steps. Consider the common case of triangular elements. Suppose two data files exist describing the mesh, the first, @file{model.nodes} say, consists of a description of the x-y coordinates of the nodes (vertices) of the triangles. The second, @file{model.elements} say, consists of a description of which triplet of nodes defines each triangle in the mesh. Here, from a sample application, is a node file called @file{model.nodes}: @example 1 1 1 2 2 1 3 1 2 4 3 1.5 5 2 2 6 1.5 3 @end example @noindent Here is the corresponding file of the elements, called @file{model.elements} @example 1 1 2 3 2 2 5 3 3 2 4 5 4 3 5 6 @end example @noindent In each of these files, the first column is a reference number. Thus, @file{model.elements} indicates that the first triangle is defined by the nodes numbered @code{1}, @code{2} and @code{3} as defined in @file{model.nodes}. More specifically, the triangle is defined by vertices at (x,y) locations (1,1), (2,1), and (1,2). A Gri program, named @file{FEM.gri}, to draw the nodes is the following. @example set missing value -99.99 # Create data using perl-script ... system FEM.pl model.nodes model.elements > tmp # ... then plot it ... open tmp read columns x y close draw curve # ... and, finally, clean up the temporary file system rm tmp @end example @noindent The work of interpreting the data files is done by the perlscript that follows, named @file{FEM.pl} @example #!/usr/bin/perl -w $missing = -99.99; # missing value $node_file = $ARGV[0]; $element_file = $ARGV[1]; open (NODE, $node_file) or die "Cannot open '$node_file' file"; open (ELEM, $element_file) or die "Cannot open '$element_file' file"; # Read in node information, creating arrays # named $node_x[] and $node_y[]. Check that # the first column (the index) makes sense. $max_node = 1; while() @{ ($index, $node_x[$max_node], $node_y[$max_node]) = split; die "Node mismatch at index=$index" if ($index != $max_node); $max_node++; @} # Read in triangle elements, into arrays # $a[], $b[], and $c[]. Check that the # first column (the index) makes sense. $max_elem = 1; while() @{ ($index, $a[$max_elem], $b[$max_elem], $c[$max_elem]) = split; die "Element mismatch at index=$index" if ($index != $max_elem); $max_elem++; @} # Print out triangles suitable for plotting in gri. for ($i = 1; $i < $max_elem; $i++) @{ print $node_x[$a[$i]], " ", $node_y[$a[$i]], "\n"; print $node_x[$b[$i]], " ", $node_y[$b[$i]], "\n"; print $node_x[$c[$i]], " ", $node_y[$c[$i]], "\n"; # Repeat first, to close the triangle. print $node_x[$a[$i]], " ", $node_y[$a[$i]], "\n"; print $missing, " ", $missing, "\n"; @} @end example @c HTML The resultant image is below. @c HTML FEM image @c HTML @node Handling Data, Handling Headers, Finite Element Model Mesh, Examples @comment node-name, next, previous, up @section Handling Data @cindex data, dealing with odd datasets @menu * Handling Headers:: How to skip or read header lines * Ignoring Columns:: Ignoring columns that are not of interest * Column Algebra:: How to do algebra on columns * Combining Columns:: Combining columns from separate files * Plotting Several Columns:: Plotting several y-columns vs one x-column @end menu @c HTML @node Handling Headers, Ignoring Columns, Handling Data, Handling Data @comment node-name, next, previous, up @subsection Handling headers @cindex skipping header lines @cindex header lines, skipping @b{Case 1 -- known number of header lines.} This is easy. If you know that the file has, say, 10 header lines, you can just do this: @example open file skip 10 read columns x y ... @end example @b{Case 2 -- header itself indicates number of header lines.} Quite often the first line of a file will indicate the number of header lines. For example, suppose the first line contains a single number, indicating the number of header lines to follow: @example open file read .skip. skip .skip. read columns x y ... @end example @b{Case 3 -- header lines marked by a textual key.} Sometimes header lines are indicated by a textual key, for example, the characters @code{HEADER} at the start of the line in the file. The easy way to skip such a header is to use a system command. Depending on your familiarity with the operating system (here presumed to be Unix), you might choose to use Grep, Awk, or Perl. Here are examples: @example open "grep -v '^HEADER' file |" @end example For more on the @code{|} mechanism, see @ref{Open}. The Grep command prints lines which do not match the indicated string (because of the @code{-v} switch), and the @code{^} character stands for the start of the line (@ref{Grep}). Thus all lines with the key word at the @strong{start} of the line are skiped. @cindex reading information from header lines @cindex header lines, reading information from @b{Case 4 -- reading and using information in header.} Consider a dataset in which the first line gives the time of observation, followed by a list of observations. This might be, for example, an indication of the data taken from a weather balloon released at a particular time from a fixed location, with the main data being air temperature as a function of elevation of the balloon. The time indication might be, for instance, the hour number. One might need to know the time to print a label on the diagram. You could do that by: @example open file read .time. read columns x y draw curve sprintf \label "Time of observation is %f hour" .time. draw title "\label" @end example @noindent where the @code{sprintf} command has been used to change the numerical time indication into a synonym that can be inserted into a quoted string for drawing the title of the diagram (@ref{Sprintf}). Here the time has been assumed to be a decimal hour. You might also have three numbers on the line, perhaps a day, an hour and a minute. Then you could do something like @example open file read .d. .h. .m. read columns x y draw curve sprintf \label "Obs. %.0f:%.0f, day %.0f" .h. .m. .d. draw title "\label" @end example @noindent Here the @code{%.0f} code is used to ensure no numbers will be written after the decimal point. Naturally, you could convert this to a decimal day, by e.g. @example ... .dday. = @{rpn .day. .hour. 24 / .min. 24 / 60 /@} sprintf \label "Decimal day is %.4f" .dday. ... @end example @noindent (Some of you might know how many minutes in a day, but I'm silly so I kept the extra mathematical step -- nothing is lost by being straightforward!) @c HTML @node Ignoring Columns, Column Algebra, Handling Headers, Handling Data @comment node-name, next, previous, up @subsection Ignoring columns that are not of interest Quite often a dataset will have many columns, of which only a couple are of interest to you. Consider for example oceanographic data which has columns storing, in order, these variables: (1) depth in water column, (2) "in situ" temperature, (3) "potential" temperature, (4) salinity, (5) conductivity, (6) density, (7) sigma-theta, (8) sound speed, and (9) oxygen concentration. But you might only be interested in plotting a graph of salinity on the x-axis and depth on the y-axis. Here are several ways to do this: @example open file read columns y * * x draw curve @end example @noindent where the @code{*} is a place-keeper to indicate to skip that column. For a large number of columns, or as an aesthetic choice, you might prefer to write this a @example open file read columns y=1 x=4 draw curve @end example Many users would just as soon not bother with this syntax, preferring instead to use system tools with which they are more familiar. So a Gawk user might write @example open "gawk '@{print($1, $4)@}' file |" read columns y x draw curve @end example @noindent For more on the Gawk command see @ref{Awk}. @c HTML @node Column Algebra, Combining Columns, Ignoring Columns, Handling Data @comment node-name, next, previous, up @subsection Algebra on column data Suppose the file contains (x,y), but you wish to plot 2y times x. You could do the doubling of y within Gri, as @example open file read columns x y y *= 2 draw curve @end example @noindent or you could use a system tool, e.g. gawk, as in this example (@ref{Awk}). @example open "gawk '@{print($1,2*$2)@}' file|" read columns x y draw curve @end example The latter is preferable in the sense that it is more powerful. The reason for this is that Gri allows you to manipulate the x and y columns, using so-called RPN mathematics (@ref{rpn Mathematics}), but you cannot blend the columns. For example, you cannot easily form the ratio y/x in Gri. (Actually, you can, by looping through your data and doing the calculation index by index, but if you knew that already you wouldn't need to be reading this section!) Such blending is trivial in the operating system, though, as in the following Gawk example (@ref{Awk}). @example open "gawk 'print @{($1, $2/$1)@}' file |" read columns x y draw curve @end example @c HTML @node Combining Columns, Plotting Several Columns, Column Algebra, Handling Data @comment node-name, next, previous, up @subsection Combining columns from different files Suppose you want to plot a column (@code{y}, say) from one file versus a second column (@code{x}) from a second data file. The easy way is to use a system command to create a new file, for example the Unix command @code{paste} -- but of course you don't want to clutter your filesystem with such files, so you should do this withing Gri: @example open "paste file1 file2 |" read columns x y draw curve @end example @c HTML @node Plotting Several Columns, Commands, Combining Columns, Handling Data @comment node-name, next, previous, up @subsection Plotting several y-columns versus on x-column Sometimes you'll have a datafile with the first column being x, and the other columns being various things to plot versus x. For example, you might have the data @example 1 8 11 9 2 22 21 20 3 11 10 9 4 20 15 10 @end example @noindent in a file called @code{test.dat}. Let's say the x-column is time, and the y-columns are the readings from three temperature sensors. The following illustrates how you might plot these data. If you think the new-command which starts this script is useful, just insert it in your @file{~/.grirc} file and you can just use it without re-defining it each time. This will give Gri a command called @code{draw curves}. @example `draw curves \xname \y1name ...' Draw multiple y columns versus an x column. Assumes that the datafile is open, and that x is in the first column, with the y values in one or more following columns. The number of columns is figured out from the options, as is the name of the x-axis, and the labels to be used on each of the y curves. @{ # NB. the 3 below lets us skip the words 'draw' # and 'curves', and the name of the x-column. .num_of_y_columns. = @{rpn wordc 3 -@} if @{rpn .num_of_y_columns. 1 >@} show "ERROR: `draw curves' needs at least 1 y column!" quit end if set x name @{rpn 2 wordv@} set y name "" # Loop through the columns. .col. = 0 while @{rpn .num_of_y_columns. .col. <@} # The x-values will be in column 1, with y-values # in columns 2, 3, ..., of the file. .ycol. = @{rpn .col. 2 +@} rewind read columns x=1 y=.ycol. # At this point, you may want to change line thickness, # thickness, color, dash-type, etc. For illustration, # let's set dash type to the column number. set dash .col. draw curve draw label for last curve @{rpn .col. 3 + wordv@} .col. += 1 end while @} open test.dat draw curves time y1 y2 y3 @end example @c HTML @node Commands, Overview Of Gri Commands, Plotting Several Columns, Top @comment node-name, next, previous, up @chapter List of Commands in the Gri Language @cindex programming, complete list of Gri commands @cindex syntax of Gri commands @cindex keywords of Gri commands @menu * Overview Of Gri Commands:: General classification of commands * Command Syntax:: Syntax of the commands * List Of Gri Commands:: @end menu @c HTML @node Overview Of Gri Commands, Command Syntax, Commands, Commands @comment node-name, next, previous, up @section Overview of Gri Commands @cindex types of gri commands @cindex overview of gri commands @cindex gri commands, categories of The Gri commands may be divided roughly into a few categories, as indicated in the following list. @itemize @bullet @item @strong{Working with files}: Commands are @code{open}, @code{close}, @code{skip}, @code{read}, and @code{rewind}. @item @strong{Controlling parameters of the drawn material}: Various @code{set} commands control values of parameters, like size of plot, linewidth, font, etc. @item @strong{Drawing things}: Various @code{draw} commands let you draw data, axes, etc. @item @strong{Interacting with the user}: The @code{query} command gets instructions from the user. The @code{show} command displays messages to user. @item @strong{Controlling program flow}: The @code{if} statement controls optional execution of commands (@ref{If Statements}). The @code{while} statement allows loops. @item @strong{Moving around in directories}: The @code{pwd}, @code{cd} and @code{ls} commands do the usual unix things. @item @strong{Using the operating system} The @code{system} command passes instructions to the operating system; the output may be saved into a synonym by using @code{\syn = system ...}. The @code{get env} command determines the value of any unix environment variables the system has defined. For more discussion (@ref{Operating System}). @item @strong{Statistical operations}: Some very limited capabilities exist; for example, @code{regress} does linear regression. @item @strong{Mathematical operations}: Simple mathematical manipulation of column, grid, and image data is provided. Also, wherever Gri expects a number, it will accept a reverse-polish expression; for example, @code{set x size 10} could also be written @code{set x size @{rpn 20 2 /@}}. For details (@ref{Mathematics}). @end itemize @c HTML @node Command Syntax, List Of Gri Commands, Overview Of Gri Commands, Commands @comment node-name, next, previous, up @section Command syntax The syntax description is enclosed within angled single quotes, optional items are enclosed in square brackets, multiword items are enclosed in curly braces, and vertical bars separate different legitimate choices. For example, the documentation item for the command for drawing contours @example `draw contour \ [.value. | \ @{.min. .max. .inc. [.inc_unlabelled.]@}] \ [unlabelled]' @end example @noindent indicates that following are legal: @example draw contour # gri selects levels draw contour unlabelled # " but unlabelled draw contour 10 # single contour line draw contour 10 unlabelled # " but unlabelled draw contour 0 100 10 # contours at z=0,1, draw contour 0 10 1 unlabelled # " but unlabelled # contours at 0, 0.1, ... labelled at 0, 1 draw contour 0 10 1 0.1 @end example @noindent Note that items enclosed in braces must appear in their entirety; for example, @example draw contour 0 10 # WRONG; missing .inc. @end example @noindent which might look similar @code{draw contour .min. .max. .inc.} to you, looks like garbage to Gri. Gri will recognize it as an attempt at the @code{draw contour} command (because the first 2 words match the syntax) but it will then get confused, spit out an error message, and quit. @c HTML @node List Of Gri Commands, Assert, Command Syntax, Commands @comment node-name, next, previous, up @section List of all Gri commands Commands are listed below in the order in which they are defined in the @file{gri.cmd} file (@ref{Invoking Gri}). What you see here is similar to, but not identical to, the text of the online help. Gri usually accepts both American and English spellings (As an example of spelling latitude, Gri accepts @code{grey} anywhere the manual says @code{gray}, and @code{colour} for @code{color}.) @cindex gri commands, complete list of @cindex commands, complete list of @cindex spelling of gri commands @cindex gray vs Grey spelling @cindex grey vs Gray spelling @cindex colour vs Color spelling @menu * Assert:: Assert something to be true (for debugging) * Cd:: Change directory * Close:: Close a file * Convert:: Convert various data types * Create:: Create columns from specified function * Debug:: Set to debugging mode * Delete:: Delete various data structures * Differentiate:: Differentiate things * Draw:: Draw various things * End Group:: End a group * Expecting:: Make Gri warn of incompatibilites * Filter:: Filter (smooth) various data structures * Flip:: Flip or transpose grid or image * Get Env:: Get a unix environment variable * Group:: Start a group of drawn objects * Heal:: Interpolate across missing values * Help:: Give on-line help * If:: If and if/else statements * Ignore:: Ignore some of data recently read in * Input:: Input PostScript file into output file * Insert:: Run another command file * Interpolate:: Interpolate grid data to new x/y grid * List:: List source of a gri command * Ls:: List files in current directory * Mask:: Mask the image * New:: Get space for new variable or synonym * Newpage:: Start a new page * New Postscript File:: Start a new PostScript file * Open:: Open a data file * Postscript:: Insert a line into the PostScript file * Pwd:: Print working directory * Query:: Get user input * Quit:: Exit from gri * Read:: Read something * Regress:: Do linear regressions on columnar data * Reorder:: Reorder columns * Rescale:: Re-determine scales for x/y axes * Resize:: Resize plot width/height for maps * Return:: Return early from command or insert file * Rewind:: Rewind data file to beginning * Rpnfunction:: Define an rpn function * Set:: Set various preference flags, etc * Show:: Show values of various things * Skip:: Skip some lines in data file * Sleep:: Sleep for a while * Smooth:: Smooth data * Source:: Run another command file * Sprintf:: Print variable values into a synonym * State:: Save or restore the graphics state * Superuser:: Enable some programmers debugging commands * System:: Performing system commands within gri * Unlink:: Delete file * While:: Loop over some code while a condition is true * Write:: Write data to a file @end menu @c HTML @node Assert, Cd, List Of Gri Commands, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{assert} @cindex debugging, with @code{assert} command @cindex @code{assert} command, for debugging @findex assert @example `assert .condition. ["message"] @end example @noindent The condition may be a variable, a synonym, or an RPN expression. If this condition is true (i.e. evaluates to a non-zero number), do nothing. If the condition is false, the program will terminate with an error condition (in unix, it will terminate with a non-zero exit code). Before termination, a message will be printed, the form of which depends on the optional @code{"message"} string. If no @code{"message"} string is given, the the printed message will indicate the name of the command-file and the line at which the assert command was encountered. If a @code{"message"} string is given, and if it ends in a newline (@code{"\\n"}), then this string is printed. If a @code{"message"} string is given, and if it does not end in @code{"\\n"}, then the string is printed along with an indication of the location in the command-file. (Perl users will recognize this as being patterned on the @code{"die"} command.) @c HTML @node Cd, Close, Assert, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{cd} @cindex changing directories @cindex directories, changing @cindex @code{cd} command @findex cd @example `cd [\pathname]' @end example @noindent If a pathname specified, change to that directory. Normal unix filenames are used, as in the C-shell convention. For example, the commands @code{cd ~/src} and @code{cd $HOME/src} are equivalent. You may specify relative pathnames as in @code{cd ../sister_directory}. If no \pathname directory path is specified, go to the home directory, exactly as @code{cd ~} and @code{cd $HOME} do. @c HTML @node Close, Convert, Cd, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{close} @cindex files, closing @cindex closing files @findex close @cindex @code{close} command @example `close [\filename]' @end example @noindent If no filename is specified, close the most recently opened data-file; otherwise close the indicated file. @c HTML @node Convert, Convert Columns To Grid, Close, List Of Gri Commands @comment node-name, next, previous, up @subsection The @code{convert} commands @menu * Convert Columns To Grid:: Create grid from (x,y,f) data * Convert Columns To Spline:: Create spline (x',y') from (x,y) data * Convert Grid To Columns:: Create (x,y,f) data from grid * Convert Grid To Image:: Create an image from grid data * Convert Image To Grid:: Create a grid from image data @end menu @node Convert Columns To Grid, Convert Columns To Spline, Convert, Convert @comment node-name, next, previous, up @subsubsection @code{convert columns to grid} @findex convert columns to grid @cindex @code{convert columns to grid} command Various forms exist: @example `convert columns to grid OPTIONS' @end example @noindent where the @code{OPTIONS} may be omitted or selected from this list: @example `neighbor' `boxcar [.xr. .yr. [.n. .e.]]' `objective [.xr. .yr. [.n. .e.]]' `barnes [.xr. .yr. .gamma. .iter.]' @end example @noindent For more discussion on the methods see @ref{Ungridded Data}. All these commands ``grid'' columnar (x,y,z) data. That is, they fill up a grid based on some form of interpolation of the possibly randomly-spaced columnar data. There are many methods in existence for doing this, and Gri implements several of them as alternatives. The grid will have been defined by commands such as @code{set x grid}, @code{set y grid}, @code{read grid x} and @code{read grid y}. As of version 2.1.9, Gri does not require a grid to have been pre-defined; it will create a regular 20 by 20 grid, spanning the range of x and y data, as a default. This is a good starting point in many cases. @table @emph @item `neighbor' method Very fast but very limited. @item `boxcar' method Slower but a lot better. Still, this can produce noisy contours if the data are not densely and uniformly ditributed through domain. @item `objective' method Somewhat slower than `boxcar', but produces better fields since the averaging function is smooth. @item `barnes' method Somewhat slower than `objective', but only by a constant factor (that is, independent of number of data). This produces by far the best results, since the smoothing function has variable spatial scale. This is the default method if no method is supplied. @end table All except the @code{neighbor} method may take optional arguments to define the x and y scales of the smoothing function (called @code{.xr.} and @code{.yr.}). (The barnes method has two other optional arguments -- see below.) If you do not supply these arguments, Gri will make a reasonable choice and inform you of its decision. Many users find that it is best to @code{convert columns to grid} with no additional parameters as a first step, to get advice on values to use for the optional parameters. The default @code{.xr.} and @code{.yr.} are calculated by determining the span in x and in y directions, and dividing each by the square root of the number of data points. These numbers are then multiplied by the square root of 2. The method is as proposed by S. E. Koch and M. DesJardins and P. J. Kocin, 1983. ``An interactive Barnes objective map anlaysis scheme for use with satellite and conventional data,'', J. Climate Appl. Met., vol 22, p. 1487-1503. If @code{.xr.} and @code{.yr.} were supplied but negative, then Gri interprets this as an instruction to modify the default values, described in last paragraph, by multiplying by the absolute values of the negative numbers given, instead of muliplying by square root of 2. If the @code{chatty} option is turned on then Gri will print out the values of (dx,dy) that it has calculated; this gives you some guidance for supplying your own values of @code{(.xr.,.yr.)} if you choose to supply them yourself. It is also a good idea to let these parameters be a guide for your grid spacing; for example, Koch et al., 1983, suggest using grid spacing of 0.3 to 0.5 times (dx,dy). And now, the details @dots{} @itemize @bullet @item @strong{``Neighbor'' method} The @code{convert columns to grid neighbor} method is useful for (x,y,z) data which are already gridded (i.e., for which x and y take only values which lie on the grid), or nearly gridded. The (x,y,z) data are scanned from start to finish. For each data point, the nearest grid point is found. Nearness is measured as Cartesian distance, with scale factor given by the distance between the first and second grid points. In other words, distance is given by D=sqrt(dx*dx+dy*dy) where dx is ratio of distance from data point to nearest grid point, in x-units, divided by the difference between the first two elements of the x-grid, and dy is similarly defined. Once the grid point nearest the data point is determined, Gri adds the z-value to a list of possible values to store in the grid. Once the entire data set has been scanned, Gri then goes back to each grid point, and chooses the z-value of the data point that was nearest to the grid point -- that is, it stores the z value of the (x,y,z) data triplet which has minimal D value. Note that this scheme is independent of the order of the data within the columns. @cindex computational cost, of @code{convert columns to grid} command The @code{neighbor} method is useful when the data are already pre-gridded, meaning that the (x,y,z) triplets have x and y values which are already aligned with the grid. @strong{Computational cost:} For @code{P} data points, @code{X} x-grid points, and @code{Y} y-grid points, the method calculation cost is proportional to @code{P*[log2(X)+log2(Y)]} where @code{log2} is logarithm base 2. As discussed below, this is often several orders of magnitude lower than the other methods of gridding. @item @strong{``Objective'' method} In the @code{objective} method, a smoothing technique known as objective mapping is applied. It is essentially a variable-size smoothing filter of approximately Gaussian shape (it is method ``two'' of Levy and Brown [1986 J. Geophysical Res. vol 91, p 5153-5158]) The parameters @code{.xr.} and @code{.yr.} give the width of the filter. With the optional additional parameters @code{.n.} and @code{.e.} are specified, then grid values will be assigned the missing value if there are fewer than @code{.n.} (x,y,f) data in the neighborhood of the gridpoint, even after enlarging the neighborhood by widening and heightening by root(2) up to @code{.e.} times. (The enlargement is only done if fewer than @code{.n.} points are found.) If these parameters are not specified in the command, then values @code{.n.}=5 and @code{.e.}=1 are assumed. The special case where @code{.e.} is negative tells Gri to @strong{always} fill in each grid point, by extending the neighborhood to enclose the entire dataset if necessary. @strong{Computational cost:} For @code{P} data points, @code{X} x-grid points, and @code{Y} y-grid points, the method calculation cost is proportional to @code{P*X*Y}. Given that @code{X} and @code{Y} are determined by the requirement for smoothness of contours and the size of the graph, they are more or less fixed for all applications. They are often in the range of 20 or so -- on 10 cm wide graph, this yields a contour footprint of 1/2 cm, which is often small enough to yield smooth contours. Therefore, the computational cost scales linearly with the number of data points. Compared to the ``neighborhood'' method, this is more costly by a factor of @code{X*Y/log_2(X)/log_2(Y)} which is normally in the range from 20 to 50. @item @strong{``Boxcar'' method} In the @code{boxcar} method, the grid points are derived from simple averages calculated in rectangles @code{.xr.} wide and @code{.yr.} tall, centred on the gridpoints. The @code{.n.} and @code{.e.} parameters have similar meanings as in the ``objective'' method. @strong{Computational cost:} Roughly same as @code{objective} method described above. @item @strong{``Barnes'' method} This is the default scheme. The Barnes algorithm is applied. If no parameters are specified, @code{.xr.} and @code{.yr.} are determined as above, with @code{.gamma.} set to 0.5, and @code{.iter.} set to 2 so that two iterations are done. On successive iterations, the smoothing lengthscales @code{.xr} and @code{.yr} are each reduced by multiplying by the square root of @code{.gamma.}. Smaller @code{.gamma.} values yield better resolution of small-scale features on successive iterations. Koch et al., 1983, recommend using a @code{.gamma.} value in the range 0.2 to 1, with two iterations. Provided that all the grid points are close enough to at least some column data, the entire grid is filled. But if @code{.xr.} and @code{.yr.} are too small, the weighting function can fall to zero, since it is exponential in the sum of the squares of the x-distance/@code{.xr.} and the y-distance/@code{.yr.}; in that case missing values result at those grid points. On a 32 bit computer, the weighting function will fall to zero when x-distance/@code{.xr.} and y-distance/@code{.yr.} are less than about 15 to 20. If weights have been read in (@ref{Read Columns}), then these values are applied in addition to the distance-based weighting. (The normalization means that weights for two data points of e.g. 1 and 2 will yield the same result as if the weights had been given as 10 and 20.) The computational cost at each iteration scales as @code{P*X*Y)}. This is comparable to that of the ``objective'' and ``boxcar'' methods. Since normally two iterations are done, ``barnes'' is about double the cost of these methods. (Note: versions prior to 2.1.8 were much slower for large datasets, being proportional to @code{P*P}.) References: (1) Section 3.6 in Roger Daley, 1991, ``Atmospheric data analysis,'' Cambridge Press, New York. (2) S. E. Koch and M. DesJardins and P. J. Kocin, 1983. ``An interactive Barnes objective map anlaysis scheme for use with satellite and conventional data,'', J. Climate Appl. Met., vol 22, p. 1487-1503. @end itemize The Barnes algorithm is as follows: @tex The gridded field is estimated iteratively. Successive iterations retain largescale features from previous iterations, while adding details at smaller scales. The first estimate of the gridded field, here denoted $G_{ij}^{(0)}$ (the parenthetic superscript indicating the order of the iteration) is given by a weighted sum of the input data, with $z_k$ denoting the k-th $z$ value. $$ G_{ij}^{(0)} = { {\sum_1^{n_k} W_{ijk}^{(0)} z_k} \over {\sum_1^{n_k} W_{ijk}^{(0)}} } $$ The weights $W_{ijk}^{(0)}$ are defined in terms of a Gaussian function decaying with distance from observation point to grid point: $$ W_{ijk}^{(0)} = \exp \left[ - { {(x_k-X_i)^2} \over {L_x^2} } - { {(y_k-Y_j)^2} \over {L_y^2} } \right] $$ \noindent Here $L_x$ and $L_y$ are lengths which define the smallest $(x,y)$ scales over which the gridded field will have significant variations (for details of the spectral response see Koch et al. 1983). Note: if the user has supplied weights then these are multiplied into the normal distance-based weights; i.e. $w_i W_{ijk}$ is used instead of $W_{ijk}$. The second iteration derives a grid $G_{ij}^{(1)}$ in terms of the first grid $G_{ij}^{(0)}$ and ``analysis values'' $f_k^{(0)}$ calculated at the $(x_k,y_k)$ using a formula analogous to the above. (Interpolation based on the first estimate of the grid $G_{ij}^{(0)}$ can also be used to calculate $f_k^{(0)}$, with equivalent results for a grid of sufficiently fine mesh.) In this iteration, however, the weighted average is based on the difference between the data and the gridded field, so that no further adjustment of the gridded field is done in regions where it is already close to through the observed values. The second estimate of the gridded field is given by $$ G_{ij}^{(1)} = G_{ij}^{(0)} + { {\sum_1^{n_k} W_{ijk}^{(1)} (f_k - f_k^{(0)})} \over {\sum_1^{n_k} W_{ijk}^{(1)}} } $$ \noindent where the weights $w_{ik,1}$ are defined by analogy with $W_{ik}^{(0)}$ except that $L_x$ and $L_y$ are replaced by $\gamma^{1/2}L_x$ and $\gamma^{1/2}L_y$. The nondimensional parameter $\gamma$ ($0<\gamma<1$) controls the degree to which the focus is improved on the second iteration. Just as the weighting function forced the gridded field to be smooth over scales smaller than $L_x$ and $L_y$ on the first iteration, so it forces the second estimate of the gridded field to be smooth over the smaller scales $\gamma^{1/2}L_x$ and $\gamma^{1/2}L_y$. The first iteration yields a gridded field which represents the observations over scales larger than $(L_x,L_y)$, while successive iterations fill in details at smaller scales, without greatly modifying the larger scale field. In principle, the iterative process may be continued an arbitrary number of times, each time reducing the scale of variation in the gridded field by the factor $\gamma^{1/2}$. Koch et al. 1983 suggest that there is little utility in performing more than two iterations, providing an appropriate choice of the focussing parameter $\gamma$ has been made. Thus the gridding procedure defines a gridded field based on three tunable parameters: $(L_x,L_y,\gamma)$. @end tex @ifinfo The gridded field is estimated iteratively. Successive iterations retain largescale features from previous iterations, while adding details at smaller scales. The first estimate of the gridded field, here denoted @code{G_(ij)^0} (the superscript indicating the order of the iteration) is given by a weighted sum of the input data, with @code{z_k} denoting the k-th @code{z} value. @example sum_1^n W_(ijk)^0 z_k G_(ij)^(0) = ---------------------- sum_1^n W_(ijk)0 @end example @noindent where the notation @code{sum_1^n} means to sum the elements for the @code{k} index ranging from 1 to @code{n}. The weights @code{W_(ijk)^0} are defined in terms of a Guassian function decaying with distance from observation point to grid point: @example ( (x_k - X_i)^2 (y_k - Y_j)^2 ) W_(ijk)^0 = exp(- -------------- - --------------- ) ( L_x^2 L_y^2 ) @end example @noindent Here @code{L_x} and @code{L_y} are lengths which define the smallest @code{(x,y)} scales over which the gridded field will have significant variations (for details of the spectral response see Koch et al. 1983). Note: if the user has supplied weights then these are applied in addition to the distance-based weights. That is, @code{w_i W_(ijk)} is used instead of @code{W_(ijk)}. The second iteration derives a grid @code{G_(ij)^1} in terms of the first grid @code{G_(ij)^0} and ``analysis values'' @code{f_k^0} calculated at the @code{(x_k,y_k)} using a formula analogous to that above. (Interpolation based on the first estimate of the grid @code{G_(ij)^0} can also be used to calculate @code{f_k^0}, with equivalent results for a grid of sufficiently fine mesh.) In this iteration, however, the weighted average is based on the difference between the data and the gridded field, so that no further adjustment of the gridded field is done in regions where it is already close to through the observed values. The second estimate of the gridded field is given by @example sum_1^n W_(ijk)^1 (f_k - f_k^0) G_(ij)^1 = G_(ij)^0 + ------------------------------- sum_1^n W_(ijk)^1 @end example @noindent where the weights @code{w_@{ik,1@}} are defined by analogy with @code{W_@{ik@}^0} except that @code{L_x} and @code{L_y} are replaced by @code{gamma^@{1/2@}L_x} and @code{gamma^@{1/2@}L_y}. The nondimensional parameter @code{gamma} (@code{0255 into the user values 10->20, as in @example set image range 10 20 set image grayscale black 10 white 20 @end example @noindent then the output grid will be of value 10 where the pixel value is 0, etc. If the image is in color, the grid values will represent the result of mapping the colors to grayscale in the standard way (Foley and VanDam, 1984). [BUG: as of 1.063, the colorscale is ignored completely, and I'm not sure what happens.] The image data are interpolated onto the grid using a nearest-neighbor substitution. This command insists that the image x/y grids have already been defined. @c HTML @node Create, Create Columns From Function, Convert Image To Grid, List Of Gri Commands @comment node-name, next, previous, up @subsection The @code{create} commands @menu * Create Columns From Function:: prepare to draw a function * Create Image Grayscale:: prepare to draw banded image @end menu @node Create Columns From Function, Create Image Grayscale, Create, Create @comment node-name, next, previous, up @subsubsection @code{create columns from function} @findex create @cindex @code{create columns from function} command @example `create columns from function' @end example @noindent Plot a function of x which is defined in synonym \function. @example ENVIRONMENT \function = function to plot. \xmin = minimum x value \xmax = maximum x value \xinc = increment in x values EXAMPLE \function = "cos(x)" \xmin = "0" \xmax = "2 * 3.14" \xinc = "0.1" create columns from function draw curve @end example @noindent NOTE: This only works on machines which have the @code{awk} command available at the commandline. This means most unix machines and some vax machines. @node Create Image Grayscale, Debug, Create Columns From Function, Create @comment node-name, next, previous, up @subsubsection @code{create image grayscale} @cindex image, banded @findex create image grayscale @example `create image grayscale banded .band.' @end example @noindent Make a banded grayscale with in units of .band. pixel values each. Thus, pixel values 0 to (.band. - 1) on the image will map to 0, while values from .band. to (2 * .band. - 1) will map to .band., etc. For example, .band. = 2 gives grayscale = (0 0 2 2 4 4 6 6 ... 252 252 254 254). @c HTML @node Debug, Delete, Create Image Grayscale, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{debug} @cindex debugging @findex debug @cindex @code{debug} command @example `debug [.n.]|[clipped values in draw commands]|off' @end example @noindent With no optional parameters, sets the value of @code{..debug..} to 1. (Normally, @code{..debug..} is 0.) You may use @code{..debug..} in @code{if} statements, etc. Note that @code{..debug..} is also set to 1 when gri is invoked with the commandline switch @code{-d}. With @code{.n.} specified, @code{..debug..} is set to @code{.n.}; a value of zero for @code{.n.} turns debugging off, while 1 turns it on. Higher values may be used for deeper debugging, if you choose: @example if @{rpn ..debug.. 2 <@} # Code to do if ..debug.. is greater than 2. end if @end example @noindent Note that you can assign to @code{..debug..} as you can to any other variable; @code{debug .n.} is equivalent to @code{..debug.. = .n.}. With the @code{clipped} option, Gri prints any clipped data encountered during any @code{draw ...} commands, EXCEPT in the case of @code{postscript} clipping, where no check is possible. (Note that @code{..debug..} is not affected.) All these forms of debugging are cancelled by @code{debug off}. @c HTML @node Delete, Differentiate, Debug, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{delete} @cindex deleting variables, synonyms, scales, etc @cindex grid, deleting @cindex scales, deleting @cindex synonyms, deleting @cindex variables, deleting @findex delete @cindex @code{delete} command @example `delete .variable.|\synonym [.variable.|\synonym [...]]' `delete columns [where missing]' `delete columns [randomly .fraction.]' `delete grid' `delete [x|y] scale' @end example @noindent Delete some item or characteristic. @itemize @bullet @item @code{delete .variable.} Delete definition of variable @code{.variable.}, making it undefined. Any number of variables or synonyms may be specified on one line. @item @code{delete \synonym} Delete definition of synonym @code{\synonym}, making it undefined. Any number of variables or synonyms may be specified on one line. @item @code{delete \@@alias} Delete the item named by the alias (@ref{Alias Synonyms}). @item @code{delete} with an @code{&} item Delete the item in the calling program. @item @code{delete columns} Delete column data. @item @code{delete columns where missing} Completely delete all column data for which any one of x, y, etc is missing. @item @code{delete columns randomly .fraction.} Randomly select fraction @code{.fraction.} of the non-missing column data, and designate them as being missing. @item @code{delete grid} Delete grid data. @item @code{delete scale} Delete scales for both x and y, so next @code{read columns} will set it. @item @code{delete x scale} Delete scales for x, so next @code{read columns} will set it. @item @code{delete y scale} Delete scales for y, so next @code{read columns} will set it. @end itemize @c HTML @node Differentiate, Draw, Delete, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{differentiate} @cindex differentiation @findex differentiate @cindex @code{differentiate} command @example `differentiate @{x|y wrt index|y|x@} | @{grid wrt x|y@}' @end example @noindent Differentiate column data or grid data. Only the @code{x} and @code{y} columns may be differentiated. They may be differentiated either with respect to (``wrt'') the index (forming a first difference) or with respect to the other column. The derivative is done with the backwards-difference algorithm. Grid data may differentiated with respect to @code{x} direction or @code{y} direction. Grid differentiation is done with a centred difference, with endpoints being assigned the derivative of the neighboring interior point (so that the second derivative is zero at the edges of the grid). @c HTML @node Draw, Draw Arc, Differentiate, List Of Gri Commands @comment node-name, next, previous, up @subsection The @code{draw} commands @findex draw Draw commands do actual drawing on the page. You can draw axes, lineplots, symbols, contours, images, and text. @strong{NOTE} Gri likes drawings to have axes, so if a @code{draw} command is executed before any axes have been drawn, Gri will draw axes after it draws the item. (You can get drawings without axes by preceding any other @code{draw} commands with the command @code{draw axes none}.) Many users have been surprised by the results of this rule. For example, if you do @code{set graylevel 0.5} before @code{draw curve}, you'll find that the axes are drawn in gray also. To avoid this, make sure to do @code{draw axes} before you modify the graylevel.) @menu * Draw Arc:: Draw an arc segment * Draw Arrow:: Draw single arrow * Draw Arrows:: Draw many arrows (using columns) * Draw Axes If Needed:: Draw axes if haven't done so yet * Draw Axes:: Draw axes * Draw Border Box:: Draw border around plot * Draw Box:: Draw a box, possibly filled * Draw Circle:: Draw a circle * Draw Contour:: Draw contour(s) * Draw Curve:: Draw a curve of y(x) column data * Draw Essay:: Draw text, adjusting position for each line * Draw Gri Logo:: Draw a Gri logo * Draw Grid:: Draw the location of grid points * Draw Image Histogram:: Draw histogram of values in image * Draw Image Palette:: Draw palette used in image plots * Draw Image:: Draw image * Draw Isopycnal:: Draw isopycnal line on TS plot * Draw Isospice:: Draw iso-spice line on TS plot * Draw Label Boxed:: Draw a label in a box * Draw Label Whiteunder:: Draw a label with white ink under it * Draw Label For Last Curve:: What it says * Draw Label:: Draw text somewhere * Draw Line From:: Draw line segment * Draw Line Legend:: Draw legend displaying line types * Draw Lines:: Draw sequence of parallel lines * Draw Patches:: Draw grayscale patches showing z(x,y) * Draw Polygon:: Draw a polygon * Draw Regression Line:: Draw line from regression between x and y * Draw Symbol At:: Draw a symbol at a point * Draw Symbol Legend:: Draw a symbol and a string describing it * Draw Symbol:: Draw symbols at (x,y), or at a point * Draw Time Stamp:: Draw a timestamp at top of plot * Draw Title:: Draw a title for plot * Draw Values:: Draw numbers beside z(x,y) * Draw X Axis:: Draw the x axis * Draw X Box Plot:: Draw box plots showing x spread * Draw Y Axis:: Draw the y axis * Draw Y Box Plot:: Draw box plots showing y spread * Draw Zero Line:: Draw y=0 or x=0 @end menu @node Draw Arc, Draw Arrow, Draw, Draw @comment node-name, next, previous, up @subsubsection The @code{draw arc} command @findex draw arc @cindex arc, drawing @cindex drawing arcs @example `draw arc [filled] .xc_cm. .yc_cm. .r_cm. .angle_1. .angle_2.' @end example Draw an "arc", that is, a portion of a circle. The center of the circle is at the coordinate (@code{.xc_cm.}, @code{.yc_cm.}), and the circle radius is @code{.r_cm.}, all three quantities being in cm on the page, @emph{not} in user-units. The arc starts at angle @code{.angle_1.}, measured in degrees counterclockwise from a horizontal line, and extends to angle @code{.angle_2.}, in the same units. If the keyword @code{filled} is present, the arc is filled with the current color. Otherwise it is drawn with the current "curve" linewidth @ref{Set Line Width}. @node Draw Arrow, Draw Arrows, Draw Arc, Draw @comment node-name, next, previous, up @subsubsection @code{draw arrow} @cindex arrows, drawing single @example draw arrow from .x0. .y0. to .x1. .y1. [cm] @end example With no optional parameters, draw an arrow from (@code{.x0.}, @code{.y0.}) to (@code{.x1.}, @code{.y1.}), where coordinates are in user units. The arrow head will be at (@code{.x1.}, @code{.y1.}), and its size is as set by most recent call to @code{set arrow size}. With the @code{cm} keyword present, the coordinates are in centimetres on the page. NOTE: This will not cause auto-drawing of axes. @node Draw Arrows, Draw Axes If Needed, Draw Arrow, Draw @comment node-name, next, previous, up @subsubsection @code{draw arrows} @findex draw arrows @cindex @code{draw arrows} command @example `draw arrows' @end example @noindent Draw a vector field consisting of arrows emanating from the coordinates stored in the (x, y) columns. The lengths and orientations of the arrows are stored in the (u, v) columns, and the scale for the (u,v) columns is set by @code{set u scale} and @code{set v scale}. @strong{See also} (1) To set arrow size, use @code{set arrow size}. (2) To get a single arrow, use @code{draw arrow}. @node Draw Axes If Needed, Draw Axes, Draw Arrows, Draw @comment node-name, next, previous, up @findex draw axes if needed @cindex @code{draw axes if needed} command @subsubsection @code{draw axes if needed} @example `draw axes if needed' @end example @noindent Draw axes frame if required. Used within gri commands that auto-draw axes. NOTE: this should only be done by developers. @node Draw Axes, Draw Border Box, Draw Axes If Needed, Draw @comment node-name, next, previous, up @findex draw axes @cindex @code{draw axes} command @subsubsection @code{draw axes} @example `draw axes [.style.|frame|none]' @end example @noindent With no style (@code{.style.}) specified, draw x-y axes frame labelled at left and bottom. The value of @code{.style.} determines the style of axes: @itemize @bullet @item @code{.style. = 0} Draw x-y axes frame labelled at left and bottom. Since this is the default, it's best to leave it out altogether to make your code easier to understand. @item @code{.style. = 1} Draw axes without tics at top and right @item @code{.style. = 2} Draw axes frame with no tics or labels; same as @code{draw axes frame} @end itemize With the keyword @code{frame} specified, draw axes frame with no tics or labels (just like @code{.style.} = 2, but preferable because it makes for code that is easier to read and understand). With the keyword @code{none} specified, prevent Gri from automatically drawing axes when drawing curves. Note: @code{set axes style} can also be used to set axes properties, and then simply using @code{draw axes}, or letting axes be auto-drawn, will result in the desired effect (@ref{Set Axes Style}). However, if the @code{draw axes} command explicitly asks for a particular style, then it over-rides the style set by @code{Set Axes Style}. @node Draw Border Box, Draw Box, Draw Axes, Draw @comment node-name, next, previous, up @findex draw border box @cindex @code{draw border box} command @subsubsection @code{draw border box} @example `draw border box .xleft. .ybottom. .xright. .ytop. \ .width_cm. .brightness.' @end example @noindent Draw gray box, as decoration or alignment key for pastup. The box, with outer lower left corner at (@code{.xleft.}, @code{.ybottom.}) and outer upper right corner at (@code{.xright}., @code{.ytop.}) -- both coordinates being in centimetres on the page -- is drawn with thickness @code{.width_cm.} and with graylevel @code{.brightness.} (0 for black; 1 for white). The gray line is drawn inside the box. After drawing the gray line, a thin black line is drawn along the outside edge. If the geometry is not specified with @code{.xleft.} and the other parameters, then a reasonable margin is used around the present axes area, and the defaults (@code{.border.} = 0.2, @code{.brightness.} = 0.75) are used. NOTE: This command does not cause auto-drawing of axes. @node Draw Box, Draw Circle, Draw Border Box, Draw @comment node-name, next, previous, up @subsubsection @code{draw box} @findex draw box @cindex @code{draw box} command @example `draw box filled .xleft. .ybottom. .xright. .ytop. [cm|pt]' @end example @noindent Draw filled box spanning indicated range, with lower-left corner at (@code{.xleft.}, @code{.ybottom.}) and upper-right corner at (@code{.xright.}, @code{.ytop.}). The corners are specified in user coordinates, unless the optional @code{cm} or @code{pt} keyword is present, in which case they are in centimetres or points on the page. An error will result if you specify user coordinates but they aren't defined yet. No checking is done on the rectangle; for example, there is no requirement that @code{.xleft.} be to the left of @code{.xright.} in your coordinate system. NOTE: if the box is specified in user units, this command will cause auto-drawing of axes, but not if the box is specified in @code{cm} or @code{pt} units @example `draw box .xleft. .ybottom. .xright. .ytop. [cm|pt]' @end example @noindent Draw box spanning indicated range, with lower-left corner at (@code{.xleft.}, @code{.ybottom.)} and upper-right corner at (@code{.xright.}, @code{.ytop.}). The corners are specified in user coordinates, unless the optional @code{cm} or @code{pt} keyword is present, in which case they are in centimetres or points on the page. An error will result if you specify user coordinates but they aren't defined yet. No checking is done on the rectangle; for example, there is no requirement that @code{.xleft.} be to the left of @code{.xright.} in your coordinate system. @node Draw Circle, Draw Contour, Draw Box, Draw @comment node-name, next, previous, up @subsubsection @code{draw circle} @cindex circles, drawing @findex draw circle @cindex @code{draw circle} command @example draw circle with radius .r_cm. at .x_cm. .y_cm. @end example @noindent Draw circle of specified radius (in cm) at the specified location (in cm on the page). @node Draw Contour, Draw Curve, Draw Circle, Draw @comment node-name, next, previous, up @subsubsection @code{draw contour} @cindex drawing contours @cindex contouring @findex draw contour @cindex @code{draw contour} command @example `draw contour [@{.value. \ [unlabelled | @{labelled "\label"@}]@} \ | @{.min. .max. .inc. \ [.inc_unlabelled.] [unlabelled]@}]' @end example @noindent This command draws contours based on the "grid" data previously read in by a @code{read grid data} command or created by gridding column data with a @code{create grid from columns} command. If the grid data don't exist, or if the x and y locations of the grid points do not exist (see @code{set x grid}, @code{set y grid}, etc), Gri will complain. With no optional parameters, draw labelled contours at an interval that is picked automatically based on the range of the data. With a single numerical value (@code{.value.}), draw the indicated contour. With the addition of @code{labelled "\label"}, put the indicated label instead of a numeric label. This can be useful for using scientific notation instead of computer notation for exponents, e.g. @code{draw contour 1e-5 labelled "10$^@{-5@}$"}. With (@code{.min.}, @code{.max.} and @code{.inc.}) given, draw contours for z(x,y) = @code{.min.}, z(x,y) = @code{.min. + .inc.}, z(x,y) = @code{.min. + 2*.inc.}, ..., z(x,y) = @code{.max.} With the additional value @code{.inc_unlabelled.} specified, extra unlabelled contours are drawn at this finer interval. With the optional parameter @code{unlabelled} at the end of any form of this command (except the @code{labelled "\label"} variation, of course), Gri will not label the contour(s). @strong{Hint:} It can be effective to draw contours at a certain interval with labels, and a thicker pen, e.g. @example set line width rapidograph 3x0 draw contour -2 5 1 0.25 set line width rapidograph 1 draw contour -2 5 1 @end example @b{Interpolation method:} The interpolation scheme is the same used for converting grid-values to image values (@ref{Convert Grid To Image}). @strong{See also} @code{set contour labels} @node Draw Curve, Draw Essay, Draw Contour, Draw @comment node-name, next, previous, up @subsubsection @code{draw curve} @findex draw curve @cindex @code{draw curve} command @cindex x-y graphs @cindex region painting @cindex paint regions with color @cindex filled regions @cindex drawing curves @cindex curves, drawing Several forms exist. @example `draw curve' @end example @noindent Draws a curve connecting the points (x,y), which have been read in by a command like @code{read columns x y}. Line segments are drawn between all (x,y) points, except: (1) no line segments are drawn to any missing data (see @code{set missing value}), and (2) if clipping is turned on (see @code{set clip on}), no line segments are drawn outside the clipping region. @strong{See also} @code{draw curve overlying} @example `draw curve overlying' @end example @noindent Like @code{draw curve}, except that before drawing, the area underneath the curve (+/- one linewidth) is whited out. This clarifies graphs where curves overlie other curves or the axes. @strong{See also} @code{draw curve}. @example `draw curve filled [to @{.y. y@}|@{.x. x@}]' @end example @noindent The form @code{draw curve filled ...} draws filled curves. If the @code{to .value.} is not specified, fill the region defined by the x-y points using the current paint colour (see @code{set graylevel}). To complete the shape, an extra line is drawn between the first and last points. The form @code{draw curve filled to .y. y} fills the region between y(x) and y = @code{.y.}; do not connect the first and last points as in the case where @code{to .yvalue.} is not specified. The form @code{draw curve filled to .x. x} fills the region between x(y) and x = @code{.x.} @node Draw Essay, Draw Gri Logo, Draw Curve, Draw @comment node-name, next, previous, up @subsubsection @code{draw essay} @findex draw essay @cindex @code{draw essay} command @example `draw essay "text"|reset' @end example @noindent Draw indicated text on the page. Succeeding calls draw text further and further down the page, starting at the top. The current font size is used; to alter this, use @code{set font size} before @code{draw essay}. When @code{reset} is present instead of text, the drawing position is reset to the top of the page. Use this after a @code{new page} command to ensure that the next text lines will appear at the top of the page as expected. EXAMPLE: @example set font size 2 cm draw essay "Line 1, at top of page" draw essay "Line 2, below top line" @end example @node Draw Gri Logo, Draw Grid, Draw Essay, Draw @comment node-name, next, previous, up @subsubsection @code{draw gri logo} @findex draw gri logo @cindex @code{draw gri logo} command @cindex logo, how to draw @example `draw gri logo .x_cm. .y_cm. .height_cm. .style. \fgcolor \bgcolor' @end example @noindent Draw a Gri logo at given location with given style and colors. The lower-left corner of the logo will be @code{.x_cm.} centimeters from the left-hand side of the page and @code{.y_cm.} centimeters from the bottom of the page. The logo will be @code{.height_cm.} centimeters tall. The textual parameters @code{\fgcolor} and @code{\bgcolor} give the foreground and background colors, respectively, and these are used in styles as noted in the table below @example .style. style ======= =================== 0 stroke curve 1 fill with color \fgcolor, no background 2 fill with color \fgcolor it in tight box of color \bgcolor 3 as 2 but in square box 4 draw in \fgcolor on top of shifted copy in \bgcolor @end example An example is given below @example draw gri logo 1 1 3 4 blue green @end example @node Draw Grid, Draw Image Histogram, Draw Gri Logo, Draw @comment node-name, next, previous, up @subsubsection @code{draw grid} @findex draw grid @cindex @code{draw grid} comman @example `draw grid' @end example @noindent Draw plus-signs at locations where grid data are non-missing. @node Draw Image Histogram, Draw Image Palette, Draw Grid, Draw @comment node-name, next, previous, up @subsubsection @code{draw image histogram} @findex draw image histogram @cindex @code{draw image histogram} command @cindex image, histogra @example `draw image histogram \ [box .llx_cm. .lly_cm. .urx_cm. .ury_cm.]' @end example @noindent With no optional parameters, draw histogram of all unmasked parts of the image, placing it above the current top of the plot. When the @code{box} options are present, they specify the box (in centimetre coordinates on the page) in which the histogram plot is to be done. @node Draw Image Palette, Draw Image, Draw Image Histogram, Draw @comment node-name, next, previous, up @subsubsection @code{draw image palette} @findex draw image palette @cindex @code{draw image palette} comman @example `draw image palette [axisleft|axisright|axistop|axisbottom] [left .left. right .right. [increment .inc.]] [box .xleft_cm. .ybottom_cm. .xright_cm. .ytop_cm.]' @end example @noindent @cindex image, drawing palette @cindex image, drawing colorscale palette @cindex colorscale, drawing @cindex palette for image colorscale, drawing With no optional parameters, draw palette for image, placed above the current top showing values ranging from @code{.min_value.} to @code{.max_value.} as given in @code{set image range}. Optional keywords (@code{axisleft}, etc) control the orientation of the palette, the default being @code{axisbottom}. The optional parameters @code{.left.} and @code{.right.} may be used to specify the range to be drawn in the palette. If the additional optional parameter @code{.inc.} is present, it specifies the interval between tics on the scale; if not present, the tics are at increments of 2 * (@code{.right.} - @code{.left}.). (If @code{.inc.} has the wrong sign, it will be corrected without warning.) When the optional @code{box} parameters are present, they prescribe the bounding box to contain the palette. The units are centimetres on the page. If these parameters are not present, the box will be drawn above the image plot. @cindex hint, palette range @strong{Hint} It is a good idea to make the palette range @code{.left.} to @code{.right.} extend a little beyond the range of full white and full black, since otherwise neither pure white nor pure black will appear in the colorbar. For example @example set image grayscale black 0 white 1 increment 0.1 draw image palette left -0.1 right 1.1 increment 0.1 @end example @cindex hint, contour lines on image palette @strong{Hint} Continuous-tone images with superimposed contours are often effective. To get the contour lines drawn on the image palette, do something like this @example draw image .left. = 0 .right. = 9 .inc. = 1 .space. = 3 .height. = 1 draw image palette left .left. \ right .right. \ increment .inc. \ box \ ..xmargin.. \ @{rpn ..ymargin.. ..ysize.. + .space. + @} \ @{rpn ..xmargin.. ..xsize.. +@} \ @{rpn ..ymargin.. ..ysize.. + .space. + .height. + @} draw contour .left. .right. .inc. unlabelled .c. = .left. while @{rpn .right. .c. <= @} .c_cm. = @{rpn .c. .left. - \ .right. .left. - / \ ..xsize.. * ..xmargin.. +@} draw line from \ .c_cm. \ @{rpn ..ymargin.. ..ysize.. + .space. + @}\ to \ .c_cm. \ @{rpn ..ymargin.. ..ysize.. + .space. + .height. +@} \ cm .c. += 1 end while @end example @node Draw Image, Draw Isopycnal, Draw Image Palette, Draw @comment node-name, next, previous, up @subsubsection @code{draw image} @findex draw image @cindex @code{draw image} comman @example `draw image' @end example @noindent Draw black/white image made by @code{convert grid to image} or by @code{read image}. @node Draw Isopycnal, Draw Isospice, Draw Image, Draw @comment node-name, next, previous, up @subsubsection @code{draw isopycnal} @findex draw isopycnal @cindex @code{draw isopycnal} command @cindex T-S diagram, drawing isopycnals on @cindex temperature-salinity diagram, drawing isopycnals on @cindex isopycnals @cindex oceanographic plots isopycnals on TS diagram @example `draw isopycnal \ [unlabelled] .density. [.P_sigma. [.P_theta.]]' @end example Draw isopycnal curve for a temperature-salinity diagram. This curve is the locus of temperature and salinity values which yield seawater of the indicated density, at the indicated pressure. The UNESCO equation of state is used. For the results to make sense, the x-axis should be salinity and the y-axis should be either in-situ temperature or potential temperature. The @code{.density.} unit is kg/m^3. If the supplied value exceeds 100 then it will be taken to indicate the actual density; otherwise it will be taken to indicate density minus 1000 kg/m^3. (The deciding value of 100 kg/m^3 was chosen since water never has this density; the more intuitive value of 1000 kg/m^3 would be inappropriate since water can have that density at some temperatures.) Thus, 1020 and 20 each correspond to an actual density of 1020 kg/m^3. The reference pressure for density, @code{.P_sigma.}, is in decibars (roughly corresponding to meters of water depth). If no value is supplied, a pressure of 0 dbar (i.e. atmospheric pressure) is used. The reference pressure for theta, @code{.P_theta.}, is in decibars, and defaults to zero (i.e. atmospheric pressure) if not supplied. This option is used if the y-axis is potential temperature referenced to a pressure other than the surface. Normally the potential temperature is, however, referenced to the surface, so that specifying a value for @code{.P_theta.} is uncommon. By default, labels will be drawn on the isopycnal curve; this may be prevented by supplying the keyword @code{unlabelled}. If labels are drawn, they will be of order 1000, or of order 10 to 30, according to the value of @code{.density.} supplied (see above). The label format defaults to "%g" in the C-language format notation, and may be controlled by @code{set contour format}. The label position may be controlled by @code{set contour label position} command (bug: only non-centered style works). Setting label position is useful if labels collide with data points. Labels are drawn in the whiteunder mode, so they can white-out data below. For this reason it is common to draw data points after drawing isopycnals. If the y-axis is in-situ temperature, the command should be called without specifying @code{.P_sigma.}, or, equivalently, with @code{.P_sigma.} = 0. That is, the resultant curve will correspond to the (S,T) solution to the equation @example .density. = RHO(S, T, 0) @end example @noindent where @code{RHO=RHO(S,T,p)} is the UNESCO equation of state for seawater. This is a curve of constant sigma_T. If the y-axis is potential temperature referenced to the surface, @code{.P_theta.} should not be specified, or should be specified to be zero. The resultant curve corresponds to a constant value of potential density referenced to pressure @code{.P_sigma.}, i.e. the (S,theta) solution to the equation @example .density. = RHO(S, theta, .P_sigma.) @end example @noindent For example, with @code{.P_sigma.=0} (the default), the result is a curve of constant sigma_theta. If the y-axis is potential temperature referenced to some pressure other than that at the surface, @code{.P_theta.} should be supplied. The resultant curve will be the (S,theta) solution to the equation @example .density. = RHO(S, T', .P_sigma.) @end example @noindent where @example T'=THETA(S, theta, .P_theta., .P_sigma.) @end example @noindent where @code{THETA=THETA(S,T,P,Pref)} is the UNESCO formula for potential temperature of a water-parcel moved to a reference pressure of @code{Pref}. Note that @code{theta}, potential temperature referenced to pressure @code{.P_theta.}, is the variable assumed to exist on the y-axis. @node Draw Isospice, Draw Label Boxed, Draw Isopycnal, Draw @comment node-name, next, previous, up @subsubsection @code{draw isospice} @findex draw isospice @cindex @code{draw isospice} command @cindex T-S diagram, drawing spice lines on @cindex temperature-salinity diagram, drawing spice lines on @cindex spice lines, on TS diagram @cindex oceanographic plots, iso-spice lines on TS diagrams @example `draw isospice .spice. [unlabelled]' @end example @noindent Draw an iso-spice line for a "TS" diagram, using (S, T) data stored in files in a subdirectory named @code{iso-spice0} in a directory named by the unix environment variable @code{GRI_EOS_DIR}. You must set this environment variable yourself, in the normal unix way. If @code{GRI_EOS_DIR} is not defined, Gri looks in the directory @file{/data/po/ocean/EOS/iso0}; of course, this will work only for people on the same machine as the author. Only certain iso-spice lines are stored in these files, so only certain values of @code{.spice.} are allowed. They are 21.75, 22.00, 22.25, ..., 30.75. You must supply @code{.density.} in exactly this format (with 2 decimal places), or else Gri will not find the appropriate TS file, and will give a "can't open file" error. NB: isopycnals ranging from about 23.00 to 26.00 cross a TS diagram spanning 34Symbols in gri @c HTML

    @c HTML @node Draw Symbol Legend, Draw Symbol, Draw Symbol At, Draw @comment node-name, next, previous, up @subsubsection @code{draw symbol legend} @findex draw symbol legend @cindex @code{draw symbol legend} command @example `draw symbol legend \symbol_name "label" \ at .x. .y. [cm]' @end example @noindent Draw indicated symbol at indicated location, with the indicated label beside it. The label is drawn one M-space to the right of the symbol, vertically centered on the indicated @code{.y.} location. @node Draw Symbol, Draw Time Stamp, Draw Symbol Legend, Draw @comment node-name, next, previous, up @subsubsection @code{draw symbol} @findex draw symbol @cindex @code{draw symbol} command @example `draw symbol [[.code.|\name] \ | [graylevel z] \ [color [hue z|.h.] \ [brightness .b.] \ [saturation .s.]]]' @end example @noindent With no optional parameters, draw symbols at the (x,y) data. If a z-column has been read with @code{read columns}, then its value codes the symbol to draw, according to the table below. (The value of z is first rounded to the nearest integer.) If no z-column has been read, the symbol X is drawn at each datum. With the optional numerical/name code specified, then the symbol of that number or name is drawn at each (x,y) datum, whether or not a z-column exists. The numerical/name codes are: @c HTML

    Symbols in Gri
    @c HTML

    @c HTML With the optional @code{graylevel z} fields specified, the graylevel is given by the @code{z} column (0=black, 1=white). With the optional @code{color} field specified, the color is specified, either directly in the command (the @code{hue .h.} form) or in the z column. For more information on color, refer to the @code{set color hsb ...} command. Examples: both @code{draw symbol bullet color} and @code{draw symbol bullet color hue z} draw bullets whose hue is given by the value in the z column. The hue (or the color, in other words) blends smoothly across the spectrum as the numerical value ranges from 0 to 1. The value 0yields red, 1/3 yields green, 2/3 yields blue, etc. If the @code{brightness} and the @code{saturation} are not specified, they both default to the value 1, which yields pure, bright colors. Example: draw all in green dots @code{draw symbol bullet color hue 0.333 brightness 1 saturation 1} Example: display spectrum of dots @example set symbol size 0.3 open "awk 'END@{ \ for(c=0;c<1;c+=1/40) \ print(c,c,c)@}' | " read columns x y z close draw symbol bullet color hue z @end example @node Draw Time Stamp, Draw Title, Draw Symbol, Draw @comment node-name, next, previous, up @subsubsection @code{draw time stamp} @findex draw times stamp @cindex @code{draw time stamp} command @example `draw time stamp \ [fontsize .points. \ [at .x_cm. .y_cm. cm \ [with angle .deg.]]]' @end example @noindent Draw the command-file name, PostScript file name, and time, at the top of graph. Normally, the timestamp is drawn at the top of the page, in a fontsize of 10 points. But the user can specify the fontsize, and additionally the location (in cm) and additionally the angle measured in degrees anticlockwise from the horizontal. NOTE: If you want to have the plot drawn in landscape mode, ensure that @code{set page landscape} precedes @code{draw time stamp.} @node Draw Title, Draw Values, Draw Time Stamp, Draw @comment node-name, next, previous, up @subsubsection @code{draw title} @findex draw title @cindex @code{draw title} command @example `draw title "\string"' @end example @noindent Draw the indicated string above the plot. @node Draw Values, Draw X Axis, Draw Title, Draw @comment node-name, next, previous, up @subsubsection @code{draw values} @findex draw values @cindex @code{draw values} command @example draw values \ [.dx. .dy.] \ [\format] \ [separation .xcm. .ycm.] @end example @noindent Draw values of @code{z} column, at corresponding (@code{x}, @code{y}) locations. If the @code{separation} keyword is present, the distance between successive points is checked, and points are skipped unless the x and y separations exceed the indicated distances. @itemize @bullet @item @code{draw values} Draw the values of @code{z(x,y)}, positioned 1/2 M-space to the right of @code{(x,y)} and vertically centred on @code{y}. The values are written in a good general format known as @code{%lg}, in C terminology. @item @code{draw values %.2f} Draw values of @code{z(x,y)} positioned as described above, but using the indicated format string. This format string specifies that 2 numbers be used after the decimal place, and that floating point should be used. See any C manual for format codes. @item @code{draw values .dx. .dy.} Print values of @code{z(x,y)} at indicated offset vector (@code{.dx.},@code{.dy.}), measured in centimeters, from the values of @code{(x,y)} at which the data are defined. @item @code{draw values .dx. .dy. %.3f} Print values of @code{z(x,y)} at indicated distance from @code{(x,y)}, indicated format. @end itemize @node Draw X Axis, Draw X Box Plot, Draw Values, Draw @comment node-name, next, previous, up @subsubsection @code{draw x axis} @findex draw x axis @cindex @code{draw x axis} command @example draw x axis [at bottom|top|@{.y. [cm]@} [lower|upper]] @end example @noindent Draw an x axis, optionally at a specified location and of a specified style. @itemize @bullet @item @code{draw x axis} Draw a lower x axis (ie, one with the numbers below the line) at the bottom of the box defined by @code{set y axis}. @item @code{draw x axis at bottom} Draw a lower x axis (ie, one with the numbers below the line) at the bottom of the box defined by @code{set y axis}. @item @code{draw x axis at top} Draw an upper x axis (ie, one with the numbers above the line) at the top of the box defined by @code{set y axis} (or above any existing stacked x axes there) @item @code{draw x axis at .y.} Draw a lower x axis at indicated value of @code{.y.}. @item @code{draw x axis at .y. upper} Draw an upper x axis at indicated value of .y. @end itemize @node Draw X Box Plot, Draw Y Axis, Draw X Axis, Draw @comment node-name, next, previous, up @subsubsection @code{draw x box plot} @findex draw x box plot @cindex @code{draw x box plot} command @example draw x box plot at .y. [size .cm.] @end example @noindent Draw Tukey box plots (which give a summary of histogram properties). Box plots were invented by Tukey for eda (exploratory data analysis). The centre of the box is the median. The box edges show the first quartile (q1) and the third quartile (q3). The distance from q3 to q1 is called the inter-quartile range. The whiskers (i.e., the lines with crosses at the end) extend from q1 and q3 to the furthest data points which are still within a distance of 1.5 inter-quartile ranges from q1 and q3. Beyond the whiskers, all outliers are shown: open circles are used for data within a distance of 3 inter-quartile ranges beyond q1 and q3, and in closed circles beyond that. As a side effect, this command stores q1, q2, and q3 into variables @code{..q1..}, @code{..q2..}, and @code{..q3..}. @itemize @bullet @item @code{draw x box plot at .y.} Draw Tukey's box plot, spreading in the x direction, centered at y=@code{.y.} and of default width 0.5 cm. @item @code{draw x box plot at .y. size .cm.} Draw Tukey's box plot, spreading in the x direction, centered at y=@code{.y.} and of width @code{.cm.} centimetres. @end itemize @node Draw Y Axis, Draw Y Box Plot, Draw X Box Plot, Draw @comment node-name, next, previous, up @subsubsection @code{draw y axis} @findex draw y axis @cindex @code{draw y axis} command @example draw y axis [at left|right|@{.x. cm@} [left|right]] @end example @noindent Draw a y axis, optionally at a specified location and of a specified style. @itemize @bullet @item @code{draw y axis} Draw a left-hand-side y axis (ie, one with the numbers to the left of the line) at left of box defined by `set x axis' @item @code{draw y axis at left} Draw a left-hand-side y axis (ie, one with the numbers to the left of the line) at left of box defined by @code{set x axis}. @item @code{draw y axis at right} Draw a right-hand-side y axis (ie, one with the numbers to the right of the line) at right of box defined by @code{set x axis}. @item @code{draw y axis at .x.} Draw a left-hand-side y axis (ie, one with the numbers to the left of the line) at indicated value of @code{.x.} @item @code{draw y axis at .x. right} Draw a right-hand-side y axis (ie, one with the numbers to the right of the line) at indicated value of @code{.x.} @end itemize @node Draw Y Box Plot, Draw Zero Line, Draw Y Axis, Draw @comment node-name, next, previous, up @subsubsection @code{draw y box plot} @findex draw y box plot @cindex @code{draw y box plot} command @example draw y box plot at .x. [size .cm] @end example @noindent Draw Tukey box plots (which give summary of histogram properties). @itemize @bullet @item @code{draw y box plot at .x.} Draw Tukey's box plot, spreading in the y direction, centered at x=@code{.x.} and of default width 0.5 cm. @item @code{draw y box plot at .x. size .cm.} Draw Tukey's box plot, spreading in the y direction, centered at x=@code{.x.} and of width @code{.cm.} centimetres. @end itemize As a side effect, this command stores q1, q2, and q3 into variables @code{..q1..}, @code{..q2..}, and @code{..q3..}. @node Draw Zero Line, End Group, Draw Y Box Plot, Draw @comment node-name, next, previous, up @subsubsection @code{draw zero line} @findex draw zero line @cindex @code{draw zero line} command @example draw zero line [horizontally|vertically] @end example @noindent Draw lines corresponding to x=0 or y=0. @itemize @bullet @item @code{draw zero line} Draw line y=0 if it is within axes. @item @code{draw zero line horizontally} Draw line y=0 if it is within axes. @item @code{draw zero line vertically} Draw line x=0 if it is within axes. @end itemize @c HTML @node End Group, Expecting, Draw Zero Line, List Of Gri Commands @comment node-name, next, previous, up @subsubsection @code{end grouip} @findex end group @cindex @code{end group} command @example end group @end example @noindent @emph{Command not implemented yet. Syntax may change.} @c HTML @node Expecting, Filter, End Group, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{expecting} @cindex changes to Gri, protection against @cindex protection against changes to Gri @findex expecting @cindex @code{expecting} command @cindex incompatibilities, keeping track of @example expecting version a.b expecting version a.b.c @end example @noindent Show a list of incompatibilites that have been introduced since the named version. This command can make your commandfiles more reliable against changes to Gri. There are two forms of the version number. Modern versions use the triplet form, e.g. @code{expecting version 2.8.7}, but prior to October 1996 the version numbers were written in decimal form, so that you would write @code{expecting version 1.069} for example. @c HTML @node Filter, Flip, Expecting, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{filter} @cindex columns, filtering @cindex images, filtering @cindex filtering image data @cindex filtering column data @cindex smoothing column data @findex filter @cindex @code{filter} command @itemize @bullet @item @code{filter column x|y|z|u|v|weight recursively a[0] a[1] ... b[0] b[1] ...} Filter indicated column, using a two-pass recursive filter. The first pass runs from the start to the end, while the second pass runs from the end to the start; in this way, the phase shift inherent in this type of filter is removed entirely. The coefficients are used in the following formula (demonstrated on the @code{x} column): @example x_new[i] = b[0] * x[i] \ + b[1] * x[i-1] \ + b[2] * x[i-2] \ + ... \ - a[1] * x_new[i-1] \ - a[2] * x_new[i-2] \ - ... @end example @noindent Thus, for example, setting @code{a[i]} = 0 results in a simple backwards-looking moving-average filter applied in two passes. The real power of this type of filter, however, comes when non-zero @code{a[i]} coefficients are given, thus adding recursion (i.e., @code{x_new[i]} depends on @code{x_new[i-...]}). See any standard reference on digital filters for an explanation. You might find that the Matlab command @code{butter} an easy way to design filter coefficients. Here are some examples: @example # Filter x column with simple 2-point moving # average. (This slurs into a 3-point moving # average, in effect, since the filter is run # forwards and then backwards.) filter column x recursively 0 0 0.5 0.5 # Use filter designed with the Matlab # command butter(2,0.1), which creates a # 2nd order lowpass butterworth filter # with a cutoff frequency of 0.1 # (in units which have a frequency # of 1 corresponding to one-half the # sampling rate). filter column x recursively \ 1 -1.561 0.6414 \ 0.0201 0.0402 0.0201 @end example @item @code{filter grid rows|columns recursively a[0] a[1] ... b[0] b[1] ...} @noindent Apply recursive filter (see @code{filter column ... recursively} for meaning of this filter operation) to the individual rows or columns of the grid data. For example, the command @code{filter grid columns recursively 0 0 0.5 0.5} applies a 2-point moving average filter across the columns, smoothing the grid in the x-direction. @item @code{filter image highpass} Remove low-wavenumber components from image (ie, sharpen edges). Do this by subtracting a Laplacian smoothed version of the image. @item @code{filter image lowpass} Remove high-wavenumber components from image (ie, smooth shapes). Do this by Laplacian smoothing. @end itemize @strong{See also} @ref{Smooth}. @c HTML @node Flip, Get Env, Filter, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{flip} @cindex grid, flipping @cindex image, flipping @cindex flipping grids and images @findex flip @cindex @code{flip} command @example `flip grid|image x|y' @end example @noindent Flip grid or image by relecting it about a horizontal or vertical centerline. @itemize @bullet @item @code{flip grid x} Flip grid so right-hand side becomes left-hand side. @item @code{flip grid y} Flip grid so bottom side becomes top side. @item @code{flip image x} Flip image so right-hand side becomes left-hand side. @item @code{flip image y} Flip image so bottom side becomes top side. @end itemize @c HTML @node Get Env, Group, Flip, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{get env} @cindex environment variables @cindex unix environment variables @cindex operating system, getenv @cindex operating system, environment variables @findex get env @cindex @code{get env} command @example `get env \result \environment_variable' @end example @noindent Get the value of an "environment variable" from the unix operating system, and store the result in the indicated synonym. This makes most sense on unix systems (hence the name, patterned after the unix command @code{getenv}). This command can be useful in making gri programs resistant to changes in data-file locations. Suppose, for example, there is a file called @file{data}, normally in a local directory called @code{Bravo}. The line @code{open Bravo/data} will fail if the Bravo directory is moved. But if the name of the datafile is stored in an unix environment variable, @code{DIR_BRAVO} say, then the gri program will work no matter where the Bravo data are moved, so long as an appropriate environment variable is modified when the data are moved. Example: @example get env \dir DIR_BRAVO if @{rpn "\dir" "" ==@} show "Cannot determine location of the Bravo data," show "which should be stored in the environment" show "variable DIR_BRAVO. You should" show "do something like" show "export DIR_BRAVO='/data/Bravo/'" show "in your ~/.environment file" quit end if open \dir/data ... @end example @c HTML @node Group, Heal, Get Env, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{group} @findex group @cindex @code{group} command @example `group ["\name"]' @end example @noindent @emph{Command not implemented yet. Syntax may change.} @c HTML @node Heal, Help, Group, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{heal} @findex heal @cindex @code{heal} command @example heal columns|@{columns along x|y@} @end example The @code{heal} command heals over gaps in either columnar or gridded data. This is done by linear interpolation across the missing-value gaps. @itemize @bullet @item @code{heal columns} @noindent Fill in missing values in x, y, z, ... columns, by linear interpolation to neighboring valid data. All gaps in the data will get replaced by a linear function of index which matches the data at the indices just before and just after the gap. For example, if the y data were like @example 111 3 -9 -9 -9 7 333 @end example @noindent where @code{-9} is the missing-value code, then they would get replace by @example 111 3 4 5 6 7 333 @end example @noindent Notes: (1) This is done @strong{independently} for all existing columns. (2) Gaps at the start and end of the columns are not filled in. @item @code{heal grid along x} @noindent Scan in the x direction, filling in missing values by linear interpolation. Since this uses the the x-grid, you must first have done @code{read grid x} or @code{set x grid}. @item @code{heal grid along y} @noindent Scan in the y direction, filling in missing values by linear interpolation. Since this uses the the y-grid, you must first have done @code{read grid y} or @code{set y grid}. @end itemize @c HTML @node Help, If, Heal, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{help} @findex help @cindex @code{help} command @example `help [*|command_name|@{- topic@}]' @end example @noindent Give help on a command or topic. @itemize @bullet @item @code{help} Print a general help message. @item @code{help *} Prints complete help info. @item @code{help command_name} Prints help on the command whose name begins with the string @code{command_name}. The string may be several words long; e.g. @code{help set} or @code{help set x axis}. @item @code{help - topic_name} The minus sign tells Gri that the string to follow it is a topic, not a command. Topics Gri knows about are listed by the one-word @code{help} request. @end itemize @c HTML @node If, Ignore, Help, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{if} @cindex if statements @findex if @cindex @code{if} command (@strong{See also} @ref{If Statements}.) @example `if @{[!] .flag.@}|\flag|@{@{"string1" == "string2"@}@}' @end example @noindent Control program flow. The @code{if} block is ended with a line containing @code{end if}. Optional @code{else} and @code{else if} blocks are allowed. Note that rpn expressions are allowed, and a special form of string comparison is allowed, as in the examples below. @example if .flag. # List of Gri commands to be done if .flag. is 1. # This list may extend across any number of lines. end if @end example @noindent If the variable @code{.flag.} is not equal to 0, do the code between the @code{if} line and the @code{end if} line. @example if .flag. # Commands done if .flag. is 1 else # Commands done if .flag. is 0 end if @end example @noindent If the variable @code{.flag.} is not equal to 0, do the code between the @code{if} line and the @code{else} line. If @code{.flag.} is equal to 0, do the code between the @code{else} line and the @code{end if} line. @example if ! .flag. # Commands done if .flag. is 0 end if @end example @noindent If the variable @code{.flag.} is equal to 0, do the code between the @code{if} line and the @code{end if} line. @example if @{rpn .flag. 10 <@} # Commands done if 10 is less than .flag. end if @end example @noindent If the variable @code{.flag.} is greater than 10, do the code between the @code{if} line and the @code{end if} line. @example if \smooth # Commands done if \smooth is 1 else # Commands done if \smooth is 0 end if @end example @noindent If the number stored in the synonym @code{\smooth} is not equal to 0, do the code between the @code{if} line and the @code{else} line. If the synonym stores a representation of a number not equal to zero, do the @code{else} part. If the synonym contains text that does not decode to a number, generate error message. @example if @{"\item" == "Temperature"@} # Commands done if the synonym \item is equal to the # indicated text string. end if @end example @noindent If the synonym @code{\item} has the value @code{Temperature} stored in it, do the indicated code. @example if @{rpn "\item" "Temperature" ==@} # Commands done if the synonym \item # equals indicated text string. end if @end example @noindent As above, but using the @code{rpn} calculator (@ref{rpn Mathematics}). @example if @{rpn "\item" "Temperature" !=@} # ... end if @end example @noindent As above, but do the indicated code if @code{\item} is @strong{not} equal to @code{Temperature}. @c HTML @node Ignore, Input, If, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{ignore} @findex ignore @cindex @code{ignore} command @example `ignore last .n.' @end example @noindent Ignores last @code{.n.} lines read by @code{read columns}. @c HTML @node Input, Insert, Ignore, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{input} @findex input @cindex @code{input} command @example `input \ps_filename \ [.xcm. .ycm. \ [.xmag. .ymag. \ [.rot_deg.]]]' @end example @noindent Input the named PostScript file directly into the Gri output PostScript file. (If the filename has punctuation, insert it in double quotes, e.g. @code{input "../thefile"}.) If no options are specified, the file is input at normal scale, with normal margins. (Aside to PostScript programmers: the named file is sandwiched between @code{gsave} and @code{grestore} commands.) If @code{.xcm.} and @code{.ycm.} are specified, then the origin is moved to the named location first. If, in addition, @code{.xmag.} and @code{.ymag.} are specified, then these are used as scale factors after translation. Finally, if @code{.rot_deg.} is specified in addition, then the indicated counterclockwise rotation is applied after translation and scaling. Hint: if the results look wrong, the first thing to do is to think carefully about the order of the (translation, scaling, rotation) operations. @c HTML @node Insert, Interpolate, Input, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{insert} @findex insert @cindex @code{insert} command @example `insert \filename' @end example @noindent Perform the commands in the indicated file. If the file name is absolute (i.e. starts with @code{.}, or with @code{/} or with @code{~}) then an error results if the file is not present (or cannot be read by this user). However, if the file name starts with a normal letter, Gri will try harder to locate the file. If it is not in the local directory, and if a @code{set path to "PATH" for commands} has been done, then Gri will search the colon-separated directories for the file (@ref{Set Path To}). If you don't want path-searching done, use the @code{source} command instead (@ref{Source}). @c HTML @node Interpolate, List, Insert, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{interpolate} @findex interpolate @cindex @code{interpolate} command @cindex contouring, interpolating to new grid @cindex grid, interpolating from one to another @example interpolate x grid to .left. .right. .inc.|@{/.cols.@}' interpolate y grid to .bottom. .top. .inc.|@{/.rows.@}' @end example @noindent Transform grid by interpolating between existing grid data, according to a new x or y grid specified in the manner of @code{set x grid} and @code{set y grid}. Note that the new grid is neccessarily regular, while the first grid needn't have been. The data of the new grid are constructed by interpolation, using the same interpolation algorithm as the @code{convert grid to image} command. @c HTML @node List, Ls, Interpolate, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{list} @findex list @cindex @code{list} command @example `list \command-syntax' @end example @noindent List the source of a gri command. Often this is just the name of a C function internal to gri (try @code{list list} for an example), but when the command is written in the gri programming language the source will be more understandable (try @code{list set panel}). @c HTML @node Ls, Mask, List, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{ls} @cindex files, listing @cindex directory listing @findex ls @cindex @code{ls} command @example `ls [\file_specification]' @end example @noindent List files in current directory. (The current directory can be printed by the gri command @code{pwd} and can be set by the gri command @code{cd}.) @code{ls \file_specification} lists files in current directory which match the file specification. Normal unix file specification options are understood. @c HTML @node Mask, New, Ls, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{mask} @cindex masking image @cindex image, masking @findex mask @cindex @code{mask} command @example `mask the image [to @{uservalue .u.@}|@{imagevalue .i.@}]' @end example @noindent Examine both the image and the mask pixel by pixel. For any pixels which have a mask value of 1 (which indicates an invalid region of the image), change the image value. If no @code{to} phrase is present, change the image value to 0 in pixel units. If the @code{to uservalue .u.} phrase is present, change the pixel to hold the imagevalue that corresponds to this uservalue (see @code{set image range} command for a discussion of this correspondance). If the @code{to imagevalue .i.} phrase is present, change the pixel to hold that imagevalue (in range 0 to 255 inclusive for 8-bit images). @c HTML @node New, Newpage, Mask, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{new} @findex new @cindex @code{new} command @cindex synonyms, multiple copies of @cindex synonyms, making local versions @cindex variables, making local versions @cindex variables, multiple copies of @example new .variable_name. | \synonym_name \ [.variable_name. | \synonym_name \ [...]] @end example @noindent @code{new} sets aside storage for new version of the named variable(s) and/or synonym(s). Any number of variables and synonyms may be specified. If a given variable/synonym already exists, this will create a new version of it, and future assignments will be stored in this new version @strong{without} affecting the pre-existing version. If the variable/synonym is @code{delete}ed, the new version is deleted, making the old, unaltered, version accessible again. This command is used mostly for temporary use, to prevent clashing with existing values. Suppose you want to change the font size inside a new command or an if block. Then you might do the following, where the variable @code{.tmp.} is used to store the old font size. Note that the use of the @code{new/delete} statements prevents the assignment to the local version of the variable @code{.tmp.} from affecting the value known outside the @code{if} block, if in fact @code{.tmp.} happened to exist outside the block. @example set font size 10 draw label "This is in fontsize 10" at 10 2 cm if .want_title. new .tmp. .tmp. = ..fontsize.. set font size 22 draw label "This is 22 font" at 10 5 cm set font size .tmp. delete .tmp. end if draw label "This is 10 font" at 10 8 cm @end example @strong{Special case}: for local synonyms (e.g. @code{\.word1.}, etc.), the @code{new} operator checks to see whether the synonym is standing for an "ampersand" argument, signalling a changeable argument that is a variable or a synonym. In such a case, @code{new} creates a new instance of the item in the calling context. The test suite has examples (@ref{Test Suite}). @c HTML @node Newpage, New Postscript File, New, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{new page} @cindex page breaks @findex new page @cindex @code{new page} command @example `new page' @end example @noindent Finish the present page, and start a new page. All settings (of linewidth, axes, landscape/portrait, etc) are retained on the new page. Among these settings is the flag that tells gri whether you need axes plotted along with your data. @node New Postscript File, Open, Newpage, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{new postscript file} @findex new postscript file @cindex @code{new postscript file} command @example `new postscript file "name"' @end example @noindent Finish the present Postscript file, and start a new page with the given name. All settings (of linewidth, axes, landscape/portrait, etc.) and data are retained on the new file. @c HTML @node Open, Opening Simple Files, New Postscript File, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{open} @findex open @cindex @code{open} command @cindex netCDF files, opening @cindex operating system, filtering datafiles @cindex system commands acting as datafiles @cindex data files, opening @cindex opening data files There are two styles of @code{open} command. In the first style, a simple file is to be opened. In the second style a unix-like "pipe" is opened, i.e. Gri will read the output of a system command instead of a file. @menu * Opening Simple Files:: * Opening Pipes:: * Opening URLs:: @end menu @node Opening Simple Files, Ascii Files, Open, Open @comment node-name, next, previous, up @subsubsection Opening simple files @menu * Ascii Files:: * Binary Files:: * NetCDF Files:: @end menu @node Ascii Files, Binary Files, Opening Simple Files, Opening Simple Files @comment node-name, next, previous, up @b{Ascii Files} Most applications involve ascii files, and these are very easy to handle in Gri. For example given a data file named @file{foo.dat}, just use the command @example open foo.dat @end example @noindent and then you can read the data using various commands. Thus a complete program might be @example open foo.dat read columns x y draw curve @end example If a filename contains blanks or punctuation symbols, you must put it in double quotes (@code{"}), e.g. @example open "foo bar.dat" @end example Indeed, Gri accepts double-quotes on any @code{open} command and some folks use it on all commands, as a matter of habit. Gri can handle compressed files appropriately, e.g. @example open foo.data.gz @end example @noindent so that there is no need to uncompress data for use with Gri. @cindex compressed files, opening @cindex gzipped files, opening @cindex opening gzipped @cindex opening compressed files Gri is quite persistant in looking for your file, and if a given file is not found, it will then check to see if a compressed version is available, and use that instead. Thus @example open foo.dat @end example @noindent will look for a file named @file{foo.dat.gz} if @file{foo.dat} is not available. (Only files compressed with the GNU @code{gzip} utility are handled.) If the @code{open} command was successful in opening the file, it will set the value of the synonym @code{\.return_value.} to the @b{full} pathname of the file. Thus, if @code{open a.dat} is done in directory @code{/home/gri}, then @code{\.return_value.} will equal the string @code{/home/gri/a.dat}. @node Binary Files, NetCDF Files, Ascii Files, Opening Simple Files @comment node-name, next, previous, up @cindex binary data @b{Binary Files} @cindex endian file compatibility, caution @cindex little-endian vs big-endian data, caution @cindex big-endian vs little-endian data, caution Like most computer programs, Gri has some trouble with binary files. One big issue is the so-called "endian" character of the computer. Some computers store multi-byte values with the most significant bytes first, while others store them with the most significant bytes last. The problem is that nothing is stored in data files to indicate which convention was employed. For this reason, a version of Gri compiled on a so-called "big-endian" computer will misinterpret multi-byte values that were created on a so-called "little-endian" computer. Many folks in the scientific community have converted to using the NetCDF format (see next section) for precisely this reason, since this format is independent of the endian character of the computer. Presuming an appropriate endian character, however, reading is straightforward. A command of the form @example open foo.dat binary @end example @noindent tells Gri that the data are stored in a binary format. With the above syntax, Gri expects images to be in @code{unsigned char} (8 bits), while other data, such as columns and grids, are expected to be in 32-bit format (suitable for reading into a so-called "float" variable in the C programming language). You may also specify the format directly, as in the following examples; Gri then interprets all data as being in the indicated format and then converts to the internal format before using the data. @example open \filename binary uchar open \filename binary 8bit open \filename binary int open \filename binary float open \filename binary double open \filename binary 16bit @end example As with ascii files, Gri will automatically uncompress any files that are compressed, and if it fails to find a given filename, it will try to open a compressed version of it (i.e. one with a @file{.gz} suffix). @node NetCDF Files, Opening Pipes, Binary Files, Opening Simple Files @comment node-name, next, previous, up @b{NetCDF Files} @cindex netcdf data The NetCDF format provides the best of both worlds. It is binary, so that data are relatively compact, and may be read very quickly. (Reading ascii data is time-consuming in C++, the language in which Gri is written.) But it does not suffer the endian problem problem of normal binary files (see previous section), since information about the endian character is stored in the file itself, and Gri uses this information to decode the data without difficulty, regardless of the endian characteristics of the computer on which Gri is running and of the computer that created the data. For more information on netCDF format, see @code{http://www.unidata.ucar.edu/packages/netcdf/index.html} @c HTML @c HTML here . The syntax of opening NetCDF files is as below @example open foo.nc netCDF @end example @noindent and the syntax for reading such files is described in sections on the various @code{read} commands (see e.g. @ref{Read Columns}). @node Opening Pipes, Opening URLs, NetCDF Files, Open @comment node-name, next, previous, up @subsubsection Opening pipes @cindex pipes, opening files through them Sometimes it makes sense to get Gri to work with the results of another command in the OS. Gri handles this by creating a so-called "pipe", thus reading the output from the other command. (Readers familiar with the unix OS will know what pipes are all about, and especially why they are a good thing. Other readers might wish to skip this section.) Suppose we wish to plot an x-y plot using just the first few lines of a datafile named @file{foo.dat}. Unix users will know that a good way to see the first few lines of such a file would be to type the command @code{head foo.dat}. They also know that these lines could be provided to a second unix command, named @file{do_foo} say, by the command @code{head foo.dat | do_foo}. This uses a so-called "pipe", designated by the vertical line (called a pipe symbol below). Gri can read the output from system commands by using a syntax in which the (quoted) system command ends in a pipe symbol, e.g. @example open "head foo.dat |" @end example @noindent as in the example above. @strong{Aside}: When pipe-open commands are used, Gri creates a temporary file (often located in @file{/usr/tmp}, but that varies with machine). This is automatically cleaned up when Gri completes executation, but if Gri dies (or is interrupted) before it finishes, you'll be left with an extra file in this temporary-storage directory. It's up to you to clean that directory up from time to time. Some common examples of pipe-open commands are given below. @enumerate @item @cindex csv data @cindex data, csv @cindex data, comma-separated values @cindex data, stored in comma-separated values @cindex data, from a spreadsheet @cindex data, spreadsheet @cindex comma-separated values @cindex spreadsheet data @strong{Comma-separated values} are common in files created by, or intended for, spreadsheets. Since Gri expects data elements to be separated by blanks (or tabs), you'll have to convert the commas into blanks. There are many ways to do that using pipes, e.g. @file{sed} system utility, e.g. @example open "sed -e 's/,/ /g' foo.dat |" @end example Other unix facilities, such as @code{tr} will also work, of course. If the file has headers, you'll want to remove them also. This can be done with the @code{skip} command (@ref{Skip}) but you could also do it at the open stage, e.g. to remove the first two lines, use @example open "sed -e 's/,/ /g' foo.dat | tail +2 |" @end example @item @strong{Manipulating column data} is done by e.g. @example open "cat foo.dat | awk '@{$1, $2 * 22@}' |" @end example @noindent where @file{awk} has been used to multiply the second column in the file named @file{foo.dat} by 22. @item @strong{Time-based and geographical data} are sometimes encountered. For an example, suppose that longitude/latitude (i.e. x/y) data are stored in Hour.minutesecond format, e.g. 12.2133 means hour 12, minute 21, second 33. Gri doesn't read HMS format, but gawk can be told to: @cindex geography, converting hour-minute-second to decimal hour @cindex maps, converting hour-minute-second to decimal hour @cindex conversion, hour-minute-second to decimal hour @cindex hms format @cindex hour, minute, second data @cindex gawk, using to convert files from HMS to decimal @example open "cat datafile.HMS | \ awk '@{ \ split($1, hms, \".\"); \ h = hms[1]; \ m = int(hms[2] / 100); \ s = hms[2] - 100 * m; \ x = h + m / 60 + s / 3600; \ split($2, hms, \".\"); \ h = hms[1]; \ m = int(hms[2] / 100); \ s = hms[2] - 100 * m; \ y = h + m / 60 + s / 3600; \ print(x,y) \ @}' | " read columns x y @end example @item @strong{Timeseries data} are often stored in formats that blend letters and numbers. For one thing, using letters (e.g. @code{aug}) removes an ambiguity in numerically-based data. (Example: 02/03/2000 means one thing to an American and another thing in the rest of the world. However, everybody agrees on what 2000-Feb-03 means.) Suppose, for example, that we have data in a format such as @example Tue_Jul_25_11:07:51 0.62 Tue_Jul_25_11:22:51 0.59 Tue_Jul_25_11:37:51 0.56 @end example @noindent (stored in a file called @file{foo.dat} say) and we want a graph of the y-variable (0.62, 0.59, 0.56) versus x-variable, time expressed say as seconds in the day. Then here is how that could be done: @example open "cat foo.dat |\ sed -e 's/_/ /g' -e 's/:/ /g' |\ awk '@{print ($4*3600+$5*60+$6, $7)@}' |" read columns x y draw curve @end example Note that the actual day information is skipped in this example; seasoned @code{awk} users could easily fill in the code to handle datasets spanning several days. @end enumerate @node Opening URLs, Postscript, Opening Pipes, Open @comment node-name, next, previous, up @subsubsection Opening URLs @cindex URL, how to open Gri can open a URL, @emph{if} you have the @code{wget} program on your machine. (@code{wget} is available from the GNU website @url{http://www.gnu.org/software/wget/}.) The URL must be enclosed in quotes (since otherwise, Gri will interpret the @code{//} sequence as indicating an old way of denoting comments). For example, @example open "http://gri.sourceforge.net/gridoc/examples/example1.dat" read columns x y show columns @end example If you don't have @code{wget} installed on your machine, the above won't work, but you can always use another fetching program, with a system call, as in the following: @example \url = "http://gri.sourceforge.net/gridoc/html/examples/example1.dat" open "lynx -dump \url |" read columns x y draw curve @end example @c HTML @node Postscript, Pwd, Opening URLs, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{postscript} @cindex write PostScript commands directly to output file @cindex postscript file, write to @findex postscript @cindex @code{postscript} command @example `postscript \string' @end example @noindent Write the indicated string to the PostScript output file, after substitution of synonyms if there are any. Example: @example \a = "45" # angle \w = "8.5" # page width postscript gsave \w 72 mul 0 translate \a rotate # ... other code to do stuff postscript grestore @end example Here is how to draw an image palette vertically instead of horizontally: @example \X = "3" # cm \Y = "10" # cm \a = "90" # degrees counterclockwise postscript gsave \X 28.35 mul \Y 28.35 mul translate \a rotate # Palette is at user's origin draw image palette box 0 0 10 1 postscript grestore @end example NOTE: the @code{postscript} command is @strong{very} dangerous, and should normally only be used by developers. Most of the code concerning this is in the file @file{doline.cc}; look for the string @code{postscriptCmd} to find the relevant code. @c HTML @node Pwd, Query, Postscript, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{pwd} @cindex directory, how to find out @findex pwd @cindex @code{pwd} command @example `pwd' @end example @noindent Print current directory (which can be set by @code{cd}). @c HTML @node Query, Quit, Pwd, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{query} @findex query @cindex @code{query} command @cindex user interaction, @code{query} command @cindex interaction with user, @code{query} command @example `query \synonym|.variable. \ ["\prompt" ["\default"|.default.]]' @end example @noindent Ask the user for the value of a variable (number) or synonym (text string). Gri recognizes the type of the item being asked for, either a variable or synonym, by the presence of a dot or backslash in the second word of the command line. If a prompt string is given (in quotes), then this string is shown to the user. If a default is given (in parentheses), then it will be displayed also, and if the user types carriage-return, then that item will be assigned to the variable or synonym. If the default has more than one item, then Gri considers this a restrictive list of possibilities, and will demand that the answer be in that list, going into an infinite query loop until an item from the list (or carriage-return, meaning take first item) is found. The items in the list are to be separated by spaces, not commas or any other non-whitespace characters. NOTE: The @code{-y} command-line option bypasses all query commands, fooling Gri into thinking that the user typed a carriage-return to all questions. Thus the defaults, if they exist, are selected. @c HTML @node Quit, Read, Query, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{quit} @cindex quiting Gri @cindex stopping Gri @findex quit @cindex @code{quit} command @example `quit [.exit_status.]' @end example @noindent Exits the gri program. If an exit status (@code{.exit_status.}) is specified, then Gri returns this value, rounded to the nearest integer, as the ``exit status'' (a concept meaningful mostly in the unix environment, where it designates an error). @c HTML @node Read, Read Colornames, Quit, List Of Gri Commands @comment node-name, next, previous, up @subsection The @code{read} commands There are several varieties of @code{read} command. Those commands used for reading numerical information (e.g. @code{read columns}) are able to decode variables and synonyms as well as simple numbers. @menu * Read Colornames:: Read colornames * Read Columns:: Read (x,y,...) columnar data * Read Grid:: Read grid for contouring * Read Image Colorscale:: Read colormap for color image * Read Image Grayscale:: Read colormap for gray image * Read Image Mask:: Read mask for image * Read Image:: Read image * Read From:: Change which open file looked at * Read Synonym or Variable:: Read individual synonym or variable * Read Line:: Read whole line @end menu @node Read Colornames, Read Columns, Read, Read @comment node-name, next, previous, up @subsubsection @code{read colornames} @findex read colornames @cindex @code{read} command @cindex @code{read colornames} command @cindex colors, reading from X11 database @cindex X11 colors, reading @example `read colornames from RGB ["\filename"]' @end example @noindent With no filename given, reads an X11-format @code{rgb.txt} file that is provided with gri. Otherwise, reads the named file and tries to interpret it as an X11 file. The file format has 4 or more columns, the first three giving the red, green and blue values in the range 0 to 255, and the last columns giving the colorname (which may have more than one word). Once you have read in a colorname table, the named colors may be used as builtin colors (@ref{Set Color}). To view the names and RGB values of the colors Gri knows, including builtin ones and ones from @code{read colornames}, use @code{show colornames}. This command is akin to @code{set colorname} (@ref{Set Colorname}), except that the latter uses the Gri notation of color constituents being in the range from 0 to 1, whereas for @code{read colornames} uses an X11 database, so that the color constitutents range from 0 to 255. @node Read Columns, Read Grid, Read Colornames, Read @comment node-name, next, previous, up @subsubsection @code{read columns} @findex read columns @cindex @code{read columns} command @example `read columns ...' @end example Read numbers into columns. These columns have predefined meanings and names. For example, @code{read columns x y} instructs Gri to read data into columns called @code{x} and @code{y}; it is these data that Gri will use if you tell it to @code{draw curve}. Other columns are: @code{z}, used for contouring a function @code{z=z(x,y)}; @code{weight}, used for weighting data points; @code{u} and @code{v}, used for arrow (vector) plots. If the keyword @code{appending} is given as the last word on the @code{read columns} line, then the new data will be appended to any existing columnar data; otherwise they will overwrite any existing data. As a special case, if the @code{x} column is not indicated (e.g. @code{read columns y}) then Gri creates x-values automatically, in the sequence 0, 1, 2, etc. @itemize @bullet @item @code{read columns x y} Read @code{x} in column 1, @code{y} in column 2 until blank-line found. Only the first two numbers on each line will be read; any extra numbers (or words) on the line will be ignored. @item @code{read columns * y * * x} Read @code{x} in column 5, @code{y} in column 2. The @code{*} character is a spacer. It instructs Gri to skip the first, third, and fourth words on the data line. These words need not be numbers. This example illustrates a general mechanism of using the @code{*} character to skip over unwanted items in the data file. Note that there is no need to supply @code{*} characters for trailing extraneous words; Gri will skip them anywary. Finally, note that any order of @code{x} and @code{y} (and the other columns; see below) is allowed. @item @code{read columns y=2 x=5} or @code{read columns x=5 y=2} As above; read @code{x} in column 5 and @code{y} in column 2. The column number may be specified in this manner for all the named column variables. No spaces are allowed before or after the @code{=} sign. The first column is called column 1. Whether this format is used or the @code{*} format is a matter of choice, except that numbered format also permits using a given number to fill several variables (for example @code{read columns x=1 y=2 u=1 v=2}). @cindex netCDF files, reading columns @item @code{read columns x="netCDF_name" ...} If the file is a @code{netCDF} file, opened by e.g. @code{open myfile.nc netCDF}, then the @code{netCDF} variables for the columns, e.g. @example open latlon.nc netCDF read columns x="longitude" y="latitude" @end example @noindent Note: the data @strong{must} be stored as the @code{netCDF} ``float'' type. For more information on netCDF format, see @code{http://www.unidata.ucar.edu/packages/netcdf/index.html} @c HTML @c HTML here . @item @code{read columns * y z * x} Read @code{x} in column 5, @code{y} in column 2, and @code{z} in column 3. The @code{z} column is used for contouring. @item @code{read columns x y u v} @cindex direction field, how to read @cindex vector field, how to read @cindex arrows, how to read direction field Read @code{x} and @code{y} in first two columns, and the ``arrow'' data @code{u} and @code{v} as third and fourth columns. @item @code{read columns .rows. x y} Read @code{.rows.} rows of column data. @end itemize @cindex column data, x in one file and y in another Sometimes you'll have @code{x} in one file and @code{y} in another. In that case, use the operating system or an editor to put the columns in one file. In unix, the easy way is @example open "paste file_with_x file_with_y |" read columns x y @end example NOTE FOR BINARY FILES: For ascii files, Gri will proceed to a new line after it has read the items requested; it skips any words appearing on the data line after the last object of interest. Thus @code{read columns x y} will read the first two columns and ignore any other columns that might be present. But for binary files, Gri has no way of knowing how to "skip" to the next line (see @code{skip} command), so you will have to flesh out the @code{read columns} command with as many spacers as are present in your data. For example, if you have four numbers in each data record and want to interpret the first two as @code{x} and @code{y}, you would use @code{read columns x y * *} to read the data. RETURN VALUE: @cindex @code{\.return_value.}, from @code{read columns} Sets @code{\.return_value} to @code{N rows N non-missing N inside-clip-region} @node Read Grid, Read Image Colorscale, Read Columns, Read @comment node-name, next, previous, up @subsubsection @code{read grid} @findex read grid @cindex reading grid data @cindex grid, reading @cindex @code{read grid} command @code{read grid} commands read grid characteristics. (The ``grid'' is the object that is contoured.) For normal ascii or binary files, the commands to read the grid's x-locations, y-locations and data are: @example `read grid x [.rows.]' `read grid y [.rows.]' `read grid data [spacers] \ [.rows. .cols.] [spacers] [bycolumns]' @end example @cindex netCDF files, reading grid data For @code{netCDF} files, the commands are as follows (note that it is not possible to specify the number of data to read, nor to read the grid by columns). @example `read grid x = "variable_name"' `read grid y = "variable_name"' `read grid data = "variable_name"' @end example @noindent The ordering of the y-grid data is the same as if they were read from a normal file: the first number is considered to be at the top of the plot. For more information on netCDF format, see @code{http://www.unidata.ucar.edu/packages/netcdf/index.html} @c HTML @c HTML here . Details of the non-netCDF commands: @itemize @bullet @item @code{read grid x [.cols.]} Read the @code{x} locations of the grid points, one number per line. If @code{.cols.} is supplied, then that many values will be read; otherwise, reading will stop at end-of-file or blank-line. @item @code{read grid y [.rows.]} As above, but for y grid; @code{.rows.} is the number of rows. The first number to be read corresponds to the location of the @strong{top} edge of the grid. Thus, if you were to view the column of numbers with a text editor, they would be oriented the same way as the corresponding elements will appear on the page. @item @code{read grid data [.rows. .cols.]} Read data for a grid having @code{.rows.} and @code{.cols.} columns. (If @code{.rows.} and @code{.cols.} are not supplied, but the grid already exists, then those pre-existing values are used. If they are specified here, then they are checked for consistency with the pre-existing values if they exist.) Gri will read @code{.rows.} lines, each containing @code{.cols.} numbers. (Extra information in the file can be skipped; see discussion of the @code{*} keyword below.) Gri will interpret the first line it reads as the grid data corresponding to a value of y equal to @code{y[.rows.]}. Thus, file should be arranged like this: @example f(x[1], y[.rows.]) ... f(x[.cols.], y[.rows.]) . . . f(x[1], y[3]) ... f(x[.cols], y[3]) f(x[1], y[2]) ... f(x[.cols], y[2]) f(x[1], y[1]) ... f(x[.cols], y[1]) @end example @item @code{read grid data [.rows. .cols.] bycolumns} As above, but the @code{bycolumns} keyword tells Gri to read the data one column at a time, instead of one row at a time. Each line is expected to contain @code{.rows.} numbers (as opposed to @code{.cols.} numbers, as in the format where the @code{bycolumns} keyword is not present). (Extra information in the file can be skipped; see discussion of the @code{*} keyword below). The first line of the data file contains the first column of the gridded data, corresponding to x equal to @code{x[1]}). The file should look like this: @example f(x[1], y[1]) ... f(x[1], y[.cols.]) f(x[2], y[1]) ... f(x[2], y[.cols.]) f(x[3], y[1]) ... f(x[3], y[.cols.]) . . . f(x[.rows.],y[1]) ... f(x[.rows.], y[.cols.]) @end example @item @code{read grid data * * [.rows. .cols.]} As @code{read grid data .rows. .cols.} except that the first two words on each line are skipped. As usual, trailing extraneous numbers are also skipped. @end itemize @strong{See also} @code{set x grid}, @code{set y grid} @noindent RETURN VALUE: @cindex @code{\.return_value.}, from @code{read grid ...} @code{read grid x} sets @code{\.return_value} to @code{N cols} @code{read grid y} sets @code{\.return_value} to @code{N rows} @code{read grid data} sets @code{\.return_value} to @code{N rows N cols} @node Read Image Colorscale, Read Image Grayscale, Read Grid, Read @comment node-name, next, previous, up @subsubsection @code{read image colorscale} @findex read image colorscale @cindex @code{read image colorscale} command @cindex image colorscale, reading @cindex colorscale of image, reading from file @example `read image colorscale [rgb|hsb]' @end example @noindent Read colorscale for image, from 256 lines each containing values for Red, Green, and Blue (or Hue, Saturation and Brightness), separated by whitespace. The values are expected to be in the range 0 to 1, and are clipped to these limits if not. For hints on how to create such an input file, @ref{Read Image Grayscale}. If the example given there has the following code instead, @example open "awk 'BEGIN @{ \ for(i=0;i<256;i++) @{ \ print((i - 50)/50, 1, 1) \ @} \ @}' |" read image colorscale hsb @end example @noindent then a linear full-color spectrum running from red at 10C to magenta at 15C is achieved. @node Read Image Grayscale, Read Image Mask, Read Image Colorscale, Read @comment node-name, next, previous, up @subsubsection @code{read image grayscale} @findex read image grayscale @cindex @code{read image grayscale} command @cindex @code{read image greyscale} command @cindex image grayscale, reading @cindex grayscale of image, reading from file @example `read image grayscale' @end example @noindent Read grayscale for an image, from 256 lines each containing a single value. The values are expected to be in the range 0 to 1, and are clipped to these limits if not. For 8-bit images, Gri multiplies these values by 255, and uses this list for the grayscale mapping. Such a list is created by @code{write image grayscale}. As an example, consider the code fragment (@ref{Images}). @example set image range 5 30.5 set image grayscale black 10 white 15 @end example @noindent is equivalent to @example set image range 5 30.5 open "awk 'BEGIN @{\ for(i=0;i<256;i++) @{\ print(1-(i-50)/50)\ @} \ @}' |" read image grayscale close @end example @noindent because the image formula is @quotation Temperature = 5C + 0.1C * pixelvalue @end quotation @noindent where the pixelvalue ranges from 0 to 255. Therefore, a temperature of 10C is a pixelvalue of 50, and 15C is 100. To get a grayscale ranging between these values, therefore, we create a linear function which maps the 50th pixelvalue into grayvalue 1, and the 100th pixelvalue into grayvalue 0. That is what the awk line does; to see the actual numbers, you could insert the line @code{write image grayscale to TMP} and look at the file @file{TMP} (bear in mind that Gri will clip the values to the range 0 to 1). Sometimes you will have a file, say named @file{map.dat}, with RGB numbers in the range 0-255, rather than 0-1 as Gri requires. To read them, use the operating system to convert the numbers for you (@ref{Open}). @example open "cat map.dat \ | awk '@{print(($1+$2+$3)/3/255)@}' |" read image grayscale close @end example @node Read Image Mask, Read Image, Read Image Grayscale, Read @comment node-name, next, previous, up @subsubsection @code{read image mask} @findex read image mask @cindex @code{read image mask} command @cindex mask for image, reading @cindex image mask, reading @example `read image mask rasterfile|@{.rows. .cols.@}' @end example @noindent Read image mask. The mask is associated with the image read in by the @code{read image} command in the following way. When computing image histograms, Gri ignores any pixels in the image for which the corresponding pixel in the mask is set to @code{1}. @itemize @bullet @item @code{read image mask rasterfile} The image size is specified in the rasterfile file itself, so it is not specified. @item @code{read image mask .rows. .cols.} The file must contain @code{.rows.*.cols.} binary data. Pixel order is the same as for images. @end itemize @node Read Image, Read From, Read Image Mask, Read @comment node-name, next, previous, up @subsubsection @code{read image} @findex read image @cindex @code{read image} command @cindex images, reading @noindent There are several types of @code{read image} commands, depending on the file format. If the file is "raw", with no embedded information about things like the width and height, then we need to specify everything, as in the first format given below. The other formats make use of the header information in, e.g. PGM files. @strong{Headerless images} @example `read image .rows. .cols. \ [box .xleft. .ybottom. .xright. .ytop.] \ [bycolumns]' @end example @noindent With no options specified (@code{read image .rows. .cols.}), read binary data defining an @code{image}. The image range must have previously have been set by @code{set image range}. The data are as written by "unsigned char" format in C. When the @code{box} option is specified, the geometry of the image, in user coordinates, is specified in terms of the cartesian coordinates of the lower-left corner (@code{.xleft.}, @code{.ybottom.}) and upper-right corner (@code{.xright.}, @code{.ytop.}). If the @code{box} option is not specified, this geometry can be specified with either @code{read x grid} or @code{set x grid}, plus either @code{read y grid} or @code{set y grid}. With the @code{bycolumns} keyword present, the image is read sweeping from top-to-bottom, then left-to-right, instead of the usual order. @strong{Sun rasterfile images} @example `read image rasterfile [box .xleft. .ybottom. .xright. .ytop.]' @end example @noindent Read image in Sun rasterfile format. Image geometry is inferred from the header, so @code{.rows.} and @code{.cols} parameters are not given. @strong{PGM images} @example `read image pgm [box .xleft. .ybottom. .xright. .ytop.]' @end example @noindent Read image in PGM (Portable Gray Map) format. Image geometry is inferred from the header, so @code{.rows.} and @code{.cols} parameters are not given. Both ascii and binary PGM formats are supported (that is, files with magic characters of P2 and P5). @strong{NOTE} that there are many image formats and Gri doesn't try to deal with them all. The idea is to use another program to convert images to a file format that Gri understands. In the future Gri may support PNG and other popular formats, especially in the Linux versions, for which libraries exist to ease the input. @node Read From, Read Synonym or Variable, Read Image, Read @comment node-name, next, previous, up @subsubsection @code{read from \filename} @findex read from @cindex @code{read from} command @cindex file, selecting between open files @example `read from \filename' @end example @noindent Cause future @code{read} commands to read from the indicated file. If that file is not open, an error message will result. Use @code{read from \filename} to shuffle reading among several open files. Gri can look up filenames for @code{read from} in terms of their @b{full} pathnames or their @b{local} pathnames. Thus, a local file called @code{a.dat} in the directory @code{/home/gri} can be referred to by @code{read from a.dat} or by @code{read from /home/gri/a.dat}, which comes in handy if you need to work with two files of the same name, in other directories. However, since Gri has the ability to search for files in a "path" (@ref{Set Path To}), you may not have specified an exact path name; this is why the @code{open} command provides a return value which names the full pathname (@ref{Opening Simple Files}). @node Read Synonym or Variable, Read Line, Read From, Read @comment node-name, next, previous, up @subsubsection @code{read} synonym/variable @findex read @cindex @code{read ...} command @cindex variables, reading @cindex synonyms, reading @cindex reading variables @cindex reading synonyms @example `read [* [*...]] \synonym|.variable. [\synonym|.variable. [...]]@}' @end example @noindent Read one or more items from the next line of the input file. These items may be synonyms or variables. The token @code{*} indicates that the word in the datafile should be skipped. As usual, the datafile may be embedded in the commandfile, providing the last data line is blank. Normally one would use synonyms for words, and variables for numbers. The items are separated by one or more "whitespace" characters (e.g. space or TAB). Thus, if a file contained the line @example Temperature 10.3 @end example @noindent then the line @example read \var_name .var_value. @end example @noindent would have the same result as @example \var_name = "Temperature" .var_value. = 10.3 @end example This command ignores any trailing items on the line. That is, the next @code{read} command will start on the next line of the file. In a sense then, you get just one shot at analysing the input line in your datafile. If you need flexibility, you may wish to read the @strong{whole} contents of the line into a synonym, which may be done using the @code{read line} command instead, to read it in as a string. (@ref{Read Line}). @cindex reading attributes in NetCDF files @cindex netCDF files, reading attributes, units, etc If the input file is in the netCDF format, the indicated item will be read. For example, @code{read \time:_MissingValue} reads the missing value for the variable called @code{time}. This conveniently allows your data file to dictate axes names, units, missing values, etc. Example: @example # Plot profile of TU81N (age-corrected tritium) open profile.nc netCDF read columns x="TU81N" y="z" read \@{z:_FillValue@} # assume same for all read \@{z:long_name@} read \@{z:units@} read \@{TU81N:long_name@} read \@{TU81N:units@} close set missing value \@{z:_FillValue@} set x name "\@{TU81N:long_name@} (\@{TU81N:units)@}" set y name "\@{z:long_name@} (\@{z:units)@}" set y axis decreasing draw curve @end example For more information on netCDF format, see @code{http://www.unidata.ucar.edu/packages/netcdf/index.html} @c HTML @c HTML here . @node Read Line, Regress, Read Synonym or Variable, Read @comment node-name, next, previous, up @subsubsection @code{read line} @findex read line @cindex @code{read line raw} command @cindex @code{read line} command @cindex lines in data files, parsing @cindex parsing headers in data files @cindex variables, reading @cindex synonyms, reading @cindex reading variables @cindex reading synonyms @example `read line \synonym' @end example @noindent Read the next line of the datafile (or commandfile), trim off a trailing comment if there is one, and then store the next line of datafile into the named synonym. @c HTML @node Regress, Reorder, Read Line, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{regress} @cindex statistics, performing regression @cindex linear regression @cindex regression, linear @findex regress @cindex @code{regress} command @example `regress @{y vs x [linear]@}|@{x vs y [linear]@}' @end example @noindent Perform linear regression of @code{y} as a function of @code{x} or @code{x} as a function of @code{y}. @itemize @bullet @item @code{regress y vs x} Linear regression of y vs x. Several quantities are reported and also saved into builtin variables. The intercept is defined as @code{..coeff0..}, its 95 percent confidence limit is defined as @code{..coeff0_sig..}. Thus the confidence range is @code{..coeff0..-..coeff0_sig..} to @code{..coeff0..+..coeff0_sig..}. Similarly the slope and confidence limit are stored in @code{..coeff1..} and @code{..coeff1_sig..} The squared correlation coefficient is stored in @code{..R2..}. @strong{Historical note} prior to version 2.1.15, a different meaning was attached to @code{..coeff0_sig..} and @code{..coeff1_sig..}; they used be defined as standard errors, without having been multiplied by the appropriate student-t coefficient. @item @code{regress x vs y} Linear regression of x vs y; for notation see above. @item @code{regress y vs x linear} Linear regression of y vs x; for notation see above. @item @code{regress x vs y linear} Linear regression of x vs y; for notation see above. @end itemize @noindent @c HTML @node Reorder, Rescale, Regress, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{reorder} @cindex columns, reordering @cindex reordering Columns @findex reorder @cindex @code{reorder} command @example `reorder columns randomly \ |@{ascending in x|y|z@} \ |@{descending in x|y|z@}' @end example @noindent Reorder the columns in various ways. In the @code{randomly} style, the column data are shuffled randomly by index, retaining the correspondance between a given x and y. This is useful with @code{draw symbol} using colored dots -- it prevents the overpainting of one dot on another from biasing the color field to values that happened to occur near the end of the column data. If you prefer the overpainting to be done in random order, use this command to reorder the columns randomly. The random number is selected using the system @code{rand} call, with the seed being provided by the PID (process ID) of the job. The @code{ascending} and @code{descending} styles do what you'd expect. @c HTML @node Rescale, Resize, Reorder, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{rescale} @cindex axes, forcing rescaling @cindex rescaling axes @cindex math on columns, rescaling after @findex rescale @cindex @code{rescale} command @example `rescale' @end example @noindent Re-determine the scales for the x and y axes. Typically used after a column math operation, when you want the new data to be auto-scaled. (Note: normally, if the axes have already been drawn, Gri won't rescale automatically just because you modify the column data. This is designed so that you can add offsets to curves, etc, while staying in saved axes. But if the axes have not been drawn yet when you modify the column data, then Gri will automatically rescale the axes it is planning to draw.) @c HTML @node Resize, Return, Rescale, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{resize} @cindex maps, scales @findex resize x @cindex @code{resize x} command @example `resize @{x for maps@}|@{y for maps@}' @end example @noindent Resize the axes frame region in such a way that geographical objects appear in correct proportions. This assumes that y is degrees latitude and x is degrees longitude. @itemize @bullet @item @code{resize x for maps} Resize the plot width for maps, assuming that x represents longitude and y represents latitude. Before using this, you must have defined scales for both x and y, and a size for y (ie, you must have done @code{set x axis ...}, @code{set y axis ...} and @code{set y size}); this command sets the x size, thus eliminating @code{set x size.} The result is that, at the central latitude (y), a centimetre on the page will correspond to an equal distance on the earth, in both the north-south and east-west directions. @item @code{resize y for maps} Resize the plot height for maps, assuming that x represents longitude and y represents latitude. Before using this, you must have defined scales for both x and y, and a size for x (ie, you must have done @code{set x axis ...}, @code{set y axis ...} and @code{set x size}); this command sets the y size, thus eliminating @code{set y size.} The result is that, at the central latitude (y), a centimetre on the page will correspond to an equal distance on the earth, in both the north-south and east-west directions. @strong{See also} @code{resize x for maps}. @end itemize @c HTML @node Return, Rewind, Resize, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{return} @findex return @cindex @code{return} command @example `return' @end example @noindent Return early from a user-defined function or an @code{insert} file. Or, in the main gri program, do the same thing as @code{quit}. @c HTML @node Rewind, Rpnfunction, Return, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{rewind} @findex rewind @cindex @code{rewind} command @example `rewind \filename' @end example @noindent Rewind a data-file to the beginning. If no filename is given, this is done for the currently active file; otherwise the named file is rewound. @c HTML @node Rpnfunction, Set, Rewind, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{rpnfunction} @cindex rpn functions @cindex defining rpn functions @cindex functions in rpn expressions @findex rpnfunction @cindex @code{rpnfunction} command @example `rpnfunction name replacement-words' @end example @noindent Create a new keyword for use in rpn expressions. Inside any RPN expression which follows this line, the word @code{name} will be substituted with the indicated replacement words. For example, the following shows the definition and use of a function which computes the sine of twice an angle, by multiplying whatever is on the stack by @code{2}, and then taking the sine of the result. @example rpnfunction sin2 2 * sin show "expect the number 1 to follow: " @{rpn 45 sin2@} @end example The replacement words will have any synonyms in them translated first, unless they start with an underscore followed by a double backslash. Similarly, variables are substituted unless they start with an underscore. These exceptions are to allow the use of the @code{defined} operator (@ref{rpn Mathematics}). Note: The mathematical constants @code{e} and @code{pi} are stored using @code{rpnfunctions}. Also, two @code{rpnfunctions} are provided for finding the slope and intercept of a line joining two points, e.g. @cindex linear interpolation @cindex @code{linear_slope} rpn operator @cindex @code{linear_intercept} rpn operator @cindex rpn operator @code{linear_slope} @cindex rpn operator @code{linear_intercept} @example # Expect answers 1 and 10 ... show "slope=" @{rpn 0 1 1 11 linear_slope@} show "inter=" @{rpn 0 1 1 11 linear_intercept@} @end example These are useful in @code{set grid missing above .intercept. .slope.} and @code{set z missing above .intercept. .slope.}. @c HTML @node Set, Set Axes Style, Rpnfunction, List Of Gri Commands @comment node-name, next, previous, up @subsection The @code{set} commands @findex set @cindex @code{set} command Set various flags and parameters which Gri will use in later commands. @menu * Set Axes Style:: Set type of axes * Set Arrow Size:: Set size for arrow heads * Set Arrow Type:: Set type of arrow heads * Set Beep:: Set error beeping on or off * Set Bounding Box:: Set PostScript bounding box * Set Clip:: Set clipping region * Set Color:: Set color of pen * Set Colorname:: Create a color name * Set Contour Format:: Set format for numbers on contours * Set Contour Label For:: Set existence of contour labels * Set Contour Label Position:: Set spacing of contour labels * Set Contour Labels:: Control various things about contour lables * Set Dash:: Set style of dashed lines * Set Environment:: (Developer cmd) * Set Error Action:: Set error behavior * Set Flag:: Set flag to control Gri (developer cmd) * Set Font Color:: Set color of pen used for text * Set Font Encoding:: Set font encoding vector * Set Font Size:: Set size of text * Set Font To:: Set font for text * Set Graylevel:: Set graylevel of pen * Set Grid Missing:: Set missing region of grid * Set Ignore Initial Newline:: Set to ignore initial blank line * Set Ignore Error Eof:: Set ability to tolerate EOF on files * Set Image Colorscale:: Set colorscale mapping for image * Set Image Grayscale:: Set grayscale mapping for image * Set Image Missing Value Color:: Set missing value color in image * Set Image Range:: Set range of data that image can hold * Set Input Data Window:: Set data window for reading columns * Set Input Data Separator:: Set separator between data items * Set Line Cap:: Set line end (cap) type * Set Line Join:: Set method for intersections of line segments * Set Line Width:: Set width of lines * Set Missing Value:: Set "missing" value * Set Page Size:: Set page size * Set Page:: Set page style * Set Panel:: Establish geometry for a panel of multipanel plot * Set Panels:: Prepare for multipanel plot * Set Path To:: Set search-path for data or command files * Set Postscript Filename:: Set name of PostScript file * Set Symbol Size:: Set size of symbols * Set Tic Size:: Set size of tics on axes * Set Trace:: Set printout of statements as executed * Set Transparency:: Set transparency of the pen * Set U Scale:: Set scale for u (i.e. x) component of arrows * Set V Scale:: Set scale for v (i.e. y) component of arrows * Set X Axis:: Set range of x axis * Set X Format:: Set format for numbers on x axis * Set X Grid:: Set x mesh of contour grid * Set X Margin:: Set margin to left of x axis * Set X Name:: Set name of x axis * Set X Size:: Set length of x axis * Set X Type:: Set type of x axis (log/linear) * Set Y Axis:: Set range of y axis * Set Y Format:: Set format for numbers on y axis * Set Y Grid:: Set y mesh of contour grid * Set Y Margin:: Set margin below y axis * Set Y Name:: Set name of y axis * Set Y Size:: Set length of y axis * Set Y Type:: Set type of y axis (log/linear) * Set Z Missing:: Set missing region of z column @end menu @node Set Axes Style, Set Arrow Size, Set, Set @comment node-name, next, previous, up @subsubsection @code{set axes style} @findex set axes style @cindex @code{set axes style} command @example set axes style .style. \ | @{offset [.dist_cm.]@} \ | rectangular|none|default @end example @noindent Tell Gri how you want the axes to look, when they are drawn later. @itemize @bullet @item @code{set axes style 0} Set axes to be rectangular, with an x-y axis frame labelled at the left and bottom and tic marks on all axes. @item @code{set axes style 1} As style @code{0}, but only put tics on the lower and left axes. @item @code{set axes style 2} As style @code{0} but without labels or tics on any axis, i.e. just an axis frame. @item @code{set axes style offset [.dist_cm.]} Set axes so that the actual x and y axes will be drawn with a space separating them from the data area. The space, if not set by the @code{.distance_cm.} option, will be equal to the current tic size (see @code{set tic size}). This command can be used together with any other @code{set axes style} command. It applies to both the @code{draw axes} command and with any @code{draw x|y axis} command in which the axis location is not explicitly given. @item @code{set axes style rectangular} Set axes to be rectangular, with an x-y axes frame labelled at the left and bottom. @item @code{set axes style none} Tell gri not to bother drawing axes before drawing curves, etc. @item @code{set axes style default} Same as @code{set axes style 0}, and with @code{offset} turned off. @end itemize @node Set Arrow Size, Set Arrow Type, Set Axes Style, Set @comment node-name, next, previous, up @subsubsection @code{set arrow size} @findex set arrow size @cindex @code{set arrow size} command @cindex arrows, setting size of heads @example `set arrow size .size. \ | @{as .num. percent of length@} \ | default' @end example @noindent Set the arrowsize (which is stored in the builtin variable @code{..arrowsize..}). @itemize @bullet @item @code{set arrow size .size.} Set the arrow size (ie, half-width of the arrowhead) to @code{.size.} centimetres. @item @code{set arrow size as .num. percent of length} Set the arrow size to be the indicated percentage of arrow length, as in "HWP" in the singles ads. (As a flag to this, @code{..arrowsize..} is set to the negative of the fractional size measured in percent.) @item @code{set arrow size default} Set the arrow size to the default of 0.2 cm. @end itemize @node Set Arrow Type, Set Beep, Set Arrow Size, Set @comment node-name, next, previous, up @subsubsection @code{set arrow type} @findex set arrow type @cindex @code{set arrow type} command @cindex arrows @example set arrow type .which. @end example Set type of arrow, according to the value of @code{.which.}, rounded to the nearest integer. A rounded @code{.which.} value of 0 yields the default arrows, drawn with three line strokes. Value 1 yields outlined arrows, sometimes used on definition sketches. Value 2 yields filled, swept-back arrow heads. This command uses the ``line join'' parameters that are presently active (@ref{Set Line Join}). So, by default, the arrow ends are rounded (because the default line-join parameter is 1). To get pointy ends, first set the line join parameter to 0. @node Set Beep, Set Bounding Box, Set Arrow Type, Set @comment node-name, next, previous, up @subsubsection @code{set beep} @findex set beep @cindex @code{set beep} command @cindex errors, beeping @cindex beeping on errors @example `set beep on|off' @end example @noindent The command @code{set beep on} makes gri beep on errors and @code{query}. @code{set beep off} (the default) turns this beeping off. @node Set Bounding Box, Set Clip, Set Beep, Set @comment node-name, next, previous, up @subsubsection @code{set bounding box} @findex set bounding box @cindex @code{set bounding box} command @cindex bounding box, setting @example `set bounding box .xleft. .ybottom. .xright. .ytop. [pt|cm]' @end example @noindent Set the PostScript bounding box for the graph to the indicated values. The bounding box is used by some programs to determine the region of the page on which marks have been made. For example, La@TeX{} uses the bounding box to decide how to position figures in documents. Normally, the bounding box is computed automatically unless the @code{-no_bounding_box} commandline option has been specified; (@ref{Invoking Gri}). But if @code{set bounding box} is done, the automatically computed value is ignored and the given box is used instead. Use this if Gri makes mistakes in its automatic selection of bounding box. The coordinates of the bounding box may be specified in (1) user coordinates, as defined @strong{at the moment} the command is executed, or (2) in points on the page, measured from an origin at the lower-left (72 point per inch), or (3) in centimeters on the page. Which coordinate system is used depends on the last keyword -- use @code{pt} for points, @code{cm} for centimeters, and nothing at all for user-units. The most common use is in points, since that is how many other application packages, e.g. La@TeX{} and dvips, specify the bounding box. If the box is specified in the user units, the user units in effect @strong{at the moment} of executing the @code{set bounding box} command are used. This must be born in mind if the coordinate system is changing during the execution of the program, e.g. if margins are changing or the x and y axes are changing. For this reason it often makes sense to put this command at the end of the commandfile. @node Set Clip, Set Color, Set Bounding Box, Set @comment node-name, next, previous, up @subsubsection @code{set clip} @findex set clip @cindex @code{set clip} command @example `set clip [postscript] \ @{on [.xleft. .xright. .ybottom. .ytop.]@} \ @{to curve@} \ | off' @end example @noindent Control clipping of following drawing commands. Note that the commands have two styles, one of which includes the keyword @code{postscript}. PostScript clipping does a cleaner job, but it results in larger file sizes. @emph{Important} if you are using @code{postscript} clipping, then you be @emph{sure} to turn it off using @code{set clip postscript off}, instead of @code{set clip off}; otherwise Gri will get mixed up. @itemize @bullet @item @code{set clip on} Don't plot data outside axes. @item @code{set clip postscript on} As above, but Postscript clipping. @item @code{set clip on .xleft. .xright. .ybottom. .ytop.} Don't plot data outside indicated box. @item @code{set clip postscript on .xleft. .xright. .ybottom. .ytop.} As above, but Postscript clipping. @item @code{set clip off} Plot all data, whether inside the axes or not. @item @code{set clip postscript off} As above, but Postscript clipping. @item @code{set clip to curve} set clip to the curve, as would be drawn by a @code{draw curve filled} command, i.e. to the polygon constructed by running along the xy points, in order, followed by a final segment from the last point back to the first point. This is a "postscript" clip, as explained in the next item. @item @code{set clip postscript to curve} As above, but Postscript clipping. @example draw axes set clip postscript on 10 20 0 1 draw curve set clip postscript off @end example @item @code{set clip postscript off} Turn PostScript clipping off. @strong{See also} @code{set input data window}. @cindex data, clipping using @code{set input clip} @cindex clipping data using @code{set input clip} @end itemize @node Set Color, Set Colorname, Set Clip, Set @comment node-name, next, previous, up @subsubsection @code{set color} @findex set color @findex set colour @cindex @code{set color} command @cindex @code{set colour} command @example `set color \name | \ @{rgb .red. .green. .blue.@} | \ @{hsb .hue. .saturation. .brightness.@}' @end example @noindent Set the color of the ``pen'' used for drawing lines and text. Normally lines and text are drawn in the same color, but the text color can be specified independently if desired (@ref{Set Font Color}). This might be useful to get contour lines of one color and labels of another. The spelling @code{colour} is also accepted. In the @code{set color \name} style, set the drawing color to the indicated name, either from the builtin list (@code{white}, @code{LightGray}, @code{darkslategray}, @code{black}, @code{red}, @code{brown}, @code{tan}, @code{orange}, @code{yellow}, @code{green}, @code{ForestGreen}, @code{cyan}, @code{blue}, @code{skyblue}, @code{magenta}), or from a list created by @code{read colornames}. In the latter case, if the colorname has more than one word in it, use quotes, e.g. @code{set color "ghost white"}. In the @code{set color rgb ...} style, set the individual color components as indicated. The numbers @code{.red.}, @code{.green.} and @code{.blue.} range from 0 (for no contribution of that color component to the final color) to 1 (for maximal contribution). Values less than 0 are clipped to 0; values greater than 1 are clipped to 1. EXAMPLES: @example set color rgb 0 0 0 # black set color rgb 1 1 1 # white set color rgb 1 0 0 # bright red set color rgb 0.5 0 0 # dark red (only 50 percent) set color rgb 0 1 0 # pure green set color rgb 1 1 0 # yellow: red + green @end example In the @code{set color hsb ...} style, set the individual color components as indicated. The numbers @code{.hue.}, @code{.saturation.} and @code{.brightness.} range from 0 to 1. The color, represented by .hue., ranges from 0 for pure red, through 1/3 for pure green, and 2/3 for pure blue, and back to 1 again for pure red. The purity of the color, represented by .saturation., ranges from 0 (none of the hue is visible) to 1 (the maximal amount is present). The brightness of the color, represented by @code{.brightness.}, ranges from 0 (black) to 1 (maximal brigntness). Values less than 0 are clipped to 0; values greater than 1 are clipped to 1. EXAMPLES: @example set color hsb 0 1 1 # pure, bright red set color hsb 0 1 0.5 # half black, half red set color hsb .333 1 1 # pure, bright green @end example @node Set Colorname, Set Contour Format, Set Color, Set @comment node-name, next, previous, up @subsubsection @code{set colorname} @findex set colorname @cindex @code{set color name} command @example `set colorname \name @{rgb .red. .green. .blue.@} \ | @{hsb .hue. .saturation. .brightness.@}' @end example @noindent Create a colorname with the indicated color. The color components range from 0 to 1, and will be clipped to these values if they are outside this range. EXAMPLE (borrowing a color from @file{/usr/lib/X11/rgb.txt}): @example set colorname peachpuff rgb 1 @{rpn 218 255 / @} @{rpn 185 255 / @} draw box filled 2 2 3 3 cm @end example This command is akin to @code{read colornames} (@ref{Read Colornames}), except that the latter uses an X11 database, so the color constituents range from 0 to 255, whereas for @code{set colorname} they range from 0 to 1. @node Set Contour Format, Set Contour Label For, Set Colorname, Set @comment node-name, next, previous, up @subsubsection @code{set contour format} @findex set contour format @cindex @code{set contour format} command @example `set contour format \style|default' @end example @noindent Normally, Gri draws the numeric labels of contours using a format code called @code{%g} in the "C" language. You may specify any other "long" format using this command. For example, @code{set contour format %.1f} tells Gri to use one decimal place in the numbers, and also to prefer the "float" notation to the exponential notation. @code{set contour format default} resets to the default @code{%f} format. You may use quotes around the format if you need to, to make the item be a single word (e.g. @code{set contour format "%.1f m/s"}). @node Set Contour Label For, Set Contour Label Position, Set Contour Format, Set @comment node-name, next, previous, up @subsubsection @code{set contour label for} @findex set contour label for @cindex @code{set contour label for} command @example `set contour label for lines exceeding .x. cm' @end example @noindent Make it so contour lines shorter than @code{.x.} centimeters will not be labelled. @node Set Contour Label Position, Set Contour Labels, Set Contour Label For, Set @comment node-name, next, previous, up @subsubsection @code{set contour label position} @findex set contour label position @cindex @code{set contour label position} command @cindex contours, spacing of labels on @cindex labels, on contours @example `set contour label position \ @{.start_cm. .between_cm.@} \ | centered \ | default' @end example @noindent By default, contour labels are drawn at the location 1 cm into the contour curve, measured from the startpoint of the contour (e.g., for contours crossing the axes frames, the label will be 1 cm from the frame), and then at a uniform distance along the contour. By default, this uniform distance is the average dimension of the plotting area inside the axes. If @code{.start_cm.} and @code{.between_cm.} are specified, the first label is drawn at a distance @code{.start_cm.} from the start of the contour, and thereafter at a separation of @code{.between_cm.}. If the @code{centered} option is used, then the contour labels are centered along the length of the line. @node Set Contour Labels, Set Dash, Set Contour Label Position, Set @comment node-name, next, previous, up @subsubsection @code{set contour labels} @findex set contour labels @cindex @code{set contour labels} command @cindex contours, orientation of labels @cindex contours, whiting/nowhiting under the labels @cindex labels on contour lines, controlling orientation and white-under @example set contour labels rotated \ | horizontal \ | whiteunder \ | nowhiteunder @end example @noindent The first two options control whether contour labels are rotated to line up with the contour lines, or whether they are horizontal (the default). The second two options control whether the region under contour labels is whited out before drawing the label. The default is @code{whiteunder}, which has the visual effect of the label having been drawn on a piece of paper and then pasted on. This can look jarring when the material under the contour is an image. When @code{nowhiteunder} is specified, the contour line is broken to make space for the text, but no whiting out is done. @node Set Dash, Set Environment, Set Contour Labels, Set @comment node-name, next, previous, up @subsubsection @code{set dash} @findex set dash @cindex @code{set dash} command @cindex dashed lines @cindex lines, dashed @vindex @code{..length_dash..}, length/cm of dashes @vindex @code{..length_blank..}, length/cm of blanks @example `set dash [.n.|@{.dash_cm. .blank_cm. ...@}|off]' @end example @noindent Control dash-style for following @code{draw curve} and @code{draw line} commands. @itemize @bullet @item @code{set dash} Set to dashed line (0.4cm dashes, 0.1cm blanks). @item @code{set dash .n.} Set to indicated pre-defined dashed line, according to table: @example .n. dash/cm blank/cm 0 - - ... (Solid line) 1 0.2 0.1 2 0.4 0.1 3 0.6 0.1 4 0.8 0.1 5 1.0 0.1 10 w w 11 w 2w 12 w 3w 13 w 4w 14 w 5w 15 w 6w @end example @noindent Where @code{w} is written, it indicates the current linewidth. Thus, types 10 through 15 give square-dotted lines. @item @code{set dash .dash_cm. .blank_cm. .dash_cm. .blank_cm. ...} Set to indicated dashed line. The series of lengths @code{.dash_cm.} and @code{.blank_cm.} give the lengths of dash and blank portions (measured in centimeters). Any number of dash/blank lengths may be given. For example, @code{set dash 0.5 0.1 0.1 0.1} looks good. @item @code{set dash off} Turn dashing off, setting to a solid line. @end itemize @node Set Environment, Set Error Action, Set Dash, Set @comment node-name, next, previous, up @subsubsection @code{set environment} @findex set environment @cindex @code{set environment} command @cindex developer command @code{set environment} @example `set environment' @end example @noindent Set environment (graylevel, axis length, etc) so that following plotting commands will make use of anything set by either a @code{set} command or by direct manipulation of builtin variables like @code{..xsize..}, etc. NOTE: this should @strong{only} be done by developers. @node Set Error Action, Set Flag, Set Environment, Set @comment node-name, next, previous, up @subsubsection @code{set error} @findex set error @cindex @code{set error} command @cindex Handling errors with @code{set error} command @example `set error action to core dump' @end example @noindent Make Gri dump core when any error is found, to facilitate debugging. @node Set Flag, Set Font Color, Set Error Action, Set @comment node-name, next, previous, up @subsubsection @code{set flag} @findex set flag @cindex @code{set flag} command @cindex developer command @code{set flag} @example `set flag \name [off]' @end example @noindent Set the indicated flag to YES. The name of the flag is contained in a single word, e.g. @code{set flag dan_28sep_test}. The action of the flags may change with time and is undocumented. This command is provided to enable selected users (e.g., the developer himself) to use test features of Gri before they are frozen into a fixed syntax and action. The keyword @code{off} turns the indicated flag off. NOTE: this should @strong{only} be done by developers. @example FLAG DATE ACTION jinyu1 29sep94 'convert columns to grid' outputs (x,y,z,z_predicted) emulate_gre 9jun97 'E' format on axes yields scientific notation kelley1 17jun97 for kelley only - quit contour trace if hit nonlegit kelley2 17jun97 for kelley only: print info while contour tracing @end example @node Set Font Color, Set Font Encoding, Set Flag, Set @comment node-name, next, previous, up @subsubsection @code{set font color} @findex set font color @findex set font colour @cindex font, setting color of @cindex text, color used for @cindex color, for text @cindex @code{set font color} command @cindex @code{set font colour} command @example set font color \name | \ @{rgb .red. .green. .blue.@} | \ @{hsb .hue. .saturation. .brightness.@} @end example @noindent The syntax is the same as @code{set color}, except that this applies to text only. By default, text is drawn in the same color as lines, so text color is changed as line color is changed (e.g. by using the @code{set color} or @code{set graylevel} commands)). However, once @code{set font color} is used in a Gri program, the font thereafter maintains a separate color from the lines. @node Set Font Encoding, Set Font Size, Set Font Color, Set @comment node-name, next, previous, up @subsubsection @code{set font encoding} @findex set font encoding @cindex font, setting encoding vector of @cindex text, encoding vector of @cindex font encoding @cindex @code{set font encoding} command @cindex postscript-standard font encoding @cindex ISO latin 1 font encoding @example set font encoding PostscriptStandard | isolatin1 @end example @noindent Permits one to control the so-called ``font encoding'' used in text. The default font encoding is ISO-Latin-1, which is best for English and other European languages. To learn how to enter accents in a text editor, and for a brief overview of font encodings, (@ref{Non-English Text}). If the so-called ``Postscript Standard'' font encoding is required, this command permits changing the encoding. Note: few users will ever need this command. If you don't even know what ``font encoding'' is about, ignore this command! @node Set Font Size, Set Font To, Set Font Encoding, Set @comment node-name, next, previous, up @subsubsection @code{set font size} @findex set font size @cindex @code{set font size} command @cindex font size @example `set font size @{.size. [cm]@}|default' @end example @noindent Set the size of the font for drawing of text. @itemize @bullet @item @code{set font size .size.} Set font size to @code{.size.} points. (A point is 1/72 of an inch, or 1/28 of a centimetre.) @item @code{set font size .size. cm} Set font size to @code{.size.} centimetres. @item @code{set font size default} Set font size to default = 12 pts. @end itemize @cindex American Geophysical Union, recommended font size If your figure is to be reproduced by a journal, you should check with them about the range of font size they need. This will, of course, depend on whether your figure is reduced or enlarged during reproduction. For example, American Geophysical Union (publishers of J. Geophysical Res.) recommends that one use fonts no smaller than 8 points. They also recommend that the range in fontsize in a given figure not exceed 2. @node Set Font To, Set Graylevel, Set Font Size, Set @comment node-name, next, previous, up @subsubsection @code{set font to} @findex set font to @cindex @code{set font to} command @example `set font to \fontname' @end example @noindent Set font to named style. Note that the backslash is @strong{not} to be written, but here merely means that this word has several alternatives. For example, one might say @code{set font to Courier}. The allowed fontnames are: @code{Courier}, a typewriter font (and the only monospaced font in Gri); @code{Helvetica} (the default), a sans-serif font commonly used in drafting scientific graphs; @code{HelveticaBold}, a bold version of Helvetica; @code{Times} (also called @code{TimesRoman}), a font used in most newspapers; @code{TimesBold}, a bold version of Times; @code{Palatino} (also called @code{PalatinoRoman}), similar to Times; @code{Symbol}, included for completeness, is a mathematical font in which "a" becomes $\alpha$ of the math mode, etc. For reference on these fonts see any book on PostScript. The default font is @code{Helvetica}. @node Set Graylevel, Set Grid Missing, Set Font To, Set @comment node-name, next, previous, up @subsubsection @code{set graylevel} @findex set graylevel @findex set greylevel @cindex @code{set graylevel} command @cindex @code{set greylevel} command @cindex graylevel, command @cindex lines, gray, command @example `set graylevel .brightness.|white|black' @end example @noindent Set graylevel for lines to indicated numerical value between 0=black and 1=white, or to the named color. @cindex American Geophysical Union, recommended gray levels Note: if your diagram is to be reproduced by a journal, it is unlikely that the reproduction will be able to distinguish between any two graylevels which differ by less than 0.2. Also, graylevels less than 0.2 may appear as pure black, while those of 0.8 or more may appear as pure white. These guidelines are as specified by American Geophysical Union (publishers of J. Geophysical Res.), as of 1998. @node Set Grid Missing, Set Ignore Initial Newline, Set Graylevel, Set @comment node-name, next, previous, up @subsubsection @code{set grid missing} @findex set grid missing @cindex @code{set grid missing} command @cindex grid, missing values @cindex contouring, clipping out invalid areas General format is @example `set grid missing \ @{above|below .intercept. .slope@} \ | @{inside curve@}' @end example @noindent The style @example `set grid missing above|below .intercept. .slope' @end example @noindent sets grid to missing value for all points above/below the line defined by @tex $y = {\rm .intercept.} + {\rm .slope.} x$ @end tex @ifinfo y = .intercept. + .slope. * x @end ifinfo The style @example `set grid missing inside curve' @end example @noindent sets the grid to the missing value throughout an area described by the curve last read in with @code{read columns}. This is useful for e.g. excluding land areas while contouring ocean properties. The curve may contain several "islands," each tracing (clockwise) a region inside of which the grid is to considered missing. If the first point in an island doesn't match the last, then an imaginary line is assumed which connects them. Multiple islands may be separated by missing-value codes. @strong{See also} @code{Set Z Missing}. @node Set Ignore Initial Newline, Set Ignore Error Eof, Set Grid Missing, Set @comment node-name, next, previous, up @subsubsection @code{set ignore initial newline} @findex set ignore initial newline @cindex @code{set ignore initial newline} command @example `set ignore initial newline [off]' @end example @noindent Make Gri ignore a newline if it occurs as the first character of the next data file. This is used for files made by FORTRAN programs on VAX/VMS computers. @node Set Ignore Error Eof, Set Image Colorscale, Set Ignore Initial Newline, Set @comment node-name, next, previous, up @subsubsection @code{set ignore error eof} @findex set ignore error eof @cindex @code{set ignore error eof} command @cindex files, testing for eof @cindex eof on files @cindex testing for end of file @cindex testing for file eof @example `set ignore error eof' @end example @noindent Stop Gri from considering that to encounter an end of file in future @code{read} commands consitutes an error; Gri will simply warn about future EOFs. @node Set Image Colorscale, Set Image Grayscale, Set Ignore Error Eof, Set @comment node-name, next, previous, up @subsubsection @code{set image colorscale} @findex set image colorscale @findex set image colourscale @cindex @code{set image colorscale} command @cindex @code{set image colourscale} command @cindex colorscale, setting for images @cindex image plots, setting colorscale @example set image colorscale hsb .h. .s. .b. .im_value. \ hsb .h. .s. .b. .im_value. [increment .im_value.] set image colorscale rgb .r. .g. .b. .im_value. \ rgb .r. .g. .b. .im_value. [increment .im_value.] set image colorscale \ \name .im_value. \ \name .im_value. \ [increment .im_value.] @end example @noindent Set colorscale mapping for image, using HSB (hue, saturation, brightness) specification, RGB (red, green, blue) color specification, or named colors. The image range must previously have been set by @code{set image range}, so that the @code{.im_value.} values will have meaning. Two pairs of (color, image-value) are given, and possibly an increment. Normally the colors are smoothly blended between the endpoints, but if an increment is supplied, the colors are quantized. The HSB method allows creation of spectral palettes, while the other two methods create simple blending between the two endpoints. EG: To get a spectrum ranging between pure red (H=0) for image value of -10.0, and pure blue (H=2/3) for image value of 10.0, do this: @example set image colorscale hsb 0 1 1 -10 hsb .666 1 1 10 @end example EG: To get a scale running from pure red (at image-value 10.0) into pure blue (at image-value 25.1), but with the colors blending intuitively in between (i.e., blending as paint might), use @code{rgb} color specification, as follows: @example set image colorscale rgb 1 0 0 10 rgb 0 0 1 25.1 @end example EG: To get a quantized blend between the X11 colors @code{skyblue} at image value of 0 and @code{tan} at image value of 20, and with steps at image values incrementing by 5, do this: @example set image colorscale skyblue 0 tan 20 increment 5 @end example @noindent Note that the traversal is through RGB space, so it is intuitive, not spectral. See @code{set color} for a list of X11 colors known to Gri. See also @code{read image colorscale} (@ref{Read Image Colorscale}). @node Set Image Grayscale, Set Image Missing Value Color, Set Image Colorscale, Set @comment node-name, next, previous, up @subsubsection @code{set image grayscale} @findex set image grayscale @findex set image greyscale @findex set image grayscale using histogram @findex set image greyscale using histogram @cindex @code{set image grayscale} command @cindex @code{set image greyscale} command @cindex @code{set image grayscale using histogram} command @cindex @code{set image greyscale using histogram} command @cindex grayscale, setting for images @cindex image plots, setting grayscale @example `set image grayscale using histogram \ [black .bl. white .wh.]' `set image grayscale \ [black .bl. white .wh. [increment .inc.]]' @end example @noindent Set up a grayscale mapping for images. The image range must have previously have been set by @code{set image range}. @example `set image grayscale using histogram [black .bl. white .wh.]' @end example @noindent Create a grayscale mapping using linearized cumulative histogram enhancement. The image must already exist. This creates maximal contrast in each range of graylevels, and is useful for tracing subtle features between different images (for example, it makes it easier to trace fronts between successive satellite images). The entire histogram is expanded, from the smallest value in the image to the largest. With no options specified, the histogram is done from 0 in the image to 255 in the image. If the black/white options are specified, the histogram is done between these values. @example `set image grayscale \ [black .bl. white .wh. [increment .inc.]]' @end example @noindent With no optional parameters, create a grayscale mapping for the current image, scaling it from black for the mininum value in the image to white for the maximum value. The image range must have previously have been set by @code{set image range}. The optional parameters @code{.wh.} and @code{.bl.} specify the values to be drawn in white and black in the image, with smooth linear blending in between. Normally the blending from white to black is smooth (linear), but if the additional optional parameter @code{.inc.} is specified, the blending is quantized, jumping to darker values at (@code{.wh.} + @code{.inc.}), (@code{.wh.} + 2* @code{.inc.}), etc. (The sign of @code{.inc.} will be altered, if necessary, to ensure that (@code{.wh.} + @code{.inc.}) is between @code{.wh.} and @code{.inc.}.) The colour switches to pure white at the value @code{.wh.}, and remains pure white everywhere on the "white" side of this value. Similarly, the transition to pure black occurs at the value @code{.bl.}. In other words, neither pure white nor pure black is present inside the interval from @code{.wh.} to @code{.bl.}. Therefore, when using the @code{draw image palette} command, you might want to extend the range by one increment so as to get an example of both pure white and pure black. @example .w. = 0 .b. = 1 .i. = 0.2 set image grayscale white .w. black .b. increment .i. draw image palette left \ @{rpn .w. .i. -@} \ right @{rpn .b. .i. +@} \ increment .i. @end example @node Set Image Missing Value Color, Set Image Range, Set Image Grayscale, Set @comment node-name, next, previous, up @subsubsection @code{set image missing value color} @findex set image missing value color @findex set image missing value colour @cindex @code{set image missing value color} command @cindex @code{set image missing value colour} command @example `set image missing value color to white|black|\ @{graylevel .brightness.@}|@{rgb .r. .g. .b.@}` @end example @noindent Set the color of ``missing'' pixels (white by default). The image range must have previously have been set by @code{set image range}. Pixels with missing values can result from creating images from grids which have missing values; see the @code{convert grid to image} command. The @code{.brightness.} parameter in the @code{graylevel} style ranges from 0 for black to 1 for white. The @code{rgb} parameters allow setting to full color. @node Set Image Range, Set Input Data Window, Set Image Missing Value Color, Set @comment node-name, next, previous, up @subsubsection @code{set image range} @findex set image range @cindex @code{set image range} command @example `set image range @{.min_value. .max_value.@}|@{from grid@}' @end example @noindent In the first style, specify the minimum and maximum image values. In the second, set the image range from the range of the grid data. In either case, Gri needs to know the image range because it stores images in a limited format capable of holding only 256 distinct values. Unlike some other programs, Gri encourages (forces) the user to specify things in terms of user-units, not image-units. This has the advantage of working regardless of the number of bits per pixel. Thus, for example, @code{set image grayscale}, @code{set image colorscale}, @code{draw image grayscale}, etc, all use *user* units. When an image is created by @code{convert grid to image}, values outside the range spanned by @code{.0value.} and @code{.255value.} are clipped. (There is no need, however, for @code{.0value.} to be less than @code{.255value.}.) This clipping discards information, so make sure the range you give is larger than the range of data in the grid. EXAMPLE: consider a satellite image in which an internal value of 0 is meant to correspond to 0 degrees Celsius, and an internal value of 255 corresponds to 25.5 degrees. (This is a common scale.) Then Gri command @code{set image range 0 25.5} would establish the required range. If this range were combined with a linear grayscale mapping (see @code{set image grayscale}), the resultant granularity in the internal representation of the user values would be (25.5-0)/255 or 0.1 degrees Celsius; temperature variations from pixel to pixel which were less than 0.1 degrees would be lost. All other image commands *require* that the range has been set. Thus, all these commands fail unless @code{set image range} has been done: @code{draw image}, @code{draw image palette}, @code{read image}, @code{convert grid to image}, @code{set image grayscale}, and @code{set image colorscale}. NOTE: If a range already exists when @code{set image range} is used, then the settings are altered. Thoughtless usage can therefore lead to confusing results. (The situation is like setting an axis scale, plotting a curve with no axes, then altering the scale and plotting the new axes. It's legal but not necessarily smart.) @node Set Input Data Window, Set Input Data Separator, Set Image Range, Set @comment node-name, next, previous, up @subsubsection @code{set input data window} @findex set input data window @cindex @code{set input data window} command @example `set input data window x|y @{.min. .max.@}|off' @end example @noindent Create a data window for following @code{read} statements. @itemize @bullet @item @code{set input data window x .min. .max.} For future reading commands, ignore all data with x less than @code{.min.} or x greater than @code{.max.} The data not in the interval will not be read in at all. This will hold until @code{set data window x off} is done, in which case all data will be read in. @item @code{set input data window x off} Return to normal conditions, in which all data are read in. @item @code{set input data window y .min. .max.} Analgous to command for x. @item @code{set input data window y off} Analagous to command for x. @end itemize EXAMPLE: To set the input data window as the current x axis plus a border of 5 centimetres to left and right, do the following: @example set input data window x \ @{rpn ..xleft.. xusertocm 5 - xcmtouser@} \ @{rpn ..xright.. xusertocm 5 + xcmtouser@} @end example @strong{See also} @code{set clip} @cindex input data window @cindex data, clipping using @code{set input data window} @cindex clipping data using @code{set input data window} @node Set Input Data Separator, Set Line Cap, Set Input Data Window, Set @comment node-name, next, previous, up @subsubsection @code{set input data separator} @findex set input data separator @cindex @code{set input data separator} command @example `set input data separator TAB|default' @end example @noindent Set the separator between data items. The @code{default} method is to assume that data items are separated by one or more spaces or tabs, and also to ignore any spaces or tabs at the start of a data line. In the @code{TAB} method the data are assumed to be separated by a SINGLE tab character. (Multiple tabs will result in null values being assigned to items -- almost certainly not what you want!) Also, initial spaces and tabs on lines are NOT skipped. Use the @code{TAB} method only after thinking carefully about the above, since the assignment of null values is problematic. @node Set Line Cap, Set Line Join, Set Input Data Separator, Set @comment node-name, next, previous, up @subsubsection @code{set line cap} @findex set line cap @cindex @code{set line cap} command @cindex setting line cap type @cindex line cap @example `set line cap .type.' @end example @noindent Set the type of ends (caps) of lines. Use @code{.type.} of value 0 for square ends, cut off precisely at the end of line, or 1 for round ends which overhang half the line width, or 2 for square ends which overhang half the line width. The selected style is used for the ends of line segments, as well as at corners. In PostScript parlance, therefore, this command sets both the linecap and the linejoin parameters. This command only applies to lines drawn with @code{draw curve}, @code{draw line} and @code{draw polygon}. Axes are always drawn with a line cap of 0. @node Set Line Join, Set Line Width, Set Line Cap, Set @comment node-name, next, previous, up @subsubsection @code{set line join} @findex set line join @cindex @code{set line join} command @cindex setting line join type @cindex line join @example `set line join .type.' @end example @noindent Set the type of intersection of lines. Use @code{.type.} of value 0 for mitered joins (pointy ends that may extend beyond the data points), a value of 1 for rounded ends (the default), or a value of 2 for bevelled (squared-off) ends. See the @code{setlinejoin} command in any text on the PostScript language for more information. This command only applies to lines drawn with @code{draw curve}, @code{draw line} and @code{draw polygon}. Axes are always drawn with a line join of 0. @node Set Line Width, Set Missing Value, Set Line Join, Set @comment node-name, next, previous, up @subsubsection @code{set line width} @findex set line width @cindex @code{set line width} command @cindex setting line width @cindex line width @example `set line width \ [axis|symbol|all] \ .width_pt. \ | @{rapidograph \name@} \ | default' @end example @noindent Set the width of lines used to draw curves (default), axes, symbols, or all of the above. The width may be set to a value specified in points (conversion: 72 pt = 1 inch), to a named rapidograph width, or to the default value. The initial default values are: 0.709pt (or rapidograph 3x0) for curves; 0.369pt (or rapidograph 6x0) for axes; 0.369pt (or rapidograph 6x0) for symbols. (To learn more about standard pen widths, see the ISO 9175-1 documents.) @cindex American Geophysical Union, recommended line thickness If your figure is to be reproduced by a journal, you should check with them about the range of line thicknesses they recommend. This will, of course, depend on whether your figure is reduced or enlarged during reproduction. For example, American Geophysical Union (publishers of J. Geophysical Res.) recommends that one use line thicknesses no less than 0.5 points and no more than 4 points. @cindex rapidograph scaling for line width @cindex slides, suggested line widths @cindex overhead projection images, suggested line widths @cindex projected images, suggested line widths The rapidograph settings match the standard set of widths used in technical fountain pens. The table below gives width names along with the width in points and centimetres, as given in the specifications supplied with Rapidograph technical fountain pens. Names marked by the symbol @code{*} are in sequence increasing by the factor root(2). Texts on technical drawing often suggest using linewidths in the ratio of 2 or root(2). On many printers, the variation in width from root(2) increase is too subtle to see, so the factor-of-2 rule may be preferable. To get sizes in a sequence doubling in width, pick from the list (@code{6x0}, @code{3x0}, @code{1}, @code{3.5} @code{7}). To get a sequence increasing in width by root(2), pick from the list (@code{6x0}, @code{4x0}, @code{3x0}, @code{0}, @code{1}, @code{2.5}, @code{3.5}, @code{6}, @code{7}). The eye can distinguish curves with linewidths differing by a factor of root(2) if the image is of high quality, but a factor of 2 is usually better. Similarly, for overhead projections and projected slides, one would do well to use linewidths differing by a factor of 4. This is the list of @code{rapidograph} linewidths: @example Name pt cm ==== ===== ===== * 6x0 0.369 0.013 * 4x0 0.510 0.018 * 3x0 0.709 0.025 00 0.850 0.03 * 0 0.992 0.035 * 1 1.417 0.05 2 1.701 0.06 * 2.5 1.984 0.07 3 2.268 0.08 * 3.5 2.835 0.1 4 3.402 0.12 * 6 3.969 0.14 * 7 5.669 0.2 @end example @node Set Missing Value, Set Page Size, Set Line Width, Set @comment node-name, next, previous, up @subsubsection @code{set missing value} @findex set missing value @cindex @code{set missing value} command @cindex missing values @example `set missing value .value.|none' @end example @noindent If a numerical value is given, set the missing-value code to that value, and also store this value in the builtin variable @code{..missingvalue..} and the builtin synonym @code{\.missingvalue..} also. After this command, Gri will ignore any data that are within 0.1 percent of this value. (This feature is commonly used in geophysical data.) If @code{none} is given, turn off this feature. The default is that the feature is turned off. @node Set Page Size, Set Page, Set Missing Value, Set @comment node-name, next, previous, up @subsubsection @code{set page size} @findex set page @cindex @code{set page size} command @example `set page size letter|legal|folio|tabloid|A0|A1|A2|A3|A4|A5' @end example @noindent Set the page dimension, as indicated below. @table @emph @item letter American "letter" size: 8.5 x 11 inches @item legal American "legal" size: 8.5 x 14 inches @item folio American "folio" size: 8.5 x 13 inches @item tabloid American "tabloid" size: 11 x 17 inches @item A5 Metric size: 14.8 x 21.0 cm @item A4 Metric size: 21.0 x 29.7 cm @item A3 Metric size: 29.7 x 42.0 cm @item A2 Metric size: 42.0 x 59.4 cm @item A1 Metric size: 59.4 x 84.1 cm @item A0 Metric size: 84.1 x 118.9 cm @end table The effect is to possibly alter the PostScript "bounding box." If all the drawn material fits within the indicated page, then the bounding box is not altered. (In other words, Gri will still keep the bounding box tight on the drawn items.) However, if any drawn item extends beyond the indicated size, it will be clipped to the boundary. @node Set Page, Set Panel, Set Page Size, Set @comment node-name, next, previous, up @subsubsection @code{set page} @findex set page @cindex @code{set page} command @example `set page portrait \ | landscape \ | @{factor .mag.@} \ | @{translate .xcm. .ycm.@}' @end example @noindent Control orientation or scaling of what is drawn on the paper. @cindex portrait orientation of page @cindex orientation of page, portrait @cindex page orientation, portrait @itemize @bullet @item @code{set page portrait} Print graph normally (default). @cindex landscape orientation of page @cindex orientation of page, landscape @cindex page orientation, landscape @item @code{set page landscape} Print graph sideways. @item @code{set page factor .mag.} Scale everything to be drawn on the paper by the indicated magnification factor. This @strong{must} be called before any drawing commands. @item @code{set page translate .xcm. .ycm.} Translate everything to be drawn on the paper by the indicated x/y distances. This @strong{must} be called before any drawing commands. @end itemize @strong{Note}: The order of the factor/translate commands matters, so you may need to experiment. For example, @example set page translate 2 1 set page factor 0.5 @end example @noindent moves anything that would have been drawn at the lower-left corner of the paper onto the point 2cm from the left side and 1cm from the bottom side of the paper, and then applies the multiplication factor. Reversing the order gives quite different results. PostScript gurus should note that the following two commands are inserted into the PostScript file: @example 56.900000 28.450000 translate 0.500000 0.500000 scale @end example @node Set Panel, Set Panels, Set Page, Set @comment node-name, next, previous, up @subsubsection @code{set panel} @findex set panel @cindex @code{set panel} command @cindex Multi-panel plots @cindex Window-pane plots @example set panel .row. .col. @end example @noindent Establish the geometry for the panel in the indicated row and column; that is, select which defined panel to draw into. The bottom row has @code{.row.} = 1, and the leftmost column has @code{.col.} = 1. This must be used only after defining the panel layout using @code{Panels .row. .col. .dx_cm. .dy_cm.}. @node Set Panels, Set Path To, Set Panel, Set @comment node-name, next, previous, up @subsubsection @code{set panels} @findex set panels @cindex @code{set panels} command @cindex Multi-panel plots @cindex Window-pane plots @example set panels .rows. .cols. [.dx_cm. .dy_cm.] @end example @noindent Set up for multipanel plots, with spacing @code{.dx_cm.} between the columns and @code{.dy_cm.} between the rows. If the spacings are not supplied, 2cm is used. The panels fill the rectangle which would otherwise contain the single axis frame, as set by @code{set x size} and @code{set x margin}, etc. The global variables @code{.panel_dx.}, @code{.panel_dy.}, @code{.panel_xmargin.}, @code{.panel_ymargin.}, @code{.panel_xsize.}, and @code{.panel_ysize} are created, to be used by later calls to @code{set panel}. EXAMPLE @example # Draw 2 panels across, 3 up the page. # The Panel interiors will be in region cornered # by (2,2), (12,22) cm set x margin 2 set y margin 2 set x size 10 set y size 20 set panels 2 3 # Create dummy scale set x axis 0 1 set y axis 0 1 # Draw blank axes et panel 1 1 raw axes set panel 1 2 draw axes set panel 1 3 draw axes set panel 2 1 draw axes set panel 2 2 draw axes set panel 2 3 draw axes @end example @strong{See also} @code{set panel .row. .col.} @node Set Path To, Set Postscript Filename, Set Panels, Set @comment node-name, next, previous, up @subsubsection @code{set path} @findex set path @cindex @code{set path} command @cindex path, for command files @cindex path, for data files @cindex command files, path to search for @cindex data files, path to search for @cindex @code{\\.path_data.} builtin synonym @cindex @code{\\.path_commands.} builtin synonym @cindex builtin synonym @code{\\.path_data.} @cindex builtin synonym @code{\\.path_commands.} @example set path to "\path"|default for data|commands @end example @noindent Set the directory path that @code{open} will search for data files, or that @code{insert} will search for command files. This search will @emph{not} be done if the filename starts with a @code{/}, @code{~}, or @code{.} character. The path is formatted in a colon-separated manner, following the normal Unix convention, and searching is from left to right. For example, the path @code{".:/usr/lib/gri"} tells Gri to search for the file first in the local directory (named @file{.}), and if it is not found there, to look next in the directory named @file{/usr/lib/gri}. The indicated path is stored in either @code{\.path_data.} or @code{\.path_commands.}, as appropriate. At startup time, each of these paths is set to @file{"."}, the current directory, and this value is reset if the @code{default} keyword is provided to this command. If you need to know where the file was eventually found, save the @code{\.return_value.} just after the @code{open} command was executed. For example, the following defines the synonym @code{\uk}, which is the full pathname of the file containing some sort of data about Great Britain. @example set path to "/atlases/world:/atlases/northern_hemisphere" for data open britain.dat # we don't know where file is ... \gb = "\.return_value." # ... until now! # Can later do command such as # read from \gb # or # rewind \gb # to work with this particular file, even if # there is another file open that also is # named "britain.dat". @end example @node Set Postscript Filename, Set Symbol Size, Set Path To, Set @comment node-name, next, previous, up @subsubsection @code{set postscript filename} @findex set postscript filename @cindex @code{set postscript filename} command @cindex name, of PostScript file @cindex postscript filename @example `set postscript filename "\name"' @end example @noindent Set name of PostScript file, over-riding the present name. @node Set Symbol Size, Set Tic Size, Set Postscript Filename, Set @comment node-name, next, previous, up @subsubsection @code{set symbol size} @findex set symbol size @cindex @code{set symbol size} command @cindex setting symbol size @cindex symbols, setting size @example `set symbol size .diameter_cm.|default' @end example @noindent Control the diameter of symbols drawn by @code{draw symbol} command. @itemize @bullet @item @code{set symbol size .diameter_cm.} Make symbol size be @code{.diameter_cm.} centimeters in diameter. @item @code{set symbol size default} Set to default diameter of 0.1 cm. @end itemize @node Set Tic Size, Set Trace, Set Symbol Size, Set @comment node-name, next, previous, up @subsubsection @code{set tic size} @cindex axes, setting tic size @cindex tic size, setting @findex set tic size @cindex @code{set tic size} command @example `set tic size .size.|default' @end example @noindent Control size of tics on axes. @itemize @bullet @item @code{set tic size .size.} Set tic size to @code{.size.} centimetres. @item @code{set tic size default} Set tic size to default of 0.2 cm. @item @code{set tics in|out} Make axis tics point inward or outward. The default is outward. @end itemize @node Set Trace, Set Transparency, Set Tic Size, Set @comment node-name, next, previous, up @subsubsection @code{set trace} @findex set trace @cindex @code{set trace} command @example `set trace [on|off]' @end example @noindent Control printing of command lines as they are processed. @itemize @bullet @item @code{set trace} Make Gri print command lines as they are processed. @item @code{set trace on} Same as @code{set trace}. @item @code{set trace off} Prevent printing command lines (default). @end itemize @node Set Transparency, Set U Scale, Set Trace, Set @comment node-name, next, previous, up @subsubsection @code{set transparency} @findex set transparency @cindex @code{set transparency} command @example `set transparency .transparency.' @end example @noindent Set the transparency of drawn items, 0 for opaque and 1 for invisibly faint. @emph{This command is provisional, as of summer 2004, and this part of the documentation needs to be fleshed out so users can build intuition on transparency. For example, a quick quiz: what color do you think comes from drawing red on top of yellow, or on top of blue? } @node Set U Scale, Set V Scale, Set Transparency, Set @comment node-name, next, previous, up @subsubsection @code{set u scale} @findex set u scale @cindex @code{set u scale} command @example `set u scale .cm_per_unit.|@{as x@}' @end example @noindent Set scale for x-component of arrows. @itemize @bullet @item @code{set u scale .cm_per_unit.} Set scale for @code{u} component of arrows. @item @code{set u scale as x} Set scale for u component of arrows to be the same as the x-scale. Equivalent to @code{set u scale as @{rpn ..xsize.. ..xright.. ..xleft.. - /@}}. @end itemize NOTE: this only works if the x-scale is LINEAR (see @code{set x type}). @node Set V Scale, Set X Axis, Set U Scale, Set @comment node-name, next, previous, up @subsubsection @code{set v scale} @findex set v scale @cindex @code{set v scale} command @example `set v scale .cm_per_unit.|@{as y@}' @end example @noindent Set scale for y-component of arrows. @itemize @bullet @item @code{set v scale .cm_per_unit.} Set scale for @code{v} component of arrows. @item @code{set v scale as y} Set scale for v component of arrows to be the same as the y-scale. Equivalent to @code{set v scale as @{rpn ..ysize.. ..ytop.. ..ybottom.. - /@}}. @end itemize NOTE: this only works if the y-scale is LINEAR (see @code{set y type}). @node Set X Axis, Set X Format, Set V Scale, Set @comment node-name, next, previous, up @subsubsection @code{set x axis} @findex set x axis @cindex @code{set x axis} command @example `set x axis top' `set x axis bottom' `set x axis increasing' `set x axis decreasing' `set x axis unknown' `set x axis .left. .right. [.incBig. [.incSml.]] [labelling .labelling_value.]' `set x axis labels [add] .position_1. "label_1" [.position_2. "label_2" [...]]' `set x axis labels automatic' @end example @noindent Control various things about the x axis. @itemize @bullet @item @code{set x axis top} Make next x-axis to be drawn have labels above the axis. @item @code{set x axis bottom} Make next x-axis to be drawn have labels below the axis. @item @code{set x axis increasing} Make next x-axis to be drawn have numeric labels increasing to the right. This applies only if autoscaling is done; otherwise, the supplied values (@code{.left. .right. [.incBig. [.incSml.]]}) are used. @item @code{set x axis decreasing} Make next x-axis to be drawn have numeric labels decreasing to the right. This applies only if autoscaling is done; otherwise, the supplied values (@code{.left. .right. [.incBig. [.incSml.]]}) are used. @item @code{set x axis unknown} Make Gri forget any existing scale for the x axis, whether set by another @code{set x axis} command or automatically, during reading of data. This is essentially a synonym for @code{delete x scale}. @item @code{set x axis .left. .right.} Make x-axis range from @code{.left.} to @code{.right.} @item @code{set x axis .left. .right. .incBig.} Make x-axis range from @code{.left.} to @code{.right.}, with labelled increments at @code{.incBig.} Note: In the case of log axes, and provided that @code{set x type log} has been called previously, the @code{.incBig.} parameter has a different meaning: it is the interval, in decades, between numbered labels; the default is 1. @item @code{set x axis .left. .right. .incBig. labelling .labelling_value.} As above, but with the axis labels including the indicated value, and incremented larger and smaller by @code{.incBig}. (This does not work for logarithmic axes.) @item @code{set x axis .left .right. .incBig. .incSml.} Make x-axis range from @code{.left.} to @code{.right.}, with labelled increments at @code{.incBig.}, and small tics at @code{.incSml.} NOTE: if the axis is logarithmic, the value of @code{.incSml.} takes on a special meaning: if it is positive then small tics are put at values 2, 3, 4, etc. between the decades, but if @code{.incSml.} is negative then no such small tics are used. @item @code{set x axis .left .right. .incBig. .incSml. labelling .labelling_value.} As above, but with the axis labels including the indicated value, and incremented larger and smaller by @code{.incBig}. (This does not work for logarithmic axes.) @item @code{set x axis labels .position. "label" [.position. "label" [...]]} @cindex axis labels, controlling @cindex day-of-week axis Override the automatic labelling at axis tics, and instead put the indicated labels at the indicated x values. For example, a day-of-week axis can be created by the code: @example set x axis 0 7 1 set x axis labels 0.5 "Mon" 1.5 "Tue" 2.5 "Wed" \ 3.5 "Thu" 4.5 "Fri" 5.5 "Sat" \ 6.5 "Sun" @end example The command replaces any existing labels, unless the `add' keyword is present, in which case the new label information is appended to any existing information. @item @code{set x axis labels automatic} Return to automatically-generated axis labels, undoing the command of the previous item. @end itemize @node Set X Format, Set X Grid, Set X Axis, Set @comment node-name, next, previous, up @subsubsection @code{set x format} @findex set x format @cindex @code{set x format} command @example `set x format \format|default|off @end example @noindent Set format for numbers on x axis. The format is specified in the manner of the "C" programming language. The C formats (i.e., @code{%f}, @code{%e} and @code{%g}) are permitted. For example, @code{set x format %.1f} tells Gri to use 1 decimal place, and to prefer the "float" notation to the exponential notation. The form @code{set x format off} tells Gri not to write numbers on the axis. To get spaces in your format, enclose the format string in double-quotes, e.g., you might use @code{set x format "%.0f$\circ$ W"} for a map, or @code{set x format "%f "} to make the numbers appear to the left of their normal location. The default format is @code{%lg}. @node Set X Grid, Set X Margin, Set X Format, Set @comment node-name, next, previous, up @subsubsection @code{set x grid} @findex set x grid @cindex @code{set x grid} command @example `set x grid .left. .right. .inc.|@{/.cols.@}' @end example @noindent Create x-grid for contour or image. If a grid already exists, an error will be declared; the way to interpolate from an existing grid to a new one is with the @code{interpolate x grid} command. @itemize @bullet @item @code{set x grid .left. .right. .inc.} Create x-grid ranging from the value @code{.left.} at the left to @code{.right.} at the right, stepping by an increment of @code{.inc.}. @item @code{set x grid .left. .right. /.cols.} Create x-grid with @code{.cols.} points, ranging from the value @code{.left.} at the left to @code{.right.} at the right. @end itemize @node Set X Margin, Set X Name, Set X Grid, Set @comment node-name, next, previous, up @subsubsection @code{set x margin} @findex set x margin @cindex @code{set x margin} command @example `set x margin @{[bigger|smaller] .size.@}|default' @end example @noindent Control x margin, that is, the space between the left-hand side of the page and the left-hand side of the plotting area. (Note that axis labels are drawn inside the margin; the margin extends to the axis line, not to the labels.) @itemize @bullet @item @code{set x margin .size.} Set left margin to @code{.size.} cm. It is permissible to have negative margins, with the expected effect. @item @code{set x margin bigger .size.} Increases left margin by @code{.size.} cm. @item @code{set x margin smaller .size.} Decreases left margin by @code{.size.} cm. @item @code{set x margin default} Set left margin to default = 6 cm. @end itemize @node Set X Name, Set X Size, Set X Margin, Set @comment node-name, next, previous, up @subsubsection @code{set x name} @findex set x name @cindex @code{set x name} command @example `set x name "\name"|default' @end example @noindent Set name of x-axis to the indicated string. An empty string (@code{set x name ""}) causes the x axis to be unlabelled. The @code{default} is @code{"x"}. @node Set X Size, Set X Type, Set X Name, Set @comment node-name, next, previous, up @subsubsection @code{set x size} @findex set x size @cindex @code{set x size} command @example `set x size .width_cm.|default' @end example @noindent Set the width of the plotting area. This does not include axis labels, only the interior part of the plot. @itemize @bullet @item @code{set x size .width_cm.} Set width of x-axis in centimeters. @item @code{set x size default} Set width of x-axis to default = 10 cm. @end itemize @node Set X Type, Set Y Axis, Set X Size, Set @comment node-name, next, previous, up @subsubsection @code{set x type} @findex set x type @cindex @code{set x type} command @example set x type linear|log|@{map E|W|N|S@} @end example @noindent Control transformation function mapping user units to centimetres on the page. @itemize @bullet @item @code{set x type linear} Set to linear axis. @item @code{set x type log} Set to log axis. To avoid clashes in the linear to log transform, this command should precede the creation of an axis scale, either explicitly through the @code{set x axis .left. .right. ...} command or implicitly through the @code{read columns} command. @item @code{set x type map E|W|N|S} @cindex maps, format of x axis Set to be a map. This means that whole numbers on the axis will have a degree sign written after them (and then the letter @code{E}, etc) and that numbers which are multiples of 1/60 will be written in degree-minute format, and that similarly numbers which are divisible by 1/3600 will be in degree-minute-second format. If none of these things apply, the axis labels will be written in decimal degrees. Note that this command overrides any format set by @code{set x format}. BUG: this only has an effect if the axis is not already of type @code{log}. @end itemize @node Set Y Axis, Set Y Format, Set X Type, Set @comment node-name, next, previous, up @subsubsection @code{set y axis} @findex set y axis @cindex @code{set y axis} command @example `set y axis left' `set y axis right' `set y axis increasing' `set y axis decreasing' `set y axis .bottom. .top. [.incBig. [.incSml.]] [labelling .labelling_value.]' `set y axis labels [add] .position_1. "label_1" [.position_2. "label_2" [...]]' `set y axis labels automatic' @end example @noindent Control various things about the y axis. @itemize @bullet @item @code{set y axis name horizontal} Make y-axis name be horizontal. @item @code{set y axis name vertical} Make y-axis name be vertical (default). @item @code{set y axis left} Make next y-axis to be drawn have labels to the left of the axis. @item @code{set y axis right} Make next y-axis to be drawn have labels to the right of the axis. @item @code{set y axis increasing} Make next y-axis to be drawn have numeric labels increasing up the page. This applies only if autoscaling is done; otherwise, the supplied values (@code{.left. .right. [.incBig. [.incSml.]]}) are used. @item @code{set y axis decreasing} Make next y-axis to be drawn have numeric labels decreasing up the page. This applies only if autoscaling is done; otherwise, the supplied values (@code{.left. .right. [.incBig. [.incSml.]]}) are used. @item @code{set y axis unknown} Make Gri forget any existing scale for the y axis, whether set by another @code{set y axis} command or automatically, during reading of data. This is essentially a synonym for @code{delete y scale}. @item @code{set y axis .bottom. .top.} Make y-axis range from @code{.bottom.} to @code{.top.} @item @code{set y axis .bottom. .top. .incBig.} Make y-axis range from @code{.bottom.} to @code{.top.}, with labelled increments at @code{.incBig.} @item @code{set y axis .bottom. .top. .incBig. labelling .labelling_value.} As above, but with the axis labels including the indicated value, and incremented larger and smaller by @code{.incBig}. (This does not work for logarithmic axes.) @item @code{set y axis .bottom. .top. .incBig. .incSml.} Make y-axis range from @code{.bottom.} to @code{.top.}, with labelled increments at @code{.incBig.}, and small tics at @code{.incSml.} NOTE: if the axis is logarithmic, the value of @code{.incSml.} takes on a special meaning: if it is positive then small tics are put at values 2, 3, 4, etc. between the decades, but if @code{.incSml.} is negative then no such small tics are used. @item @code{set y axis .bottom. .top. .incBig. .incSml. labelling .labelling_value.} As above, but with the axis labels including the indicated value, and incremented larger and smaller by @code{.incBig}. (This does not work for logarithmic axes.) @item @code{set y axis labels .position. "label" [.position. "label" [...]]} Override the automatic labelling at axis tics, and instead put the indicated labels at the indicated y values. For example, a physical-condition axis can be created by the code: @example set y axis 0 1 0.5 set y axis labels 0.25 "Weak" 0.75 "Strong" @end example The command replaces any existing labels, unless the `add' keyword is present, in which case the new label information is appended to any existing information. @item @code{set y axis labels automatic} Return to automatically-generated axis labels, undoing the command of the previous item. @item @code{set y axis name vertical} Cause future y axes to be drawn with the name aligned vertically (the default). @item @code{set y axis name horizontal} Cause future y axes to be drawn with the name aligned horizontally. @end itemize @node Set Y Format, Set Y Grid, Set Y Axis, Set @comment node-name, next, previous, up @subsubsection @code{set y format} @findex set y format @cindex @code{set y format} command @example `set y format \format|default|off' @end example @noindent Set format for numbers on y axis. The format is specified in the manner of the "C" programming language. The C formats (i.e., @code{%f}, @code{%e} and @code{%lg}) are permitted. For example, @code{set y format %.1f} tells Gri to use 1 decimal place, and to prefer the "float" notation to the exponential notation. The form @code{set y format off} tells Gri not to write numbers on the axis. To get spaces in your format, enclose the format string in double-quotes, e.g., you might use @code{set y format "%.0f$\circ$ N"} for a map, or @code{set y format "%f"} to make the numbers appear to the right of their normal location. The default format is @code{%lg}. @node Set Y Grid, Set Y Margin, Set Y Format, Set @comment node-name, next, previous, up @subsubsection @code{set y grid} @findex set y grid @cindex @code{set y grid} command @example `set y grid .bottom. .top. .inc.|@{/.rows.@}' @end example @noindent Create y-grid for contour or image. If a grid already exists, an error will be declared; the way to interpolate from an existing grid to a new one is with the @code{interpolate x grid} command. @itemize @bullet @item @code{set y grid .bottom. .top. .inc.} Create y-grid ranging from the value @code{.bottom.} at the bottom to @code{.top.} at the top, stepping by an increment of @code{.inc.}. @item @code{set y grid .bottom. .top. /.rows.} Create y-grid with @code{.rows.} points, ranging from the value @code{.bottom.} at the bottom to @code{.top.} at the top. @end itemize @node Set Y Margin, Set Y Name, Set Y Grid, Set @comment node-name, next, previous, up @subsubsection @code{set y margin} @findex set y margin @cindex @code{set y margin} command @example `set y margin @{[bigger|smaller] .size.@}|default' @end example @noindent Control y margin, that is, the space between the bottom side of the page and the bottom of the plotting area. (Note that axis labels are drawn inside the margin; the margin extends to the axis line, not to the labels.) @itemize @bullet @item @code{set y margin .size.} Set bottom margin to @code{.size.} centimeters. It is permissible to have negative margins, with the expected effect. @item @code{set y margin bigger .size.} Increases bottom margin by @code{.size.} centimeters. @item @code{set y margin smaller .size.} Decreases bottom margin by @code{.size.} centimeters. @item @code{set y margin default} Set bottom margin to default = 6 cm. @end itemize @node Set Y Name, Set Y Size, Set Y Margin, Set @comment node-name, next, previous, up @subsubsection @code{set y name} @findex set y name @cindex @code{set y name} command @example `set y name "\name"|default' @end example @noindent Set name of y-axis to the indicated string. An empty string (@code{set y name ""}) causes the x axis to be unlabelled. The @code{default} is @code{"y"}. @node Set Y Size, Set Y Type, Set Y Name, Set @comment node-name, next, previous, up @subsubsection @code{set y size} @findex set y size @cindex @code{set y size} command @example `set y size .height_cm.|default' @end example @noindent Set the width of the plotting area. This does not include axis labels, only the interior part of the plot. @itemize @bullet @item @code{set y size .height_cm.} Set height of y-axis in centimeters. @item @code{set y size default} Set width of y-axis to default = 10 cm. @end itemize @node Set Y Type, Set Z Missing, Set Y Size, Set @comment node-name, next, previous, up @subsubsection @code{set y type} @findex set y type @cindex @code{set y type} command @example set y type linear|log|@{map N|S|E|W@} @end example @noindent Control transformation function mapping user units to centimetres on the page. @itemize @bullet @item @code{set y type linear} Set to linear axis. @item @code{set y type log} Set to log axis. To avoid clashes in the linear to log transform, this command should precede the creation of an axis scale, either explicitly through the @code{set y axis .left. .right. ...} command or implicitly through the @code{read columns} command. @item @code{set y type map N|S|E|W} @cindex maps, format of y axis Set to be a map. This means that whole numbers on the axis will have a degree sign written after them (and then the letter @code{N}, etc), and that numbers which are multiples of 1/60 will be written in degree-minute format, and that similarly numbers which are divisible by 1/3600 will be in degree-minute-second format. If none of these things apply, the axis labels will be written in decimal degrees. Note that this command overrides any format set by @code{set y format}. BUG: this only has an effect if the axis is not already of type @code{log}. @end itemize @node Set Z Missing, Show, Set Y Type, Set @comment node-name, next, previous, up @subsubsection @code{set z missing} @findex set z missing @cindex @code{set z missing} command @example set z missing above|below .intercept. .slope. @end example @noindent Set @code{z} column to be missing whenever the associated @code{y} and @code{x} columns are above/below the line defined by @tex $y = {\rm .intercept.} + {\rm .slope.} x$ @end tex @ifinfo y = .intercept. + .slope. * x @end ifinfo @c HTML @node Show, Skip, Set Z Missing, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{show} @findex show @cindex @code{show} command @example `show ...' @end example @noindent Show some information by printing it to standard output. @itemize @bullet @item @code{show all} Show lots of information about plot. @item @code{show axes} @cindex axes, displaying information about Show information about axes. @item @code{show color} Show the current pen color used for lines and text. This is not to be confused with image color, which is independent. @item @code{show colornames} @cindex RGB values of known colors @cindex color, displaying names and RGB values of Show all colors known by name, as defined by @code{read colornames} command and also the builtin colors defined automatically (e.g. @code{white}, @code{black}, @code{red}, etc), (@ref{Read Colornames}). @item @code{show columns} Show x, y, z, u, v column data. @item @code{show columns statistics} @cindex statistics of column data @cindex column, displaying statistics of Show means, std devs, etc for columns. @item @code{show flags} Show values of all flags. (Developers only.) @item @code{show grid} @cindex grid data, displaying Show an indication of the grid data (used for contouring). @item @code{show grid mask} @cindex grid mask, displaying Show 1 if grid data are valid or 0 if contours will not extend into this region. @c REMOVED FOR 2.6.0 @item @code{show hint of the day} @c REMOVED FOR 2.6.0 @cindex hint of the day, displaying @c REMOVED FOR 2.6.0 Show a Gri hint for today, picked at random from hints stored on the web @c REMOVED FOR 2.6.0 at @c REMOVED FOR 2.6.0 @c HTML @c REMOVED FOR 2.6.0 @file{http://gri.sourceforge.net/gridoc/html/HINTS.html} @c REMOVED FOR 2.6.0 @c HTML @c REMOVED FOR 2.6.0 These will be downloaded at most once per day. Since the download might @c REMOVED FOR 2.6.0 take a couple of seconds, the hint is only downloaded once per day, @c REMOVED FOR 2.6.0 being cached for later uses in the given day, in a user file called @c REMOVED FOR 2.6.0 @file{~/.gri-hint-cache}. This command will @c REMOVED FOR 2.6.0 produce warning if the system program @code{lynx} is not available for @c REMOVED FOR 2.6.0 downloading. @item @code{show image} @cindex image, displaying histogram of Show information about image, such as a histogram of values, and, if the image is small enough, the actual data. @item @code{show license} Show the license for Gri, which outlines how users are allowed to share it freely. @item @code{show misc} Show miscellaneous information about the plot, the data, etc. @item @code{show next line} Show next line of data-file. @item @code{show synonyms} @cindex synonyms, displaying list of Show values of all synonyms, whether built-in or user-defined. @item @code{show stopwatch} @cindex timing things @cindex stopwatch, for timing things @cindex @code{show stopwatch} command Show elapsed time since first call to this command in the given Gri program. @item @code{show time} Show the current time. @item @code{show traceback} @cindex traceback Show traceback (i.e., the tree of commands being done at this instant). @item @code{show variables} @cindex variables, displaying list of Show values of all variables, whether built-in or user-defined. @item @code{show .value.} Show value of indicated variable. @item @code{show @{rpn ...@}} Show result of computing indicated expression. @item @code{show "some text"} @cindex @code{show} command, how to get a tab @cindex @code{show} command, how to get a newline @cindex tab, in a @code{show} command @cindex newline, in a @code{show} command Print the indicated string. You may use a double-slash to prevent Gri from substituting synonym values; thus it is common to do e.g. @example \var = "Temperature" show "Plotting \\var = 'var'" @end example @noindent which will produce the output line @example Plotting \\var = 'Temperature' @end example @item @code{show "time=" .time. "; depth=" .depth.} Print strings and values as indicated. If the last item is ellipses (three dots with no spaces between them), then no newline is printed; this makes the next @code{show} statement print on the same line. @cindex @code{\<<}, for newline in @code{show} commands @cindex @code{\>>}, for horizontal tab in @code{show} commands @cindex newline, using @code{\<<} in @code{show} @cindex tab, using @code{\>>} in @code{show} @cindex @code{show} command, using @code{\<<} for newline @cindex @code{show} command, @code{\>>} for horizontal tab To get a newline in a printed string, use the three-character glyph @code{\<<}, and to get a horizontal tab, use @code{\>>}, as in the examples below @example \a = "HI" show "\\a=\a" system echo -e "a\\nb" show "first line\<>(tabbed) second line" show "first line\<<\>>(tabbed) second line" @end example @end itemize @c HTML @node Skip, Sleep, Show, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{skip} @findex skip @cindex @code{skip} command @cindex data files, positioning within @cindex files, positioning within @example `skip [forward|backward] [.n.]' @end example @itemize @bullet @item @code{skip} For ascii files, skip next line in the data file. For binary files, skip forward 1 byte. @item @code{skip backward} For ascii files, skip backward 1 line in the data file. For binary files, skip backward 1 byte. @item @code{skip .n.} or @code{forward .n.} For ascii files, skip forward @code{.n.} lines in the data file. For binary files, skip forward @code{.n.} bytes. @item @code{skip backward .n.} For ascii files, skip backward @code{.n.} lines in the data file. For binary files, skip backward @code{.n.} bytes. @end itemize @c HTML @node Sleep, Smooth, Skip, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{sleep} @cindex sleep, causing Gri to @cindex process, causing Gri to sleep @cindex @code{sleep} command @example `sleep .sec.' @end example Cause Gri to sleep for the indicated number of seconds, which should be a positive integer. This command is ignored if @code{.sec.} is zero or negative, and the value of @code{.sec.} is first rounded to the nearest integer. Normally, this command is used only by the developer, as a way to slow down Gri execution, to allow easier monitoring for debugging purposes. Beware: it is tricky to kill a sleeping job! @c HTML @node Smooth, Source, Sleep, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{smooth} @cindex columns, filtering @cindex smoothing column data @findex smooth @cindex @code{smooth} command All these smoothing commands ignore the @strong{location} of the data. For equispaced data these algorithms have the standard interpretation in terms of digital filters. For non-equispaced data, the interpretation is up to the user. @example `smooth @{x [.n.]@} \ | @{y [.n.]@} \ | @{grid data [.f.|@{along x|y@}]@}' @end example The @code{smooth x} command does smoothing by the following formula @example x[i-1] x[i] x[i+1] ------ + ---- + ------ 4 2 4 @end example The @code{smooth x .n.} command does boxcar smoothing with centred boxcars @code{.n.} points wide. The @code{smooth y} command does the same as @code{smooth x}, but on the @code{y} column. @cindex grid data, smoothing @cindex smoothing grid data @cindex contours, smoothing grid data @findex smooth grid data @cindex @code{smooth grid data} command There are several methods of smoothing grid data. Note that isolated missing values are filled in by each method. (Let the author know if you'd like that `feature' to be an option.) The @code{smooth grid data} command smooths gridded data, by weighted average in a plus-shaped window about each gridpoint. The smoothing algorithm replaces each interior gridpoint value @code{z[i][j]} by @example z[i][j] z[i-1][j] + z[i+1][j] + z[i][j-1] + z[i][j+1] ------- + --------------------------------------------- 2 8 @end example @noindent Points along the edges are smoothed by the same formula, after inventing image points outside the domain by planar extrapolation. The @code{smooth grid data .f.} command performs partial smoothing. A temporary fully-smoothed grid @code{zSMOOTH[i][h]} is constructed as above, and a linear combination of this grid and the original grid is used as the replacement grid: @example z[i][j] = (1-f) * z[i][j] + f * zSMOOTH[i][j] @end example @noindent where @code{f} is the value indicated on the command line. Thus, @code{smooth grid data 0} performs no smoothing at all, while @code{smooth grid data 1} is equivalent to @code{smooth grid data}. The @code{smooth grid data along x} command smooths the grid data across @code{x} (i.e., horizontally), by replacing each value @code{z[i][j]} with the value @example z[i][j] z[i-1][j] + z[i+1][j] ------- + --------------------- 2 4 @end example @noindent Points along the edges are smoothed by the same formula, after inventing image points outside the domain by linear extrapolation. The @code{smooth grid data along y} command does the same thing as @code{smooth grid data along x}, but the smoothing is along @code{y}. @strong{See also} @ref{Filter}, a generalization of @code{smooth x|y} which allows for more sophisticated filters. @c HTML @node Source, Sprintf, Smooth, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{source} @findex source @cindex @code{source} command, for running another command file @cindex running a commandfile @example `source \filename' @end example @noindent Perform the commands in the indicated file. If the file cannot be found, an error results. Contrast this with the @code{insert} command (@ref{Insert}), which has the ability to search for the file through a user-specified path (@ref{Set Path To}). @c HTML @node Sprintf, State, Source, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{sprintf} @findex sprintf @cindex @code{sprintf} command @cindex variables, storing values within synonyms (strings) @cindex strings, storing variable values within @cindex synonyms, storing variable values within @example `sprintf \synonym "format" .variable. [.variable. [...]]' @end example @noindent Write numbers into a synonym (text string). This is useful for labelling plots. @noindent @code{sprintf \out "a = %lf b = %.2f" .a. .b.} - Create a synonym called @code{\out}, and print the values of the variables @code{.a.} and @code{.b.} into it. If @code{.a.} = 1 and @code{.b.} = 0.112, then @code{\out} will be @code{"a = 1 b = 0.11"} Formatting codes are as in the C programming language, eg: @example %.2f -- Use floating point with 2 decimal places. %9.2f -- As above, but number takes 9 characters. %e -- Use exponential notation. @end example @noindent @strong{CAUTION}: Variables are stored in the @strong{floating point} in Gri, so you must use a format like @code{"%f"}, @strong{not} an integer code like @code{"%d"}. If you want an integer, use @code{"%.0f"}. @cindex format, for sprintf command @c HTML @node State, Superuser, Sprintf, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{state} @cindex saving graphics state @cindex restoring graphics state @cindex graphics state, saving and restoring @findex @code{state} command @example `state save|restore|display' @end example @noindent The @code{save} operation pushes a record of the graphics state (pen and font characteristics, margins, axis lengths, min/max/inc values on axes, etc) onto a stack. The @code{restore} operation replaces the present state with whatever is on top of the stack, and then pops the stack. Use @code{display} to see some of the state properties. The @code{state} command is useful for temporary changes of axis properties, etc. BUG: only line characteristics (width, color) and font characteristics (font, size, color) are saved so far. In fact, the full list of what should be saved has not yet been finalized by the author. @c HTML @node Superuser, System, State, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{superuser} @cindex debugging using superuser flags @cindex superuser flags @findex superuser @cindex @code{superuser} command @example `superuser [value]' @end example @noindent Allow extra debugging information and commands. Normally, this command and the corresponding commandline flag @code{-superuser} are only used by programmers altering the Gri source. These are the flags and their meanings: @itemize @bullet @item @strong{1} Print cmdline before/after substituting synonyms. @item @strong{2} Print cmdline before/after substituting rpn expressions. @item @strong{4} Print all new commands as they are being defined @item @strong{8} Print the system commands that are used with @code{open "...|"} and in other instances. @item @strong{128} Changeable; only author should use this. @item @strong{256} Changeable; only author should use this. @end itemize Note that all flags are equal to 2 raised to an integer power. Since the flag values are detected by a bitwise OR, you can combine flags by adding; thus specifying a flag of 5 yields flags 1 and 4 together; specifying 15 yields flags 1, 2, 4 and 8. @c HTML @node System, Unlink, Superuser, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{system} @cindex gawk, sample of use @cindex operating system commands, printing results of @cindex system commands, printing results of @cindex operating system commands, assigned to synonyms @cindex system commands, assigned to synonyms @findex system @cindex @code{system} command @example `system \system-command' @end example @noindent Tell the operating system to perform the indicated action. Whatever string follows the word @code{system} is passed directly to the operating system, @strong{after} substitution of synonyms if any exist. @cindex comments, and system commands @cindex quoting in system commands If your system command contains double-slashes, you must protect them from Gri (which will interpret them as comments) by enclosing in double-quotes, e.g. @code{system cat A | sed -e "s/foo//g" | cat > B}. (In the particular case of the @code{sed} command you could also do @code{system cat A | sed -e "s:foo::g" | cat > B}. Note that @code{rpn} expressions are not evaluated, and variable values are not substituted before passing the string to the operating system. The exit status is stored in the builtin variable @code{..exit_status..}. There are two ways to use the system: @itemize @bullet @item @strong{Assign output to synonym}: The form @code{\synonym = system ...} does the system command and then inserts the output from that command into the indicated synonym.) @item @strong{Just run a command}: The command @code{system ls} will list the files in the current directory. @end itemize For long commands, there are two approaches, the second preferred: @itemize @bullet @item @strong{Use continuation lines}: String a lot of information onto one effective system line, using the @code{\} line-continuation character at the ends of lines. The problem is that it is very easy to lose one of these backslashes. The next method is better. @item @strong{Here-is syntax} The here-is syntax of many unix shells is also provided. If the system command contains the characters @code{<<} followed by a word (with no space between!) then Gri will issue a system command which includes not only this line but also all succeeding lines, until a line is found which matches the indicated word precisely (with no leading space allowed). The @code{<< "WORD"} syntax is also supported, meaning that the operating system is being told not to mess with the dollar-signs -- needed in perl. Be careful using this inside a new-command. Gri Recognizes the end of the body of a new-command by a line with @code{@}} in the @strong{first column}, and no non-white characters thereafter. If you system command happens to use a line with a curly brace (as in a loop in perl, for example), you must put whitespace before the brace. This won't affect the system command, but it will let Gri correctly realize that this is @strong{not} the end of the new-command. For more information on new-commands (@ref{Parsing}). @strong{Caution:} Before sending the string to the system, Gri first translates any synonyms present. Be careful with this, since system commands calling awk, etc, very often use backslashes for the newline character @code{\n} within strings. If you have a synonym whose name starts with @code{\n}, you can get a conflict. For example, the awk command @code{print "foo\nbar";} should print a line with @code{foo} on it, followed by a line with @code{bar} on it, but it will instead print a single line with @code{fooMISTAKE}, if you had previously defined a synonym as @code{\nbar = "MISTAKE"}. One way to avoid this mistake is to make sure any @code{\n} characters appear at the end of strings, and then simply avoid having a synonym named @code{\n}. Here is a Perl example. @example \m = "Foo bar" system perl <<"EOF" $a = 100; print "foo bar is \m, and a is $a\n"; print "BETTER: foo bar is \m, and a is $a\n"; print "Q: was a 100?\n"; EOF @end example @end itemize @strong{Some more examples}: @itemize @bullet @item To get the first 15 lines of a file called @file{foo.dat} inserted into another file called @file{bar.dat}, you might do the following. Only the first method works; the second will fail because @code{.n.} will not be translated before passing to the operating system. @example \num = "-15" system head \num foo.dat > bar.dat # Following will not work correctly because .num. # will not be translated .num. = -15 system head .num. foo.dat > bar.dat @end example @item Issue a unix command to get a listing of files in the current working directory, and pipe them into the @code{more} system command. @example system ls -l *c | more @end example @item Store the date and time into a synonym, and use it in a title: @example \time = system date ... draw title "Plotted at time \time" @end example @item Use @code{awk} to prepare a two-column table of x, ranging from 0 to 1 in steps of 0.1, and sin(x). The table is stored in a file whose suffix is the process ID of the Gri job. This file is then opened, and the data plotted. Finally, a system command is issued to remove the temporary file. @example system awk 'BEGIN @{ \ for (x=0; x<1; x+=0.1) @{ \ printf("%f %f\n", x, sin(x)) \ @} \ @}' > tmp.\.pid. open tmp.\.pid. read columns x y close system rm tmp.\.pid. draw curve @end example @strong{Note}: in unix, this command calls the Bourne shell, not the C-shell that is often used interactively. For many simple uses, the only difference from normal interactive use will be that @code{~} is not expanded to the home directory. For example, you should write @example system awk -f $HOME/foo/bar/cmd.gawk @end example @noindent instead of the @example system awk -f ~/foo/bar/cmd.gawk @end example @noindent that you might expect from interactive C-shell use. @noindent RETURN VALUE: @cindex @code{\.return_value.}, from @code{system ...} Sets @code{\.return_value} to system status @code{N status} @end itemize @c HTML @node Unlink, While, System, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{unlink} @cindex removing files with unlink @cindex unlink, to remove files @findex unlink @cindex @code{unlink} command @example `unlink \filename' @end example @noindent Delete a filename and possibly the file to which it refers. On non-unix machines, this simply means to delete the file. On unix machines, the action is more subtle. The unix OS permits several processes to use a given file at once. Therefore, @code{unlink} doesn't immediately remove the file, but instead waits until other processes are done with it. Most users will never realize the difference, however, and it is safe to think of @code{unlink} as simply removing the file. To learn more, type @code{man unlink} in a unix shell. A common use of @code{unlink} is to remove files that were created with the @code{tmpname} facility (@ref{Using OS Inside Gri}), e.g. @example \tmp = tmpname # do some system commands to put data into this file open \tmp read columns x y draw curve unlink \tmp @end example @c HTML @node While, Write, Unlink, List Of Gri Commands @comment node-name, next, previous, up @subsection @code{while} @cindex loops @findex while @cindex @code{while} command @example `while .test.|@{rpn ...@}' @end example @noindent Perform statements in loop while the value of @code{.test.} or the RPN expression is nonzero. The end of the loop designated by a line containing the words @code{end while}. The value @code{.test.} may be an rpn expression. To leave the loop prematurely, use a @code{break} statement. Upon encountering a @code{break} statement, Gri jumps to the line immediately following the loop. If the @code{-chatty} option is nonzero, a notification is printed every 1000 passes through the loop, as a debugging measure to catch unintended infinite loops. @noindent @strong{Examples}: @itemize @bullet @item Loop forever, printing a message over and over. @example while 1 show "This loops forever. Need to 'break'" end while @end example @item Read number pairs from a file, plotting bullets at the indicated locations. Note the use of an infinite loop, with a break condition following an end-of-file test. (Do not be tempted to write such loops as @code{while !..eof..} because that would not catch the end of file until the next time through the loop. The result would be to draw the last bullet twice, since the @code{read} will not update the variables when the end of file is encountered.) @example while 1 read .x. .y. if ..eof.. break end if draw symbol bullet at .x. .y. end while @end example @item Loop 10 times, printing the values of @code{.i.} as they range 0, 1, @dots{}, 9. After exiting from the loop, @code{.i.} will equal 10. Be @strong{careful} to use the correct rpn greater-than test to avoid an infinite loop. @example .i. = 0 while @{rpn .i. 10 >@} show .i. .i. += 1 end while @end example @end itemize @c HTML @node Write, Write Columns, While, List Of Gri Commands @comment node-name, next, previous, up @subsection The @code{write} commands @findex write @cindex @code{write} command The @code{write} commands write various things. @cindex file, saving results into @cindex save results in a file If the filename is @file{stdout}, the information is written to the standard output device (ie, the screen); if it is @file{stderr}, the information is written to the standard error device (ie, the screen). @strong{IMPORTANT NOTE}: The @code{write} commands @strong{append} to the output file, as opposed to overwriting the contents of the file. Therefore if you've run the Gri script before, and want fresh output, make sure to do something like the following @example system rm -f the_grid.dat write grid to grid.dat @end example @menu * Write Columns:: Write columns to a file * Write Contour:: Write contour (x,y) data to a file * Write Grid:: Write grid data to a file * Write Image:: Write various properties of image to a file @end menu @node Write Columns, Write Contour, Write, Write @comment node-name, next, previous, up @subsubsection @code{write columns} @cindex writing to a file, column data @cindex column data, writing to a file @cindex data in columns, writing to a file @example `write columns to \filename' @end example @noindent Append data columns to the end of the indicated file. @node Write Contour, Write Grid, Write Columns, Write @comment node-name, next, previous, up @subsubsection @code{write contour} @cindex writing to a file, contour data @cindex contour data, writing to a file @cindex data in contours, writing to a file @example `write contour .value. to \filename' @end example @noindent Append to the named file the (x,y) pairs defining the contour of the indicated value. The first line of output is a header line, containing two numbers: the contour value and the missing value. Then the (x,y) pairs are written a line at a time, with missing values being used to indicate ends of segments. A blank line is written after the last data pair. For example, if the contour contained two closed regions, Gri would output a pair of missing values as one of the xy pairs, to denote the separation of the two curves. You could read and plot the output as in this example @example write contour 10 to contour.out open contour.out read .contour_value. .missing. set missing value .missing. read columns x y draw curve @end example @node Write Grid, Write Image, Write Contour, Write @comment node-name, next, previous, up @subsubsection @code{write grid} @cindex writing to a file, grid data @cindex grid data, writing to a file @cindex data in grid, writing to a file @cindex grid data, write to file @example `write grid to \filename [bycolumns]' @end example @noindent Append grid to the end of the named file. Storage is in @code{%f} format, and is in normal image order. If the keyword @code{bycolumns} is present, then the grid is transposed first, in such a way that @code{read grid data bycolumns} performed on that file will read back the original grid data. @node Write Image, Programming, Write Grid, Write @comment node-name, next, previous, up @subsubsection @code{write image} @cindex writing to a file, image data @cindex image data, writing to a file @cindex data in image, writing to a file @example `write image ... to \filename' @end example @noindent The variants of this command write various things about the image to the named file, as illustrated in the following table. @itemize @bullet @item @code{write image to image.dat} @cindex image data, write to file Append image to the end of the named file. Storage is by unsigned-char, and is in normal image order. There is no header. @item @code{write image rasterfile to image.dat} Append image to the end of the named file, in Sun Rasterfile format. @item @code{write image pgm to mask.dat} Append image mask to the end of the named file, in PGM 'rawbits' format. @item @code{write image mask to mask.dat} @cindex image mask data, write to file Append image mask to the end of the named file. Storage is by unsigned-char, and is in normal image order. @item @code{write image mask rasterfile to mask.dat} Append image mask to the end of the named file, in Sun Rasterfile format. @item @code{write image mask pgm to mask.dat} Append image mask to the end of the named file, in PGM 'rawbits' format. @item @code{write image colorscale to colorscale.dat} @cindex image palette data, write to file Append image colorscale transform to the end of the named file. Storage is a series of 256 lines, each containing 3 numbers (for Red, Green and Blue) in the range 0 to 1. The file is suitable for reading with the @code{read image colorscale} command. @item @code{write image grayscale to grayscale.dat} Append image grayscale transform to the end of the named file. Storage is a series of 256 lines, each containing a number in the range 0 to 1. The file is suitable for reading with the @code{read image grayscale} command. @end itemize @c HTML @node Programming, Defaults, Write Image, Top @comment node-name, next, previous, up @chapter Programming in the Gri Language @cindex programming in Gri The Gri programming language has @code{if} statements to control program flow, and a @code{while} statement to repeat commands. There are two data types in Gri: ``variables'' (to store numbers) and ``synonyms'' (to store character strings). Gri recognizes commands by matching statements against its list of known commands. This list is extensible; it is easy to add new commands as extensions to Gri. @menu * Defaults:: How Gri normally acts * Online Help:: Getting help from gri itself * Long Command Lines:: Continued lines * Variables:: Variables (for storing numbers) * Synonyms:: Synonyms (for storing character strings) * If Statements:: If statements * Loops:: Repeating command lines * Mathematics:: Doing mathematics on columns, grids etc * rpn Mathematics:: Doing mathematics on variables * Text:: Doing things with characters strings * Adding New Commands:: How to customize Gri by adding new commands * Missing Values:: How to specify missing data * Hints:: Hints for good Gri programming * Debugging:: Debugging Gri programs * Error Messages:: What to do about Gri error messages * Missing Values:: Missing value code * Operating System:: Using Gri in OS and OS in Gri * Resource File:: Personalizing Gri @end menu @c HTML @node Defaults, Online Help, Programming, Programming @comment node-name, next, previous, up @section Defaults @cindex default values At startup time, Gri sets the values of some things, like font size. Since Gri is still under development, some of these defaults might change, so you should not rely on them remaining the same. Presently, the defaults are equivalent to: @example set arrow size 0.2 # (cm) set axes style 0 set beep off set clip off set clip postscript off set contour format %lg set contour label position ? ? set contour labels horizontal set contour labels whiteunder set dash off set font size 12 # (pt) set font to helvetica set graylevel 0 # Black ink set ignore initial newline off set input data window x off set input data window y off # Following set (curve, axes, symbol) widths to width # of rapidograph pens called (6x0, 3x0, 6x0) set line width 0.709 # (pt) for curves set line width axis 0.369 # (pt) for axes set line width symbol 0.369 # (pt) for symbols set missing value 1.0e22 set page portrait set page factor 1 set symbol size 0.1 # (cm) set tic size 0.2 # (cm) set tics out set trace off set x format %lg set x margin 6.0 # (cm) set x name "x" set x size 10 # (cm) set x type linear set y axis name vertical set y format %lg set y margin 6.0 # (cm) set y name "y" set y size 10 # (cm) set y type linear @end example @noindent (NOTE: Programmers may alter the gri source file @file{defaults.h} and then recompile Gri, if they feel the need to change these things. Also, see the file @file{startup.c} and the function @code{gr_begin()} in @file{gr.c}.) @c HTML @node Online Help, Long Command Lines, Defaults, Programming @comment node-name, next, previous, up @section Online Help @cindex help, online @cindex online help Type @code{help} to get a list of available commands and other topics of interest. Here's how Gri responds @example Type `help' followed by a command-name: assert cd close convert create debug delete differentiate draw expecting filter flip get help if ignore input insert interpolate list ls mask move new open pwd query quit read regress reorder rescale resize return rewind set show skip sleep smooth source sprintf state superuser system write Or type `help -' followed by a topic from this list: example extending files math strings synonyms variables manual @end example Some commands have more words than shown. You can type these additional words to narrow the help down; otherwise Gri will give you help on all commands that begin with the indicated words. For example, try @code{help set} and @code{help set x}. When you ask for help on a multi-word command, Gri tells you about all commands which begin with the words you've typed. Thus, @example help help draw help draw zero help draw zero line @end example @noindent narrow in on the command @code{draw zero line}. The response to the most complete request is @example `draw zero line [horizontally|vertically]' draw zero line Draw line y=0 if it is within axes draw zero line horizontally Draw line y=0 if it is within axes draw zero line vertically Draw line x=0 if it is within axes @end example The part enclosed in angled quotes is the syntactical description of the command. (NOTE: The square brackets indicate an optional word (in this case) or words. The vertical bar indicates that either the item on the left or the item on the right may appear; it is a logical OR operator. The only other special characters in syntax descriptions are the braces @code{@{@}}, which are used to enclose multiple words which act as one unit; they are used to clarify the choices presented to the OR operator.) Following the syntactical description are examples. Each example is indented 2 spaces, and a description of it (which always starts with an upper-case character and ends with a period, to indicate that it is an English description) follows that, indented by an additional 2 spaces. @c HTML @node Long Command Lines, Variables, Online Help, Programming @comment node-name, next, previous, up @section Long Command Lines @cindex continued lines @cindex commands extending over several lines To extend a command across several lines, use a backslash @code{\} at the @strong{very} end of all lines but the last: @example draw line from \ 10 20 \ to \ 10 30 @end example @c HTML @node Variables, About Variables, Long Command Lines, Programming @comment node-name, next, previous, up @section Variables @cindex numbers, stored in variables @cindex variables @cindex programming, variables @menu * About Variables:: What variables are used for, and how * User Variables:: Defining your own variables * Built-in Variables:: Variables pre-defined by Gri @end menu @node About Variables, User Variables, Variables, Variables @comment node-name, next, previous, up @subsection About variables Variables store numbers. As it reads your program, Gri substitutes variable values any place a variable appears where a number normally would. For example, in the code below @code{.number.} is a variable storing the value 10, so the two @code{read} statements have the same effect: @example .number. = 10 read columns .number. x y read columns 10 x y @end example Variable names begin and end with a single period (example: @code{.num.}). (Gri uses this odd notation to distinguish variable names from ``normal'' words, which is necessary because Gri does not have a limited list of keywords as other languages do. Thus, the C programming language is happy to let you use a variable name like @code{latitude}, since it is not a keyword, but Gri is not, since it might like to use that word itself in a new command.) You should not use names beginning and ending with double periods, because Gri uses names like that to store built-in variables for its own use (e.g., @code{..xsize..} saves the width of the plot). To store a number into a variable, use a command like @example .time. = 10 @end example @noindent or @example .time. = @{rpn 10 sin@} @end example Storage is automatically set aside when you assign into a nonexistent variable; no ``declaration'' statements are required as in the C language. The Gri command, @code{new} (@ref{New}), allows you to have several ``versions'' of a variable. This is useful for local storage in new commands, inside @code{if} statements, etc, since it lets you use temporary variables without worrying about overwriting values outside the local block of code. The syntax is @code{new .variable. = value} (where, as usual, @code{value} may be an rpn expression (@ref{rpn Mathematics}). Here is an example: @example `foo bar' @{ new .a. # Get storage .a. = 10 # Store a local value show "Locally, .a.=" .a. " (expect 10)" delete .a. # Delete this local one @} .a. = 1 show "Global version has .a.=" .a. " (expect 1)" foo bar @end example To see if a given named variable (or synonym) exists, use the RPN operator @code{defined} (@ref{rpn Mathematics}). @node User Variables, Built-in Variables, About Variables, Variables @comment node-name, next, previous, up @subsection User variables @cindex variables, defined by user @cindex user-defined variables You can get Gri to read values for variables from your file. Here's how to read a number from a header line and then read that many lines of columnar data: @example open file.dat read .num. read columns .num. x y @end example You can define variables within the Gri program: @example .num. = 10 read columns .num. x y @end example @cindex interaction with user, @code{query} command You can get variables interactively from the user, using the @code{query} command. (If the user types carriage-return, or if the command-line flag @code{-y} was specified when invoking Gri, the value 100 will be assigned to @code{.num.}). For example, @example query .num. "Number of rows to read?" (100) read columns .num. x y @end example Gri allows you to use a previous value of the variable in the default string, as in this example: @example .start. = 8 # default .stop. = 2 # default query .start. "Start time? " (.start.) query .stop. "Stop time? " (.stop.) @end example Variables can be manipulated using reverse polish notation (RPN) mathematical operations (@ref{rpn Mathematics}). Variables are often useful in @code{if} statements. Here are some examples: @example read .num_pts. if .num_pts. show "There are some data" read columns .num_pts. x y else show "There are no data" end if # ... read .latitude. if @{rpn .latitude. 10 <@} read .num. read .num. x y draw curve else show "Skipping data North of 10deg N" read .num. skip .num. end if @end example @node Built-in Variables, Synonyms, User Variables, Variables @comment node-name, next, previous, up @subsection Built-in variables @cindex variables, built-in @cindex built-in variables Built-in variables (@ref{Index of Builtins}) have names which begin and end with @strong{two} periods. For example, @code{..xsize..} is the width of the x-axis in centimetres. You may use these variables as you wish (example: @code{..xsize.. = 4} is an alternative to @code{set x size 4}), but you must be aware that these are not ``free'' variables for you to use for arbitrary purposes. You can find out what the built-in variables are by the command @code{show variables}. There are two types of variables @itemize @bullet @item @strong{Startup} variables, which are created by Gri at startup time. These variables can be relied upon to exist (barring changes in Gri itself), unless you @code{delete} them. @item @strong{Spontaneous} variables (which are created by certain Gri commands, and only exist if these commands have been executed). For example, the @code{regress} command defines @code{..coeff0..} (the intercept of the fitted line), @code{..coeff1..} (the slope of the fitted line), @code{..R2..} (the correlation coefficient). @end itemize To see the values of the built-in variables (along with the user variables), use @code{show variables}. Here are some useful builtin variables: @itemize @bullet @item @code{..arrowsize..} @cindex arrows, size of heads stored in @code{..arrowsize..} @vindex @code{..arrowsize..}, size of arrows Stores either a positive number representing the halfwidth of arrowheads measured in centimetres, or a negative number giving the negative of the ratio of arrowhead halfwidth to arrow length (@ref{Set Arrow Size}). @item @code{..batch..} @cindex batch processing @vindex @code{..batch..}, flag used for batch mode Flag used for batch mode. @item @code{..debug..} @vindex @code{..debug..}, flag used for debugging @cindex debug command-line option @cindex debugging, using @code{..debug..} Equal to 1 if the @code{-debug} command-line flag was set. Flag used for debugging (@ref{Invoking Gri}). The @code{..debug..} built-in variable is useful in isolating code to use only in test runs. For example, you might use @example if ..debug.. show "Following are the column data" show columns end if @end example When you run the program with command-line @code{gri -debug file.gri} the code in the @code{if} block will print out the columnar data, but when you run it with @code{gri file.gri} these lines are not printed. @item @code{..eof..} @vindex @code{..eof..}, flag indicating end-of-file Flag indicating whether an end-of-file was encountered on the last @code{read columns}. @item @code{..words_in_dataline..} @vindex @code{..words_in_dataline..} @cindex reading data, checks @cindex data files, words in lines Number of words on last dataline. This is useful in constructs like @example open tmp.dat .num. = 0 while 1 read .a. .b. if !..words_in_dataline.. show "Got empty line or EOF, so break loop" break end if show "a=" .a. "b=" .b. show "; words in line=" ..words_in_dataline.. .num. += 1 end while show "Got " .num. "data lines." @end example @item @code{..fontsize..} @cindex font, size @vindex @code{..fontsize..}, size of letters Size of letters, measured in points; there are 72.27 points in an inch and 28.45 points in a centimetre. The mathematical operators @code{pttocm} and @code{cmtopt}, which do conversion between points and centimetres, are often useful in labelling data curves (@ref{rpn Mathematics}). @item @code{..graylevel..} @cindex gray level @vindex @code{..graylevel..}, graylevel (0=black) Graylevel to use in drawing lines, text, etc. Black ink is 0; white paper is 1. @strong{See also} @code{..red..} etc. @item @code{..image_height..} @vindex @code{..image_height..}, height of image Height of image, or 0 if no image defined yet. @item @code{..image_width..} @vindex @code{..image_width..}, width of image Width of image, or 0 if no image defined yet. @item @code{..length_dash..} @vindex @code{..length_dash..}, length/cm of dashes Length in cm of dashes in dashed lines. @item @code{..length_blank..} @vindex @code{..length_blank..}, length/cm of blanks Length in cm of blanks in dashed lines. @item @code{..linewidth..} @vindex @code{..linewidth..}, width of lines Width of lines for data curves (@ref{Set Line Width}). @item @code{..linewidthaxis..} @vindex @code{..linewidthaxis..}, width of lines on axis Width of lines on axes (@ref{Set Line Width}). @item @code{..linewidthsymbol..} @vindex @code{..linewidthsymbol..}, width of lines in symbols Width of lines in symbols (@ref{Set Line Width}). @item @code{..missingvalue..} @vindex @code{..missingvalue..}, missing value code Missing value code, also stored in the synonym @code{\.missingvalue.}; (@ref{Set Missing Value}). @item @code{..num_col_data..} @vindex @code{..num_col_data..}, number column data Number of column data that exist. You might want to use this after @code{read columns} to see if a data file actually had any data in it, or use it in accessing individual elements of columns (@ref{rpn Mathematics}). @item @code{..publication..} @cindex publication quality plots, built-in variable @code{..publication..} @vindex @code{..publication..}, flag for final copy of plot Flag for final copy of plot. The command-line option @code{-p} sets the value of @code{..publication..} to 1. A typical, and highly recommended, code fragment is @example if !..publication.. draw time stamp end if @end example @item @code{..red..}, @code{..green..}, @code{..blue..} @vindex @code{..blue..} Description of present color. The values are between 0 and 1, with (0,0,0) being black and (1,1,1) being white. If color is gray, all these will be equal. You may assign to these, but it will @strong{not} change the color. @item @code{..symbolsize..} @cindex symbol size, stored in @code{..symbolsize..} @vindex @code{..symbolsize..}, size of symbols Size of symbols in centimetres. @item @code{..superuser..} @vindex @code{..superuser..}, was -superuser flag set? Equal to 0 if the flag was not set, or equal to the flag if it was. @item @code{..tic_direction..} @vindex @code{..tic_direction..}, direction of axis tics Direction of axis tics, 1 for inside or 0 for outside. @item @code{..tic_size..} @vindex @code{..tic_size..}, size/cm of axis tics Size of axis tics in centimetres. @item @code{..trace..} @vindex @code{..trace..}, for tracing program execution Equal to 1 if the @code{-trace} command-line flag was set. Used for tracing program execution. @item @code{..xinc..} @vindex @code{..xinc..}, x increment on axes x increment on axes. @item @code{..xleft..} @vindex @code{..xleft..}, x value at left of plot x value at left of plot. @item @code{..xmargin..} @cindex margins @vindex @code{..xmargin..}, left margin Left margin, in centimetres. @item @code{..xright..} @vindex @code{..xright..}, x value at right of plot x value at right of plot. @item @code{..xsize..} @cindex length of axes @cindex axes, length of @vindex @code{..xsize..}, x-axis length x-axis length in centimetres. @item @code{..ybottom..} @vindex @code{..ybottom..}, y value at bottom of plot y value at bottom of plot. @item @code{..yinc..} @vindex @code{..yinc..}, y increment on axes y increment on axes. @item @code{..ymargin..} @vindex @code{..ymargin..}, bottom margin Bottom margin in centimetres. @item @code{..ysize..} @vindex @code{..ysize..}, y-axis length y-axis length in centimetres. @item @code{..ytop..} @vindex @code{..ytop..}, y value at top of plot y value at top of plot @item @code{..exit_status..} @vindex @code{..exit_status..}, exit status from @code{system} call The exit status from the most recent @code{system} call (or 0 if no system calls have been done yet). @end itemize You may use any of these built-in variables anywhere. For example, here's how to stack 3 graphs vertically on the page: @example .offset. = @{rpn ..ysize.. 3 + @} open file1 read columns x y close draw axes draw curve ..ymargin.. += .offset. open file2 read columns x y draw axes draw curve close ..ymargin.. += .offset. open file3 read columns x y draw axes draw curve close @end example @cindex mathematics, rpn notation, example The first line needs a bit of explanation. It is a reverse-polish expression. The format is @code{@{} followed by @code{rpn} followed by an expression followed by @code{@}}. Within the expression, spaces must separate operands. This makes @code{.offset.} equal to the height of y-axis plus 3 cm, so plots are separated by 3 cm. To learn more about @code{@{rpn ... @}} (@ref{rpn Mathematics}). Another possibly unfamiliar thing is the code @code{+=}. It means take the thing on the left hand side, and add to it the thing on the right hand side. (In this case, it is used to increase the y margin by the value of @code{.offset.}.) @c HTML @node Synonyms, Naming Convention, Built-in Variables, Programming @comment node-name, next, previous, up @section Synonyms @cindex character variables (synonyms) @cindex synonyms, for storing character strings @cindex programming, synonyms @cindex synonyms, naming convention Synonyms are used by Gri to store character strings. Gri denotes synonyms with words beginning with backslash (e.g., @code{\syn}), following the @TeX{} convention. @menu * Naming Convention:: Their names with a backslash, e.g. @code{\syn} * Using Synonyms:: Some usage examples * Important Builtin Synonyms:: e.g. @code{\.command_file.} * Alias Synonyms:: e.g. @code{\@@alias} * Local Synonyms:: Working with the arguments of newcommands @end menu @node Naming Convention, Using Synonyms, Synonyms, Synonyms @comment node-name, next, previous, up @subsection Naming convention for synonyms @cindex naming convention for synonyms @cindex synonyms, naming convention Synonym names begin with a backslash (e.g., @code{\filename}). After the backslash, Gri expects a letter (upper or lower case) or one or more periods. Following this is an arbitrary string of letters, numbers, or underscores. If there are periods at the start, then the same number of periods must be used at the end. The following are some examples @example \simple = "Howdie" \.longer_example. = "Dots and underscores are ok too" \a2 = "OK for number at end ..." \a3bb = "... and inside" @end example Gri defines several synonyms for its own use, so that if you modify these, you may get strange results. Each of these starts and ends with a single period. There is an exception to the above rule, one which mostly comes up when using netCDF files which may have variable names that may contain punctuation. Gri permits synonym names to have punctuation characters (but not blanks or tabs) in synonym names, provided that the second character in the name is an opening brace and that the last character is a closing brace, e.g. @example \@{foo.bar@} = "Foo bar" @end example @noindent This is used particularly for files in the netCDF format, for reading variable attributes, which by netCDF convention use a colon (@code{:}) to separate variable name and attribute name (@ref{Read Synonym or Variable}). For more information on netCDF format, see @code{http://www.unidata.ucar.edu/packages/netcdf/index.html} @c HTML @c HTML here . Synonyms may be freely embedded in strings (a common example is @code{draw title "Data from file `\datafile'"}. They may also appear anywhere in commands (e.g., @code{open \filename}). The exception to this rule is that Gri ignores your synonyms within math mode, in order to prevent clashes (e.g. you might define @code{\alpha} as a synonym storing the value @code{"foo bar"}, but Gri will ignore this within math-mode, so that @code{$\alpha$} will still mean the Greek letter alpha). To get a backslash in a string without Gri thinking it is part of a synonym, use two backslashes (e.g., @code{show "The backslash character \\ is used for synonyms."}). This may sometimes be required in @code{system} commands (@ref{System}), to prevent Gri from converting substrings like @code{\n} (which many system commands use to represent the newline character). For example, the command @code{system perl -e 'print "foo\nbar";'} will be mangled if Gri has already been told that @code{\nbar} is a synonym. (There will be no problem if @code{\nbar} is not an existing synonym, since Gri will then just leave it in place.) To be sure that no mangling can occur, replace each backslash with two backslashes. This tells Gri not to try to substitute a synonym at that location. In the example below, the first system call prints @code{fooled you!} on one line line, because Gri substituted for what it thought was a synonym called @code{\nbar}; the second (correctly) prints @code{foo} on one line and @code{bar} on the next. @cindex @code{system} command, how to get a tab @cindex @code{system} command, how to get a newline @cindex tab, in a @code{system} command @cindex newline, in a @code{system} command @example \nbar = "led you!" system perl -e 'print "foo\nbar\n";' system perl -e 'print "foo\\nbar\\n";' @end example Similarly, if your system command is expecting to see @code{\t} (for a tab character), then you must write @code{\\t} to prevent Gri from trying to substitute a synonym named @code{\t}. The @code{show} command has a special syntax for permitting newlines and tabs in strings (@ref{Show}). @node Using Synonyms, Generalizing Code, Naming Convention, Synonyms @comment node-name, next, previous, up @subsection Some uses for synonyms @cindex character variables (synonyms) @cindex synonyms, extracting individual words from @cindex synonyms, assigning values to @cindex synonyms, constructing using the operating system @cindex user-defined synonyms @cindex synonyms, for storing output from system commands @cindex operating system commands, assigned to synonyms @cindex system commands, assigned to synonyms @cindex operating system, example of using to construct filenames @cindex system commands, example of using to construct filenames @cindex filenames, constructing using the operating system Synonyms store strings and are useful for anything strings are useful for, e.g. filenames, plot labels, names of variables, etc. @menu * Generalizing Code:: * Storing OS Output:: * Storing User Responses:: * Storing File Contents:: * Extracting Words From Strings:: @end menu @node Generalizing Code, Storing OS Output, Using Synonyms, Using Synonyms @comment node-name, next, previous, up @subsubsection Using synonyms to generalize code Synonyms are often used to store filenames, since then only a single line of a file may need to be altered, in order to work with another file, e.g. @example \filename = "columns.dat" open \filename # a lot more code using the file name @end example @node Storing OS Output, Storing User Responses, Generalizing Code, Using Synonyms @comment node-name, next, previous, up @subsubsection Using synonyms to store OS output Synonyms provided a convenient way to store information from the OS. @example # Show the date. \date = system date show "Time is \date" # Show the command file name, then use the system # to construct a filename with the same beginning # but ".dat" as the ending instead of ".gri". show "The commandfile name is \.command_file." \fn = system echo `basename \.command_file. .gri`.dat show "A filename constructed from this is \fn" @end example This example uses the Unix system commands @code{echo} and @code{basename} to construct a filename ending in @file{.dat}, from the command file name (stored in the builtin string @code{\.command_file.}), assuming that the command file name ends in @file{.gri}. NOTE: As usual, if the system command contains the Gri comment designator (the string @code{#}), protect it with double-quotes (@ref{System}). @node Storing User Responses, Storing File Contents, Storing OS Output, Using Synonyms @comment node-name, next, previous, up @subsubsection Storing user responses via @code{query} You can ask the user for the contents of strings: @cindex interaction with user, @code{query} command @example query \filename "What's the data file?" ("file.dat") @end example @noindent The prompt @code{What's the name of the data file?} is typed to the terminal, and whatever string the user types is inserted into the synonym @code{\filename}. If the user types nothing, but simply presses carriage return, the (optional) default string (which must be enclosed in parentheses as shown) is put into @code{\filename}. Note that the default is ignored if it is not written properly: it must be enclosed in double quotes enclosed in parentheses, with no intervening spaces. @node Storing File Contents, Extracting Words From Strings, Storing User Responses, Using Synonyms @comment node-name, next, previous, up @subsubsection Storing File Contents You can read the contents of synonyms from a file: @example open \directory_file read \file_name close open \file_name read columns x y @end example @noindent The first (space-separated) word is read into the the first synonym after the @code{read} command, the second word into the second synonym, and so on. If the word you want is not near the front of the line, you can use the command @code{read line} to get the whole line, then use the method described above to extract the word you want. Indexing begins with 0, remember. @node Extracting Words From Strings, Important Builtin Synonyms, Storing File Contents, Using Synonyms @comment node-name, next, previous, up @subsubsection Working with words within strings Sometimes a synonym will contain several words that you need to work with indidually (e.g. it might contain a list of files that should be processed). There are two ways to do this. @table @emph @item The @code{word of} syntax. @example \sentence = "This sentence has five words" \first_word = word 0 of "\sentence" \last_word = word 4 of "This sentence has five words" @end example @item The @code{[]} syntax @cindex @code{[]} syntax for selecting words in synonyms Individual words of synonyms may be accessed by prefixing the synonym name with the index number of the word (starting at 0) enclosed in square brackets. The number in the square brackets may be a constant, a variable, or a synonym, but not a more complicated expression. If the index value is a floating-point number, it is first rounded to the nearest integer. If the index value is negative or exceeds the number of words minus 1, then an empty string is retrieved. If @strong{no number} appears in the square brackets, the result is the number of words in a synonym. @example \syn = "This has 4 words in it" show "\[0]syn ... gives 'This'" show "\[1]syn ... gives 'has'" .i. = 3 show \[.i.]syn ... gives 'words'" \i = "3" show \[\i]syn ... gives 'words'" show "\[]syn ... gives '6', i.e. number of words" @end example @end table @node Important Builtin Synonyms, Alias Synonyms, Extracting Words From Strings, Synonyms @comment node-name, next, previous, up @subsection Some important builtin synonyms @cindex synonyms, global @cindex global synonyms @cindex built-in synonyms, global @cindex global built-in synonyms @cindex synonyms, built-in, list of @cindex return value, @code{\.return_value.} @vindex @code{\.return_value.}, Return value @vindex @code{\.ps_file.}, PostScript file name @vindex @code{\.readfrom_file.}, data file name @vindex @code{\.command_file.}, command-file name @vindex @code{\.missingvalue.}, command-file name @vindex @code{\.home.}, home directory @vindex @code{\.system.}, operating system name @vindex @code{\.user.}, user's login name @vindex @code{\.time.}, time and date @cindex directory, stored in synonym @code{\.wd.} @cindex working directory, stored in synonym @code{\.wd.} @cindex @code{\.wd.} synonym, storing working directory @vindex @code{\.wd.}, working directory @vindex @code{\.version.}, version of Gri @vindex @code{\.pid.}, process ID of job Within mathematics mode (portions of strings enclosed within dollar-signs), Gri stores the definitions of many Greek letters and mathematical symbols as math-mode synonyms (@ref{Mathematical Text}). Global synonyms are shared among commands. To see the built-in global synonyms (@ref{Index of Builtins}) use @code{show synonyms}, which produces output that looks something like the following. @example Synonyms... \.missingvalue. = "10000000000000000000000.000000" \.return_value. = "" \.version. = "2.7.0" \.pid. = "3043" \.wd. = "/home/kelley" \.time. = "Sun May 20 13:18:32 2001" \.user. = "kelley" \.host. = "Intrusion.phys.ocean.dal.ca" \.system. = "unix" \.home. = "/home/kelley" \.lib_dir. = "/usr/share/gri" \.command_file. = "stdin" \.readfrom_file. = "stdin" \.ps_file. = "gri-00.ps" \.path_data. = "." \.path_commands. = "." @end example @cindex time @cindex date @cindex @code{\.return_value.}, general These things will be obvious to unix users; for example @code{\.pid.} is the process ID of the job (often used in names for temporary files), and @code{\.wd.} is the working directory (often used in @code{draw title} commands to indicate in which directory the gri job was run. Some commands set @code{\.return_value.} to non-blank; the meaning of the return value varies from command to command. @node Alias Synonyms, Local Synonyms, Important Builtin Synonyms, Synonyms @comment node-name, next, previous, up @subsection Alias synonyms: the @code{\@@alias} syntax @cindex alias synonyms, with the @code{\@@alias} notation @cindex @code{\@@alias} notation @cindex synonyms, aliasing with the @code{\@@alias} notation Sometimes you need to work with a variable or a synonym whose name can only be determined at run-time, perhaps through interaction with the user, examination of a datafile, or examination of the command provided to the OS when invoking Gri. Gri handles this by so-called "alias" synonyms, which store the names of other items. The syntax is simple. Suppose that a synonym, called @code{\pointer} say, contains the @strong{name of} another synonym, or a variable. Then you may use @code{\@@pointer} anyplace you would normally use the item named. @table @emph @item Illustrations of using the value of a named item The following prints an approximation to Pi followed by the name of movie star. @example .pi. = 3.14 \pi_pointer = ".pi." show \@@pi_pointer # just like 'show .pi.' \hero = "Gregory Peck" \our_hero = "\\hero" show "\@@our_hero" # just like 'show "\hero"' @end example @item Illustrations of assigning to a named item The following prints an approximation to 2*Pi and yet another star; the point is that the alias appears to the left of an assignment operator. @example # Print approximation to 2*Pi .pi. = 3.14 \pi_pointer = ".pi." \@@pi_pointer *= 2 show .pi. # Stars don't shine alone \hero = "Gregory Peck" \our_hero = "\\hero" \@@our_hero = "Harrison Ford" show "\hero" @end example @end table @node Local Synonyms, If Statements, Alias Synonyms, Synonyms @comment node-name, next, previous, up @subsection Local synonyms @cindex synonyms, local @cindex local synonyms @vindex @code{\.proper_usage.} @vindex @code{\.words.} @vindex @code{\.word0.} @vindex @code{\.word1.} @cindex built-in synonyms, local @cindex local built-in synonyms @cindex command lines, parsing in new Gri commands @cindex programming, parsing command lines @cindex programming, using local built-in synonyms Local synonyms are created by Gri upon entry to a Gri command. You use them to parse the command line that was used in calling the new command, to look for options, gather filenames, etc. Local synonyms are known only from within the local Gri command. They are not listed by @code{show synonyms}, but they can be used freely in commands like @code{show "Number of words is \.words."}. @itemize @bullet @item Within any new Gri command, the number of words in the line that called the command is available in @code{\.words.}. The RPN operator @code{wordc} also yields the same value (@ref{Solitary Operators}). @item The first word in the calling line is @code{\.word0.}, the second @code{\.word1.}, etc. (Note that this is the C convention, @strong{not} the FORTRAN convention. If @code{\.words.} is 2, then @code{\.word0.} and @code{\.word1.} are defined, but @code{\.word2.}, which FORTRAN programmers expect, will not be defined.) If you don't know the place of the synonym in advance (i.e. 0 versus 1, for @code{\.word0.} versus @code{\.word1.}), then use the RPN operator @code{wordv} instead (@ref{Unary Operators}). @item Within any new Gri command, the proper calling usage is available in @code{\.proper_usage.}. This is useful in tests of syntax (@ref{Adding New Commands}). For example: @example `draw depths from \file' Draw depth data stored in indicated file. If the filename contains periods or slashes, you'll have to enclose it in double quotes, as in the second example: draw depths from file upper_cove draw depths from file ../old_data/upper_cove @{ if @{rpn \.words. 4 !=@} show "FATAL ERROR in `\.proper_usage.':" show " Need 4 words; got \.words. words." quit end if # Right number of words, so continue onward... @} @end example @end itemize These synonyms help you scan for optional words in commands. Suppose you have defined a new command @code{New Thing [option]}. If you call it with @code{New Thing}, then (within @code{New Thing}) @code{\.words.} will be @code{"2"}, @code{\.word0.} will be @code{"New"} and @code{\.word1.} will be @code{"Thing"}. On the other hand, if you call it with @code{New Thing 22.3} then @code{\.words.} will be @code{3}, @code{\.word0.} will be @code{"New"}, @code{\.word1.} will be @code{"Thing"} as before, and @code{\.word2.} will be @code{"22.3"}. @strong{EXAMPLE} Here is a new command to label lines drawn by @code{draw curve}: @example `Draw Label For Last Curve "label"' Draw a label for the last curve drawn, using ..xlast.. and ..ylast.. built-in variables. @{ new .draw_label_for_last_curve_graylevel. .draw_label_for_last_curve_graylevel. = ..graylevel.. set graylevel 0 draw label "\.word5." at \ @{rpn ..xlast.. xusertocm 0.1 + xcmtouser@} \ @{rpn ..ylast.. yusertocm \ ..fontsize.. pttocm 2 / - ycmtouser@} set graylevel .draw_label_for_last_curve_graylevel. delete .draw_label_for_last_curve_graylevel. @} open file.dat read columns x y draw curve \label = "Illustration" Draw Label For Last Curve "\label" @end example @noindent (Note that Gri has a built-in command @code{draw label for last curve "\label"} written much as above, so there is no need for you to enter this new command into your @file{.grirc} file. But you might want to check @file{gri.cmd} to see how a full command does checking of the calling syntax (@ref{Invoking Gri}). @c HTML @node If Statements, Loops, Local Synonyms, Programming @comment node-name, next, previous, up @section If Statements @cindex programming, if statements @cindex if statements Gri has @code{if} statements to make your programs more flexible. Here's an example: @cindex interaction with user, @code{query} command @example query \thick "Use thick lines? (0 or 1)" ("0") if \thick set line width 2 else set line width 0.5 end if @end example @noindent If you answer 1 to the question, the line thickness will be set at 2 points. If you answer 0 then a thin line will be used. If you press carriage return a thin line will be used. The item following the @code{if} can be @itemize @bullet @item a number (1 means true; anything else means false) @item a variable (1 means true; anything else means false). Example: @example if .plot_contours. draw contour end if @end example @item a synonym which expands to a number (1 means true; anything else means false). Example: @example \plot_contours = "1" if \plot_contours draw contour end if @end example (Don't worry about the fact that synonyms are strings; Gri expands the string value before interpreting the @code{if} statement.) @item an expression of the form @code{@{string1 == string2 @}}. The symbol @code{==} is an operator which tests for string equality. This expands to @code{1} if the strings are equal, or @code{0} otherwise. The strings may be either synonyms or string constants. If the string constant contains only one word, then it is not necessary to enclose it in quotes, but it is clearer to do so. Examples: @cindex labels, on axes @example if @{"\variable" == "Salinity"@} set x name "Salinity" else set x name "Unknown" end if @end example @item a rpn (reverse polish notation) expression (@ref{rpn Mathematics}): @example if @{rpn .time. 100 <@} # ie, (100 < time), not (time < 100) show "Time > 100" else if @{rpn .time. 100 >@} show "Time < 100" else if @{rpn "\item" "later" ==@} show "Time ... later babe" else show "Time is equal to 100" end if if @{rpn .time. 10 * 100 ==@} show "Time is equal to 10" else show "Time is not equal to 10" end if @end example @end itemize There is no need to put the else part in if you don't need it. You can do @example set line width 0.5 if \use_thick_lines set line width 2 end if @end example @noindent if you wish. If you want just the else part, you can do @example if ! \use_thick_lines set line width 0.5 end if @end example (The exclamation point denotes logical negation: @code{! true} equals @code{false}.) If statements may be nested many levels deep. You may also have @code{else if} blocks, as in: @example if @{"\variable" == "S"@} set x name "Salinity" set x axis 32 33 0.5 .1 else if @{"\variable" == "T"@} set x name "Temperature" set x axis 15 20 1 0.5 else set x name "Unknown" end if @end example @c HTML @node Loops, Mathematics, If Statements, Programming @comment node-name, next, previous, up @section Loops Gri provides only one type of loop, the @code{while} loop, described elsewhere (@ref{While}). @c HTML @node Mathematics, rpn Mathematics, Loops, Programming @comment node-name, next, previous, up @section Mathematics Gri lets you do some simple mathematical manipulations on your column and grid data. @subsection Column data @cindex column mathematics @cindex mathematics, on columns @cindex powers, of columns or variables @cindex exponentiation @cindex logarithms The column operators are @code{=}, @code{+=}, @code{-=}, @code{*=}, @code{/=}, @code{^=} (exponentiation) and @code{_=} (logarithm). There must be spaces before and after the operators, but no space between the 2 letters of the operators. The operations may be applied not only to @code{x} and @code{y} as shown, but also to @code{z} (used to hold data to be contoured or written as symbols), and @code{u} and @code{v} (used to store vector fields). The axis scales are @strong{not} changed by mathematical operations on the columns, regardless of whether the scales were set manually or by Gri command (@ref{Axis Scaling}). Elements of columns are available by the @code{@@} reverse polish operator (@ref{rpn Mathematics}). Examples: @itemize @bullet @item To multiply all the x data by 10, use @code{x *= 10}; to add 5 to each y-value, use @code{y += 5}. @item To set all the y data to 10, do @code{y = 10}. (This will only work if you've already read column data.) @end itemize See also @ref{Tertiary Operators} for a method of assigning or altering column data using the RPN operator. @subsection Grid data @cindex grid data mathematical operations @cindex mathematics, on grid data Various commands let you alter grid data as used in contouring (@ref{Contour Plots}). Possible commands are as follows. @example grid data = number grid data += number grid data -= number grid data *= number grid data /= number grid data ^= number # take data to power 'number' grid data _= number # take log base 'number' grid x = number grid x += number #... others as in `grid data' grid y = number grid y += number #... others as in `grid data' @end example @subsubsection Image data @cindex image mathematical operations @cindex mathematics, on images Various commands let you alter image data (@ref{Images}.). Possible commands are as follows. @example image += number image -= number image *= number image /= number image ^= number # power image _= number # logarithm @end example @subsubsection Image grayscale/colorscale @cindex colorscale modification @cindex grayscale modification @cindex image grayscale/colorscale modification @cindex mathematics, on image grayscale/colorscale Various commands let you alter image data (@ref{Images}). Possible commands are as follows. @example image grayscale += number image grayscale -= number image grayscale *= number image grayscale /= number image grayscale ^= number # power image grayscale _= number # logarithm image colorscale += number image colorscale -= number image colorscale *= number image colorscale /= number image colorscale ^= number # power image colorscale _= number # logarithm @end example @subsubsection Variables @cindex scalar operations @cindex mathematics, on variables Possible commands are: @example .variable. = number .variable. += number .variable. -= number .variable. *= number .variable. /= number .variable. ^= number # power .variable. _= number # logarithm @end example @c HTML @page @node rpn Mathematics, Stack Operators, Mathematics, Programming @comment node-name, next, previous, up @section Rpn (reverse-polish notation) Calculator @cindex examples of @code{rpn} mathematics @cindex @code{rpn} mathematics, examples @cindex mathematics, @code{rpn} notation, description Gri can do simple mathematics on numbers. The syntax is reverse-polish notation (@code{rpn}), which is used in some calculators. Most users can learn rpn in a few minutes, so don't worry if you don't know RPN yet. @strong{Syntax}: rpn expressions can be used anywhere Gri expects a number. RPN expressions start with a opening curly brace (@code{@{}) which is immediately followed by the word @code{rpn}. rpn expressions end with a closing curly brace (@code{@}}). Instead of @code{set x size 10} you could write @code{set x size @{rpn 20 2 /@}}, where the expression @code{@{rpn 20 2 /@}} tells Gri to insert the number 20 onto a stack, then insert the number 2 above it on the stack, and then divide the top two items on the stack. The following are equivalent: @example set x size @{rpn 20 2 /@} # 10 = 20/2 set x size @{rpn 30 2 / 5 -@} # 10 = (30/2-5) set x size @{rpn pi 3.1415 / 10 *@} # 10 = 10*pi/pi @end example If an rpn expression contains a variable whose value is ``missing'', then the value of the result of the expression will also be missing (unless the value of the missing variable is thrown away with a ``pop'' operator). However, if a missing value just happens to occur as the result of an intermediate calculation, then the result is not considered to be missing. RPN operations can be divided roughly into the following groups. @menu * Stack Operators:: Operate on the rpn stack * Rpn Functions:: Define a new rpn operator * Tertiary Operators:: Act on top three items on stack * Binary Operators:: Act on top two items on stack * Unary Operators:: Act on top item on stack * Solitary Operators:: Act alone * Manipulation of Columns etc:: Act on data columns * rpn Examples:: A few examples @end menu @c HTML @node Stack Operators, Rpn Functions, rpn Mathematics, rpn Mathematics @comment node-name, next, previous, up @subsection Stack Operators @cindex @code{pop} rpn stack operator @cindex rpn stack operator @code{pop} @cindex @code{dup} rpn stack operator @cindex rpn stack operator @code{dup} @cindex @code{exch} rpn stack operator @cindex rpn stack operator @code{exch} @cindex @code{roll_left} rpn stack operator @cindex rpn stack operator @code{roll_left} @cindex @code{roll_right} rpn stack operator @cindex rpn stack operator @code{roll_right} @cindex @code{pstack} rpn stack operator @cindex rpn stack operator @code{pstack} Stack operators manipulate or display the stack. @code{pop} removes the top item from the stack (@ref{Unary Operators}). @code{dup} duplicates the top item on the stack (@ref{Unary Operators}). @code{exch} reorders the top two items on the stack (@ref{Binary Operators}). @code{pstack} prints the items on the stack (without changing the stack). @code{roll_right} rolls the items to the right. @code{roll_left} rolls the items to the left. For example, the following shows how you might use @code{exch} or @code{roll_right} to change the sense of a subtraction. @example show @{rpn 1 2 -@} " ... yields -1" show @{rpn 1 2 exch -@} " ... yields 1" show @{rpn 1 2 roll_right -@} " ... yields 1" @end example @c HTML @node Rpn Functions, Tertiary Operators, Stack Operators, rpn Mathematics @comment node-name, next, previous, up @subsection Rpn function Operators @code{rpnfunction} operators are user-defined operators. The parser replaces any such operator with the user-defined rpn expression. The @code{rpnfunction} operators are both general and powerful. An @code{rpnfunction} may be composed of any legal primitive rpn constructs or even other legal @code{rpnfunction} constructs. For details, (@ref{Rpnfunction}). @c HTML @node Tertiary Operators, Binary Operators, Rpn Functions, rpn Mathematics @comment node-name, next, previous, up @subsection Tertiary Rpn Operators @table @code @item @{rpn 0 4 "hello" substr @} @cindex RPN operator @code{substr} @cindex substrings, getting with RPN operator @code{substr} @cindex @code{substr} RPN operator Extract 4 characters from the indicated string, starting at character number 0 (i.e. the start of the string). In other words, replace the three items on the top of the stack with the single item @code{\"hell\"}. @end table @c HTML @node Binary Operators, Unary Operators, Tertiary Operators, rpn Mathematics @comment node-name, next, previous, up @subsection Binary Operators @cindex binary operators in rpn expressions @cindex logical operators in rpn expressions @cindex comparison operators in rpn expressions @cindex @code{<} comparison operator in rpn expressions @cindex @code{>} comparison operator in rpn expressions @cindex @code{==} comparison operator in rpn expressions @cindex mathematical operators in rpn expressions @cindex conversion between user and page units @cindex page units, converting to user units @cindex user units, converting to page units @cindex larger of two numbers, rpn operator @code{sup} @cindex smaller of two numbers, rpn operator @code{inf} @cindex rpn operator @code{sup}, finds larger of pair @cindex rpn operator @code{inf}, finds smaller of pair @cindex @code{sup} rpn operator, finds larger of pair @cindex @code{inf} rpn operator, finds smaller of pair Binary operators act on the @strong{top two} items on the stack. Most binary operators replace two items on the stack with one item, e.g. @code{@{rpn 1 2 /@}} yields 0.5. However, a few binary operators replace one pair of items with a new pair of items, e.g. the @code{xyusertocm} operator replaces an (x,y) pair in user coordinates with an (xcm,ycm) pair in coordinates of centimeters on the page. The binary operators are illustrated below, in rough alphabetical order. @table @code @item @{rpn 3 2 +@} @cindex @code{+} rpn operator @cindex rpn operator @code{+} Add 2 to 3. @item @{rpn 3 2 -@} @cindex @code{-} rpn operator @cindex rpn operator @code{-} Subtract 2 from 3. @item @{rpn 3 2 *@} @cindex @code{*} rpn operator @cindex rpn operator @code{*} Multiply 3 by 2. @item @{rpn 3 2 /@} @cindex @code{/} rpn operator @cindex rpn operator @code{/} Divide 3 by 2. @item @{rpn 3 2 <@} @cindex @code{<} rpn operator @cindex rpn operator @code{<} @cindex HP calculators, RPN notation different from @cindex RPN notation, difference from old-series HP calculators Test whether 2 is less than 3, yielding 1. Note: this convention may be confusing to users who are familiar with HP calculators from decades past. Present-day calculators use this convention, but possibly older calculators used the reverse convention, using @code{>} where Gri uses @code{<}. @item @{rpn 3 2 <=@} @cindex @code{<=} rpn operator @cindex rpn operator @code{<=} Test whether 2 is less than or equal to 3. @item @{rpn 3 2 >@} @cindex rpn operator @code{>} Test whether 2 is greater than 3, yielding 0. @item @{rpn 3 2 >=@} @cindex @code{>=} rpn operator @cindex rpn operator @code{>=} Test whether 2 is greater than or equal to 3, yielding 0. @item @{rpn 3 2 ==@} @cindex rpn operator @code{==} Test whether 2 and 3 are equal, yielding 0. (Do not confuse this with the asignment operator @code{=}, described next.) @item @{rpn 10 ".ten." =@} @cindex @code{=} rpn operator assigns to variables, synonyms, and columns @cindex rpn operator @code{=} @cindex assigning to columns, variables and synonyms within RPN expressions @cindex variables, assigning within RPN expressions @cindex synonyms, assigning within RPN expressions @cindex columns, assigning within RPN expressions @cindex column dat, assigning within RPN expressions Assign the value @code{10} to the variable named @code{.ten.}. The variable name must be put in quotes, or else Gri will insert the value of the variable (if it exists) into the expression, instead of trying to assign to it. After the assignment is done, the stack is cleared of both the value and the variable name. For example, in the following code @example @{rpn 3.1415 ".pi." =@} show .pi. @end example the first line evaluates to a blank line, and the second prints the value of Pi. NOTE: Do not confuse this with the @code{==} equality operator described above. @item @{rpn "hello" "\\greeting" =@} Assign the value @code{"hello"} to the synonym @code{\greeting}. See notes at the above item. @item @{rpn 3.14159 0 "x" =@} Assign the value Pi to the first element (at index @code{0}) of the @code{x} column. All columns may be assigned to in this way, e.g. the following is a technique for plotting a quadratic function: @example .i. = 0 .n. = 10 while @{rpn .i. .n. >@} @{rpn .i. .n. 1 - / .i. "x" =@} @{rpn x .i. @@ 2 power .i. "y" =@} .i. += 1 end while draw curve @end example @item @{rpn 0 1 &@} @cindex @code{&} rpn operator @cindex rpn operator @code{&} Test whether 0 and 1 are both true, yielding 0. @item @{rpn 0 1 and@} @cindex @code{and} rpn operator @cindex rpn operator @code{and} Test whether 0 and 1 are both true, yielding 0. @item @{rpn y x area@} Calculate the area under the curve y=y(x). For details (@ref{Manipulation of Columns etc}). @item @{rpn 0 1 |@} @cindex @code{|} rpn operator @cindex rpn operator @code{|} Test whether either 0 or 1 is true, yielding 1. @item @{rpn 0 1 or@} @cindex @code{or} rpn operator @cindex rpn operator @code{or} Test whether either 0 or 1 is true, yielding 1. @item @{rpn 2 3 exch@} @cindex @code{exch} rpn operator @cindex rpn operator @code{exch} Exchange 2 and 3 on the stack, yielding @code{3 2} on the stack. (See also @code{pop} and @code{dup}.) @item @{rpn x 0 @@@} @cindex @code{@@} rpn operator, for accessing columnar data Yields the value of the first number in the x column. A similar form also works for @code{y}, etc. (@ref{Manipulation of Columns etc}). @item @{rpn 2 3 inf@} @cindex @code{inf} rpn operator @cindex rpn operator @code{inf} Pick the smaller of two values, yielding 3. (Opposite to @code{sup}.) @item @{rpn 2 3 power@} @cindex @code{power} rpn operator @cindex rpn operator @code{power} @cindex HP calculators, RPN notation different from @cindex RPN notation, difference from old-series HP calculators Take 2 to the 3rd power, yielding 8. Note: This convention may be confusing to users who are familiar with HP calculators from decades past. Present-day calculators use this convention, which they write as @code{y^x}, but older calculators used the reverse convention, labelling the key @code{x^y}. @item @{rpn 2 3 remainder@} @cindex @code{remainder} rpn operator @cindex rpn operator @code{remainder} Calculate the remainder after dividing 2 by 3, yielding 2. The return value for @code{@{rpn A B remainder@}} is @code{B - n * A}, where @code{n} is the quotient of @code{A/B}, rounded towards zero to an integer. In this case, @code{2/3} rounds to an @code{n} value of zero, yielding 2 as the resulting remainder. @item @{rpn "heLLo" "s/L/l/g" sed@} @cindex @code{sed} rpn operator @cindex rpn operator @code{sed} Switch all instances of @code{L} into @code{l}, yielding the string @code{"hello"} on the stack. This can be helpful for working with filenames, etc. The work is preformed with a system call to the @code{sed} utility (present on unix systems), and therefore this command will fail if @code{sed} is not installed, or if the OS cannot be contacted. @item @{rpn "file" ".dat" strcat@} @cindex @code{strcat} rpn operator @cindex rpn operator @code{strcat} Concatenate the two strings, yielding the string @code{"file.dat"}. @item @{rpn 2 3 sup@} @cindex @code{sup} rpn operator @cindex rpn operator @code{sup} Pick the larger of two values, yielding 3. (Opposite to @code{inf}.) @end table @c HTML @node Unary Operators, Solitary Operators, Binary Operators, rpn Mathematics @comment node-name, next, previous, up @subsection Unary Operators @cindex rpn, system calls @cindex rpn, conversion of string to number @cindex system calls in rpn expressions @cindex string, conversion to number in rpn expressions @cindex conversion, string to number, in rpn expressions @cindex checking for missing value in rpn expressions @cindex missing value, checking for in rpn expressions Unary operators replace the last item on the stack with another item. For example, the @code{sin} operator takes the sine of the number on the top of the stack; e.g., @code{@{rpn 45 sin@}} yields the sine of 45 degrees. The unary operators are illustrated below, in rough alphabetical order. @table @code @item @{rpn 0 !@} @cindex @code{!} rpn operator @cindex rpn operator @code{!} @cindex logical negation, @code{!} rpn operator @cindex negation, @code{!} rpn operator Replace 0 (false) with its logical negation 1 (true). @item @{rpn 0 not@} @cindex @code{not} rpn operator @cindex rpn operator @code{not} @cindex logical negation, @code{not} rpn operator @cindex negation, @code{not} rpn operator Replace 0 (false) with its logical negation 1 (true). @item @{rpn -3 abs@} @cindex @code{abs} rpn operator @cindex rpn operator @code{abs} Calculate the absolute value of @code{-3}. @item @{rpn 0.5 acos@} @cindex @code{acos} rpn operator @cindex rpn operator @code{acos} Calculate the inverse cosine of 0.5, yielding 60 (degrees). @item @{rpn 2 acosh@} @cindex @code{acosh} rpn operator @cindex rpn operator @code{acosh} Calculate the inverse hyperbolic cosine of 2, yielding 1.317. (Note: argument must equal or exceed 1, or an error results.) @anchor{age-rpn-operator} @item @{rpn "filename" age@} @cindex makefiles, emulating action with the @code{age} rpn operator @cindex file age, determined with the @code{age} rpn operator @cindex @code{age} rpn operator @cindex rpn operator @code{age} Calculate the ``age'' of the indicated file, in seconds. An age of zero indicates that the file was created, or last modified, within 1 second of the execution of the @code{age} operator. On unix (and similar) machines, the calculation is done on unix machines with the @code{stat()} subroutine. On other machines, the @code{age} operator may cause an error. The age of a non-existent file is reported as the number of seconds since the system clock's reference time, i.e. since 1970-jan-1 on unix machines. This convention is so that scripts like that in the example below will work as intended. A typical use of this command is the creation of data-files from shell scripts, as illustrated below. The idea is to update (or create) the file @file{file.dat} using the system-executable script @file{creator.pl}, but only to do so if @file{creator.pl} is younger than @file{file.dat}. @example if @{rpn "file.dat" age "creator.pl" age <@} system "./creator.pl > file.dat" end if open file.dat @end example For the convenience in such usage, a non-existent file is assigned the maximum possible file age on the given OS, e.g. on a unix machine, the age is reported as though the non-existent file had been created on January 1, 1970 on a unix machine. @item @{rpn 0.5 asin@} @cindex @code{asin} rpn operator @cindex rpn operator @code{asin} Calculate the inverse sine of 0.5, yielding 30 (degrees). @item @{rpn 1 atan@} @cindex @code{atan} rpn operator @cindex rpn operator @code{atan} Calculate the inverse tangent of 1, yielding 45 (degrees). @item @{rpn 0.5 atanh@} @cindex @code{atan} rpn operator @cindex rpn operator @code{atan} Calculate the inverse hyperbolic tangent of 0.5, yielding 0.549306 (radians). @item @{rpn 0 argv@} @cindex @code{argv} rpn operator, access commandline arguments @cindex arguments on command line, accessing with @code{argv} rpn operator @cindex commandline arguments, accessing with @code{argv} rpn operator Returns the name of the Gri command-file, which is considered as the first "optional" argument. (It may seem odd that the name of the command-file is considered an option, but Gri does this for consistency with C and other languages. It is useful.) Other arguments provided when Gri was invoked are provided as @code{rpn 1 argv}, etc. A string consisting of a single blank character results if one tries to access beyond the list of arguments that were actually supplied. See also the @code{argc} solitary operator (@ref{Solitary Operators}), which returns the number of optional arguments. For example, if Gri is invoked as @example gri myscript.gri file1.dat file2.dat @end example @noindent and if @file{myscript.gri} contained @example .n. = @{rpn argc@} .i. = 0 while @{rpn .n. .i. <@} show "argument " .i. " is " @{rpn .i. argv@} .i. += 1 end while @end example @noindent then the output would be @example argument 0 is myscript.gri argument 1 is file1.dat argument 2 is file2.dat @end example For usage within the Emacs gri-mode, see @ref{Filename arguments when running gri}. @item @{rpn "hi" ascent@} @cindex @code{ascent} rpn operator @cindex rpn operator @code{ascent} Determine ascent of this string (in cm), in the present font and fontsize. (See also @code{descent} and @code{width}.) @item @{rpn "3.1" atof@} @cindex @code{atof} rpn operator @cindex rpn operator @code{atof} Calculate the numerical value contained in indicated string. @item @{rpn 1.5 ceil@} @cindex @code{ceil} rpn operator @cindex rpn operator @code{ceil} Calculate the next higher integer, yielding 2. (Opposite of @code{floor}.) @item @{rpn 45 cos@} @cindex @code{cos} rpn operator @cindex rpn operator @code{cos} Calculate the cosine of 45 degrees, yielding 0.707. @item @{rpn 1 cosh@} @cindex @code{cosh} rpn operator @cindex rpn operator @code{cosh} Calculate the hyperbolic cosine of 1 (radian), yielding 1.543. @item @{rpn 1 cmtopt@} @cindex @code{cmtopt} rpn operator @cindex rpn operator @code{cmtopt} Convert from 1 centimeter to so-called ``point'' units, yielding 28.45. (Opposite of @code{pttocm}.) @item @{rpn 170 dec2hex@} @cindex converting decimal values to hexadecimal strings @cindex hexadecimal, converting to from decimal Convert a number into a string which is its hexadecimal representation. Before the conversion, the number is rounded to the nearest integer, and if the result is negative, an error results. The string is double-quoted, with letters (if there are any) being in upper case. For example @code{\hex = @{rpn 63 dec2hex@}} is equivalent to @code{\hex = "3F"}. Compare with @code{hex2dec}, the inverse. @item @{rpn "\\syn" defined@} @cindex testing for existence of a synonym @cindex synonyms, checking for existence of @cindex existence of a synonym, testing Test whether the synonym is defined at the moment, returning 1 if so and 0 if not. (Note the double-backslash in the synonym name, which is required.) @item @{rpn ".var." defined@} @cindex existence of a variable, testing @cindex testing for existence of a variable @cindex variables, checking for existence of Test whether the variable is defined at the moment, returning 1 if so and 0 if not. @item @{rpn "\\@@alias" defined@} @cindex testing for existence of an aliased synonym @cindex alias synonyms, checking for existence of @cindex existence of an alias synonym, testing Test whether the variable/synonym item that is named by the alias (@ref{Alias Synonyms}) is defined at the moment, returning 1 if so and 0 if not. @item @{rpn "hi" descent@} @cindex @code{descent} rpn operator @cindex rpn operator @code{descent} Calculate the descent (below the baseline in cm) for the given string, in the present font and fontsize. (See also @code{ascent} and @code{width}.) @item @{rpn "/home/me/data/timeseries" directory_exists@} @cindex @code{directory_exists} rpn operator @cindex file permissions, testing with @code{file_exists} and @code{directory_exists} @cindex rpn operator @code{directory_exists} Determine whether indicate directory exists, yielding @code{1} if it does and @code{0} otherwise. (See also @code{file_exists}.) @item @{rpn 2 dup@} @cindex @code{dup} rpn operator @cindex rpn operator @code{dup} Duplicate the top item on stack, yielding @code{2 2} on the stack. (See also @code{exch} and @code{pop}.) @item @{rpn 1 exp@} @cindex @code{exp} rpn operator @cindex rpn operator @code{exp} Calculate the value of @code{e} raised to the indicated power, yielding 2.71828. @item @{rpn 2 exp10@} @cindex @code{exp10} rpn operator @cindex rpn operator @code{exp10} Calculate the value of @code{10} raised to the indicated power, yielding 100. @item @{rpn "foo.dat" file_exists@} @cindex @code{file_exists} rpn operator @cindex rpn operator @code{file_exists} Determine whether the indicate file exists, yielding @code{1} if it does and @code{0} otherwise. (See also @code{directory_exists}.) @item @{rpn 1.5 floor@} @cindex @code{floor} rpn operator @cindex rpn operator @code{floor} Calculate the nearest smaller integer, yielding 1. (Opposite of @code{ceil}.) @item @{rpn "AA" hex2dec@} @cindex converting hexadecimal strings to decimal values @cindex hexadecimal, converting to decimal Convert a string, representing a hexadecimal value, into an integer. The string must be double-quoted, and it may contain either lower- or upper-case letters; this is in contrast to the inverse function, @code{dec2hex}, which returns upper-case. This operator is most often used in working with colours, since Gri handles colour components in decimal terms, whereas many other applications refer to the components in hexadecimal notation. Compare with @code{dec2hex}, the inverse. @item @{rpn 3 ismissing@} @cindex @code{ismissing} rpn operator @cindex rpn operator @code{ismissing} Yields 1 if the indicated value is a ``missing value'' or 0 otherwise. @item @{rpn 100 log@} @cindex @code{log} rpn operator @cindex rpn operator @code{log} Calculate the base-10 logarithm of 100, yielding 2. @item @{rpn 10 ln@} @cindex @code{ln} rpn operator @cindex rpn operator @code{ln} Calculate the natural logarithm of 10, yielding 2.30259. @item @{rpn x mean@} Yields the mean value of the (non-missing) numbers in the x column. A similar form also works for @code{y}, etc. (@ref{Manipulation of Columns etc}). @item @{rpn x max@} Yields the largest value of the (non-missing) numbers in the x column. A similar form also works for @code{y}, etc. (@ref{Manipulation of Columns etc}). @item @{rpn x min@} Yields the smallest value of the (non-missing) numbers in the x column. A similar form also works for @code{y}, etc. (@ref{Manipulation of Columns etc}). @item @{rpn 28.45 pttocm@} @cindex @code{pttocm} rpn operator @cindex rpn operator @code{pttocm} Calculate the number of centimeters in 28.45 printers points, yielding 1. (Opposite of @code{cmtopt}.) @item @{rpn 1 2 pop@} @cindex @code{pop} rpn operator @cindex rpn operator @code{pop} Remove the top item from the stack, yielding @code{1} on the stack. Generates an error if the stack is empty. (See also @code{exch} and @code{dup}.) @item @{rpn 4 sqrt@} @cindex @code{sqrt} rpn operator @cindex rpn operator @code{sqrt} Calculate the square root of 4, yielding 2. (Negative arguments yield errors.) @item @{rpn 45 sin@} @cindex @code{sin} rpn operator @cindex rpn operator @code{sin} Calculate the sine of 45 (degrees), yielding 0.707107. @item @{rpn 2 sinh@} @cindex @code{sinh} rpn operator @cindex rpn operator @code{sinh} Calculate the hyperbolic sine of 2, yielding 3.62686. @item @{rpn "hello" strlen@} @cindex @code{strlen} rpn operator @cindex rpn operator @code{strlen} Determine the number of characters in string, including the quotation marks, e.g. 7 here. @item @{rpn "date" system@} @cindex @code{system} rpn operator @cindex rpn operator @code{system} Call the indicated system function and insert its ouput on the stack, yielding the date as a character string. @item @{rpn 45 tan@} @cindex @code{tan} rpn operator @cindex rpn operator @code{tan} Calculate the tangent of 45 (degrees), yielding 1. @item @{rpn tanh@} @cindex @code{tanh} rpn operator @cindex rpn operator @code{tanh} Calculate the hyperbolic tangent of 2, yielding 0.964028. @item @{rpn "hi" width@} @cindex @code{width} rpn operator @cindex rpn operator @code{width} Determine width of this string (in cm), in the present font and fontsize. (See also @code{ascent} and @code{descent}.) @item @{rpn 0 wordv@} @cindex RPN operator @code{wordv} @cindex @code{wordv} RPN operator Returns the first word used in invoking the present command. Similar to the @code{\.word0.} synonym (@ref{Local Synonyms}). Example: @example `let us test .it.' @{ .w. = 0 while @{rpn .w. wordc >@} show "The " .w. "-th word is `" @{rpn .w. wordv@} "'." .w. += 1 end while @} let us test "this thing" let us test "this" "thing" let us test "Pi is" @{rpn 3.14@} @end example If you are using this to parse options given to the command, it is up to you to skip the non-optional words in the command. In this case, for example, we skipped the first three words (@code{let}, @code{us}, and @code{test}). @item @{rpn 1 xusertocm@} @cindex @code{xusertocm} rpn operator @cindex rpn operator @code{xusertocm} Calculate the x coordinate, in centimeters measured from left-hand side of page, corresponding to a user-value of x=1. (Opposite of @code{xcmtouser}.) @item @{rpn 1 xcmtouser@} @cindex @code{xcmtouser} rpn operator @cindex rpn operator @code{xcmtouser} Calculate the x value, in user units, for a point that is 1 centimeter from the left-hand edge of the paper. (Opposite of @code{xusertocm}.) @item @{rpn 1 yusertocm@} @cindex @code{yusertocm} rpn operator @cindex rpn operator @code{yusertocm} Calculate the y coordinate, in centimeters measured from bottom side of page, corresponding to a user-value of x=1. (Opposite of @code{ycmtouser}.) @item @{rpn 1 ycmtouser@} @cindex @code{ycmtouser} rpn operator @cindex rpn operator @code{ycmtouser} Calculate the y value, in user units, for a point that is 1 centimeter from the bottom edge of the paper. (Opposite of @code{yusertocm}.) @end table @c HTML @node Solitary Operators, Manipulation of Columns etc, Unary Operators, rpn Mathematics @comment node-name, next, previous, up @subsection Solitary Operators @cindex rpn operator @code{argc}, yielding number of commandline arguments @cindex @code{argc} rpn operator, yielding number of commandline arguments Solitary operators do not act on items on the stack; rather, they generate items themselves and insert them on the stack. The solitary operators are illustrated below, in alphabetical order. @table @code @item @{rpn argc@} Yields number of command-line arguments given by the user when Gri was invoked. Thus, invoking Gri as @example gri myfile.gri file1.dat file2.dat @end example @noindent yields 3, for arguments @file{myfile.gri}, @code{file1.dat}, and @code{file2.dat}. These arguments are accessible through the @code{argv} unary operator (@ref{Unary Operators}). @item @{rpn e@} @cindex e, base of natural logarithms, in RPN expressions Yields the base of natural logarithms, i.e. @code{2.718}... @item @{rpn pi@} @cindex pi, in RPN expressions Yields Pi, i.e. @code{3.141}... @item @{rpn rand@} @cindex RPN operator @code{rand} @cindex @code{rand} RPN operator @cindex random numbers, generating in RPN expressions Generate a random number in the range 0 to 1, using the C subroutine @code{drand48()} if it is available, otherwise the less well-distributed @code{rand()} subroutine. @item @{rpn wordc@} @cindex RPN operator @code{wordc} @cindex @code{wordc} RPN operator Returns number of words used in invoking the present command. Similar to the @code{\.words.} synonym (@ref{Local Synonyms}). Example: @example `let us test .it.' @{ show "This command has " @{rpn wordc@} " words" @} let us test 10 let us test @{rpn 3 1 +@} let us test "this" let us test "this thing" @end example The operator @code{wordv} may be used to extract the words of the command (@ref{Unary Operators}). @end table @c HTML @node Manipulation of Columns etc, rpn Examples, Solitary Operators, rpn Mathematics @comment node-name, next, previous, up @subsection Manipulation of Columns etc @subsubsection Columns @cindex column data, accessing individual values and stats @cindex standard deviation, column data @vindex @code{..num_col_data..}, number column data Individual data in the @code{x}, @code{y}, @code{z}, @code{u}, @code{v} and @code{weight} columns can be accessed with the @code{@@} operator. The first point has index 0. Examples: @example show "first x is " @{rpn x 0 @@ @} show "last x is " @{rpn x ..num_col_data.. 1 - @@ @} show "and here are all the data:" .i. = 0 while @{rpn .i. ..num_col_data.. >@} show @{rpn x .i. @@ @} .i. += 1 end while @end example @cindex maximum, column data @cindex minimum, column data @cindex statistics, column data @cindex column data, statistics @cindex mean, calculating for column data @cindex standard deviation, calculating for column data @cindex skewness, calculating for column data @cindex kurtosis, calculating for column data The mean value is available from the @code{mean} operator (e.g., @code{.xmean. = @{rpn x mean @}}, while the standard deviation is given by @code{stddev}, the skewness is given by @code{skewness}, and the kurtosis is given by @code{kurtosis} (using the definition that yields 3 for a gaussian distribution). The minimal and maximal values are given by @code{min} and @code{max}. @cindex @code{area} rpn operator @cindex rpn operator @code{area} @cindex area under curve The area under the curve y=y(x) is found by @code{@{rpn y x area @}}, defined by @ifinfo @code{0.5 * sum ( (y[i] + y[i-1]) * (x[i] - x[i-1]) )} for @code{i} ranging from 1 to @code{..num_col_data..}-1. @end ifinfo @tex ${1}\over{2} \left( \sum_1^{n-1} (y_i + y_{i-1}) (x_i - x_{i-1}) \right)$ for data with $i$ ranging $0$--$..num\_col\_data..-1$ @end tex @subsubsection Grid @cindex grid data -- accessing individual values and stats @cindex maximum, grid data @cindex minimum, grid data @cindex grid data -- minimum, maximum, mean Grid data can be accessed with e.g. @code{@{rpn grid min @} }, @code{@{rpn grid max @} }, and @code{@{rpn grid mean @} }. @cindex rpn operator @code{interpolate} @cindex grid, interpolating to given (x,y) value @cindex interpolating grid to given (x,y) value The value of the grid at a given @code{(.x.,.y.)} coordinate may be found by by e.g. @code{@{rpn grid .x. .y. interpolate@}}. The interpolation scheme is the same as that used in converting grids to images. @c HTML @node rpn Examples, Text, Manipulation of Columns etc, rpn Mathematics @comment node-name, next, previous, up @subsection rpn Examples Here are some reverse-polish expressions and the corresponding algebraic interpretations: @itemize @bullet @item @code{@{rpn 1 2 + 10 / @}} = (1+2)/10 @item @code{@{rpn .a. .b. + .c. + .d. / @}} = (.a.+.b.+.c.)/.d. @item @code{@{rpn e 2 / @}} = e/2 (Gri knows values of ``e'' and ``pi'') @item @code{@{rpn 23 sin 100 * 12 cos + @}} = cos(12) + 100sin(23) @item @code{@{rpn 5 2 power @}} = 25 @item @code{@{rpn 2 log exp @}} = exp(log 2) @item @code{@{rpn 2 ln exp10 @}} = 10^ln2 @item @code{@{rpn 1.7 floor @}} = 1 (rounds down to nearest integer. Note that the floor of -1.7 is -2) @item @code{@{rpn 10.1 2 remainder @}} = 0.1 (remainder of 10.1 after division by 2; see C function @code{remainder(x,y)}) @item @code{@{rpn -10.1 2 remainder @}} = -0.1 @item @code{@{rpn -10.1 -2 remainder @}} = -0.1 @item @code{@{rpn .num. 10 > @}} = 1 if 10 exceeds .num., or 0 otherwise @end itemize @noindent NOTES: @itemize @bullet @cindex trigonometric operations in rpn math @cindex mathematics, trigonometric operations @item The units of @code{sin}, @code{cos}, etc, are degrees, not radians. @item @cindex page units @cindex user units @cindex mapping page location units to user units @cindex transforming page location units to user units @cindex scales, accessing @cindex mathematics, rpn notation, example The scales of the plot are accessible to @code{rpn}. For example, with the command @example draw label "hi" at 10 20 @end example @noindent you draw the indicated string at the indicated location in user coordinates. To put it 0.15 centimetres to the right of this location and 0.1 centimetres lower, you could do as follows: @example draw label "\label" at \ @{rpn .x. xusertocm 0.15 + xcmtouser@} \ @{rpn .y. yusertocm 0.10 - ycmtouser@} @end example (Note that the x and y scales have individual translations from "user" to "cm" coordinates.) @item Some conversion factors are built into @code{rpn}; @code{cmtopt} converts from centimetres to points (by dividing by 28.45; the conversion factor to inches is 72.27) while @code{pttocm} converts from points to centimetres. For example, here is how to label a data curve with a label placed near the last y-value of the data set: @cindex drawing labels for data curves @cindex labels, on data curves @example draw curve .y. = @{rpn ..ylast.. yusertocm 0.5 - ycmtouser@} draw label "Smoothed" at ..xlast.. .y. @end example @end itemize @c HTML @node Text, Embedded Synonyms, rpn Examples, Programming @comment node-name, next, previous, up @section Text Strings Any text can be drawn in any size; Gri does not limit font size to a list, e.g. 10 point, 12 points, etc. Several fonts are available in Gri, e.g. Times, Helvetica, etc.; these are all standard PostScript fonts. Support for some non-English languages (e.g. French) is also provided. And, finally, Gri supports inclusion of simple mathematical expressions (Greek letters, superscripts, etc.) in text, using a LaTeX-style syntax. @menu * Embedded Synonyms:: Embedding synonyms in text strings * Mathematical Text:: Mathematical symbols and Greek letters * Non-English Text:: French, etc. * Adjustment Of Character Position:: thinspaces @end menu @c HTML @node Embedded Synonyms, Mathematical Text, Text, Text @comment node-name, next, previous, up @subsection Embedding synonyms in quoted text strings @cindex synonyms, embedding in quoted text strings @cindex text strings, embedding synonyms within @strong{Outside} math strings, you can embed your synonyms at will. For example, you can include the name of a data file in the title of your plot as follows @cindex interaction with user, @code{query} command @example query \filename "File to read from?" ("data.file") open \filename read columns x y draw curve draw title "data from \filename" @end example Within math strings (ie, between matched dollar-signs), these synonyms are disabled, and only the mathematical symbols and Greek letters work. @c HTML @node Mathematical Text, Non-English Text, Embedded Synonyms, Text @comment node-name, next, previous, up @subsection Mathematical text @subsubsection Subscripts @cindex subscripts @cindex text, subscripts As in @TeX{} and La@TeX{}, you must be in math-mode to use subscripts; in other words, you must enclose the string or substring in dollar-signs. For single-character subscripts, insert an underline prior to the character to be subscripted: @example draw title "$a_2$" @end example @noindent For multiple-character subscripts, insert braces before and after the item to be subscripted: @example draw title "$a_@{22@}$" @end example @subsubsection Superscripts @cindex superscripts @cindex text, superscripts As in @TeX{} and La@TeX{}, you must be in math-mode to use superscripts; in other words, you must enclose the string or substring in dollar-signs. For single-character superscripts, insert a carat prior to the character to be superscripted: @example draw title "$a^2$" @end example @noindent For multiple-character superscripts, insert braces before and after the item to be superscripted: @example draw title "$a^@{22@}$" @end example @subsubsection Mathematical symbols @cindex mathematical Symbols @cindex greek Letters @cindex text, mathematical symbols @cindex text, Greek letters As in @TeX{} and LaTeX, you indicate mathematical symbols and Greek letters with backslash sequences. The following LaTeX symbols are defined in math mode in Gri (cf tables in Lamport's section 3): @ifinfo @example \Delta \Downarrow \Gamma \Im \Lambda \Leftarrow \Leftrightarrow \Omega \Pi \Phi \Psi \Re \Rightarrow \Sigma \Theta \Uparrow \Upsilon \Xi \alpha \approx \ast \beta \bullet \chi \circ \cong \delta \div \downarrow \epsilon \equiv \eta \exists \forall \gamma \geq \gg \in \infty \iota \kappa \lambda \langle \leftarrow \leftrightarrow \leq \ll \mu \nabla \neq \nu \omega \partial \phi \pi \pm \prod \propto \psi \rangle \rho \rightarrow \sigma \sim \subset \subseteq \sum \supset \supseteq \surd \sqrt \tau \theta \times \uparrow \upsilon \varpi \wedge \xi \zeta \vartheta \varsigma \varphi \aleph \oplus \otimes \wp \prime \emptyset \angle \neg \clubsuit \diamondsuit \spadesuit \cdot \lfloor \lceil \rceil \rfloor @end example @end ifinfo @tex ({\tt $\backslash$Delta}, $\Delta$), ({\tt $\backslash$Downarrow}, $\Downarrow$), ({\tt $\backslash$Gamma}, $\Gamma$), ({\tt $\backslash$Im}, $\Im$), ({\tt $\backslash$Lambda}, $\Lambda$), ({\tt $\backslash$Leftarrow}, $\Leftarrow$), ({\tt $\backslash$Leftrightarrow}, $\Leftrightarrow$), ({\tt $\backslash$Omega}, $\Omega$), ({\tt $\backslash$Phi}, $\Phi$), ({\tt $\backslash$Pi}, $\Pi$), ({\tt $\backslash$Psi}, $\Psi$), ({\tt $\backslash$Re}, $\Re$), ({\tt $\backslash$Rightarrow}, $\Rightarrow$), ({\tt $\backslash$Sigma}, $\Sigma$), ({\tt $\backslash$Theta}, $\Theta$), ({\tt $\backslash$Uparrow}, $\Uparrow$), ({\tt $\backslash$Upsilon}, $\Upsilon$), ({\tt $\backslash$Xi}, $\Xi$), ({\tt $\backslash$alpha}, $\alpha$), ({\tt $\backslash$approx}, $\approx$), ({\tt $\backslash$ast}, $\ast$), ({\tt $\backslash$beta}, $\beta$), ({\tt $\backslash$bullet}, $\bullet$), ({\tt $\backslash$chi}, $\chi$), ({\tt $\backslash$circ}, $\circ$), ({\tt $\backslash$cong}, $\cong$), ({\tt $\backslash$delta}, $\delta$), ({\tt $\backslash$div}, $\div$), ({\tt $\backslash$downarrow}, $\downarrow$), ({\tt $\backslash$epsilon}, $\epsilon$), ({\tt $\backslash$equiv}, $\equiv$), ({\tt $\backslash$eta}, $\eta$), ({\tt $\backslash$exists}, $\exists$), ({\tt $\backslash$forall}, $\forall$), ({\tt $\backslash$gamma}, $\gamma$), ({\tt $\backslash$geq}, $\geq$), ({\tt $\backslash$gg}, $\gg$), ({\tt $\backslash$in}, $\in$), ({\tt $\backslash$int}, $\int$), ({\tt $\backslash$infty}, $\infty$), ({\tt $\backslash$iota}, $\iota$), ({\tt $\backslash$kappa}, $\kappa$), ({\tt $\backslash$lambda}, $\lambda$), ({\tt $\backslash$langle}, $\langle$), ({\tt $\backslash$leftarrow}, $\leftarrow$), ({\tt $\backslash$leftrightarrow}, $\leftrightarrow$), ({\tt $\backslash$leq}, $\leq$), ({\tt $\backslash$ll}, $\ll$), ({\tt $\backslash$mu}, $\mu$), ({\tt $\backslash$nabla}, $\nabla$), ({\tt $\backslash$neq}, $\neq$), ({\tt $\backslash$nu}, $\nu$), ({\tt $\backslash$omega}, $\omega$), ({\tt $\backslash$partial}, $\partial$), ({\tt $\backslash$phi}, $\phi$), ({\tt $\backslash$pi}, $\pi$), ({\tt $\backslash$pm}, $\pm$), ({\tt $\backslash$prod}, $\prod$), ({\tt $\backslash$propto}, $\propto$), ({\tt $\backslash$psi}, $\psi$), ({\tt $\backslash$rangle}, $\rangle$), ({\tt $\backslash$rho}, $\rho$), ({\tt $\backslash$rightarrow}, $\rightarrow$), ({\tt $\backslash$sigma}, $\sigma$), ({\tt $\backslash$sim}, $\sim$), ({\tt $\backslash$subset}, $\subset$), ({\tt $\backslash$subseteq}, $\subseteq$), ({\tt $\backslash$sum}, $\sum$), ({\tt $\backslash$supset}, $\supset$), ({\tt $\backslash$supseteq}, $\supseteq$), ({\tt $\backslash$surd}, $\surd$), ({\tt $\backslash$sqrt}, $\surd$), ({\tt $\backslash$tau}, $\tau$), ({\tt $\backslash$theta}, $\theta$), ({\tt $\backslash$times}, $\times$), ({\tt $\backslash$uparrow}, $\uparrow$), ({\tt $\backslash$upsilon}, $\upsilon$), ({\tt $\backslash$varpi}, $\varpi$), ({\tt $\backslash$wedge}, $\wedge$), ({\tt $\backslash$xi}, $\xi$), ({\tt $\backslash$zeta}, $\zeta$), ({\tt $\backslash$vartheta}, $\vartheta$), ({\tt $\backslash$varsigma}, $\varsigma$), ({\tt $\backslash$varphi}, $\varphi$), ({\tt $\backslash$aleph}, $\aleph$), ({\tt $\backslash$oplus}, $\oplus$), ({\tt $\backslash$otimes}, $\otimes$), ({\tt $\backslash$wp}, $\wp$), ({\tt $\backslash$prime}, $\prime$), ({\tt $\backslash$emptyset}, $\emptyset$), ({\tt $\backslash$angle}, $\angle$), ({\tt $\backslash$neg}, $\neg$), ({\tt $\backslash$clubsuit}, $\clubsuit$), ({\tt $\backslash$diamondsuit}, $\diamondsuit$), ({\tt $\backslash$spadesuit}, $\spadesuit$) ({\tt $\backslash$cdot}, $\cdot$) ({\tt $\backslash$lfloor}, $\lfloor$) ({\tt $\backslash$lceil}, $\lceil$) ({\tt $\backslash$rceil}, $\rceil$) ({\tt $\backslash$rfloor}, $\rfloor$) @end tex @c HTML Click here to see the @c HTML symbols and their names. @noindent For example, you might use these as follows: @example draw title "$\alpha$ = thermal expansion coefficient" @end example Sometimes you'll want a mathematical symbol to be adjacent to a normal text string, with no space between. You can do this by enclosing in braces, as in LaTeX. @cindex text, inserting forward/backward space @cindex space in text @cindex superscripts and subscripts -- how to align using @code{\!} @cindex aligning superscripts and subscripts with @code{\!} @TeX{} and La@TeX{} handle combinations of superscripts and subscripts very cleanly, putting one above the other. Presently, Gri does not do this; for example @code{set x name "$A_1^2$"} will have the 2 appearing to the right of the 1 instead of above it. Proper positioning will be added to a later version of Gri, but in the meantime you can achieve the desired effect with the @TeX{} ``negative thinspace'' psuedo-character in math-mode. Using this feature will not hurt you when the new Gri becomes available. The symbol for a negative thinspace is @code{\!} in math-mode. It has no meaning in nonmath mode. A thinspace is 1/6 of an ``em-space'' (a @TeX{} term, normally equal to the width of the character ``M'' in the current font). In most fonts, numbers are half the width of the letter ``M'', so that 3 negative thinspaces will move leftward over a single number. Thus, if the example above becomes @code{set x name "$A_1\!\!\!^2"}, the 2 will be positioned above the 1. (Equivalently, you could write @code{set x name "$A^2\!\!_1$"}.) Depending on the actual characters you have in the super/subscripts, you might need more or less thinspaces; some experimentation might be required. Also, note that the symbol @code{\,} in math mode is a positive thinspace (which moves the next character a little bit to the right). Thus, you can add a little extra spaces between characters by doing something like @code{set x name "A$\,$B"}. To get a hat over a single character, do something like the following (which draws a hat over the character "h"): @cindex hat, drawing hat on top of character @example draw label "h$@{\!\!\!^@{^\wedge@}@}$" at 10 12 cm @end example @cindex overbar, drawing line on top of character @cindex latex overline command, emulating @cindex overline, emulating latex command To get an overbar on a rho, do this: @example draw label "$\rho\!\!\!\!^-$" at 3 3 cm @end example @c HTML @node Non-English Text, Adjustment Of Character Position, Mathematical Text, Text @comment node-name, next, previous, up @subsection Non-English characters @cindex iso-latin-1 font encoding @cindex text, ISO characters @cindex accented characters in text @cindex non-English language text @cindex French accents in text Gri relies on the ``standard'' PostScript fonts, however, and it suffers all limitations of these fonts. Gri supports both English and some other European-derived languages, permitting text with accents on letters. (It does not support Oriental or other languages at this time.) The accents are supported by using the so-called ISO-Latin-1 font-encoding scheme (also called the ISO-8859-1 scheme), and so, from what the author can gather from his reading, Gri should support various languages from western European, e.g. English, French, Spanish, Catalan, Basque, Portuguese, Italian, Albanian, Rhaeto-Romanic, Dutch, German, Danish, Swedish, Norwegian, Finnish, Faroese, Icelandic, Irish, Scottish, and as well as Afrikaans and Swahili. Gri uses the ISO-Latin-1 font encodings by default, although the so-called `standard' font-encoding may also be selected with the @code{Set Font Encoding} command (@ref{Set Font Encoding}). For more on font encodings see any book on PostScript fonts ... although the bottom line is that if you are using accented characters in your work, then you probably already know about encodings, and if you don't use accents then you needn't learn about this topic except for the pleasure of learning about other languages. The method of handling accented characters is very simple. If you can type it, Gri can draw it! It is up to you to determine how to enter the accents. Most text editors permit this, and it seems fair to say that users who need accented characters already know how to type them into their editors. @c For complete information about entering iso-latin-1 characters in Emacs, @c consult your Emacs manual in the section @c @ifinfo @c @ref{(emacs)Single-Byte Character Support} @c @end ifinfo @c @ifhtml @c @code{(emacs)Single-Byte Character Support} @c @end ifhtml @c which describes the available methods suitable for the Emacs version you @c are using. A few examples are nevertheless provided below. @c @c Consider the task of inserting French text, with the Emacs @c text-editor. There are several ways of doing this (and you may wish to @c consult your emacs info manual). A method that works in emacs-19 up to @c current emacs-20 versions uses the emacs @file{iso-transl.el} package by @c putting the following in your @file{~/.emacs} file: @c @c @example @c (require 'iso-transl) @c (iso-transl-set-language "French") @c (standard-display-european t) @c @end example @c @c Loading the iso-transl package defines three ways of entering the non-ASCII @c printable characters with codes above 127: the prefix @kbd{C-x 8}, or @c the @key{Alt} key, or a dead accent key. For example, you can enter @c uppercase A-umlaut as @kbd{C-x 8 " A} or @kbd{Alt-" A} (if you have an @c Alt key) or @kbd{umlaut A} (if you have an umlaut/diaeresis key). @c @c A more recently introduced method is to enter the mode which allows @c quick insertion of iso-latin-1 characters. Do the Emacs command @c @code{M-x iso-accents-mode} (either manually, or in a hook that's done @c automatically). Now, suppose the x-axis is to represent temperature. All @c you'd have to do is type in the command @c @c @example @c set x name "Temp'erature" @c @end example @c @c As you type, the quote mark will dissappear, and reappear as an accent on the @c @code{e}. And then, Gri will recognize this as an accented character and it @c will draw the accent on the axis label. @c Perhaps the future default way of accomplishing this task is to use MULE @c support directly. First, customize MULE using @c @code{M-x customize-group RET mule} setting the @c @code{current language environment} (e.g. latin-1) and @c the @code{default input method} (e.g. latin-1-prefix). Then, invoking @c @code{M-x toggle-input-method} (e.g. @key{C-\}) toggles into a mode similar @c to the @code{iso-accents-mode} minor-mode described above. @c HTML @node Adjustment Of Character Position, Adding New Commands, Non-English Text, Text @comment node-name, next, previous, up @subsection Adjustment Of Character Position @cindex text, thin-spaces within @cindex thin-space in text Micro-positioning is available within math-mode, via the symbols @code{\!} (which means go left one thin-space) and @code{\,} (which means go right one thin-space). (A thin-space is 1/6 the width of the letter ``M''). @c HTML @node Adding New Commands, Purpose, Adjustment Of Character Position, Programming @comment node-name, next, previous, up @section Adding new commands to Gri @cindex commands, how to add new ones to Gri @cindex new commands, how to add to Gri @cindex adding new commands to Gri @cindex extending Gri by adding new commands Gri provides so-called "newcommands" as a sort of subroutine syntax on steroids. @menu * Purpose:: What newcommands are for * Parsing:: How Gri parses commands * Simple New Command:: Simple example of adding new command * Complicated New Command:: More complicated example * Changeable Command Arguments:: The &.var. and &\syn syntax @end menu @c HTML @node Purpose, Parsing, Adding New Commands, Adding New Commands @comment node-name, next, previous, up @subsection Purpose of newcommands Gri can be extended easily. Primitive commands (e.g. @code{set x name}) can be supplemented with so-called "new commands." New commands are a little like subroutines other programming languages. For example, you might find that you often draw filled curves with a particular graylevel (say 0.5), and then return the graylevel to the previous value. This requires you to do the following each time: @example new .old_graylevel. .old_graylevel. = ..graylevel.. set graylevel 0.5 draw curve filled to 0 y set graylevel .old_graylevel. delete .old_graylevel. @end example @noindent This gets a bit tedious, and it would obviously be nicer to just say something like @example Draw my kinda curve @end example To make this shortcut, you'd tell Gri about the existence of a new command called @code{Draw my kinda curve}, and tell it that the new command can be accomplished by the longer code fragment written above. Once you've learned how to make new commands, you are likely to use them a lot. The following explains how you add new commands. For advice on programming style, etc., (@ref{Resource File}). @c HTML @node Parsing, Simple New Command, Purpose, Adding New Commands @comment node-name, next, previous, up @subsection How Gri parses commands @cindex new commands, how they are parsed Whenever Gri reads a command line, it compares it with its list of commands. This list is searched in this order: (1) the universal @file{gri.cmd} file (@ref{Invoking Gri}), (2) your resource file (@ref{Resource File}), if it exists, and then (3) your command file itself. Gri stops searching when it finds a Gri command that matches the command line. "Matching" means that the command line is identical in all words in a Gri command, scanning from the left, until it encounters a word containing @itemize @bullet @item A quote (e.g. @code{"string"}) @item A synonym name (e.g. @code{\file}) @item A variable name (e.g. @code{.number.}) @item An opening square bracket (e.g. @code{[option]}) @item An opening brace (e.g. @code{@{a|b@}}) @item A choice between two items (e.g. @code{first|second}) @item A variable-name with a @code{&} character immediately to the left (e.g. @code{&.var.}). This is a signal that the variable may be changed inside the newcommand (@ref{The Ampersand Syntax}). @item A synonym-name with a @code{&} character immediately to the left (e.g. @code{&\syn}). This is a signal that the synonym may be changed inside the newcommand (@ref{The Ampersand Syntax}). @end itemize When Gri finds a command that matches your command line, it assumes that this is the intended command, and searches no further. This means that you must be careful not to have your command hidden by other commands. For example, if your resource file contained these lines, Gri would @strong{never} execute the second new command, because calls to it match the first command. To avoid this, you may either reverse the order of the definitions, so that Gri will find the proper routine, or rename one of the routines. @example `Draw foo' Draw a foo. @{ show "drawing a foo" @} `Draw foo bar' Draw a foo bar. @{ show "drawing a foo bar" @} @end example Gri searches the @file{gri.cmd} file first, so any new command that you create that clashes with built-in commands will be ignored by Gri (@ref{Invoking Gri}). Gri will warn you of this, and proceed, ignoring your newer definition. To get around this, you can use capital letters to begin the words of your new command. By convention, Gri never uses capital letters in this way, so a clash is impossible (except with any similar command you might have defined previously, such as in your @file{~/.grirc} file). @c HTML @node Simple New Command, Complicated New Command, Parsing, Adding New Commands @comment node-name, next, previous, up @subsection Simple example of a new command @cindex new commands, simple example To make a new command called @code{Show The Time} insert the following into your @file{~/.grirc} resource file or into your command-file somewhere near the top, or at least before you use the command. @example `Show The Time' New command to show the time of day. @{ show "\.time." @} @end example @noindent EXPLANATION: @itemize @bullet @item The name of the new command is enclosed in angled single-quote marks. The words of the new command should begin with upper-case letters to prevent a name clash with a present or future built-in Gri command. @strong{Formatting convention:} Make sure that the entire definition string, from the opening angled quote to the ending angled quote, appears on one line. Otherwise Gri will give an error like @example ERROR: Can't extract syntax for new command @end example @item Following the name line, you may optionally insert any number of lines which will become the @code{help} information for the new command. See the file @file{gri.cmd} for the recommended stylistic conventions in writing help information (@ref{Invoking Gri}). If your @code{help} text includes an example that uses an opening brace (@code{@{}) you must escape the brace with a backslash, e.g. (@code{\@{}). @item Following the help lines, if they exist, the body of the new command is given, sandwiched between a starting line containing an opening brace (@code{@{}) as the @strong{only} nonwhite character, and an ending line containing a closing brace (@code{@}}) as the only nonwhite character. Any valid Gri commands may be used in the body of the new command. It is acceptable to use other new commands in the body. Recursion is also allowed -- a new command is allowed to call itself (although there is a limit on nesting, of perhaps a thousand or so; this varies with the version of Gri). @strong{Formatting convention:} It is usual, but not necessary, to use an indentation level of 2 spaces in the body of the new command. @end itemize @noindent The new command is invoked by @code{Show The Time}. Help for the command is found by @code{help Show The Time} or @code{help Show}. @c HTML @node Complicated New Command, Changeable Command Arguments, Simple New Command, Adding New Commands @comment node-name, next, previous, up @subsection Complicated example of a new command @cindex extending Gri by adding new commands, complicated example @cindex adding new commands, complicated example @cindex new commands, complicated example The following example from the global @file{gri.cmd} file illustrates how to parse/check the commandline (@ref{Local Synonyms}), which is a good practice in any code you expect to re-use. The first @code{if} statement checks that the word @code{at} is in the right place (this would not have been checked by the syntax matcher, the word having followed a string). The presence of the keyword @code{cm} is checked for, and user units or cm units are used accordingly. Local variables are created (@code{new}) and then destroyed (@code{delete}) so that this new command cannot affect outside code. @example `draw label whiteunder "\string" at .xleft. .ybottom. [cm]' Draw label for plot, located with lower-left corner at indicated (x,y) position (specified in user units or in cm on the page). Whiteout is used to clean up the area under the label. BUGS: Cannot handle angled text; doesn't check for super/subscripts. @{ if @{rpn "\.word4." "at" !=@} show "ERROR: 5th word must be `at', not `\.word4.'" show traceback quit end if new .x. .y. .oldgray. .space. if @{rpn \.words. 7 ==@} .x. = @{rpn \.word5. xusertocm@} .y. = @{rpn \.word6. yusertocm@} else if @{rpn \.words. 8 ==@} if @{rpn "\.word7." "cm" !=@} show "ERROR: Require 8th word to be `cm'" show traceback quit end if .x. = \.word5. .y. = \.word6. else show "ERROR: Require 7 or 8 words, not \.words." show traceback quit end if # Coordinates now in cm. Next, white out a box # under the text (and .space. centimetres # beyond text), then draw label. .space. = 0.1 # Space of 1mm .oldgray. = ..graylevel.. set graylevel white draw box filled \ @{rpn .x. .space. -@} \ @{rpn .y. .space. -@} \ @{rpn .x. "\.word3." width + .space. +@} \ @{rpn .y. "M" ascent + .space. + @} cm set graylevel .oldgray. draw label "\.word3." at .x. .y. cm delete .x. .y. .oldgray. .space. @} @end example @c HTML @node Changeable Command Arguments, The Ampersand Syntax, Complicated New Command, Adding New Commands @comment node-name, next, previous, up @subsection Altering command arguments -- the @code{&} syntax @cindex command arguments, how to alter @cindex newcommand arguments, how to alter @cindex arguments to new commands, how to alter @cindex the @code{&.variable.} notation @cindex the @code{&\synonym} notation @cindex variables, and the @code{&} syntax @cindex synonym, and the @code{&} syntax The Gri language permits a newcommand to change variables and synonyms passed as arguments, using a syntax that is quite similar to that employed by the C++ language. @menu * The Ampersand Syntax:: Denoting changeable arguments * Doubling A Variable:: Variables (e.g. @code{&.variable.}) * Manipulating A Synonym:: Synonyms (e.g. @code{&\synonym}) * Nesting:: Newcommands called by newcommands * Using New And Delete:: Isolating local variables and synonyms * Determining Calling Information:: The @code{\&.word?.} and @code{\&&.word?.} syntax * Implementation of Ampersand Syntax:: Algorithm Gri uses @end menu @node The Ampersand Syntax, Doubling A Variable, Changeable Command Arguments, Changeable Command Arguments @comment node-name, next, previous, up @subsubsection Overview of the @code{&} syntax Normally the arguments to a newcommand are parsed into either numerical values or strings, before execution is passed into the newcommand. This is a akin to the scheme called "call by value" in some programming languages. Gri also provides a syntax, borrowed from C++, that permits a newcommand to alter the contents of variable or synonym arguments. The technique is simple. To permit a newcommand to modify an argument that is a variable or a synonym, just put a @code{&} to the left of the item on the calling line. Then, within the newcommand, the corresponding local synonym (i.e. @code{\.word1.}, etc.) will behave as though it were the instance of the original variable or synonym. The @code{&} is placed to the left of the variable-name or synonym-name without intervening space. For example @code{foo &.var. &\syn} tells the parser that the newcommand named @code{foo} may possibly alter the values of the variable @code{.var.} and the synonym @code{\syn}, as they exist in the calling context. It is important to note that Gri pays very little attention to the @code{&} in a syntax-declaration line. All it does is to note that the item to the right of the @code{&} is not a fixed word in the newcommand being defined; this follows the usual rules for parsing newcommand syntax (@ref{Parsing}). @node Doubling A Variable, Manipulating A Synonym, The Ampersand Syntax, Changeable Command Arguments @comment node-name, next, previous, up @subsubsection Example: doubling a variable Consider the task of adding a fixed amount to a variable. If the variable we wish to double is @code{.x.}, we might write @example `double_a_particular_variable' @{ .x. = @{rpn .x. 2 *@} @} .x. = 10 double_a_particular_variable @end example @noindent Code such as that presented above occurs in many applications. (Turn the multiplication into an addition, and change @code{.x.} to @code{..ymargin..}, and you'll start to see the core of an application that draws multiple graph panels, one above another.) However, the code is too specific to be of much general use! What if we want to double some other variable instead? The code below shows how to do that. @example `double &.value.' @{ \.word1. = @{rpn \.word1. 2 *@} # line 3 @} .x. = 10 # line 5 double &.x. .y. = 3.14 double &.y. @end example @noindent At line 3 Gri interprets the @code{\.word1.} to the @strong{left} of the equals sign as a reference to the variable that is set to the value 10 in line 5. Similarly, the @code{\.word1.} to the @strong{right} of the equals sign evaluates to 10, the value in the calling program. Gri automatically determines whether an item is a variable or a synonym, and does the correct thing. Thus, for example, if line 3 above were written as @example \.word1. = "hello" # ERROR @end example @noindent an error would be reported, since @code{double} was called with a variable as an argument, and variables cannot hold strings. @node Manipulating A Synonym, Nesting, Doubling A Variable, Changeable Command Arguments @comment node-name, next, previous, up @subsubsection Example: manipulating a synonym Synonyms are treated in the same way, as is illustrated in the following example. @noindent Q: what does the following print? @example `add_a_dat &\filename' @{ \.word1. = @{rpn "\.word1." ".dat" strcat@} @} \filename = "test" add_a_dat &\filename show "\filename" @end example @noindent A: it prints @code{test.dat}. @node Nesting, Using New And Delete, Manipulating A Synonym, Changeable Command Arguments @comment node-name, next, previous, up @subsubsection Nesting One newcommand may call another, letting a deeply-nested newcommand alter values of synonyms and variables that may otherwise be hidden behind @code{new} items of the same name. This is done by using the @code{&} notation at each step. The following provides an example of passing a variable through two levels of newcommands. @noindent Q: what does the following print? @example `food critic &food' @{ \.word2. = "\.word2.s" yummy &\.word2. @} `yummy &foods' @{ \.word1. = "\.word1. are tasty" @} \a = "apple" food critic &\a show "\a" @end example @noindent A: it prints @code{apples are tasty}. @node Using New And Delete, Determining Calling Information, Nesting, Changeable Command Arguments @comment node-name, next, previous, up @subsubsection About @code{new} and @code{delete} @cindex @code{new}, used on changeable arguments @cindex @code{delete}, used on changeable arguments @cindex changeable arguments, using @code{new} on @cindex changeable arguments, using @code{delete} on If @code{new} and @code{delete} are executed on local synonyms inside newcommands (e.g. @code{new \.word1.}) they create and destroy variables and synonyms in the context of the @strong{calling program}. For example, consider the following. @noindent Q: what does the following print? @example `poetry &\s' @{ new \s # line 3 \s = "rose" \.word1. = "\.word1. is a \s" # line 5 delete \s # line 6 @} \s = "A rose " # line 8 poetry &\s show "\s" @end example @noindent A: it prints @code{A rose is a rose}. The key point here is that the instance of the synonym named @code{\s} in the calling program, set in line 8, is modified by the @code{poetry} newcommand, in line 6. This modification involves the use of a synonym, @strong{also named} @code{\s}, that "lives" wholly within the newcommand, being created in line 3 and destroyed in line 6. @node Determining Calling Information, Implementation of Ampersand Syntax, Using New And Delete, Changeable Command Arguments @comment node-name, next, previous, up @subsubsection Determining calling information @cindex @code{\&} and @code{\&&} notation @cindex newcommands, determining calling argument names with @code{\&} @cindex newcommands, determining calling argument level with @code{\&&} Newcommands may determine the name and the nesting level of changeable calling arguments. To get the name, put a single ampersand after the backslash of the local synonym of interest. To get the nesting level (0 for main program, etc.) put two ampersands after the backslash. @example `NC &.var.' @{ show "\&.word1. (expect '.a.')" show "\&&.word1. (expect 0)" @} .a. = 1 NC &.a. @end example @strong{Note}: neither of these items may be used an lvalue. That is, they may not be used to the left of an equals sign. But you can always get around that by clever use of alias synonyms (@ref{Alias Synonyms}). @node Implementation of Ampersand Syntax, Hints, Determining Calling Information, Changeable Command Arguments @comment node-name, next, previous, up @subsubsection How Gri implements the @code{&} syntax @cindex @code{&} syntax, how it is parsed @cindex parsing of the @code{&} syntax When the parser encounters an unquoted @code{&} followed immediately by the name of a variable or a synonym, it converts the whole token (@code{&} plus name) into a specially-encoded string that can be recognized inside newcommands. (This is @strong{only} done if the @code{&} and the variable name are @strong{not} enclosed in double quotes.) This specially-encoded string contains not just the name of the variable or synonym, but also the current level of nesting of newcommands. In this way a newcommand can have its own private versions of variables, created by @code{new}, that won't be misinterpreted for the identically-named variables in the calling program. The format of these specially-encoded strings is @code{#\bn\ba\bm\be\b:\bN \b_ \bl\be\bv\be\bl\b:\bL#\b}, where @code{N} stands for the name of the variable/synonym, @code{L} stands for the current level, and @code{\b} is the backspace character (hexadecimal 08 in the ascii table). This string is designed to be strange enough that users are unlikely to use it themselves. The coding scheme is not entirely arbitrary, however; note that if the backspace characters are ignored the result has the form @code{name:N_level:L}. It's also worth noting that if this string were printed on a terminal that erased characters when typing backspaces the result would be of the form @code{N_L}. Examples: @code{@.a.} in the main program (i.e. at level 0) encodes to @code{#\bn\ba\bm\be\b:\b.a. \b_ \bl\be\bv\be\bl\b:\b0#\b} and @code{&\my_syn} inside a newcommand called by the main program (i.e. at level 1) encodes to @code{#\bn\ba\bm\be\b:\b\my_syn \b_ \bl\be\bv\be\bl\b:\b1#\b}. Inside a newcommand, Gri checks to see if builtin synonyms (e.g. @code{\.word1.}) hold such specially-encoded strings. If so, then the appropriate versions of the variables are used in preference to any variables that may have been newly created by @code{new} inside the newcommand. @c HTML @node Hints, Debugging, Implementation of Ampersand Syntax, Programming @comment node-name, next, previous, up @section Hints for Gri Programming @cindex hints Here are some hints for good Gri programs: @itemize @bullet @item Whenever working with grids (for contouring) or images, make use of the @code{show grid} or @code{show image} commands. They will give you useful information about the statistics (min/max/histogram) of the items. @item Use the operating system, not Gri, to manipulate your data. For example, if you have a file whose first column is x times 100, and third is the arcsin of y, you could do: @example open "gawk '@{print $1/100, sin($3)@}' |" read columns x y @end example If you have x and y in a non-decimal geographical format (e.g. hour.minute-second format), use the operating system to convert for you (@ref{Open}). @item Use the @code{pstack} operator liberally in your rpn expressions to see what is going on (@ref{rpn Mathematics}). @item While developing programs, put a @code{show columns statistics} command after every @code{read column} command, to check that the data have been read correctly. @item Development time can be minimized by limiting the number of data being processed. For example, in a multi-panel plot, it is often necessary to try various alternatives before aesthetic scales and page layout is achieved. The process can be speeded up by limiting the number of data being processed, as shown below. (If Gri finds fewer data in the file than specified, it will simply use the data that it found; so when the program works, just change @code{.n.} into something large.) @example .n. = 100 # 10000 for later ... # Panel 1 read columns .n. x y ... # Panel 2 read columns .n. x y ... @end example @item Create new commands to do repetitive work. @item Use @code{draw time stamp} on all plots except for publication versions: @example if !..publication.. draw time stamp end if @end example @item For multiple panels on one page, do @code{delete x scale} or @code{delete y scale} before each new panel, so you will start afresh. Clearly identify code for particular panels with comments. This reduces errors you might get if you shuffle things later. @item Use the @code{..num_col_data..} built-in variable to see how many data have passed the @code{set input data window} data window in the last @code{read columns} command. The following example shows how to avoid drawing an unwanted curve: @example open \f read columns x y close if ..num_col_data.. draw curve draw label "\f" at \ @{rpn ..xlast.. xusertocm 0.5@} \ @{rpn ..ylast.. yusertocm 0.2@} cm end if @end example @cindex hint, using @code{query} to interact with user @item Use synonyms and @code{query} for filenames. This makes programs much more flexible. Note that you can string synonyms together: @example \dir = "~/EOS/iso0/" query \file "Give file in directory \dir" ("1.dat") open \dir/\file @end example It is also a good idea to give a restrictive list of possibilities in your @code{query} command, to avoid complicated @code{if} commands later (@ref{Query}). @item Use multiple @code{draw title} commands: @example draw title "Atlantic water entering Arctic Ocean" draw title "\.command_file. \.time." @end example @item Use the @code{query} command to interact with the user (@ref{Query}). The results can be stored in variables and synonyms. @end itemize @c HTML @node Debugging, Error Messages, Hints, Programming @comment node-name, next, previous, up @section Debugging Gri Programs @cindex debugging Gri programs @cindex problems and how to cope with them Here are some hints for debugging Gri programs: @itemize @bullet @item If no data appear on an xy plot, insert @code{show columns statistics} or @code{show columns} after the @code{read columns} command. It may be that you have fixed your axes, and that the axes frame does not include the data. @item @cindex tracing execution, using @code{..trace..} If you get an error message, rerun your Gri program using the @code{-trace} command-line option, to see which line is causing the problem. This often reveals logic errors (e.g. in (@code{if} statements). You may also turn tracing on or off at any point in your Gri program by setting the built-in variable @code{..trace..} to 1 or 0. Many Gri users have the Gri command aliased to be in trace mode by default. @item If Gri complains of a syntax error, consult the printed manual, one of the online manuals, or the online help facility (@ref{Online Help}). @item Check the version number (printed at startup) to see if a new version of Gri has been installed, and check the manual for known incompatabilities. @item Sprinkle @code{show} commands throughout your program, to see what's happening. Even when you are sure your program works, it is a good idea to embed @code{show} statements so are they executed if the @code{-debug} flag is set: @example if ..debug.. show "X=" .x. "and label is `\label'" end if @end example @item If your @code{draw} commands don't draw anything, check to see whether you've fooled yourself by enforcing an improper scaling; remove explict scaling (@code{set x axis ...}), clipping (@code{set clip}), data selection windows (@code{set input data window x|y}) and missing values (@code{set missing value}). Another trick is to read only a portion of the data set (@code{read columns 10 x y}) and then print out all the values (@code{show columns}). @end itemize If you determine that the bug is in Gri, not in your program, please report the bug, so that other users will not have the same hassle; (@ref{Reporting Bugs}). @c HTML @node Error Messages, Missing Values, Debugging, Programming @comment node-name, next, previous, up @section Error Messages @cindex error messages Gri error messages are in three types: @enumerate @item Operating system error messages, such as @code{segmentation fault}. These should never appear, and indicate a bug in Gri. Please report these to the author (@ref{Reporting Bugs}). @item Internal Gri error messages. The message starts with the words @code{FATAL error}, and quotes a file number and a line number, e.g. @example FATAL error: startup.c:199: ... @end example @noindent Such errors indicate either a deficiency in your computer (e.g. insufficient storage space) or an internal bug in Gri. If the message does not indicate running out of storage, please report the error to the author (@ref{Reporting Bugs}). For fatal error messages on a unix system, Gri dumps core, unless you have turned that feature off, with the @code{ulimit -c 0} unix command in a startup file. This creates a file called @file{core}, which can help you in diagnosing the Gri bug. If you have the @code{gdb} debugger, just type @code{gdb gri core} and then type @code{where} to get a traceback stack. Please email this with your other information about the Gri bug. @item An indication that your commandfile is flawed, either in syntax or in meaning. These messages end with a line indicating the offending line in your commandfile, e.g. the command @code{set x axis 0 1 -1} yields: @example ERROR: `set x axis .left. .right. .incBig.' has .incBig. of wrong sign Bad command: `set x axis 0 1 -1 ' @end example @noindent Normally, such error messages do not indicate a flaw in Gri, but rather in your reasoning, so report them to the author only if you are very sure that a Gri bug must underly them. @end enumerate @c HTML @node Missing Values, Operating System, Error Messages, Programming @comment node-name, next, previous, up @section Missing data @cindex data, missing values @cindex missing value code @cindex NaN for missing value code @vindex @code{..missingvalue..}, value for missing data Most Gri commands will ignore data points equal to a "missing value." For example, @code{draw curve} connects only points which are not equal (to within 0.01 percent) of the missing value. The curve has holes at missing data. Initially the missing-value is set to 1.0e22. You may alter this value with @code{set missing value .value.}. The built-in variable @code{..missingvalue..} stores the current value of the missing-value. Additionally, Gri will ignore anything it reads that is equal to the string @code{NaN} or @code{Inf}. These are produced by matlab, C, and other programs when dividing by zero, etc. Gri also ignores mathematical operations on data items which are equal to the missing value. Thus, for example, if your missing value is -99 then the command @code{x += 1} will not change the values equal to -99 to -98, since this would have the side-effect of making the datum no longer be considered missing. @c HTML @node Operating System, Using OS Inside Gri, Missing Values, Programming @comment node-name, next, previous, up @section Interaction Between Gri and Operating System @cindex awk, sample of use @cindex operating system commands, printing results of @cindex system commands, printing results of @cindex operating system commands, assigned to synonyms @cindex system commands, assigned to synonyms @menu * Using OS Inside Gri:: Accessing the OS from inside Gri * Using Gri Inside OS:: Tricks for using Gri in unix @end menu @node Using OS Inside Gri, Using Gri Inside OS, Operating System, Operating System @comment node-name, next, previous, up @subsection Using the OS from within Gri Gri uses the operating system internally for things like paging through help information. @cindex system calls, using dollar-parenthesis shell syntax @cindex protecting Gri programs against datafile movement @cindex unix, dollar-parenthesis notation within Gri commands @cindex @code{\$()} syntax for system commands @cindex dollar-parenthesis syntax for system commands The operating system may be called @strong{within} Gri commands, using a syntax borrowed from the @code{Bash} unix shell. After substituting synonyms in the commandline, Gri scans for dollar-parenthesis blocks (e.g. @code{\$(system-command)}, replacing them with the textual result of sending the indicated system-command to the OS. The replacements are done from left to right in the commandline, starting at the deepest nesting level. @cindex pathname of commandfile @cindex commandfile, pathname Often the dollar-parentheis syntax is used in title commands, to indicate the full pathname of the Gri commandfile, e.g. @example draw title "\$(pwd)/\.command_file." @end example In assignment to synonyms, expansion of dollar-parenthesis is not done. Thus the operating system is called twice on the second line below, and not at all on the first line; to see this, run it as @code{gri -s8 -t}. @example \dir = "\$(echo $MY_DIR)" show "\$(head -1 \dir/MY_FILE)" @end example @strong{Syntax Note} Dollar-parenthesis blocks must be prefixed with backslash to avoid confusion with math expressions within strings, for example to avoid breaking @code{draw label "$(x,y)$" at 3 3 cm}. This is an example of how @TeX{} notation and unix shell notation collide. @strong{Example} It is a good idea to employ unix environment variables to name directories containing data, so that Gri scripts will work unchanged even if the data are moved (so long as the environment variables are altered), e.g. @cindex using environment variables for directory names @cindex strings, embedding OS output into @cindex OS, embedding system output into strings @cindex calling OS from within strings @example # Figure how many lines in a file \dir ="$(echo DIRECTORY_WHERE_I_STORE_SOLAR_DATA)" open "\dir/solar_data_file_name` ... open "\$(echo DIR_ANOTHER)/another_data_set" @end example @noindent Another method is to pass instructions to the operating system with the @code{system} command. This discards output. Whatever follows the word @code{system} is first scanned for synonyms (but not rpn expressions or variables); after replacement of any existing synonyms, the line is passed directly to the operating system. Any results are printed on the terminal. Frequently used system commands are @code{awk}, @code{head}, @code{grep} and @code{sed}. Examples: @itemize @bullet @item Here's how to paste several files together to form a temporary file for plotting. (Notice that a temporary file incorporating the PID of the job is created and later removed.) @example system paste -d" " 1.dat 2.dat 3.dat > tmp.\.pid. open tmp.\.pid. read columns x y close system rm tmp.\.pid. @end example @item Here's how to plot each line in a file called @file{inp} which has the string @code{;} at the start of the line. @example system cat inp | grep -v "^;" | cat > tmp.\.pid. open tmp.\.pid. read columns x y system rm tmp.\.pid. @end example @item Here's how to use the @code{awk} system command to create a tabulated function for plotting. @example system awk \ 'BEGIN @{ \ for (x=0; x<1; x+=0.1) @{ \ printf ("%f %f\n", x, sin(x)) \ @} \ @}' \ > tmp.\.pid. open tmp.\.pid. read columns x y close system rm tmp.\.pid. draw curve @end example @cindex pipes, opening files through them @cindex opening files through pipes @noindent This example is more cleanly written using the piping facility of the @code{open} command (which automatically creates a temporary file, and destroys it when @code{close} is done) @example open "awk 'BEGIN @{ \ for(x=0;x<1;x+=0.1) @{ \ print(x,sin(x)) \ @} \ @}'|" read columns x y close draw curve @end example @item Sometimes you need just a single output item from the operating system. In this case, you can store the results from the operating system in a synonym by using the @code{\synonym = system ...} assignment command. @item @cindex temporary file allocation @cindex file, temporary @cindex filename, temporary @cindex @code{tmpname} subroutine A related command is @code{\synonym = tmpname}, which stores in the synonym the name of a temporary file created by the system. The file is created with the @code{tmpname} system call, so it is guaranteed not to clash with any existing files. Typically, the filename is something like @file{/usr/tmp/griAAAa1233}. In many cases you'll want to remove the file within Gri, once you're done, and that can be done with @code{unlink} (@ref{Unlink}) or with a @code{system rm -f} command. A useful bit of code is as follows @example \file = tmpname system ... SOME_SYSTEM_COMMANDS ... > \file ... use this new file for something ... unlink \file @end example @end itemize @node Using Gri Inside OS, Resource File, Using OS Inside Gri, Operating System @comment node-name, next, previous, up @subsection Using Gri from within the OS @strong{This section only applies to unix systems.} Save the following into a file called @file{p} and then make it executable using @code{chmod}. It runs Gri on a named file, with the @code{-yes} flag set so that any @code{query} commands are automatically answered in the affirmative, and then displays the results in a Ghostscript window. (USAGE: @code{p cmdfile.gri}) @example #!/usr/bin/sh # Run Gri, then plot in gs window case $# in 1) base=`basename $1 .gri | sed -e s/.*,#` gri -yes $base.gri && ghostview $base.ps ;; *) echo "Proper usage: $0 cmdfile.gri" ;; esac @end example @c HTML @node Resource File, Environment, Using Gri Inside OS, Programming @comment node-name, next, previous, up @section Sample Resource File @cindex files, @file{~/.grirc} initialization file @cindex @file{~/.grirc} initialization file @cindex initialization commands @cindex startup commands @cindex resource files The following shows a sample @file{~/.grirc} resource file. Much of the code here is adding new commands (@ref{Adding New Commands}.) @example # Some folks like tics to point inwards ... set tics in # Hey, I'm bored with Helvetica font, and # Palatino is a bit prettier than Times set font to PalatinoRoman # Now for something a bit less trivial. # This lets me draw a set of y-values # against a single x-value, by e.g. # open xyyy.dat # draw curves time T1 T2 T3 # where the first column of the file is # time, and the others are temperatures # at various sensors. `draw curves \xname \y1name ...' Draw multiple y columns versus an x column. Assumes that the datafile is open, and that x is in the first column, with the y values in one or more following columns. The number of columns is figured out from the options, as is the name of the x-axis, and the labels to be used on each of the y curves. @{ # NB. the 3 below lets us skip the words 'draw' # and 'curves', and the name of the x-column. .num_of_y_columns. = @{rpn wordc 3 -@} if @{rpn .num_of_y_columns. 1 >@} show "ERROR: `draw curves' needs at least 1 y column!" quit end if set x name @{rpn 2 wordv@} set y name "" # Loop through the columns. .col. = 0 while @{rpn .num_of_y_columns. .col. <@} # The x-values will be in column 1, with y-values # in columns 2, 3, ..., of the file. .ycol. = @{rpn .col. 2 +@} rewind read columns x=1 y=.ycol. # At this point, you may want to change line thickness, # thickness, color, dash-type, etc. For illustration, # let's set dash type to the column number. set dash .col. draw curve draw label for last curve @{rpn .col. 3 + wordv@} .col. += 1 end while @} @end example @c HTML @node Environment, Extras, Resource File, Top @comment node-name, next, previous, up @chapter Environment Gri comes with a few ancillary programs that may be useful. Gri also provides a simple scheme to use other system tools (e.g. @code{awk}). These are discussed here. And speaking of discussing, this chapter ends with a note about a mail-list Gri discussion group. @menu * Extras:: Extra things provided with Gri * Using System Tools:: Using Gri with other tools * Discussion Group:: Gri email list @end menu @c HTML @node Extras, gri_merge, Environment, Environment @comment node-name, next, previous, up @section Extra things provided with Gri @menu * gri_merge:: Merge files to one page * gri_unpage:: Separate multipage doc into separate files @end menu @node gri_merge, gri_unpage, Extras, Extras @comment node-name, next, previous, up @subsection @code{gri_merge} -- combine PostScript files @cindex gri_merge Merge separate PostScript files, created by Gri, into one page. To learn how it works, type @code{gri_merge -h} at the system prompt, to see: @example PURPOSE: Strings Gri PostScript files together. BUGS: With old versions, of gri, make sure to match each `set clip postscript on' with a `set clip postscript off'. USAGE (style 1): gri_merge [OPTIONS] CxR a.ps b.ps ... > merged_file.ps Merges the files onto one page, in 'C' columns and 'R' rows. The C*R files are given in the order of words on a page. The page is presumed to be 8.5x11 in size, as are all the input files, and the input files are sized to fit, and kept in natural scale. USAGE (style 2): gri_merge [OPTIONS] xcm ycm enlarge a.ps [b.ps ...] > merged_file.ps Where `enlarge' is a scale factor applied after offsetting `xcm' to the right and `ycm' upward. EXAMPLE (style 2): The following gri_merge 2 12 .5 a.ps \ 12 12 .5 b.ps \ 2 2 .5 c.ps \ 12 2 .5 d.ps > all.ps produces 4 panels from gri plots done using margins and sizes as specified in the following lines in a gri commandfile set x margin 2 set x size 15 set y margin 2 set y size 15 The OPTIONS, available if your 'perl' has 'getopts' library, are: -u graylevel -- set graylevel for underlay beneath panels, by default 0.75. Values range from 0 (black) to 1 (white), although a value of precisely 1 means do NOT draw underlay. -b graylevel -- Set value for background under individual panels, again 0 for black to 1 for white, with 1 meaning no drawing. -h -- Print this help message and quit. @end example @node gri_unpage, Using System Tools, gri_merge, Extras @comment node-name, next, previous, up @subsection @code{gri_unpage} -- split pages into files @cindex gri_unpage Given a multipage PostScript file, @code{gri_unpage} creates several new PostScript files, one for each page. To learn how it works, type @code{gri_unpage -h} at the system prompt, to see: @example PURPOSE: Chop multipage Gri PostScript file into one file per page. USAGE: gri_unpage name.ps -- create files name-1.ps, name-2.ps, etc, one for each page of name.ps. gri_unpage -h -- print this help message BUGS: 1. Bounding box is always 8.5x11 inches. 2. Assumes that all Gri fonts are used even if they aren't. @end example @c HTML @node Using System Tools, Why Use The Environment, gri_unpage, Environment @comment node-name, next, previous, up @section Using System Tools With Gri Using system tools to manipulate your data makes sense for several reasons. First, you may be familiar with those tools already. Second, learning these tools will help you in all your work. @menu * Why Use The Environment:: Introduction * Grep:: Search files for patterns * Sed:: Serial editor * Awk:: Search and manipulate data * Perl:: Search and manipulate data @end menu @node Why Use The Environment, Grep, Using System Tools, Using System Tools @comment node-name, next, previous, up @subsection Introduction Each of the programs listed in the sections below is available for Unix. Some (e.g. Perl and the Awk variant called Gawk) are available on other operating systems as well. Each of these tools is fully documented in Unix manpages, so here I'll just give an indication of a couple of useful techniques you might want to use. Bear in mind that these tools can do very similar jobs. For example, Awk can do much of what Sed and Grep can do, but also a whole lot more. If you don't know Sed or Grep, I suggest you learn Awk instead. Then again, Perl can also do anything Gawk can do, and a whole lot more! (For one thing, it is easier to work with multiple files in Perl.) In fact, Perl is the most powerful of this list. If you know none of these tools, you might want to learn Perl instead of the others. But Perl is more complicated for simple work than Awk is, so the most reasonable path might be to learn both Awk and Perl. For simple applications, you will probably want to use these tools in a piped open command, e.g. @example open "awk '@{print $1, $3/$2@}' MyFile |" @end example @noindent which creates a temporary file (automatically erased when Gri finishes) which contains the output from running the system command that preceeds the pipe symbol (@code{|}) (@ref{Open}). (Here and in all the examples of this chapter, it is assumed that the user's input file is named @file{MyFile}.) For more complicated appplications, you may use the Gri @code{system} command as follows. @example system perl >tmp <<"EOF" open(IN, "MyFile"); while() @{ ($x, $y) = split; print "$x", " ", cos($y), "\n"; @} EOF open tmp read columns x y draw curve system rm -f tmp @end example @noindent Here a temporary file, named @file{tmp}, has been used to store the results of the calculation. Note that this file was specifically cleaned up by the second @code{system} command. (Many folks, including the author, would prefer to take the perl script out of the above and make it a standalone executable script, calling it from Gri with the one-line form. But it is just a matter of style.) @node Grep, Sed, Why Use The Environment, Using System Tools @comment node-name, next, previous, up @subsection Grep @cindex grep system tool @cindex overview of grep system tool The most common application of Grep is to select lines matching a pattern, or not matching a pattern. Here is how to skip all lines with the word "HEADER" in them: @example open "grep -v 'HEADER' MyFile |" ... @end example @noindent Note that Gawk and Perl do this just as easily. @node Sed, Awk, Grep, Using System Tools @comment node-name, next, previous, up @subsection Sed @cindex sed system tool @cindex overview of sed system tool Sed is normally used for simple changes to files. For example, if you have columnar data which are separated with comma characters instead of whitespace, you could make it Gri compatible by @example open "sed -e 's/,/ /g' MyFile |" @end example @noindent Where the @code{-e} flag indicates that the next item is a command to Sed, in this case a command to switch ("s") the comma character with the blank character, globally ("g") across each line of the file. See also the overview of Perl. @node Awk, Perl, Sed, Using System Tools @comment node-name, next, previous, up @subsection Awk @cindex awk system tool @cindex gawk system tool @cindex overview of awk system tool Awk is great for one-liners. If your system lacks Awk, you can procure the GNU version, called Gawk, from the web for free. For better or worse, Gawk is not fully compatible with Awk. The good thing is that Gawk is pretty much the same on all operating systems, whereas the installed Awk may not be. I use Gawk instead of Awk, for this reason and because it is normally faster. The main concept in Awk is of "patterns" and "actions." In the Awk syntax, actions are written in braces following patterns written with no braces. (This will become clear presently.) Whenever a line in the data file matches the pattern, the action is done. The default pattern is to match to every line in the file. This is done if no pattern is supplied. The default action is to print the line, and this is done if no action is supplied. Here are a few examples. To skip first 10 lines of a file: @example open "awk 'NR>10' MyFile |" read ... @end example @noindent Here the pattern was that @code{NR} (a special Awk variable for the number of the record, starting with 1 for the first line of the file) exceeded 10. And the action was taken by default since nothing was supplied between braces, to print this line. @noindent To plot the cosine of the second column against the first column: @example open "awk '@{print ($1, cos($2))@}' MyFile |" read columns x y draw curve @end example @noindent Here no pattern was supplied, so the action was done for every line. Combining these two forms, then, and supplying both a pattern and an action, here is how one might print the first and eighth columns of the file @file{MyFile}, but only for the first 10 lines of the file: @example open "awk NR<=10 @{print ($1, $8)@} MyFile |" @end example @node Perl, Discussion Group, Awk, Using System Tools @comment node-name, next, previous, up @subsection Perl @cindex perl system tool @cindex overview of perl system tool Perl can do almost @strong{anything} with your data, since it is a full programming language designed to also emulate several Unix utilities. In perl, as in other commands, the commandline switch @code{-e} indicates that a Perl command is given in the next word of the command line. The commandline switch @code{-p} indicates to print the line, after any indicated Perl actions have been done on it. Here, for example, is how one would emulate a Sed replacement of comma by blank: @example open "perl -pe 's/,/ /g' MyFile |" @end example Perl also has a commandline switch @code{-a} indicating that lines should be "autosplit" into an array called @code{$F}. The first element of this array is @code{$F[0]}. Splitting is normally done on white-space character(s), although this may be changed if desired. Here, for example, is how to take the cosine of the second column of a file, and print this after the first column: @example open "perl -pea 'print($F[0], cos($F[1]))' MyFile |" @end example @c HTML @node Discussion Group, Emacs Mode, Perl, Environment @comment node-name, next, previous, up @cindex discussion Group @cindex email list @section Gri Discussion Group Before emailing to the Gri newsgroup, it is a good idea to consult the @c HTML @c HTML FAQ @c HTML list of answers to Frequently Asked Questions. As of summer 2000, Gri traffic has been moved to the web-based discussion groups at the SourceForge website @url{http://gri.sourceforge.net} about which little need be said here, because the website is very easy to use. @c HTML @node Emacs Mode, About Gri Mode, Discussion Group, Top @comment node-name, next, previous, up @chapter Editing Gri Files in GNU Emacs @cindex gri code, editing @cindex editing Gri code with Emacs @cindex emacs, editing mode for Gri @cindex gri-mode, editing in emacs If you use the GNU Emacs (or XEmacs) text editor, writing Gri command files is made easier with the Gri editing mode (gri-mode.el), written by Peter S. Galbraith @c HTML @code{}. @c HTML @menu * About Gri Mode:: * Gri-mode screenshots:: What it looks like. * Installing gri-mode.el:: The nuts and bolts. * Major Gri-mode commands:: It knows about Gri commands. * Other features:: IMenu, Toolbar, etc. * Dealing with many Gri versions:: gri-mode handles it. * Filename arguments when running gri:: gri-set-command-postarguments. @end menu @c HTML @node About Gri Mode, Gri-mode screenshots, Emacs Mode, Emacs Mode @comment node-name, next, previous, up @section About Gri Mode Gri mode has all the wonderful things you've come to expect from Emacs modes. Here's a brief overview of the features: @itemize @bullet @item It can @strong{complete} partially typed commands, builtin variables and synonyms (@code{gri-complete}, @key{M-Tab}) and help you edit the syntax that was thus inserted for you (@code{gri-option-select}, @kbd{C-c C-o}; @code{gri-option-kill}, @kbd{C-c C-k}). @item It can provide a short help synopsis concerning the command on the current line (@code{gri-help-this-command}, @kbd{C-c C-h}), or load the info manual for that command (@code{gri-info-this-command}, @kbd{C-c C-i}). It knows the list of all Gri commands, and can provide help or info regarding any of them (@code{gri-help}, @kbd{C-c M-h}; @code{gri-info}, @kbd{C-c M-i}) using command name completion at the prompt (@key{Tab}). @item All Gri commands are listed in a pull-down menu from the menubar, which you can use to either enter the text of the selected command, or obtain help or info about it. @item It can help you find an unknown command by listing all containing a given word (@code{gri-apropos}, @kbd{C-c C-a}). @item It fontifies your Gri code using colour coding. @item It indents if statements, loops, and so on (@code{gri-indent-line}, @key{Tab}). @item It can let you run Gri and view its output without leaving the editor (@code{gri-run}, @kbd{C-c C-r}). If an error is encountered, Emacs will rearrange the buffer so the cursor is on the bad line of the Gri command-file. @item If you've already run Gri, and therefore have a PostScript output file, the mode will let you view that file (@code{gri-view}, @kbd{C-c C-v}) even if that file is compressed. @end itemize @noindent Thus one never has to leave Emacs; type @kbd{C-c C-r} to run Gri, and if there is no error, the graph comes up automatically. If there was an error, gri-mode will move editing point to the line with the error and display the error message. Given that the mode can complete partially typed commands, this means a substantial saving in development time. Inside gri-mode, type @kbd{C-h m} for help on the mode, including a list of all commands and key definitions. @c HTML @node Gri-mode screenshots, Screenshot 1, About Gri Mode, Emacs Mode @comment node-name, next, previous, up @section Gri-mode screenshots, what it looks like. @cindex gri-mode, screenshots @cindex screen snapshots, using Gri @cindex snapshots of computer screen, using Gri @comment Now handle PostScript version @iftex In the first screenshot, the user has entered the text @code{set font} and has pressed @key{M-Tab} twice to see the list of possible completions. The @file{*Completions*} buffer is displayed in a separate frame because the user is using the @file{framepop.el} add-on package. A similar effect can be obtained using @code{special display} buffers in Emacs. @image{./screenshots/gri-screenshot-1, 400pt} Here, the user has selected the command @code{set font to} and, forgetting what valid font name could be used, then invoked @kbd{C-c C-h} to get help about that command. The user found the needed information and finished typing in `Helvetica'. @image{./screenshots/gri-screenshot-2, 400pt} Here we see the user cascading through the Gri commands pull-down menu until @code{draw axes} is reached. @image{./screenshots/gri-screenshot-3, 400pt} With the output previewed in a @code{gv} window after pressing @kbd{C-c C-v}, the user is ready to print the file using a pull-down menu. @image{./screenshots/gri-screenshot-4, 400pt} @end iftex @comment Now handle more complicated HTML version @c @ifhtml @comment First the index images pointing to new HTML files. @c HTML

    @c HTML @c HTML Possible completions to `set font'. @c HTML gri-mode displays possible completions to entered text. @c HTML
    @c HTML

    @c HTML @c HTML Displaying Help about current command. @c HTML gri-mode displays help about the current command. @c HTML
    @c HTML

    @c HTML @c HTML Cascading the command pull-down menu. @c HTML The pull-down menu listing all gri commands. @c HTML
    @c HTML

    @c HTML @c HTML Getting set to print the PostScript output. @c HTML The `Perform' menu to run gri, preview, print... @c HTML
    @c HTML

    @comment Next, generate these new HTML files (sneaky). @menu * Screenshot 1:: * Screenshot 2:: * Screenshot 3:: * Screenshot 4:: @end menu @c HTML @node Screenshot 1, Screenshot 2, Gri-mode screenshots, Gri-mode screenshots @comment node-name, next, previous, up @subsection Screenshot 1 @c HTML In the first screenshot, the user has entered the text @code{set font} and has pressed @key{M-Tab} twice to see the list of possible completions. The @file{*Completions*} buffer is displayed in a separate frame because the user is using the @file{framepop.el} add-on package. A similar effect can be obtained using @code{special buffers} in Emacs. @c HTML @c HTML @node Screenshot 2, Screenshot 3, Screenshot 1, Gri-mode screenshots @comment node-name, next, previous, up @subsection Screenshot 2 @c HTML Here, the user has selected the command @code{set font to} and, forgetting what valid font name could be used, then invoked @kbd{C-c C-h} to get help about that command. The user found the needed information and finished typing in `Courier'. Meanwhile, an idle timer displays the default setting for this command in the minibuffer after a few seconds of inactivity. @c HTML @c HTML @node Screenshot 3, Screenshot 4, Screenshot 2, Gri-mode screenshots @comment node-name, next, previous, up @subsection Screenshot 3 @c HTML Here we see the user cascading through the Gri commands pull-down menu until @code{draw axes} is reached. This menu can be used to display Info (or help) about a given command, or to insert the selection. The default is Info. This menu is a good way to browse for a command when you don't exactly remember its name. @c HTML @c HTML @node Screenshot 4, Installing gri-mode.el, Screenshot 3, Gri-mode screenshots @comment node-name, next, previous, up @subsection Screenshot 4 @c HTML With the output previewed in a @code{gv} window after pressing @kbd{C-c C-v} (or pressing the @code{gv} icon in the toolbar, or selecting it from the @code{Perform} pull-down menu), the user is ready to print the file, here using the @code{Perform} pull-down menu. @c HTML @c @end ifhtml @c HTML @node Installing gri-mode.el, Step 1, Screenshot 4, Emacs Mode @comment node-name, next, previous, up @section Installing gri-mode.el, the nuts and bolts. @cindex gri-mode, installing The Emacs @file{gri-mode.el} file is now bundled with gri, so odds are you already have it. If not, you will find it at gri's web site @c HTML http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/gri/gri/gri-mode.el @c HTML The following installation steps appear a @strong{bit} complicated. That's only because gri has changed how it gets installed a few times, and gri-mode.el works with all of these various methods. If you use gri from a Linux package (Debian or Red Hat) or if you compiled it yourself using the default configuration, you won't need to do much. To install @file{gri-mode.el}, follow these 4 steps. If gri-mode is already installed, you can skip the first two steps and move on to the last two, in which you tell Emacs that you'd like to use Gri mode when you edit files that end in @file{.gri}, the Gri suffix. (Actually, if you're using Debian linux, you can skip all of these steps since the system will assume that you want gri-mode if you're editing a Gri file.) @menu * Step 1:: Placing gri-mode.el where Emacs can find it. * Step 2:: Configuring gri-mode to where gri lives on your system. * Step 3:: Telling emacs to load gri-mode * Step 4:: Extra user configuration of gri-mode. @end menu @node Step 1, Step 2, Installing gri-mode.el, Installing gri-mode.el @comment node-name, next, previous, up @subsection Placing gri-mode.el where Emacs can find it. @cindex gri-mode, Placing gri-mode.el where Emacs can find it. (Those using gri from gri's @strong{RPM} package, a @strong{Debian} package or a @strong{Red Hat} package users can skip this, as it is done for them) Extra @file{.el} files like @file{gri-mode.el} that are not part of Emacs should be stored in a directory where Emacs will find them when you ask it to load them. The files should therefore be found in Emacs' @strong{load-path}. To see the directory list currently in the load-path, do this in Emacs: @example C-h v load-path @end example If you have access to system directories, put gri-mode.el in a @strong{site-lisp} directory, such as @file{/usr/local/share/emacs/site-lisp/} That way all users will have access to the files. If you don't have access to a site-lisp directory (e.g. you have only a user account), then create a directory where your extra @file{.el} files will be stored and add it to Emacs' load-path. For example, say you created the directory @file{~/emacs} and stored gri-mode.el there, you would then put this near the top of your @file{~/.emacs} file: @example (setq load-path (cons "~/emacs" load-path)) @end example @node Step 2, Step 3, Step 1, Installing gri-mode.el @comment node-name, next, previous, up @subsection Telling gri-mode where gri resides @cindex gri-mode, Configuring gri-mode to where gri lives on your system (Those using gri from gri's @strong{RPM} package, a @strong{Debian} package or a @strong{Red Hat} package users can skip this, as it is done for them) You may skip this section if gri is installed on your system as @file{/usr/local/bin/gri-@value{GRI-VERSION}} and @file{/usr/local/share/gri/@value{GRI-VERSION}/gri.cmd} (the default when compiling gri yourself). If not, then you may need to set the Emacs variable @code{gri*directory-tree} in a startup file such as in your @file{~/.emacs} file. The Emacs variable @code{gri*directory-tree} is used to configure gri-mode to tell it where Gri is installed on your system. For the default gri installation paths used in this gri release, gri-mode expects to find the gri executable and the file gri.cmd as: @code{gri*directory-tree/@value{GRI-VERSION}/gri.cmd} and @code{/usr/local/bin/gri-}@value{GRI-VERSION} where @code{gri*directory-tree} is by default set to @file{/usr/local/share/gri/}. If you have only one version of gri installed on your system, gri-mode will also look to find @file{gri.cmd} and the gri executable like so: @enumerate @item Gri executable in the PATH, with startup file @file{gri*directory-tree/gri.cmd}. @item Gri executable in the PATH, with startup file @file{gri*directory-tree/lib/gri.cmd}. @item Gri executable @code{gri*directory-tree/bin/gri}, with startup file @code{gri*directory-tree/lib/gri.cmd}. @end enumerate However, gri-mode was designed to support, and ease the use of, @strong{multiple installed versions} of gri. To use this feature, you must use the gri version number as a directory name under the @code{gri*directory-tree} path, like this: @example gri*directory-tree/VERSION/bin/gri gri*directory-tree/VERSION/lib/gri.cmd @end example (e.g. @file{/opt/gri/2.040/bin/gri} and @file{/opt/gri/2.040/lib/gri.cmd} with @code{gri*directory-tree} set to @code{"/opt/gri"}) or without the @strong{lib} and @strong{bin} subdirectories if the executable is found in the PATH named like @file{gri-VERSION} (This is the way Debian packages are set up): the file @file{gri*directory-tree/VERSION/gri.cmd} and the @file{gri-VERSION} executable in the PATH (e.g. @file{/usr/share/gri/2.1.18/gri.cmd} and @file{/usr/bin/gri-2.1.18} with @code{gri*directory-tree} set to @code{"/usr/share/gri"}) @strong{Important note:} You may have more than one tree and make a list of them: @example (setq gri*directory-tree '("/opt/gri/" "/usr/share/gri/")) @end example @strong{Examples:} @enumerate @item If you use a RedHat package installed like: @example /usr/bin/gri /usr/share/gri/gri.cmd @end example @noindent then you'd also use: @example (setq gri*directory-tree "/usr/share/gri/") @end example but gri-mode would know of only one installed version of gri. @item If you use a Debian GNU/Linux installation like: @example /usr/bin/gri -> /usr/bin/gri-2.1.18 /usr/share/gri/2.1.18/gri.cmd @end example @noindent then you'd use: @example (setq gri*directory-tree "/usr/share/gri/") @end example Note that all gri binaries must exist in the path with version number suffixes (e.g. @file{gri-2.1.18}) since there is no @file{/usr/share/gri/2.1.18/bin/} directory (using a similar structure to @file{opt/gri} below) where gri-mode can find the binary corresponding to a given version number. @item If you had multiple versions of Gri installed like so (this reflects the installation paths used in older gri releases): @example /opt/gri/2.040/bin/gri /opt/gri/2.040/lib/gri.cmd /opt/gri/2.041/bin/gri /opt/gri/2.041/lib/gri.cmd @end example then you'd use: @example (setq gri*directory-tree "/opt/gri/") @end example @end enumerate @node Step 3, Step 4, Step 2, Installing gri-mode.el @comment node-name, next, previous, up @subsection Telling emacs to load gri-mode @cindex gri-mode, Telling emacs to load gri-mode (Those using a @strong{Debian} package can skip this, as it is done for them) To tell emacs to use this mode with @file{.gri} files, you can load gri-mode whenever a new emacs session is starting by adding the following line to your @file{~/.emacs} file: @example (require 'gri-mode) @end example This is a good method when you only start emacs once a week and use it for every file you edit (as you should). If you startup a fresh emacs every time you edit then you probably only want to load gri-mode into emacs when you need it. In that case, instead of the @code{require} statement above, add the following lines to your @file{~/.emacs} file: @example (autoload 'gri-mode "gri-mode" "Enter Gri-mode." t) (setq auto-mode-alist (cons '("\\.gri$" . gri-mode) auto-mode-alist)) @end example The first line tells Emacs that it will find out what it needs to know about running the command @code{M-x gri-mode} by loading the file @file{gri-mode.el}. The second line tells it to run the command @code{M-x gri-mode} when a file with extension @file{.gri} is visited (thus using gri-mode with all those files). @node Step 4, Major Gri-mode commands, Step 3, Installing gri-mode.el @comment node-name, next, previous, up @subsection Extra user configuration of gri-mode @cindex gri-mode, Extra user configuration of gri-mode @strong{All users should do this at some time.} At this point, gri-mode should start up when you edit a gri file. You may optionally customize gri-mode by: @enumerate @item using the Custom interface (see the Help or Gri-Help menu or run the command @code{M-x gri-customize}), or @item manually setting variables in your @file{~/.emacs} file. These are briefly described by typing @kbd{C-h m} while in gri-mode. Then, for further infomation, use emacs' @code{describe-variable} command, bound to @kbd{C-h v}. For example, for more information about the @code{gri*WWW-program} variable, you'd type @code{C-h v gri*WWW-program} (note that emacs does @key{Tab} completion, so pressing the @key{Tab} key after typing-in gri will display all gri related variables.) @end enumerate @c HTML @node Major Gri-mode commands, Gri command names, Step 4, Emacs Mode @comment node-name, next, previous, up @section Major Gri-mode commands. @cindex gri-mode, major commands This section describes the major gri-mode commands, briefly showing how they can increase your productivity. @menu * Gri command names:: How gri-mode names all gri commands. * Possible completions:: A list of all valid commands matching so far. * Command abbreviations:: Abbreviating many words at one time. * Variable completion:: Completion of builtin variable and synonyms. * Editing the syntax:: What to do after gri-complete. * User commands:: gri-mode knows about ~/.grirc. * Gri code fragments:: Use them as short-cuts. * Info interface:: Getting help about the current command. @end menu @c HTML @node Gri command names, Possible completions, Major Gri-mode commands, Major Gri-mode commands @comment node-name, next, previous, up @subsection How gri-mode names Gri commands @cindex gri-mode, gri command names @cindex gri-mode, how it names gri commands A major feature of Gri mode is the completion of partially typed commands. Let's examine how gri-mode decides to name gri commands. A name is determined by removing bracketed options from the syntax line of a given command. This is different from what the gri parser does. In this way, the gri command @example draw label "\string" [centered|rightjustified] at .x. .y. [cm] [rotated .deg.] @end example @noindent is named by gri-mode simply @code{draw label at}. Note how the `at' stays in the name because it is not optional. So when you see @code{draw label at} in gri-mode's menus or prompts, you are more likely to associate the name with what the command actually does. @c HTML @node Possible completions, Command abbreviations, Gri command names, Major Gri-mode commands @comment node-name, next, previous, up @subsection Possible completions of gri command names @cindex gri-mode, possible completions When you press @key{M-tab} to complete a command name (or a variable or synonym name as described below), gri-mode will expand it as much as it can and do nothing further. If you type in nothing more and insist by using @code{gri-complete} (@key{M-tab}) again, gri-mode will respond by showing all possible completions in the @file{*completions*} buffer. In this way you can use @code{gri-complete} word-by-word to abbreviate commands without ever displaying completions, like you would for file completion in emacs or bash. If a completion is ambiguous, but could be exact, invoke gri-complete a second time to complete it. e.g. @example sh@key{M-tab} @end example @noindent expands to @example show @end example @noindent and informs you that 12 possible completions exists; then @example show@key{M-tab} @end example @noindent will display these completions in the completions buffer; then typing @key{M-tab} again forces completion to a complete but not unique possibility: @example show .value.|@{rpn ...@}|"\text" [.value.|@{rpn ...@}|text [...]] @end example Completions are shown immediately (without invoking gri-complete again) if the completions window is already displayed or if there are 3 possibilities or less. In this case they are displayed in the minibuffer. Note: The @file{*completions*} window is deleted after a command is fully completed. @code{gri-complete} uses its own @file{*completions*} buffer, which is not displayed in the buffer-list to avoid clutter. @c HTML @node Command abbreviations, Variable completion, Possible completions, Major Gri-mode commands @comment node-name, next, previous, up @subsection Command name abbreviation @cindex gri-mode, command name abbreviation gri-mode uses command name abbreviations in a non-Unix way in that all words that compose the command name may be abbreviated (and not only the word preceding the cursor). For example, one can type in @example dr x a@key{M-tab} @end example @noindent and it will expand1 all the words to @example draw x axis [at bottom|top|@{.y. [cm]@} [lower|upper]] @end example This is reminiscent of VMS, which the author was used to when gri-mode.el was initially created. It's likely that a gri-mode.el rewritten from scratch wouldn't have this feature since it's not part of the Unix mindset. @c HTML @node Variable completion, Editing the syntax, Command abbreviations, Major Gri-mode commands @comment node-name, next, previous, up @subsection Variable (and synonym) completion @cindex gri-mode, variable completion @cindex gri-mode, sysnonym completion It's also possible to do @key{M-tab} completion on gri builtin variable and synonym names while editing a command. Simply type in the leading @code{.} (dot) or @code{\} (slash) character and invoke completion with @key{M-tab}. For example, @example ..x@key{M-tab} @end example @noindent displays a completions buffer listing the possible completions: @example ..xmargin.. ..xsize.. ..xleft.. ..xright.. ..xlast.. @end example @noindent Typing in an extra @code{m} will complete to @code{..xmargin..} and the following help information will be displayed in the minibuffer: @example margin to left of axis area. Default is 6 cm. @end example @c HTML @node Editing the syntax, User commands, Variable completion, Major Gri-mode commands @comment node-name, next, previous, up @subsection Editing the syntax output by gri-complete @cindex gri-mode, editing gri syntax You might wonder what to do with all the bracketed code left behind by @code{gri-complete}. It certainly won't go through the gri parser without error, so you have to edit it out. The tools provided in gri-mode are @code{gri-option-select} (@kbd{C-C C-o}) and @code{gri-kill-option} (@kbd{C-C C-k}) to narrow in on a particular gri command, given a syntax description left on the line by @code{gri-complete}. The cursor location is used to decide which gri command(s) to narrow to. For example, if @code{gri-complete} is used on the line `dr x a', the result will be a line like @example draw x axis [at bottom|top|@{.y. [cm]@} [lower|upper]] @end example This is the gri way of describing many commands at once. The above syntax description is a shortcut formulation for all of: @example draw x axis draw x axis at bottom draw x axis at bottom top draw x axis at bottom bottom draw x axis at top draw x axis at top top draw x axis at top bottom draw x axis at .y. cm draw x axis at .y. cm lower draw x axis at .y. cm upper @end example The @code{gri-option-select} (@kbd{C-C C-o}) command provides easy navigation to select one of these commands. The narrowing process is governed by the cursor position. For example, to get the command narrowed down to @example draw x axis at bottom [lower|upper] @end example @noindent place the cursor somewhere in the word `bottom' and invoke @code{gri-option-select}. To complete the narrowing process, selecting @example draw x axis at bottom lower @end example @noindent move the cursor to some place in the word `lower' and invoke @code{gri-option-select again}. On the other hand, to get @example draw x axis at bottom @end example @noindent you would have put the cursor over either the word `lower' or `upper', and invoke @code{gri-kill-option} (@kbd{C-C C-k}) instead. You might want to practice using this example to learn how to do it. If you make a mistake, note that the normal Emacs undo works. @c HTML @node User commands, Gri code fragments, Editing the syntax, Major Gri-mode commands @comment node-name, next, previous, up @subsection User commands with gri-mode @cindex gri-mode, user-defined commands User gri commands defined in @file{~/.grirc} (@ref{Resource File}) or at the beginning of a gri file can also be used with @code{gri-complete}. Note that user commands are added from the current buffer whenever `gri-mode' is invoked. They may override previous user commands, but not gri system commands. @c HTML @node Gri code fragments, Info interface, User commands, Major Gri-mode commands @comment node-name, next, previous, up @subsection Inserting gri code fragments in Emacs @cindex gri-mode, gri code fragments @cindex gri-mode, enter chunks of code with short-cuts Since gri version 1.063, gri has special commands that begin with a question mark `?'. These special commands have no options, and are composed only of standard gri commands. Their purpose is to provide a short-cut for entering many lines of gri at once (e.g. bits of sample code about contouring grids, or your own preamble which you use at the time to set fonts and line widths). @code{gri-complete} acts in a special way with these commands, by replacing the abbreviated name which you are completing by all the lines contained within the gri command. The user is allowed to define new fragments in @file{~/.grirc}, and also to override the gri system fragments. You can therefore fine-tune gri's fragments to your taste. To see the names of all gri fragments, type in a question mark at the beginning of a line in a gri buffer and press @key{M-Tab} twice to @code{gri-complete} it and display possible choices. The gri commands used to replace them are found in the @file{*gri-syntax*} buffer. @c HTML @node Info interface, Other features, Gri code fragments, Major Gri-mode commands @comment node-name, next, previous, up @subsection Info interface for help on current command @cindex gri-mode, Info interface The Info system is built into Emacs (@kbd{C-h i}), and provides an easy method of navigation on-line help (including this manual). We suggest that you install the gri info files on your system (they are already installed with packaged versions of gri in Debian or Red Hat formats). Not only will Info (@kbd{C-h i}) be able to navigate through all of gri's inline manual, but gri-mode's function @code{gri-info-this-command} (@kbd{C-c C-i}) will display the correct info page about the gri command being edited on the current line. Additionally, gri-mode has the command @code{gri-info} (@kbd{C-c M-i}) which will prompt you (using @key{tab} completion) for any command to list Info about. There's also a menu-bar pull-down menu which lists all gri commands, and you can get to Info from that too. @c HTML @node Other features, Dealing with many Gri versions, Info interface, Emacs Mode @comment node-name, next, previous, up @section Other features of gri-mode @cindex gri-mode, imenu support @cindex gri-mode, toolbar @itemize @bullet @item @code{IMenu support}: IMenu is a GNU/Emacs package used to source code files. It can be setup for a particular mode to list a menu of function definitions and variable declarations. In gri-mode, the IMenu is available from the menubar and provides links to @code{new command declarations} as well as value settings for @code{variables} and @code{synomyns}. @item @code{Toolbar support}: XEmacs21 and Emacs-21 have support for a toolbar (a set of iconic buttons that are shortcuts for commands), however the two editors don't not have compatible toolbar setups. Currently gri-mode only defines a single icon for XEmacs (to run gri on the current buffer) and defines three for GNU/Emacs (to run gri, to view the postscript file, and to lookup Info about the command on the current line). @item @code{Idle Help}: When GNU/Emacs sits idle with the cursor on a command line, it looks up any defaults the command may have and displays the information in the minibuffer. For example, sitting on a line that says @code{set font size 10}, it will display @code{set font size: default is 12 point in variable ..fontsize..}. @end itemize @c HTML @node Dealing with many Gri versions, Filename arguments when running gri, Other features, Emacs Mode @comment node-name, next, previous, up @section Dealing with many Gri versions, gri-mode handles it. @cindex gri-mode, handling multiple Gri versions Earlier we explained that you might have many versions of gri installed on your system (@ref{Installing gri-mode.el}). You may use gri-mode to access these various versions with the following gri-mode commands: @itemize @bullet @item @code{gri-set-version}: Tells gri-mode to use a given version as the default for all your gri files. Tab completion is available listing all available versions (if they are not all listed, that means that the Emacs variable @code{gri*directory-tree} is not correctly set (@ref{Installing gri-mode.el})). Your selection is stored in the file @file{~/.gri-using-version} and is remembered across editing sessions. If you select @strong{default} as your answer, gri-mode reverts to using the default version of gri as installed on your system (which may change after you update it) and deletes the @file{~/.gri-using-version} file. @item @code{gri-set-local-version}: Tells gri-mode to use a given version of gri @strong{this} gri file (the one currently being edited when you invoke the command). Tab completion is again available to list all available versions. Your selection overrides the default version selected by @code{gri-set-version} for this file, and is stored as an Emacs variable at the bottom of the gri file. It is remembered across editing sessions. If you select @strong{default} as your answer, gri-mode reverts to using the default version of gri as selected by @code{gri-set-version} and deletes the Emacs variable setting at the bottom of the gri file. @end itemize @c HTML @node Filename arguments when running gri, History, Dealing with many Gri versions, Emacs Mode @comment node-name, next, previous, up @section Filename arguments when running gri @cindex gri-mode, handling filename command arguments @cindex gri-mode, handling argv and argc Usually, gri is run specifying only a gri command file to process, which lends itself well to the gri-mode command @code{gri-run}. But Gri can be also invoked from the command line using optional arguments, usually filenames but not necessarily, e.g. @example $ gri somefile.gri datafile.dat datafile2.dat ... @end example @noindent or @example $ gri somefile.gri *.dat @end example The arguments are accessed with RPN operators @file{argc} and @file{argv} (@ref{Unary Operators}). gri-mode provides a method to set the arguments (usually filenames) to use when @code{gri-run} is called in a specific gri script. Use the gri-mode command @code{gri-set-command-postarguments} to setup a string that gri-mode will use, and the gri-mode command @code{gri-unset-command-postarguments} to clear it. For ease-of-use, these commands are made available from the menubar under the @code{Perform -> Run Settings} entries. The specified string will be stored in the locally-defined (aka buffer-local) variable @code{gri-command-postarguments} and will be written within a gri comment at the bottom of the file such that Emacs remembers it across editing sessions. @c HTML @node History, Stable Stream, Filename arguments when running gri, Top @comment node-name, next, previous, up @chapter History of Gri Versions Gri, like many modern software projects, has two ``streams'' of development running side by side. One is called ``stable,'' the other ``unstable.'' @emph{Most users should use the stable stream}, which has been well tested. (The unstable version is for users who wish to try out new features that are under development.) Stable versions always have an even number as the middle number in their version designation, e.g. @code{2.6.0}, while unstable versions always have an odd number there, e.g. @code{2.7.0}. This middle number indicates a sort of family of related releases. Within a stable stream, all versions sharing a given middle number have the same features; new releases are made only to fix bugs. Thus, version @code{2.6.1} fixed bugs in version @code{2.6.0}. To learn more about the bugs, and their resolution, visit the bugs page at @uref{http://sourceforge.net/tracker/?func=browse&group_id=5511&atid=105511,gri.sourceforge.net} and adjust the "status" menu to read "closed". @menu * Stable Stream:: * Unstable Stream:: * Deprecated Commands:: @end menu @c HTML @node Stable Stream, Version 2.12, History, History @comment node-name, next, previous, up @section Stable Stream In any given stable stream, only the version with a @code{0} as the last number in the triplet has new features; the later versions only correct flaws. For example, version @code{2.6.0} offers new features compared to any of the @code{2.4.x} versions, but @code{2.6.1} differs only in the fixing of bugs. @menu * Version 2.12:: * Version 2.10:: * Version 2.8:: * Version 2.6:: * Version 2.4:: * Version 2.2:: @end menu @c HTML @node Version 2.12, Version 2.10, Stable Stream, Stable Stream @comment node-name, next, previous, up @subsection Version 2.12 @cindex version 2.12 @comment ADD-NEW-BUG-FIXES-HERE @subsubsection Version 2.12.26 [2017 January 27 @uref{https://en.wikipedia.org/wiki/Martyrs%27_Day_(India), Martyrs' Day (India)}] @strong{Bug fixes} @itemize @bullet @item @dots{} prevent some problems in debian build process @end itemize @subsubsection Version 2.12.25 [2015 July 24 @uref{https://en.wikipedia.org/wiki/Pioneer_Day_(Utah), Pioneer Day (Utah)}] @strong{Bug fixes} @itemize @bullet @item @dots{} prevent some problems in debian build process @end itemize @subsubsection Version 2.12.24 [2013 August 9 @uref{http://en.wikipedia.org/wiki/International_Day_of_the_World%27s_Indigenous_People, International Day of the World's Indigenous People}] @strong{Bug fixes} @itemize @bullet @item @dots{} obey commandline argument naming postscript file (debian bug 719033) @end itemize @subsubsection Version 2.12.23 [2011 July 6 @uref{http://en.wikipedia.org/wiki/Malawi, Malawai Independence Day}] @strong{Bug fixes} @itemize @bullet @item @uref{https://sourceforge.net/projects/gri/forums/forum/16975/topic/4596628/index/page/1} @dots{} @code{pgm} images grayscale was wrong @end itemize @subsubsection Version 2.12.22 @strong{Bug fixes} @itemize @bullet @item Fix github bug @uref{http://github.com/dankelley/gri/issues#issue/5} @dots{} @code{draw image} failed on some black/white images @end itemize @subsubsection Version 2.12.21 [2010 June 8 @uref{http://en.wikipedia.org/wiki/World_Oceans_Day, World Ocean Day}] @strong{Bug Fixes} @itemize @bullet @item Fix github bug @uref{http://github.com/dankelley/gri/issues#issue/1} @dots{} @code{convert grid to image directly} misplaced image ``patches'' by one patch width and one patch height @end itemize @subsubsection Version 2.12.20 [2010 April 9 @uref{http://en.wikipedia.org/wiki/Vimy_Ridge_Day, Vimy Ridge Day}] @strong{New Features} @itemize @bullet @item add @code{labelling} option to @code{set x axis} and @code{set y axis}. @item add @code{directly} option to @code{convert grid to image}. @end itemize @strong{Bug Fixes} @itemize @bullet @item Fix SourceForge bug @uref{https://sourceforge.net/forum/forum.php?thread_id=2913919&forum_id=16974,#2913919} @dots{} SVG: all symbols are "." @item Fix SourceForge bug @uref{https://sourceforge.net/forum/forum.php?thread_id=2913893&forum_id=16974,#2913893} @dots{} svg segfault on draw label @item Fix SourceForge bug @uref{https://sourceforge.net/forum/forum.php?thread_id=2913841&forum_id=16974,#2913841} @dots{} svg draw box filled not filled @item Fix SourceForge bug @uref{https://sourceforge.net/forum/forum.php?thread_id=2913840&forum_id=16974,#2913840} @dots{} svg images are upside-down @item Fix SourceForge bug @uref{https://sourceforge.net/forum/forum.php?thread_id=2913838&forum_id=16974,#2913838} @dots{} image postscript clip problem @end itemize @subsubsection Version 2.12.19 [2009 July 17 @uref{http://en.wikipedia.org/wiki/World_Day_for_International_Justice, World Day for International Justice}] @strong{New Features} @itemize @bullet @item Fix SourceForge ``bug'' @uref{https://sourceforge.net/forum/forum.php?thread_id=2977816&forum_id=16974,#2977816} @dots{} Fedora packaging requires more precise license declarations. @end itemize @strong{Bug Fixes} @itemize @bullet @item Fix SourceForge bug @uref{https://sourceforge.net/forum/forum.php?thread_id=3266884&forum_id=16974,#3266884} @dots{} error in docs for strlen. @end itemize @subsubsection Version 2.12.18 [2008 Sep 8 @uref{http://en.wikipedia.org/wiki/International_Literacy_Day, International Literacy Day}] @strong{Bug Fixes} @itemize @bullet @item Improve security of temporary-file handling. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=1985862&group_id=5511&atid=105511,#1985862} @dots{} SVG output had axis linewidth equal to curve line width. @end itemize @subsubsection Version 2.12.17 [2008 May 29 @uref{http://en.wikipedia.org/wiki/Oak_Apple_Day, Oak Apple Day (England)}] @strong{New Features} @itemize @bullet @item Add GNU readline support so that interactive mode will have history, command editing, etc. @end itemize @strong{Bug Fixes} @itemize @bullet @item Fix SourceForge bug @uref{https://sourceforge.net/tracker/?func=detail&atid=105511&aid=1913577&group_id=5511,#1913577} @dots{} superscripts did not end correctly, if preceeded by an inline @code{@{@}} block. @item Fix SourceForge bug @uref{https://sourceforge.net/tracker/index.php?func=detail&aid=1761562&group_id=5511&atid=105511,#1761562} @dots{} y axis name printed upside down, for log axes in which user specified a high values at the bottom end of the axis @end itemize @subsubsection Version 2.12.16 [2007 Jul 20 @uref{http://en.wikipedia.org/wiki/Apollo_11, anniversary of the first moon landing}] @strong{Bug Fixes} @itemize @bullet @item Fix Debian bug @uref{http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=130802,#130802} @dots{} postscript problem in landscape mode, refreshed in gv viewer @item Fix Debian bug @uref{http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=434010,#434010} @dots{} @code{set page landscape} requires @code{set page size} first, but it should really default to something reasonable instead. @end itemize @subsubsection Version 2.12.15 [2007 Apr 16 @uref{http://en.wikipedia.org/wiki/Mawlid, celebration of birthday of Muhammad}] @strong{Bug Fixes} @itemize @bullet @item Fix SourceForge bug @uref{https://sourceforge.net/tracker/index.php?func=detail&aid=1700978&group_id=5511&atid=105511,#1700978} @dots{} html concept index mostly broken @item Fix SourceForge bug @uref{https://sourceforge.net/tracker/index.php?func=detail&aid=1698924&group_id=5511&atid=105511,#1698924} @dots{} box plots show missing data @item Fix Debian bug #417217 @dots{} will not compile in GCC 4.3 @item Fix SourceForge bug @uref{https://sourceforge.net/tracker/index.php?func=detail&aid=1698116&group_id=5511&atid=105511,#1698116} @dots{} poorly-positioned name of RHS y-axis @end itemize @subsubsection Version 2.12.14 [2007 Jan 08: @uref{http://en.wikipedia.org/wiki/Seijin_shiki, Coming-of-Age Day (Japan)}] @strong{Bug Fixes} @itemize @bullet @item Fix SourceForge bug @uref{https://sourceforge.net/tracker/index.php?func=detail&aid=1630768&group_id=5511&atid=105511,#1630768} @dots{} Fix to segfault in clipped images (a bug that may have developed after version 2.13.3) @end itemize @subsubsection Version 2.12.13 [2006 Nov 06: @uref{http://en.wikipedia.org/wiki/Public_holidays_in_Tajikistan, Constitution Day (Tajikistan)}] @strong{Bug Fixes} @itemize @bullet @item Fix SourceForge bug @uref{https://sourceforge.net/tracker/index.php?func=detail&aid=1591475&group_id=5511&atid=105511,#1591475} @dots{} Fix to compile in Solaris CC @item Fix SourceForge bug @uref{https://sourceforge.net/tracker/index.php?func=detail&aid=1591062&group_id=5511&atid=105511,#1591062} @dots{} Fix to compile in OpenBSD @end itemize @subsubsection Version 2.12.12 [2006 July 16: @uref{http://en.wikipedia.org/wiki/Yellow_Pig%27s_Day,Yellow Pigs Day}] @strong{Bug Fixes} @itemize @bullet @item Fix SourceForge bug @uref{https://sourceforge.net/tracker/index.php?func=detail&aid=1523033&group_id=5511&atid=105511,#1523033} @dots{} Malloc error (freeing something already freed?) @item Fix SourceForge bug @uref{https://sourceforge.net/tracker/index.php?func=detail&aid=1523032&group_id=5511&atid=105511,#1523032} @dots{} @code{create columns from function} bug, if there is an existing directory called @code{tmp}. @item Fix SourceForge bug @uref{https://sourceforge.net/tracker/index.php?func=detail&aid=1491105&group_id=5511&atid=105511,#1491105} @dots{} @code{set x axis labels} had no affect for log axes (same for y) @end itemize @subsubsection Version 2.12.11 [2006 Mar 30: Hindu New Year] @strong{Bug Fixes} @itemize @bullet @item Fix SourceForge bug @uref{https://sourceforge.net/tracker/index.php?func=detail&aid=1449546&group_id=5511&atid=105511,#1449546} @dots{} x axis limits not correctly inferred from @code{set x grid} (same for y). @end itemize @subsubsection Version 2.12.10 [2006 Jan 26: Australia Day] @strong{Bug Fixes} @itemize @bullet @item Fix SourceForge bug @uref{https://sourceforge.net/tracker/?func=detail&atid=105511&aid=1408259&group_id=5511 ,#1408259} @dots{} PostScript file contained private information. This was fixed by adding new commandline arguments @code{-private} and @code{-no_private}, the former of which (the new default) means to not include the user's name, the invocation arguments, or the command-file contents (@ref{Invoking Gri}). @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=12851803&group_id=5511&atid=105511,#1285180} @dots{} NaN was mishandled. (The bug may have arisen in version 2.12.7 or thereabouts.) @item Port to the @uref{http://www.freebsd.org/,FreeBSD} operating system, with help from Christopher Illies and Roman Neuhauser. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=1217273&group_id=5511&atid=105511,#1217273} @dots{} missing some version numbers within docs @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=1196613&group_id=5511&atid=105511,#1196613} @dots{} user-supplied x-axis labels can run offscale (fix for y-axis later...) @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=1198341&group_id=5511&atid=105511,#1198341} @dots{} x-axis labels incorrectly rotated (sometimes) @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=1199280&group_id=5511&atid=105511,#1199280} @dots{} warning about @code{malloc} for RPN assignments @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=1196115&group_id=5511&atid=105511,#1196115} @dots{} @code{gri_unpage} and @code{gri_merge} mis-installed @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=1153209&group_id=5511&atid=105511,#1153209} @dots{} Emacs mode incompatible with new version of @code{gv} PostScript viewer Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=1101172&group_id=5511&atid=105511,#1101172} @dots{} @code{gri -help} incorrectly stated meaning of last argument(s) @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=835711&group_id=5511&atid=105511,#835711} @dots{} @code{draw gri logo} fails. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=1098269&group_id=5511&atid=105511,#1098269} @dots{} problem compiling on AMD64 machine. (Solution provided by Andreas Jochens, a Debian user.) @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=867515&group_id=5511&atid=105511,#867515} @dots{} problem with junk appearing in images. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=875881&group_id=5511&atid=105511,#875881} @dots{} problem compiling with gcc 2.95.3 compiler. @end itemize @subsubsection Version 2.12.9 [2005 Jan 6: @uref{http://en.wikipedia.org/wiki/Epiphany_%28feast%29,Feast of Epiphany}] @strong{Bug Fixes} @itemize @bullet @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=1094087&group_id=5511&atid=105511,#1094087} @dots{} @code{set path to} incorrectly parsed colon-separated paths @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=1085788&group_id=5511&atid=105511,#1085788} @dots{} @code{image *=}, @code{image /=}, @code{image ^=}, and @code{image _=} all gave incorrect results @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=1084123&group_id=5511&atid=105511,#1084123} @dots{} does not compile in fink @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=676767&group_id=5511&atid=105511,#676767} @dots{} on fink systems, @code{help} does not work @end itemize @subsubsection Version 2.12.8 [2004] @strong{Bug Fixes} @itemize @bullet @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=1019141&group_id=5511&atid=105511,#1019141} @dots{} @code{draw arc} ignores the present pen color @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=997741&group_id=5511&atid=105511,#997741} @dots{} PostScript broken on images with y-axis decreasing, and enclosed by PostScript clipping @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=978822&group_id=5511&atid=105511,#978822} @dots{} documentation wrong on @code{set path to} @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=932203&group_id=5511&atid=105511,#932203} @dots{} misplaced labels caused by @code{set x axis labels} @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=928277&group_id=5511&atid=105511,#928277} @dots{} @code{draw polygon} should take @code{cm} and @code{pt} units @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=930259&group_id=5511&atid=105511,#930259} @dots{} fix @code{draw arc}'s drawing of an extra line (thanks for the fix, Wolfgang Voegeli) @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=923719&group_id=5511&atid=105511,#923719} @dots{} @code{draw curve overlying} ignored the effect of @code{set dash} @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=914125&group_id=5511&atid=105511,#914125} @dots{} offpage points in axes were reported as having been drawn by @code{draw curve}. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=877613&group_id=5511&atid=105511,#877613} @dots{} @code{help} (and other commands using temporary files) does not work in OSX/Fink version. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=874483&group_id=5511&atid=105511,#874483} @dots{} @code{state save} doesn't keep track of @code{dash} settings. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=873245&group_id=5511&atid=105511,#873245} @dots{} inaccurate times are given in the warnings about slow operations on OSX platform (days are reported instead of seconds) @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=871477&group_id=5511&atid=105511,#871477} @dots{} the `missing value' feature should not be the default. The solution involved adding a new command @code{set missing value none}, which is now the default. @end itemize @subsubsection Version 2.12.7 [2003 Sep 4] @strong{Bug Fixes} @itemize @bullet @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=800022&group_id=5511&atid=105511,#800022} AKA Debian bug @uref{http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=208589,#208589}, @dots{} did not build on some Debian platforms because it was based on an old version of @code{automake}. @end itemize @subsubsection Version 2.12.6 [2003 Sep 1: Labour Day] @strong{New Features} @itemize @bullet @item Add @code{age} RPN function, for testing file ages (@ref{age-rpn-operator}). @end itemize @strong{Bug Fixes} @itemize @bullet @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=773850&group_id=5511&atid=105511,#773850} @dots{} bounding-box is increased by @code{draw symbol} even if (rectangular) postscript clipping is active. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=760130&group_id=5511&atid=105511,#760130} @dots{} Solaris cannot compile with @key{C-l} in Makefile. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=743134&group_id=5511&atid=105511,#743134} @dots{} bounding box not limited by @code{set clip postscript} @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=750561&group_id=5511&atid=105511,#750561} @dots{} during compilation, @code{make} rebuilds HTML docs even if up-to-date @end itemize @subsubsection Version 2.12.5 [2003 May 19: Victoria Day] @strong{New Features} @itemize @bullet @item Apply a patch provided Kawamura Masao, relating to (a) errors in the documentation of file locations and (b) a programming error hidden behind an unset precompiler flag. @item Add hexadecimal colornames (@ref{pen-color-hexadecimal}). @end itemize @strong{Bug Fixes} @itemize @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=739761&group_id=5511&atid=105511,#739761} @dots{} @code{draw time stamp} named the command-file incorrectly @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=720607&group_id=5511&atid=105511,#720607} @dots{} the emacs mode looked for html documentation files in an incorrect location on linux/redhat systems @end itemize @subsubsection Version 2.12.4 [2003 Apr 06] @strong{Bug Fixes} @itemize @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=696073&group_id=5511&atid=105511,#696073} @dots{} did not handle @code{\$()} syntax correctly. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=715884&group_id=5511&atid=105511,#715884} @dots{} mixup on protected-quotes within double-quoted strings @item Fix Debian bug @uref{http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=183912,#183912} @dots{} would not compile on m86k architecture. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=711354&group_id=5511&atid=105511,#711354} @dots{} @code{Creator:} comment in PostScript file named the command-file incorrectly, if there were options on the gri invocation command. Since this naming of the command-file was not especially useful, and since nobody has complained of this bug but the author, the feature has simply been deleted. Just complain if you want it back! @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=706202&group_id=5511&atid=105511,#706202} @dots{} A hint about the page orientation was not given in the Postscript comments. The lack of this hint has no affect on printing, etc., only viewing in some viewers. @end itemize @subsubsection Version 2.12.3 [2003 Mar 1] @strong{Bug Fixes} @itemize @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=685919&group_id=5511&atid=105511,#685919} @dots{} @code{-output} commandline argument failed on @file{.eps} file extension. @end itemize @subsubsection Version 2.12.2 [2003 Feb 7: Munro Day at @uref{http://www.dal.ca/,Dalhousie University}] @strong{Bug Fixes} @itemize @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=675304&group_id=5511&atid=105511,#675304} @dots{} Segmentation fault can occur on @code{read image pgm} if an image already exists, e.g. created by @code{convert grid to image}. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=647234&group_id=5511&atid=105511,#647234} @dots{} Source file @file{draw.cc} will not compile on MAC OS X 10.1.5 at optimization level 2, so drop the level to no optimization, as a temporary measure. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=671022&group_id=5511&atid=105511,#671022} @dots{} @code{flip image x|y} did not flip images correctly, except in special circumstances. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=669603&group_id=5511&atid=105511,#669603} @dots{} @code{skip backward .n.} erroneously skipped forward @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=667754&group_id=5511&atid=105511,#667754} @dots{} @code{read image pgm} segfaults on memory if an image has already been created by @code{convert grid to image} @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=664388&group_id=5511&atid=105511,#664388} @dots{} @code{read image pgm} fails if an image already exists @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=654129&group_id=5511&atid=105511,#654129} @dots{} ignoring @file{~/.grirc} file @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=654127&group_id=5511&atid=105511,#654127} @dots{} configure scripts are broken @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=649132&group_id=5511&atid=105511,#649132} @dots{} removed unused LDFLAGS phrase from Makefile @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=649134&group_id=5511&atid=105511,#649134} @dots{} tweak gcc optimization @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=649136&group_id=5511&atid=105511,#649136} @dots{} examples 8 and 9 broken @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=641406&group_id=5511&atid=105511,#641406} @dots{} RPN too aggressive on missing values @end itemize @subsubsection Version 2.12.1 [2002 Sep 25] @strong{Bug Fixes} @itemize @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=613075&group_id=5511&atid=105511,#613075} @dots{} RPN operators @code{sin}, @code{cos}, and @code{tan} were limited in range (new bug in last release) @end itemize @subsubsection Version 2.12.0 [2002 Sep 15: @uref{http://www.terryfox.org/,Terry Fox Day}, Canada.] @strong{New Features} @itemize @bullet @item Add @code{sed} RPN operator, to work on strings @ref{Binary Operators}. @item Add @code{skewness} and @code{kurtosis} RPN operators, to work on columns @ref{Manipulation of Columns etc}. @end itemize @strong{Removed Features} @itemize @item n/a @end itemize @strong{Bug Fixes} @itemize @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=606303&group_id=5511&atid=105511,#606303} @dots{} web-pages were not valid html-4.0. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=593958&group_id=5511&atid=105511,#593958} @dots{} missing-values should be ignored if they occur in intermediate results of RPN calculations. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=600395&group_id=5511&atid=105511,#600395} @dots{} won't compile with recently released version (3.2) of GCC compiler. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=600223&group_id=5511&atid=105511,#600233} @dots{} segfaults if some RPN operators are used on stacks that do not contain enough entries (e.g. @code{show @{rpn cosh@}}). @end itemize @c HTML @node Version 2.10, Version 2.8, Version 2.12, Stable Stream @comment node-name, next, previous, up @subsection Version 2.10 @cindex version 2.10 @subsubsection Version 2.10.1 [2002 Jun 1] @strong{Bug Fixes} @itemize @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=562911&group_id=5511&atid=105511,#562911} @dots{} won't build with @file{gcc-3.0} compiler. This was reported by the Debian hppa builder as Debian bug @uref{http://bugs.debian.org/148572,#148572}. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=562558&group_id=5511&atid=105511,#562558} @dots{} @code{draw title} terminates program if have non-positive data and had initially specified log axes. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=562014&group_id=5511&atid=105511,#562014} @dots{} won't build if @code{popt} library is unavailable. This was reported by the Debian ia64 builder as Debian bug @uref{http://bugs.debian.org/148493,#148493}. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=558463&group_id=5511&atid=105511,#558463} @dots{} in HTML docs, the ``press'' margin tag was misdirected. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=562017&group_id=5511&atid=105511,#562017} @dots{} parser fails with DOS end-of-line. @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=562113&group_id=5511&atid=105511,#562113} @dots{} @code{new page} postscript error in @file{gv} viewer. @end itemize @subsubsection Version 2.10.0 [2002 May 20: Victoria Day] @strong{New Features} @itemize @bullet @item In the documentation, change the names of some variables to be clearer: @code{ll_x} is now written @code{xleft}, etc. @item Add RPN binary operators @code{and}, @code{or} for logical operations @ref{Binary Operators}, along with negation operator @code{not} @ref{Unary Operators}. @item Add @code{draw arc} command (@ref{Draw Arc}). @item Add @code{set x axis labels} (@ref{Set X Axis}) and @code{set y axis labels} (@ref{Set Y Axis}) commands. @item Permit specification of @code{pt} units for @code{draw label} (@ref{Draw Label}), @code{draw box} (@ref{Draw Box}), @code{draw symbol at} (@ref{Draw Symbol At}), and @code{draw line from} (@ref{Draw Line From}). @item Add @code{set clip to curve} (@ref{Set Clip}) command. @emph{Caution:} this needs extension, and may have a bug if called twice in succession [but is this with an intervening @code{set clip off}] @item Add @code{group} and @code{end group} commands, in preparation for SVG output. So far these commands do nothing, and are basically just a signal that users should not create commands with these names since Gri will need them soon. @item Add @code{..xinc..} and @code{..yinc..} builtin variables (@ref{Axis Scaling}). @item Make the @code{open} command accept URLs as filenames (@ref{Open}). @end itemize @strong{Removed Features} @itemize @item Remove @code{gri -repair old.ps new.ps} since (a) it was only half functional, (b) it was hard to code in the new scheme of argument-processing and (c) the author was not aware of anybody every having used it. @item Make the @code{-chatty} commandline option require a value (@ref{Invoking Gri}). @end itemize @strong{Bug Fixes} @itemize @item Fix SourceForge bug @c HTML #552009 @c HTML (@code{rpn} can segfault if @code{!=} operator is written as @code{=!}) @item Fix SourceForge bug @c HTML #546109 @c HTML (bounding box wrong if postscript clipping used) @c HTML @item Fix SourceForge bug @c HTML #514495 @c HTML in which @code{set clip to curve} failed to handle missing values in the curve. @c HTML @item Fix SourceForge bug @c HTML #450465 @c HTML (@code{create columns from function} was broken). @end itemize @c HTML @node Version 2.8, Version 2.6, Version 2.10, Stable Stream @comment node-name, next, previous, up @subsection Version 2.8 @subsubsection Version 2.8.7 [2002 Apr 03] @itemize @bullet @item Fix SourceForge bug @c HTML #482120 @c HTML (@code{regress} ignores data weights) @item Fix SourceForge bug @c HTML #508657 @c HTML (missing backslash in drawing undefined synonyms) @item Fix SourceForge bug @c HTML #523450 @c HTML (log axes detect non-positive values too late) @item Fix SourceForge bug @c HTML #521045 @c HTML (installation/compilation with Solaris Workshop V6 Update 2 compiler) @end itemize @subsubsection Version 2.8.6 [2002 Feb 14] @itemize @bullet @item Fix SourceForge bug @c HTML #513002 @c HTML (minor documentation error in @code{set clip}) @item Fix SourceForge bug @c HTML #509592 @c HTML (HTML docs had midordered indices) @item Fix SourceForge bug @c HTML #506534 @c HTML (map axes give wrong minutes in negative regions). Thanks, Brian, for the patch on this! @item Fix SourceForge bug @c HTML #508088 @c HTML (grimode: gv should update, not be relaunched) @item Fix SourceForge bug @c HTML #506490 @c HTML (@code{-v} commandline option returned wrong version number) @end itemize @subsubsection Version 2.8.5 [2001 Dec 13] @itemize @bullet @item Fix SourceForge bug @c HTML #492472 @c HTML (@code{inf} rpn operator caused segfault) @end itemize @subsection Version 2.8.4 [2001 Oct 4] @itemize @bullet @item Fix SourceForge bug @c HTML #467973 @c HTML (@code{gri -version} gave wrong version number, breaking the Emacs Gri mode.) @item Fix SourceForge bug @c HTML #468014 @c HTML (@code{draw grid} disobeyed pencolor.) @end itemize @subsubsection Version 2.8.3 [2001 Oct 1] @itemize @bullet @item Fix SourceForge bug @c HTML #462243 @c HTML (endian problem in Rasterfile images + reading problem in PGM images). @end itemize @subsubsection Version 2.8.2 [2001 Sep 19] @itemize @bullet @item Fix SourceForge bug @c HTML #461444 @c HTML (wouldn't compile with the @code{mingw32} compiler, for windows 32 machines). @item Fix SourceForge bug @c HTML #454557 @c HTML (wouldn't compile with the pre-release version 3.0.1 of the GNU c++ compiler, in the case in which netCDF was already installed) @end itemize @subsubsection Version 2.8.1 [2001 Sep 7] @itemize @bullet @item Fix SourceForge bug @c HTML #450465 @c HTML (@code{create columns from function} was broken). @item Fix SourceForge bug @c HTML #454557 @c HTML (wouldn't compile with the pre-release version 3.0.1 of the GNU c++ compiler) @end itemize @subsection Version 2.8.0 [2001 Jul 30] @b{New command syntax} @itemize @bullet @item Add @code{unlink} command as a unix-familiar way to delete files (@ref{Unlink}). @item Add @code{set page size} command to clip to a given page size (@ref{Set Page}). @item Add @code{substr} RPN operator to permit extraction of sub-strings (@ref{Tertiary Operators}). @item Add @code{default} possibility for the @code{set x name} and the @code{set y name} commands. @item @cindex underscore, in numbers @cindex numbers, using underscore to separate thousand parts @cindex thousand parts, indicating in numbers using underscore Add Perl-like ability to put underscores in numerical constants, to guide your eye. These underscores are ignored by Gri, so that for example @code{.v. = 1_000} and @code{.v. = 1000} are equivalent as far as Gri is concerned. @end itemize @b{Emacs mode} (@ref{Emacs Mode}) @itemize @bullet @item Give @key{M-Tab} the ability to complete builtin variables and synonyms as well as commands @item Add ``idle-timer minibuffer help'' to display defaults for builtin variables under the cursor. @item Add fontification of builtin variables @emph{only} if they are spelled correctly. @end itemize @b{Developer changes} @itemize @bullet @item Add @code{make source-arch-indep} target in sources. This will build a source tar file in which all the architecture-independent material (documentation in HTML, postscript and Info formats) is pre-made. This makes it easier to install gri on a host that doesn't have TeX and ImageMagick installed. @item Complete the port to IBM's compiler for their AIX operating system. @end itemize @c HTML @node Version 2.6, Version 2.4, Version 2.8, Stable Stream @comment node-name, next, previous, up @subsection Version 2.6 @subsection Version 2.6.4 [2001 Jul 9: Dan's birthday] @itemize @bullet @item Fix SourceForge bug @c HTML #435688 @c HTML (remnants of @code{polar} column type, no longer supported, remained in documentation) @item Fix SourceForge bug @c HTML #435603 @c HTML (@code{set dash} produced broken PostScript) @item Fix SourceForge bug @c HTML #431114 @c HTML (@code{-0} could appear on axes) @end itemize @subsection Version 2.6.3 [2001 Jun 22] @itemize @bullet @item Fix SourceForge bug @c HTML #433250 @c HTML (@code{draw symbol} ignored dashing state sometimes) @item Fix SourceForge bug @c HTML #432549 @c HTML (contours sometimes unlabelled) @item Tweak internal coding for compilation on AIX compilers. @end itemize @subsubsection Version 2.6.2 [2001 May 19] @itemize @bullet @item Fix SourceForge bug @c HTML #425174 @c HTML (synonym interpolation broken on e.g. @code{show "[\syn]"} @item Fix SourceForge bug @c HTML #425175 @c HTML (@code{while !..eof..} acted ignored end of file) @end itemize @subsubsection Version 2.6.1 [2001 May 10] @itemize @bullet @item Fix SourceForge bug @c HTML #420499 @c HTML (gri-mode.el compatibility issues with emacs-21; Mostly bad old code.) @item Fix SourceForge bug @c HTML #421076 @c HTML (byte-compiled gri-mode.el has broken IMenu support; Affects Debian package.) @item Fix SourceForge bug @c HTML #419599 @c HTML (wouldn't compile under GNU g++ 3.x compiler) @item Fix SourceForge bug @c HTML #418065 @c HTML (documentation mentions back-tic notation, which is not available) @item Fix SourceForge bug @c HTML #417333 @c HTML (vague error message @code{RPN string operator}) @item Fix SourceForge bug @c HTML #415277 @c HTML (make fails on MSDOS) @item Fix SourceForge bug @c HTML #415149 @c HTML (@code{file.cc} parse error on MSDOS) @item Fix SourceForge bug @c HTML #414520 @c HTML (@code{draw symbol ... at} should automatically produces axes unless the location is in @code{cm} coordinates) @item Fix SourceForge bug @c HTML #414010 @c HTML (items in the html concept index were in an odd order) @item Fix SourceForge bug @c HTML #413986 @c HTML (@code{~username} was broken in @code{open}) @item Fix SourceForge bug @c HTML #411904 @c HTML (@code{/} was ugly in math mode) @end itemize @subsubsection Version 2.6.0 [2001 April 1] @itemize @bullet @item Permit @code{rewind} to take a filename. @item Make @code{open} set @code{\.return_value.} to the full pathname of the file that was opened. @item Add @code{set path} command (@ref{Set Path To}). @item Remove functioning of @code{GRIINPUTS} environment variable, since this is more cleanly handled with the newly added @code{set path to} command (@ref{Set Path To}). @item Remove @code{\.awk.} synonym, which was deemed to be unhelpful. Users with many scripts that use this variable might wish to put a line like @example \.awk. = "gawk" @end example in their @file{~/.grirc} file. @item Change the format of images in the PostScript output file, as a workaround for a bug in the @code{ps2pdf} program. @item Add ``ampersand'' (@code{\&} and @code{\&&}) syntax to permit newcommands to look up the name and nesting level of changeable arguments (@ref{Changeable Command Arguments}). @item Add ``at-sign'' (@code{@@}) syntax for aliases (@ref{Alias Synonyms}). @item Add ability to embed newlines in @code{show} commands with the @code{\<<} sequence (@ref{Show}). @item Add ability to embed TAB characters in @code{show} commands with the @code{\>>} sequence (@ref{Show}). @item Make various @code{read} commands (@ref{Read}) able to decode synonyms as well as variables and simple numbers. @item Add @code{strlen} RPN operator (@ref{Unary Operators}). @item Add @code{default} option to @code{set x format} and @code{set y format} commands. @item Add @code{new postscript file} (@ref{New Postscript File}) command. @item Switch email list from @code{majordomo} to GNU @code{mailman}. @item No longer remove comments from data lines that are read. This served little function, interfered with recent user code, and could be accomplished by reading through a @code{sed} pipe in any case. @item Make the first element of the @code{argv} array be the name of the command-file. (This makes Gri consistent with languages such as C.) @item Add chapter on test suite (@ref{Test Suite}). @item Let newcommands have changeable arguments (@ref{Changeable Command Arguments}). @item Remove @code{-s} as an abbreviation for the commandline option @code{-superuser}. @item Remove the @code{:} syntax from the commandline options. @item Add commandline option @code{-output PS_file_name}. @item Add @code{assert} command (@ref{Assert}). @item Add test suite (mainly for developers). @item Add @code{sleep} command (@ref{Sleep}). @item Remove command @code{show hint of the day}, since I no longer permission to use cgi-bin to provide the hints via web-server. @item Permit indexing of synonym words with variables, in addition to constants. @item Fix bug in interpolating synonyms in the test-expression of @code{while} loops. @item Put source on the Source Forge open-source development website, at @url{http://gri.sourceforge.net}. Gri users can benefit from this site in may ways. First, it is a great way to keep track of new versions. With a mouse-click you can cause SourceForge to email you whenever a new version of Gri is released. Second, SourceForge has newsgroups (@url{http://sourceforge.net/forum/?group_id=5511}) and email lists (@url{http://sourceforge.net/mail/?group_id=5511}) devoted to Gri. These are archived, so that you can stop monitoring them for a while and then go back and see what you've missed. Third, Source Forge has a powerful bug-tracking facility. (@url{http://sourceforge.net/bugs/?group_id=5511}) With this you may check for existing bugs reported by users, submit new bug reports, and also track the process of bug removal (e.g. optionally receiving emails when the bug is removed). @item Add @code{set colorname} command (@ref{Set Colorname}). @item Add @code{source} command (@ref{Source}). @item Add RPN operators @code{wordc} (@ref{Solitary Operators}) and @code{wordv} (@ref{Unary Operators}) for accessing the words in the present Gri command. @item Add RPN operators @code{argc} (@ref{Solitary Operators}) and @code{argv} (@ref{Unary Operators}) for accessing the command-line arguments used when Gri was invoked from the operating system. @item Add automatic support for compressed data files. So far, this only works with gzipped files (@ref{Open}). @item Add two new RPN operators, @code{file_exists} and @code{directory_exists} (@ref{Unary Operators}). @item Reorganize parts of manual (e.g. changing the section about the Emacs @file{gri-mode.el} into a chapter, with screen snapshots). @item Improve the HTML form of the manual (e.g. color-code the Gri syntax in examples, provide access to all the indices, use Jpeg format, et.). @item Add several new features to @code{gri-mode.el}: 1) Add a menubar pull-down menu listing all Gri commands, allowing the user to get @code{Help} or @code{Info} on any command or @code{Insert} it in the current Gri file. 2) Add a menubar pull-down entry to @code{Perform} to set @code{gri-run} settings such as flag options passed to gri. 3) Gri info file can have @strong{.info} extension now. 4) Made @code{gri-apropos} an alias for @code{gri-help-apropos}. 5) gri-mode now uses the customize interface (See @code{gri-customize}). 6) The @code{~/.gri-syntax} file has changed format. As a side-effect, spaces are used instead of hyphens to display Gri commands, and one can now select a command with the mouse in the @strong{Completions} buffer. @end itemize @c HTML @node Version 2.4, Version 2.2, Version 2.6, Stable Stream @comment node-name, next, previous, up @subsection Version 2.4 @subsubsection Version 2.4.4 [2000 May 7] Change so that only a warning is printed if mathematical operations are requested on empty arrays (e.g. @code{y += 10}). Previously, an error was reported and Gri exited with an error condition, which is bothersome in scripts that rely on successful completion of the Gri job. Port to the BeOS operating system. @subsubsection Version 2.4.3 [2000 Apr 1] Change location of all files, to be consistent with Redhat convention. Previously, things were in @code{/opt/gri}; now they are in more standard locations. @subsubsection Version 2.4.2 [2000 Mar 25] Remove bug in which @code{convert grid to image} produced incorrect images, visible as a patchy appearance with coarse grids. @subsubsection Version 2.4.1 [2000Jan 31] Remove bug in which @code{convert image to grid} failed to take note of the gri minimum and maximum, so that contouring of the grid was not possible for grids created from images. @subsubsection Version 2.4.0 [2000 Jan 05] Add @code{set input data separator}. Make @code{read columns} work with various input separators. Make @code{read .x.}, etc, work with various input separators. @c HTML @node Version 2.2, Unstable Stream, Version 2.4, Stable Stream @comment node-name, next, previous, up @subsection Version 2.2 @subsubsection Version 2.2.6 [1999 Nov 25] Make web-based manual easier to read by putting a light-grey background under sample code. @subsubsection Version 2.2.5 [1999 Nov 10] Fix bug in RPN calculations that prevented using a negative exponent. @subsubsection Version 2.2.4 [1999 Nov 7] Add @code{set font encoding}, and also change the encoding to ISO-Latin-1. (This doesn't hurt old code since Gri didn't make any claims to handle characters outside the normal printing-set before anyway.) Fix bug in which there were 4 dead links in the HTML version of manual. Clean up some problems with Debian distribution (thanks, Peter Galbraith!). @subsubsection Version 2.2.3 [1999 Jun 30] Fix bug in which word-of-synonym (e.g. @code{\[0]mysyn}) was not detected correctly (thanks to bug report from Kazuhiko Nakayama in Japan) @subsubsection Version 2.2.2 [-] Clean a few spelling and cross-reference errors in documentation. @subsubsection Version 2.2.1 [1999 Mar 31] For debian, properly locate the @code{netcdf} library, if it is installed. Remove remnants of old commands for polar axes. Correct error in which the right-most and upper-most pixel of images created by @code{convert grid to image} may be blank (or not, depending on roundoff error) under certain conditions of exact matchup between grid spacing and image spacing. Don't create PostScript file if the commandfile is non-existent, or if there were errors on the commandline. @subsubsection Version 2.2.0 [1999 Mar 25] First debian release. Versions exist for intel, alpha, 68K and powerpc. @c HTML @node Unstable Stream, Development Version, Version 2.2, History @comment node-name, next, previous, up @section Unstable Stream @menu * Development Version:: * Plans:: @end menu @c HTML @node Development Version, Plans, Unstable Stream, Unstable Stream @comment node-name, next, previous, up @subsection Development Version The list below shows changes that have been made in the development version of Gri, i.e. the version on CVS at @url{http://gri.sourceforge.net}. Some or all of these features may enter the next stable stream of Gri, but it is important to note that @emph{anything} that's listed here may be changed without notice! The main exception is bug fixes, which will enter the stable stream unless they are found to create new bugs. @subsubsection New Features @itemize @bullet @item n/a @end itemize @subsubsection Removed Features @itemize @bullet @item n/a @end itemize @subsubsection Bug Fixes @itemize @bullet @item Fix SourceForge bug @uref{http://sourceforge.net/tracker/index.php?func=detail&aid=618041&group_id=5511&atid=105511,#618041} @dots{} solaris compile error, relating to the subroutine @code{gethostname()} in the @file{startup.cc} source code file. @end itemize @c HTML @node Plans, Deprecated Commands, Development Version, Unstable Stream @comment node-name, next, previous, up @subsection Plans @c FOR NEXT RELEASE: @c 1) Fix bug in @code{read colorname} that caused it to try to @c interpret comments in the X11 color-name file as though @c they were actual colors. @c @c 2) Improve writing in the @code{read image} section of this manual. @c @c 3) Fix bugs in the HTML version of the manual, as reported @c by the 'tidy' checking programme. @cindex plans for future versions @cindex command-line interface @cindex image formats, other than 8-bit Some plans for future versions are given below. A more extensive list, together with target timescales and notes on the progress towards completion, is available in the to-do list at the development site (@url{http://gri.sourceforge.net}), which is also the place to go if you have suggestions for other changes to Gri. @cindex endian file compatibility, plans @cindex little-endian vs big-endian data, plans @cindex big-endian vs little-endian data, plans @subsubsection High Priority @enumerate @item Add ability to generate SVG (scalable vector graphics) output. This file type can be edited with GUI-based tools, making it easy for users to put the final touches on graphs "manually." This feature will require a great deal of work, mainly to do with grouping of graphical elements, and so I'll need to rely on advice from users. @item Switch to @code{popt} library for the processing of command-line options. (Docs on this are at @url{http://cvs.gnome.org/lxr/source/popt}.) @item Change @code{set axes style} from number-based selection to word-based selection, and print a deprecation warning if the number-based syntax is used. @item Switch from @code{tmpname} to @code{mkstemp} subroutine, for temporary filenames. @item Add readline support, to handle history, command-line editing, etc, for interactive usage (Docs on this are at @url{http://cnswww.cns.cwru.edu/~chet/readline/readline.html}.) @end enumerate @subsubsection Medium priority @enumerate @item Add optimal interpolation as another method for gridding data (@ref{Convert Columns To Grid}). @item Add ability to read PNG images (@ref{Read Image}) (Docs on this are at @url{http://www.libpng.org/pub/png/}.) @end enumerate @subsubsection Low priority @enumerate @item Add non-RPN mathematics. @item Add graphical output to the screen as commands are executed. @item Add support for both little-endian and big-endian binary data. @end enumerate @c HTML @node Deprecated Commands, Installation, Plans, History @comment node-name, next, previous, up @section Deprecated Commands @cindex deprecated commands @itemize @bullet @item @emph{version 2.9.0} @itemize @bullet @item Replace @code{set y axis label horizontal} with @code{set y axis name horizontal}. @item Replace @code{set y axis label vertical} with @code{set y axis name vertical}. @end itemize @end itemize @c HTML @node Installation, Unix-install, Deprecated Commands, Top @comment node-name, next, previous, up @chapter Installing Gri @menu * Unix-install:: * Msdos-install:: * OS2-install:: * Mac-install:: * Beos-install:: @end menu @c HTML @node Unix-install, Archiving Old Versions, Installation, Installation @comment node-name, next, previous, up @section Unix Installation @cindex directory structure of Gri installation @menu * Archiving Old Versions:: Keeping the old and the new * Linux:: Installing on linux * Precompiled Unix:: Installing precompiled versions * Uncompiled Unix:: Compiling and installing @end menu @c HTML @node Archiving Old Versions, Linux, Unix-install, Unix-install @comment node-name, next, previous, up @section Archiving Old Versions Gri, like other complex programs, sometimes changes in such a way as to break old scripts. This is less so of changes since about 1998 or so, since the syntax became pretty firm about that time. Still, disk costs are so cheap that you would be well-advised to keep a backup version of Gri, whenever you update. This is pretty simple; you need to keep a copy of the executable and the library file, and you need to write a tiny shellscript that calls this particular executable with this particular library file. For example, you might do the following @example mkdir -m 755 -p /usr/local/share/gri/@value{GRI-VERSION} cp /usr/bin/gri /usr/local/share/gri/@value{GRI-VERSION} cp /usr/share/gri/gri.cmd /usr/local/share/gri/@value{GRI-VERSION} @end example @noindent and then create a shellscript called @file{/usr/local/bin/gri-@value{GRI-VERSION}} containing @example #!/usr/bin/sh /usr/local/share/gri/@value{GRI-VERSION}/gri \ -directory /usr/local/share/gri/@value{GRI-VERSION} \ "$@@" @end example @noindent to invoke this version of Gri. To be able to access this old version of gri from within the Emacs gri-mode, you would reset the Emacs variable @code{gri*directory-tree} like so in the file @file{~/.emacs} (@ref{Step 2} in @ref{Installing gri-mode.el}) @example (setq gri*directory-tree '("/usr/local/share/gri/" "/usr/share/gri/")) @end example @c HTML @node Linux, Precompiled Unix, Archiving Old Versions, Unix-install @comment node-name, next, previous, up @subsection Installation on Linux computers @cindex linux distributions @cindex debian @cindex redhat @cindex RPM version of installation package @cindex installation, debian linux @cindex installation, redhat linux @cindex installation, linux redhat/debian Installation is easy on various flavors of linux. Versions are available from the official distributions and also at @c HTML @file{http://sourceforge.net/project/showfiles.php?group_id=5511} @c HTML The RedHat version supports intel platforms only, while the Debian version supports intel, alpha, 68K and powerpc. Installation follows the normal method for these distributions ... if you have the distribution, you surely know what to do. If you don't, you may want to switch when you see that you can install Gri by clicking an icon in a window, or by typing, e.g. in RedHat linux: @example rpm -i gri-@value{GRI-VERSION} @end example Debian-linux installation may be done with any of several GUI-based tools, or with the following system command: @example dkpg -i gri_@value{GRI-VERSION}-1_i386.deb @end example @noindent or via a properly configured @code{apt} interface that will fetch the latest version from the net: @example apt-get install gri @end example @c HTML @node Precompiled Unix, Uncompiled Unix, Linux, Unix-install @comment node-name, next, previous, up @subsection Pre-compiled unix versions Pre-compiled versions of Gri exist for various computers, e.g. SPARC (both sunOS and solaris), IBM-RS, Sequent, and Linux. The following instructions, which assume a version number @value{GRI-VERSION}, and a SPARC solaris machine, show how to install these. The compressed tar file, with a name like @file{gri-binary-SunOS5-@value{GRI-VERSION}.tar.gz} (in this example a Sun OS 5 binary is assumed, with gri version number @value{GRI-VERSION}) contains a directory which holds the executable Gri file, @file{gri}, the library file @file{gri.cmd}, an instructions file, @file{README}, and a Makefile to install Gri. Here's how to install Gri, starting with this tar file: @enumerate @item First, uncompress (unzip) the file, and un-tar it, by doing @example gunzip -c gri-binary-SunOS5-@value{GRI-VERSION}.tar.gz | tar xvf - @end example @noindent or @example zcat gri-binary-SunOS5-@value{GRI-VERSION}.tar.gz | tar xvf - @end example @noindent This will yield a new directory, with a name like @file{gri-binary-SunOS5-@value{GRI-VERSION}}, which contains the indicated files. @item Follow the instructions in the @file{README} file to install Gri. @end enumerate @c HTML @node Uncompiled Unix, Msdos-install, Precompiled Unix, Unix-install @comment node-name, next, previous, up @section Compilation on Unix computers The following steps indicate how to compile Gri on unix computers. The procedure is quite standard. @cindex configure script, how to use to compile gri @cindex compiling gri @cindex how to compile gri @table @emph @item Requirements You'll need a C++ compiler that is modern enough to handle 'templates' (i.e. almost any compiler from 1998 onward). Don't worry -- if your compiler isn't new enough, you'll see that in a minute or two! You'll need TeX and texinfo to make the info files, and optionally the netCDF library (if you wish gri to be able to read netCDF binary data files). To make the HTML manual, you'll need imagemagick, info, gs and its fonts. On Debian GNU/Linux systems, the required packages are listed as Build-Depends in the @file{control} file found in the @file{debian} directory, to which you must add the package @file{build-essential}. @item Unpack the source Type @example gunzip gri-@value{GRI-VERSION}.tgz tar xvf gri-@value{GRI-VERSION}.tar @end example @noindent (or similar commands) to uncompress and untar the contents. This will yield a new directory named @file{gri-@value{GRI-VERSION}} which contains many files. @item Move to the Gri directory @example cd gri-@value{GRI-VERSION} @end example @item Configure your compiler Next you must "configure" the Gri source files. During this step, a series of tests will be made about your operating system and your compiler. Most of these tests need no interaction from you, but there is one overall choice that you may wish to make: the place on your filesystem where Gri (and many associated library and documentation files) will reside. To get the default installation, with files residing within the directory @file{/usr/local}, type @example ./configure @end example @noindent at this time. If you'd rather the files go into another location, run the @code{configure} script differently, e.g. to get the Gri files to reside within the @file{/opt} directory, type: @example ./configure --prefix=/opt @end example @noindent In response, you'll see the results of several tests of the properties of your operating system, your C++ compiler, etc. Normally you can ignore these results. @cindex handling multiple gri versions @cindex multiple gri versions @cindex versions, handling multiple As an example, typing @code{./configure} without a @code{--prefix} option yields the directory tree (@code{...} indicates several files not displayed in this list, for brevity). In this example, the most up-to-date version is @value{GRI-VERSION}, but a previous version @value{GRI-PREVIOUS-VERSION} has also been retained. (Note that only one copy of the documentation is retained; this is all that's needed, since old versions are documented there as well as new versions.) @example /usr/local |-- bin | |-- gri -> gri-@value{GRI-VERSION} | |-- gri-@value{GRI-VERSION} | |-- gri-@value{GRI-PREVIOUS-VERSION} | |-- gri_merge | `-- gri_unpage |-- info | |-- ... `-- share `-- gri |-- 2.6.0 | |-- gri.cmd | |-- license.txt | |-- logo.dat | `-- startup.msg |-- 2.4.0 | |-- gri.cmd | |-- license.txt | |-- logo.dat | `-- startup.msg `-- doc |-- examples | |-- ... `-- html |-- ... |-- resources | |-- ... `-- screenshots |-- ... @end example @b{Trouble-shooting 1}: If the permission of the @file{configure} file is wrong, you'll get an error like @code{Permission denied}; if so, try typing @code{sh ./configure} to run it in the Bourne shell. If that fails, you are going to have to do some old-fashioned work! Start by copying the generic Makefile called @file{Makefile.generic} into @file{Makefile}, and try the following steps, perhaps editing the @file{Makefile} if you run into errors. @b{Trouble-shooting 2}: Gri uses a C++ feature called 'templates'. Unfortunately, templates are handled in different ways by different compilers. At least as of Spring 1997, the GNU compiler, vsn 2.7.x (used by many Gri folks) has problems with templates. Therefore the configure script will check to see if you are using the GNU c++ compiler, and if you are it will check whether the ("template repository") compiler flag @code{-frepo} is known on your machine. If it is not, an alternative method of templates will be used. But if it is, you'll be asked, for confirmation, whether you wish to use the @code{-frepo} flag. On many machines (e.g. Solaris) you should answer @code{n} to this question. The prompt will explain. Also, note that you can avoid the prompt by running configure as either of the two below: @example ./configure --enable-frepo ./configure --disable-frepo @end example (Such switches will be ignored unless you're using the GNU compiler.) @b{Trouble-shooting 3}: If optional system libraries like the netCDF library, if it exists, are installed in nonstandard places, you might have to change the unix environment variable @code{LD_LIBRARY_PATH}. For example, on my machine the @code{netcdf} library is not installed in @file{/usr/lib}, as the @code{configure} script assumes, but rather in @file{/usr/local/share/netcdf/lib}. Therefore I have the following line in one of my startup files: @example export LD_LIBRARY_PATH=/usr/lib:/usr/local/share/netcdf/lib @end example @item Compiling Gri Now compile Gri by typing @example make @end example @item Testing Gri @cindex test suite Type @example make check @end example @noindent to do some tests on the version of Gri that you just compiled. If no errors are reported, you may go to the next step. @item Installing Gri Assuming compilation succeeds, install @file{gri} and the ancillary file @file{gri.cmd}, by typing @example make install @end example If you wish to see where files where be installed, first try a dry run typing @example make -n install @end example @item Cleaning up Once these things are done, you may type @example make clean cd doc ; make clean @end example @noindent to clean up some files. Of course, you could just erase the whole source, but the source is probably worth a penny of hard-drive space, isn't it? @end table @c HTML @node Msdos-install, OS2-install, Uncompiled Unix, Installation @comment node-name, next, previous, up @section Compilation on x86 (PC-style) Computers Versions exist for MSDOS, windows, and Linux operating systems. (Actually, the windows version is just the MSDOS version, which can be run inside an msdos window within windows-95, windows-NT, etc.) @subsection MSDOS Operating System @cindex compilation under MSDOS @cindex MSDOS compilation To compile and install Gri under MSDOS, do this: @enumerate @item To begin, install @code{DJGPP V2}, if it is not on your system already. It can be found at @url{http://www.delorie.com/djgpp} @item Uncompress and extract from gri source package (@ref{Uncompiled Unix}). @item Type @code{make -f Makefile.dj2} to compile. If it fails, you might have to edit the file @file{Makefile.dj2} to match the characteristics of your system. Please inform the author, @c HTML Dan Kelley @c HTML at Dan.Kelley@@Dal.CA, if you think your modifications might be useful to others. @item Type @code{make -f Makefile.dj2 install} to install it (normally on the @code{C:} drive). @end enumerate If you encounter problems, read the first few lines of the Makefile (i.e. the file @file{Makefile.dj2}) for hints on things to try. For example, in the present version of @file{Makefile.dj2} these hints are given: @enumerate @item There is a good chance that this Makefile will work as is, so try that first. @item If you have the @file{netcdf} library (used for certain types of atmospheric and oceanographic datasets), then un-comment and possibly edit the appropriate @code{NETCDF_...} lines below, as instructed by the comments preceding these lines. @item If you don't want Gri inserted in the directory @file{c:/gri}, edit the @code{instdir = ...} line below. @item If you get error messages about the @file{stdcxx} library, edit the @code{LIBS} line below, rewriting @file{-lstdcxx} as @file{-lstdcx}. @item If you get compilation errors relating to @code{time} or to @code{ftime}, try putting the token @code{-DHAVE_FTIME=1} in the list of similar token in the @code{DEFS = ...} line. For consistency (basically, so the author can help you if you do this), put it right after the @code{-D_GRI_=1} token. @end enumerate To view the output, use a PostScript viewer such as GSview. @subsection LINUX Operating System @cindex compilation under Linux @cindex linux compilation @cindex LINUX compilation Linux is a good emulation of unix, and it is free. Gri for linux is compiled and installed according to the normal unix instructions. The compiled version is with a name like @code{gri-binary-solaris-2.1.10.tar.gz}; treat it as in other unix systems (@ref{Uncompiled Unix}). @c HTML @node OS2-install, Mac-install, Msdos-install, Installation @comment node-name, next, previous, up @section Compilation under OS/2 @cindex compilation under OS/2 @cindex OS/2 unix compilation Gri compiles, using the gcc compiler under OS/2, provided that the included @code{Makefile.os2} is used. Be sure to edit the first few lines to change filenames as required, especially taking care to account for whether the netCDF library is installed, etc. @c HTML @node Mac-install, Beos-install, OS2-install, Installation @comment node-name, next, previous, up @section Compilation in Macintosh OS X @cindex compilation in Macintosh OS X @cindex macintosh unix compilation @cindex darwinport @cindex fink The OS X system provides a BSD unix that suites Gri very well. With the (free) developer package, it also provides a very up-to-date version of the @code{gcc} compiler. Thus, installing Gri on Macintosh can be done using the normal Unix instructions. But there are also easier ways. Gri is compatible with Fink and Darwinports, the two popular packaging systems on OS X. If you use OS X and do not have Fink or Darwinports installed, then you should probably install one, or both. Each distribution has strengths, and each has weaknesses, and it is difficult to provide a firm recommendation between the two. @emph{Caveat.} As of mid-2007, neither distribution appears to handle package dependencies as well as is done by popular linux distributions. For example, in working through the steps listed below, the author found that his Darwinports system had a problem with a system library that handles internationalization. The "update" operation of the system was insufficient to solve the problem, and so it was necessary to do some web searching to find a patch. The patch failed, but another search revealed a second (hand-edit) patch that got it working. In excess 4 CPU hours were required to rebuild the packages that were broken. If you'd like to build a local Darwinports version of Gri, to get the latest version instead of whatever version is provided by Darwinports, follow these steps: @itemize @bullet @item Download the source from CVS at SourceForge. (If you don't know what the previous sentence means, you will quite likely have difficulties with the other steps.) @item Visit the @code{darwinports} directory of the newly-created directory tree, and type @example sudo port -d -v build @end example to build it. This will take several minutes, during which you may find it helpful to do a search on "darwinport build". For example, the O'Reilly page (@url{http://www.oreillynet.com/pub/a/mac/2004/04/09/darwinports.html?page=3}, last checked in July 2007) is very good. Note that you will be building from the source that is stored on SourceForge, not from the Darwinports source. That's the trick of issuing the @code{build version} of the @code{port} command. @item Do a "destroot" operation: @example sudo port -d -v destroot @end example @item Install it: @example sudo port -d -v install @end example Note: if you already have an older version of Gri in the Darwinports system, you must first issue the command @example sudo port deactivate gri @end example @end itemize @c HTML @node Beos-install, Bugs, Mac-install, Installation @comment node-name, next, previous, up @section Compilation under BeOS @cindex compilation under BeOS @cindex BeOS unix compilation The BeOS system compiles Gri cleanly without modification; just follow the instructions for unix. @c HTML @node Bugs, Known Bugs, Beos-install, Top @comment node-name, next, previous, up @chapter Bugs @menu * Known Bugs:: Bugs in the current version * Reporting Bugs:: How to report bugs * Killing Bugs:: How to (try to) kill bugs @end menu @c HTML @node Known Bugs, Reporting Bugs, Bugs, Bugs @comment node-name, next, previous, up @section Known bugs @cindex bugs in Gri To get a list of known bugs, in the present or past versions, visit @url{http://sourceforge.net/tracker/?atid=105511&group_id=5511&func=browse}. @c HTML @node Reporting Bugs, Killing Bugs, Known Bugs, Bugs @comment node-name, next, previous, up @cindex bugs, how to report @section Reporting Bugs Bug reports help make Gri more reliable and useful for all users, so please report any bugs you find. The scheme will be familiar to you, if you've participated in open-source work before. @enumerate @item Visit the bug-tracking part of the Source Forge Gri development site, at @url{http://sourceforge.net/bugs/?group_id=5511} to see whether your bug has already been reported. You may find that it has been reported and fixed already in a new version, in which case you should archive your existing Gri version and upgrade. If the bug has been reported and @strong{not} fixed, then you may still wish to add a supplemental bug report, so the author knows that this bug is of concern to you as well as the others. (Plus, reporting it this way ensures that you'll receive an email when the bug is fixed.) @item Debugging is made easier if the problem is reduced in scope. Therefore, please reduce your application and your data to the simplest case that produces the error. @item @cindex bug, resulting in bus error @cindex bug, resulting in segmentation fault @cindex bus error, what to do @cindex segmentation fault, what to do @cindex debugger used with Gri If you know how, please try to find the bug yourself. After all, Gri is open-source for a reason! The procedure is described in the next section (@ref{Killing Bugs}). @end enumerate @c HTML @node Killing Bugs, Debugging Software You Will Need, Reporting Bugs, Bugs @comment node-name, next, previous, up @cindex bugs, how to kill them @section Killing Bugs @menu * Debugging Software You Will Need:: * Debugging at a Glance:: * Debugging Example:: @end menu @node Debugging Software You Will Need, Debugging at a Glance, Killing Bugs, Killing Bugs @comment node-name, next, previous, up @subsection Software that you'll need This section is intended to help you find and kill bugs yourself, by indicating how the author does this work. Since Gri is open-source, all users are invited to try to kill bugs themselves! If you know nothing of C or C++, you may as well not read further, since there is little chance of your making progress. On the other hand, experienced programmers won't need any of the advice I give below. You'll need the Gri source and a C++ compiler. It also helps if you have @code{gdb}, the GNU debugger, installed; the instructions below assume that's the case. Also, the instructions assume that you're using the Emacs editor, and running @code{gdb} from within Emacs. Otherwise, you'll want to glance at the documentation on @code{gdb} to see how to use it in standalone mode. @node Debugging at a Glance, Debugging Example, Debugging Software You Will Need, Killing Bugs @comment node-name, next, previous, up @cindex electric fence, for debugging @subsection Debugging at a glance The list below is a sketch of what you might try, and in what order. @itemize @bullet @item Check the bug list to see if other users have found your bug, and also to see if there is a workaround. @item Try a more recent version of gri. If it works, you might wish to archive the version you have at the moment and upgrade. @item If you suspect your bug has something to do with system calls, as in the @code{system} command (@ref{System}) or as in piped input files (@ref{Open}), you should re-run the script with @code{gri -superuser8} instead of with @code{gri}. This will cause Gri to print out all commands that it is handing over to the operating system; you may see the error that way. (Hint: it may help to interactively cut/paste the commands into your OS shell to see what the action of the command is.) @item If your bug results in early termination, you should run Gri inside a debugger (e.g. GDB, assumed henceforth). When the program terminates, type @code{where} to see where termination occured. Often this will give a clue. In many cases, early termination results from faults in memory allocation. To check memory allocation, you'll need to recompile Gri, linking it against a debugging memory allocator. Many such tools exist; see comments in the @code{Makefile} for a hint at how to use a popular one, called ``Electric Fence.'' @item If your bug does not result in early termination, you may find the best scheme is to trim your example down as much as possible, and then run Gri inside the GDB (or other debugger) so that you can monitor program execution. The next section explains this in detail. @end itemize @node Debugging Example, Test Suite, Debugging at a Glance, Killing Bugs @comment node-name, next, previous, up @subsection A debugging Example Let's take a recent bug as an example. Peter Galbraith found that the gri script @example set color hsb 0.999 1 1 draw box filled 2 2 3 3 cm set color hsb 1.000 1 1 draw box filled 4 2 5 3 cm @end example @noindent produced odd results in a previous version of Gri; the color patches should have been of nearly the same color, but the first one was red, as expected, and the second was magenta. The list below shows how I found Peter's bug. Experienced C or C++ programmers will find all of this very familiar, and will really only need to read item 6 of the list below, since that's the only action that is really specific to Gri. (Note: for display purposes, I've broken some of the lines in the files into two lines in this list.) @enumerate @item Copy the above script (called @file{test.gri}) into the Gri source directory, and the script into an Emacs buffer. @b{Note:} all the following steps are done within Emacs, and the items in parentheses are the Emacs keys to get the indicated actions. @item If you're working from a pre-compiled version, you'll need to get the source first and do a compile yourself (@ref{Uncompiled Unix}). Then do a @code{make tags} command (type this to the unix shell) to create a so-called "tag" table. @item Run Gri in this emacs buffer (@kbd{C-cC-r}) noting from the postscript window that pops up that the colors are, indeed, mixed up. @item Load up the @code{gdb} debugger by typing @kbd{M-x gdb gri}. This will open a new Emacs buffer in which you may type commands. We'll be switching back and forth between this buffer and various source files. @item Reasoning that the error probably occurs at @code{set color} or @code{draw box}, try replacing the latter by a command such as @code{draw label "hi" at 3 3 cm"}. The color is still wrong, indicating that it is the @code{set color} command that has the problem. @item Next, we must find where the C++ code corresponding to the @code{set color} command resides. As it turns out, all @code{set} commands are defined in the source file @code{set.cc}, and this command is defined in a subroutine called @code{set_colorCmd()}. But the author knows this -- how would you? The answer is to look in the @file{gri.cmd} file, for the @code{set color} command. (Search for the string @code{`set color }.) Then read down to see the body of the command, enclosed in braces; you'll see @example @{ extern "C" bool set_colorCmd(void); @} @end example @noindent which indicates that the subroutine name is @code{set_colorCmd()}. @item Next we need to edit this subroutine to see what it is doing. There are several ways to find it (e.g. @code{grep} through the source files), but the easiest is to use the "tags" feature of Emacs, by typing @kbd{M-. set_colorCmd}. This will bring you to the indicated subroutine. @item Have a look through this subroutine to see what it is doing. It looks very much like many other Gri subroutines. A check is done on the number of words provided to the command, in the @example switch (_nword) @{ @end example @noindent line. (That's line @file{set.cc:484} at the moment -- but it may be different by the time you read this file, if I've changed it!) We are calling it with 6 words (@code{set color hsb 1.000 1 1}), so move down to the line @example case 6: @end example @noindent and you'll see that there is an @code{if} statement seeing whether this word is @code{rgb} or @code{hsv}. These statements are checking @code{_word[2]}, which is the third word of the command. (In Gri, as in C, words start at zero. Thus, for this command, @code{_word[0]} is @code{set}, @code{_word[1]} is @code{color}, and @code{_word[2]} is expected to be either @code{rgb} or @code{hsb}. We are having problems with the @code{hsb} style, so we'll move down to that code. The code that's being executed is as follows. @example @} else if (!strcmp(_word[2], "hsb")) @{ // `set color hsb .hue. .saturation. .brightness.' double hue, saturation, brightness; Require(getdnum(_word[3], &hue), READ_WORD_ERROR(".hue.")); Require(getdnum(_word[4], &saturation), READ_WORD_ERROR(".saturation.")); Require(getdnum(_word[5], &brightness), READ_WORD_ERROR(".brightness.")); // Clip if necessary CHECK_HSB_RANGE(hue); CHECK_HSB_RANGE(saturation); CHECK_HSB_RANGE(brightness); gr_hsv2rgb(hue, saturation, brightness, &red, &green, &blue); PUT_VAR("..red..", red); PUT_VAR("..green..", green); PUT_VAR("..blue..", blue); c.setHSV(hue, saturation, brightness); _griState.set_color_line(c); if (_griState.separate_text_color() == false) _griState.set_color_text(c); return true; @end example The @code{Require} lines are ensuring that we could decode the values of the variables @code{hue}, etc, from the commandline. Then we clip the range of these values. Then we convert from @code{hsb} color format to @code{rgb} color format, save the values of the colors in Gri variables with @code{PUT_VAR}, and then set the color with @code{c.setHSV}. Finally we save this color in the Gri "state" with @code{_griState.set_color_line(c)}. As it turns out, Gri outputs all colors to the PostScript file in RGB format, so the we may well suspect that the problem is in the @code{gr_hsv2rgb()} line. @item We have an idea where to look now, so let's go to the line just after it, in the editor, and insert a "breakpoint" there by typing @kbd{C-x SPC}. Then move to the @code{gdb} buffer and re-run Gri by typing @example run -directory . test.gri @end example @noindent to run Gri on our script. Then, magic happens! Gri stops at the indicated breakpoint, and Emacs will display both the @code{gdb} buffer and the @code{set.cc} buffer. The latter has a margin indication telling what line were are on. You may now type @code{gdb} commands in the @code{gdb} buffer. In particular, type @example p hue @end example @noindent to print the hue. Then type @example p red @end example @noindent to see the red value. Then type @example c @end example @noindent to continue running Gri. It will pause again. Check the hue and red values again, as above. If you like, play around with hue value in the Gri script @file{test.gri} and run gri again (type @code{r} in @code{gdb}). This seems to indicate that the conversion is working strangely. @item To see how the conversion is done, clear the breakpoints by typing @kbd{delete} in the @code{gdb} buffer, then insert a breakpoint @strong{before} @code{gr_hsv2rgb} is called. Then, run Gri again (@kbd{r} in the @code{gdb} buffer). When it stops just before this subroutine, type @kbd{s} to "step into" the subroutine. Then you'll see a conversion code from the (wonderful) textbook of Foley and Van Dam. You'll see @example void gr_hsv2rgb(double h, double s, double v, double *r, double *g, double *b) @{ h = 6.0 * pin0_1(h); s = pin0_1(s); v = pin0_1(v); int i = (int) floor(h); if (i > 5) i = 5; // Prevent problem if hue is exactly 1 double f = h - i; double p = v * (1.0 - s); ... @end example @noindent in the present version of Gri, but in the previous (buggy) version, the @code{if} statement was missing. Without this @code{if} statement, Gri produced wrong colors. With the statement, the colors are correct. @end enumerate And so ends the example. You may wish to read the Foley and Van Dam textbook to see just what I'm doing in @code{gr_hsv2rgb}, but suffice it to say that the problem in the (older) version of Gri was that @code{i} could take the value 6 if the hue was exactly equal to 1, and that was erroneous. In reading the code, you may notice that it is formatted in a uniform way: the Kernighan and Ritchie scheme (from their classic C textbook), with 8-character indents. I get this by putting the following lines in the @file{~/.emacs} file, which is used to customize the Emacs editor: @example (defun my-c-mode-common-hook () (c-set-style "K&R") (setq c-basic-offset 8) ) (add-hook 'c-mode-common-hook 'my-c-mode-common-hook) @end example If you submit patches, please use the same format as I've done, so that I can more easily see the changes you've made. @c HTML @node Test Suite, Gri in the Press, Debugging Example, Top @comment node-name, next, previous, up @chapter Test Suite @cindex test suite @cindex suite of test files The following test files are invoked by typing @code{make test}, after compiling Gri. They are provided here because they are examples of scripts that are @strong{known to work} for the version of Gri described in this manual. Heavy use is made of the @code{assert} command (@ref{Assert}) in these test files. Thus the @strong{code itself} demonstrates the features, instead of comments in the code. This is advantageous since comments tend to be incorrect! @c HTML Test file `tst_IO.gri'.

    @iftex @sp 1 @noindent Test file @file{tst_IO.gri}: @cartouche @include tst_suite/tst_IO.texi @end cartouche @end iftex @c HTML Test file `tst_control.gri'.

    @iftex @sp 1 @noindent Test file @file{tst_control.gri}: @cartouche @include tst_suite/tst_control.texi @end cartouche @end iftex @c HTML Test file `tst_rpn.gri'.

    @iftex @sp 1 @noindent Test file @file{tst_rpn.gri}: @cartouche @include tst_suite/tst_rpn.texi @end cartouche @end iftex @c HTML Test file `tst_var_syn.gri'.

    @iftex @sp 1 @noindent Test file @file{tst_var_syn.gri}: @cartouche @include tst_suite/tst_var_syn.texi @end cartouche @end iftex @c HTML @node Gri in the Press, Acknowledgments, Test Suite, Top @comment node-name, next, previous, up @chapter Gri in the Press @cindex scientific journals with Gri graphs A gentle introduction to Gri is provided in a Linux Journal article, available at @url{http://www2.linuxjournal.com/lj-issues/issue75/3743.html} on the web. In March 2000, I emailed some Gri users to ask for the names of scientific journals in which they have published Gri-produced graphs. The list, which mainly arrived on Sunday in response to an email I sent Saturday (don't Gri users take a break?) is presented below, to indicate the range of Gri use in the press. @b{Journals in Oceanography, Atmospheric Science, Earth Science, etc.} @itemize @bullet @item @strong{Bulletin on Coastal Oceanography} (in Japanese with English abstract) @item @strong{Fisheries Oceanography} @item @strong{Deep-Sea Research} @item @strong{EOS, Transactions of the American Geophysical Union} @item @strong{Estuarine, Coastal and Shelf Science} @item @strong{Geophysical Research Letters} @item @strong{Journal of Atmospheric and Oceanic Technology} @item @strong{Journal of Geophysical Research} @item @strong{Journal of Marine Research} @item @strong{Journal of Plankton Research} @item @strong{Journal of Physical Oceanography} @item @strong{Journal of the Japan Scoiety for Marine Surveys and Technology} (in Japanese with English abstract) @item @strong{Limnology and Oceanography} @item @strong{Marine Biology} @item @strong{Marine Ecology Progress Series} @item @strong{Monthly Weather Review} @item @strong{Oceanography} @item @strong{Paleoceanography} @item @strong{Progress in Oceanography} @item @strong{Quaternary Research} @item @strong{Scientia Marina} @item @strong{South African Journal of Marine Science} @item @strong{Umi no Kenkyu} (Japanese version for Journal of Oceanography, in Japanese with English abstract) @end itemize @b{Journals in Physics, Chemistry, etc.} @itemize @bullet @item @strong{Applied Physics A} @item @strong{Journal of Fluid Mechanics} @item @strong{Journal of Physical Chemistry B} @item @strong{Physica D} @item @strong{Physics of Fluids} @item @strong{Physics A} @item @strong{Physics Letters B} @item @strong{Physical Review C} @item @strong{Physical Review Letters} @item @strong{Research on Chemical Intermediates} @item @strong{Theoretical Computational Fluid Dynamics} @end itemize @b{Other Journals} @itemize @bullet @item @strong{Nature} @end itemize @b{Books, Monographs, etc.} @itemize @bullet @item @strong{The Atlas of Hawai'i} (University of Hawai'i Press) @item @strong{Differential Equations with Applications to Biology} (American Mathematical Society) @item @strong{Ocean Drilling Program} publications @end itemize @c HTML @node Acknowledgments, License, Gri in the Press, Top @comment node-name, next, previous, up @chapter Acknowledgments @cindex user input to Gri @cindex acknowledgments Over the years, many Gri users have been kind enough to help in its development. Some have done so by sending in bug reports, others by requesting features, others by submitting patches. A few of their names are: Ivo Alxneit, @cindex contributor, Ivo Alxneit @cindex Ivo Alxneit (contributor) Karin Bryan, @cindex Karin Bryan (contributor) @cindex contributor, Karin Bryan Sara Bennett, @cindex Sara Bennett (contributor) @cindex contributor, Sara Bennett Luke Blaikie, @cindex Luke Blaikie (contributor) @cindex contributor, Luke Blaikie Dave Brickman, @cindex Dave Brickman (contributor) @cindex contributor, Dave Brickman Steve Cayford, @cindex Steve Cayford (contributor) @cindex contributor, Steve Cayford Clyde Clements, @cindex Clyde Clements (contributor) @cindex contributor, Clyde Clements Andrew Collier, @cindex Andrew Collier (contributor) @cindex contributor, Andrew Collier Pierre Flament, @cindex Pierre Flament (contributor) @cindex contributor, Pierre Flament Peter Galbraith, @cindex Peter Galbraith (contributor) @cindex contributor, Peter Galbraith Dave Hebert, @cindex Dave Hebert (contributor) @cindex contributor, Dave Hebert David A. Holland, @cindex David A Holland (contributor) @cindex contributor, David A. Holland Christopher Illies, @cindex Christopher Illies (contributor) @cindex contributor, Christopher Illies Cody Kirkpatrick, @cindex Cody Kirkpatrick (contributor) @cindex contributor, Cody Kirkpatrick Thomas Larsen, @cindex Thomas Larsen (contributor) @cindex contributor, Thomas Larsen Alejandro López-Valencia, @cindex Alejandro Lopez-Valencia (contributor) @cindex contributor, Alejandro Lopez-Valencia Kawamura Masao, @cindex Kawamura Masao (contributor) @cindex contributor, Kawamura Masao Steve Matheson, @cindex Steve Matheson (contributor) @cindex contributor, Steve Matheson Brian May, @cindex Brian May, contributor @cindex contributor, Brian May Ed Nather, @cindex Ed Nather (contributor) @cindex contributor, Ed Nather Roman Neuhauser, @cindex Roman Neuhauser (contributor) @cindex contributor, Roman Neuhauser Carl Osterwisch, @cindex Carl Osterwisch (contributor) @cindex contributor, Carl Osterwisch Richard Andrew Miles Outerbridge, @cindex Richard Andrew Miles Outerbridge (contributor) @cindex contributor, Richard Andrew Miles Outerbridge Tim Powers, @cindex Tim Powers (contributor) @cindex contributor, Tim Powers Jinyu Sheng, @cindex Jinyu Sheng (contributor) @cindex contributor, Jinyu Sheng Toru Suzuki, @cindex Toru Suzuki (contributor) @cindex contributor, Toru Suzuki Keith Thompson, @cindex Keith Thompson (contributor) @cindex contributor, Keith Thompson David Trueman, @cindex David Trueman (contributor) @cindex contributor, David Trueman Wolfgang Voegeli, @cindex contributor and bug-fixer, Wolfgang Voegeli @cindex Wolfgang Voegeli (contributor and bug fixer) Jeff Whitaker, @cindex Jeff Whitaker (contributor) @cindex contributor, Jeff Whitaker and George White. @cindex George White (contributor) @cindex contributor, George White Prime among these is Peter Galbraith, who has been a close collaborator in Gri development and in my scientific work, for two (!) decades. To all, thanks. @c HTML @node License, Concept Index, Acknowledgments, Top @comment node-name, next, previous, up @chapter License @cindex license Gri is distributed under the GPL public license, an Open Source license that provides certain rights and freedom to users, notably the access to source code and the right to modify it and/or redistribute it. The full text of the GPL license is given below. @example GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) yyyy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) yyyy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. @end example @c HTML @c @summarycontents @c @contents @bye gri/doc/version.texi0000644000175000017500000000014713147557614013147 0ustar psgpsg@set UPDATED 31 January 2017 @set UPDATED-MONTH January 2017 @set EDITION 2.12.26 @set VERSION 2.12.26 gri/doc/favicon-gri.ico0000644000175000017500000000126013147557614013464 0ustar psgpsg‰PNG  IHDR‘h6bKGDÿÿÿ ½§“ pHYs``zxEtIMEÒ YU=IDATxœ’]H“qÆŸ÷Ýjï´dš¥.ç 40r²ùA¨•†¢„RQ¬0 $íÆ@“Šº°EÔEÑE923ElEÂjŠiX²üj86›åœéÚû?]¼d_=wÏáw¾8$Éç#Ž¢£Éí¦Š#"Áhôö}  Z[ÁóXNDD&ÓbxD× gçËé…( Õ×ÿVÓn§ññ%²Z™2¨×üÜ6H¶Aê3Û˜2ˆº»‰ˆÜn*+c‚’)ÊË£–òûeµËHÅ™éœ"©á¢ZKÕÙj0†âb,äÝÕã%'Sn¡þ‚ün7hîp%g`¢8l37û9F»ãd‰bÒ9\}q&#÷ÇälzÒ™  ®ÇAó~¼íí:]q`]”fÍÚÈþ׆ôÝ•u×x¹|iÕyŸ÷øþ´û}\ƒ&ÝcNBÍ¥;º”L‹ _+gçï+ÍÝ{D¢§&j-cLÌó¬õ†,‰ ”篷¥dä0îÙbª+¯*ÍŸ9Z@àÃÐ@\üV‰~ÒÖð¾ÿ€õ1±…Ëh6nª¨¹ìrŽJ@Pygg$©ÖÆmNZjµ4J‘ÔÌü_ïÆÐoÏ|ö¸Y $êSwR……ÿ$xÙ_ †ì ±ñ§Ê‹úº]c£íM7ïÝ2-÷²c•µÆ¥ï,œùô±ùö•§šV‡¨ªÎÝðÍ}IÔ§Íû¼‰:ÃJ…@Œ˜(&oKåÆ<ä—ý´?$¬GDÿ‹¾ 0Ž"‘wðIEND®B`‚gri/doc/archive-to-html.pl0000755000175000017500000000266513147557614014141 0ustar psgpsg#!/usr/bin/perl -w if ($#ARGV == 0) { $file = $ARGV[0]; } else { $file = "./gri.archive"; } open(IN, $file) or die "Cannot open $file"; print " Gri newsgroup archive

    12.8: Archive of messages sent to the gri newsgroup

    "; $count = 1; $date = "(unknown date)"; $subject = "(unknown subject)"; $from = "(unknown sender)"; $line = 0; while() { die if $line++>100000; chop; s/&/&/g; s//>/g; # Fix <>. if (/^From /) { #print "Got From ...\n"; while() { s/&/&/g; s//>/g; # Fix <>. chop; #print "Got new line '$_'\n"; if (/Date:\s(.*)/) { $date = $1; } if (/Subject:\s(.*)/) { $subject = $1; } if (/From:\s(.*)/) { $from = $1; } if (/X-Status:/) { print "

    12.8.$count. $subject

    \n"; print "On $date, $from wrote ...
    \n"; $date = "(unknown date)"; $subject = "(unknown subject)"; $from = "(unknown sender)"; last; } } $count++; } else { if (m,(http://.*),) { $url = $1; s:$url:$url:g; } if (m,mailto:\s*(.*),) { $mailto = $1; s,$mailto,$mailto,g; } if (m,[eE]mail:\s*(.*),) { $mailto = $1; s,$mailto,$mailto,g; } print "$_
    \n"; } } print " "; gri/doc/FAQ0000644000175000017500000011721213147557614011123 0ustar psgpsg Introduction This is the FAQ ("frequently asked questions") document for the Gri scientific graphing language, (c) 1991-2000 Dan Kelley (Dan.Kelley@Dal.Ca), to whom you are asked to email reports of Gri errors, or suggestions for Gri improvements or new features. The Questions Q1 Features * Q1.1 What is Gri? * Q1.2 What does `Gri' stand for? How is it pronounced? * Q1.3 What does Gri cost? * Q1.4 How long will it take to learn Gri? Q2 Documentation * Q2.1 Is there a quick-reference card for Gri? * Q2.2 Where can I get documentation for Gri? * Q2.3 Is there a cookbook of Gri program to use for guidance? * Q2.4 Is there a newsgroup for Gri? * Q2.5 Where can I get some sample Gri input files? Q3 Can Gri do ... ? * Q3.1 Can Gri do barcharts? * Q3.2 Can Gri do histograms? * Q3.3 Can Gri do error bars? * Q3.4 Can Gri draw labels for Tukey box plots? * Q3.5 Can Gri read compressed data files? * Q3.6 Can Gri use scientific notation on axes? * Q3.7 Can Gri label x-axis with day of week? * Q3.8 Can Gri draw maps? Q4 Gri and other programs * Q4.1 Is Gri better than Fortran/C/... plotting subroutines? * Q4.2 How can I include Gri plots in LaTeX files? * Q4.3 How may I convert Gri output to GIF format? * Q4.4 Is there an Emacs mode for Gri? Q5 Evolution of Gri * Q5.1 Where can I get the latest version of Gri? * Q5.2 How can I find out the most recent features of Gri? * Q5.3 Should I keep my copy of Gri up-to-date? * Q5.4 How can I protect myself against changes to Gri? Q6 Gri on various computers * Q6.1 What computers does Gri work on? * Q6.2 What kind of compiler is required to compile gri? * Q6.3 Why can't I link my compiled gri? (on HP computer) * Q6.4 Is there a Macintosh version of Gri? * Q6.5 Is there a DOS/Windows version of Gri? * Q6.6 Is there a linux version of Gri? Q7 Gri bugs * Q7.1 What are known bugs in Gri? * Q7.2 How can I report Gri bugs? The Answers _________________________________________________________________ A1 Features A1.1 What is Gri? Gri is a program for drawing scientific graphs. It makes xy plots (linegraphs and scattergraphs), contour plots, and image plots. Unlike many scientific plotting packages, Gri provides precise control over fonts, line widths, grayscales, colors, etc. Since Gri was written by a scientist, it does the kinds of plots scientists want. It has few frills; e.g., it does not do 3D mesh plots, because the author dislikes them. Gri is command-driven, not mouse driven. A1.2 What does `Gri' stand for? How is it pronounced? Gri stands for `gr-interactive', and `gr' is the name of a subroutine library that preceded Gri. The `interactive' adjective indicates that Gri can be used interactively -- that is, Gri is an interpreted language whereas Gr is a compiled language. `Gri' rhymes with `try'. A1.3 What does Gri cost? Gri is free. A commercial version, called Gre (rhymes with `tree') will be made available soon. It contains most of Gri as a subset, but also contains quite a lot of the Perl language as well, making it a fully functional and efficient programming language. A1.4 How long will it take to learn Gri? Most users can get Gri working after spending half an hour with manual (see Q2.1). Familiarity with your operating system (for example for viewing PostScript files) will speed this somewhat. After that, it's best to learn new features only as you come to need them. To begin with, you should skim the manual and the cookbook (see Q2.3), looking just at the illustrations. This will take no more than an hour. The Gri manual is like most computer manuals: it would be a waste of time to read it cover to cover before starting to use Gri. But you'll find the manual helpful as you branch out, modifying the existing examples and inventing code of your own. Learning how to use a new command usually takes only a minute but realizing that the command exists can take longer. That's why many users with sophisticated needs find it useful to spend an afternoon leafing through the entire manual at some point. Most things in Gri can be done elegantly or crudely. The elegant approach may require a little investment in time at the beginning, but this will pay off constantly as your needs grow. For example, folks who like computer programming often start using Gri "newcommands" (a form of subroutines) within a few days. Other folks might avoid newcommands, instead putting their entire program in one long "main routine". What's right for you depends on how you think and the sort of work you do. _________________________________________________________________ A2 Documentation A2.1 Is there a quick-reference card for Gri? Yes, two quick-reference cards are stored on the FTP site ftp://ftp.phys.ocean.dal.ca/users/kelley/gri. The PostScript file refcard.ps is an overview of Gri syntax and usage, while cmdrefcard.ps is a full list of Gri commands. Each of these files is also available in TeX format. A2.2 Where can I get documentation for Gri? Full documentation is available in several forms on the FTP site ftp://ftp.phys.ocean.dal.ca/users/kelley/gri. Check out the FAQ file (which you are reading now), cmdrefcard.ps (a PostScript reference card listing all Gri commands), refcard.ps (a PostScript reference card overviewing Gri), and a file called something like gri_manual_2.051.tar.gz (which is a complete PostScript manual including figures). To save time and paper, you should look at the FAQ and the two reference cards first. The Gri manual is available on the WWW (world wide web) at the URL http://gri.sourceforge.net/gridoc/html/index.html . A2.3 Is there a cookbook of Gri programs to use for guidance? Yes, at the website http://gri.sourceforge.net/gri-cookbook/index.html A2.4 Is there a newsgroup for Gri? Gri has several email-type and web-type forums for discussions. Until recently, the only such forum was a majordomo-based email list, to which one subscribed by sending to majordomo@phys.ocean.dal.ca a message containing just the two words subscribe gri, and to which one contributed by mailing to gri@phys.ocean.dal.ca. However, in summer 2000 Gri got a much better suite of newsgroups, on the SourceForge Gri site . Since these newsgroups are archived and threaded, they are a better resource than the majordomo group mentioned in the last paragraph. A2.5 Where can I get some sample Gri input files? You can get them from the anonymous FTP at ftp://ftp.phys.ocean.dal.ca/users/kelley/gri. It is in the compressed tarfile with the word 'example' contained in it. The file is compressed with the program "gzip," so you'll type gunzip gri-examples-2.1.10.tar.gz tar xvf gri-examples-2.1.10.tar (where 2.1.10 will be changed to the current version number), and the tar program will create a directory called 'examples' which contains the example .gri programs and datafiles. The 'examples' directory also contains subdirectories with names that reflect computer names (e.g., SGI, SUN4). To get run gri on all the examples, go into the appropriate subdirectory and type 'make examples'. For example: cd examples/SUN4 make examples creates files examples/SUN4/example1.ps, examples/SUN4/example2.ps, etc. _________________________________________________________________ A3 Can Gri do ... ? A3.1 Can Gri do barcharts? Gri has no specific command for barcharts, but the operating system can easily rearrange your data into a form that lets Gri draw barcharts. In the following example, the synonym \width is set to the desired width of the bars and \missing is set to an arbitrary missing value. The rest of the code will make sense to any Perl programmer. If you don't know Perl, you should learn it. \width = "1" // width of bars, in x units \missing = "-99" // missing value set missing value \missing set x axis 0 6 1 set y axis 0 20 10 draw axes none // will get whited out by the chart anyway // Create dataset system cat > barchart.dat << "EOF" 1 12 2 14 3 15 4 13 5 10 EOF // Create barchart style dataset and plot it system perl <<"EOF" open (IN, "barchart.dat") || die "Cannot open barchart.dat"; while() { ($x[$i], $y[$i]) = split(' '); $i++; } $n = $i; open (TMP, ">tmp") || die "Cannot open tmp"; for ($i = 0; $i < $n; $i++) { print TMP $x[$i] - \width / 2, " ", 0, "\n"; print TMP $x[$i] - \width / 2, " ", $y[$i], "\n"; print TMP $x[$i] + \width / 2, " ", $y[$i], "\n"; print TMP $x[$i] + \width / 2, " ", 0, "\n"; print TMP \missing, " ", \missing, "\n"; } EOF open tmp read columns x y set graylevel 0.95 draw curve filled to 0 y set graylevel 0 draw curve draw axes draw title "Demonstrate Gri barchart" A3.2 Can Gri do histograms? Gri has no specific command for histograms, but the operating system can easily rearrange your data into a histogram format. Here is Gri code to do it: open "histogram -l 0 -h 10 -i 0.5 < inputfile |" read columns x y // y is number of obs draw curve filled to 0 y where histogram is a perlscript which creates a histogram file named inputfile. An example of histogram is: #!/opt/bin/perl # Calculate histogram of 1-column data $usage ="\ NAME\ histogram -- create histogram file, given data file (1 column)\ \ SYNOPSIS\ histogram -l low -h high -i increment < input_file > output_file\ \ DESCRIPTION\ Scans the input values and finds the percentage of data in bins\ starting at value `low', ending at value `high', and incrementing by\ value `inc'.\ \ FILES\ Standard input: column of numbers\ Standard output: columns: (bin_centre, per, cum_per, num, cum_num)\ where 'per'=percentage and 'num'=number.\ "; require "getopts.pl"; $opt_l = 0; $opt_h = 0; $opt_i = 0; &Getopts('l:h:i:'); die "You must supply commandline arguments!\n$usage" if ($opt_l == $opt_h || $o pt_i == 0); $n = ($opt_h - $opt_l) / $opt_i; print STDERR "Will have $n bins, running from $opt_l to $opt_h in steps of $opt _i\n"; for ($i = 0; $i <= $n; $i++) { $bin[$i] = 0; } while(<>) { chop; ($x) = split; $i = int(0.5 + ($x - $opt_l) / $opt_i); $i = 0 if ($i < 0); $i = $n if ($i > $n); $bin[$i]++; } for ($i = 0; $i <= $n; $i++) { $x = $opt_l + $opt_i * ($i - 0.5); print "$x $bin[$i]\n"; $x = $opt_l + $opt_i * ($i + 0.5); print "$x $bin[$i]\n"; } A3.3 Can Gri do error bars? Gri has no specific command for error bars. It has no internal representation of error bar data -- that is, you can't get them by a read columns command. However, you can get error bars quite easily, simply by reading the data line by line, plotting each one as individually. Here's an example of error bars in y, where the third column stores the error: open a.dat while 1 read .x. .y. .ey. if ..eof.. break end if draw symbol bullet at .x. .y. draw line from .x. {rpn .y. .ey. -} to .x. {rpn .y. .ey. +} end while A3.4 Can Gri draw labels for Tukey box plots? Yes. Here is sample code, in which a label "My Label" is drawn to the right of the median of a Tukey plot extending in the y direction: read columns x y 1 11 2 22 1.2 3 3 5 2 20 3 10 draw y box plot at 2 draw label "My Label" at {rpn 2 xusertocm 0.4 +} \ {rpn y median yusertocm "M" ascent 2 / -} \ cm A3.5 Can Gri read compressed data files? Yes, as of version 2.6 Gri can read compressed files, e.g. open myfile.gz read columns x y will work. You may also, of course, do open "zcat myfile.gz |" read columns x y if you like. A3.6 Can Gri use scientific notation on axes? You have to trick it. Here's an example: // NOTE: this requires manual setting of axes. read columns x y 1 1.1e3 2 1.0e3 3 1.4e3 4 2.3e3 4 1.0e4 y /= 1e3 set y axis 1 5 1 set y format "%g$\times10^3$" draw curve A3.7 Can Gri label x-axis with day of week? A future version of Gri will have much more powerful and general ways of handling axes labelling. In the meantime, you have to trick Gri to get such special effects. Here's an example: set x axis 1 8 1 set y axis 0 1 .1 set font size 0 draw x axis at top draw y axis at right draw x axis at bottom set font size 12 draw y axis at left draw label "Mon" centered at 1.5 {rpn ..ymargin.. 0.7 - ycmtouser} draw label "Tue" centered at 2.5 {rpn ..ymargin.. 0.7 - ycmtouser} draw label "Wed" centered at 3.5 {rpn ..ymargin.. 0.7 - ycmtouser} draw label "Thu" centered at 4.5 {rpn ..ymargin.. 0.7 - ycmtouser} draw label "Fri" centered at 5.5 {rpn ..ymargin.. 0.7 - ycmtouser} draw label "Sat" centered at 6.5 {rpn ..ymargin.. 0.7 - ycmtouser} draw label "Sun" centered at 7.5 {rpn ..ymargin.. 0.7 - ycmtouser} Note that the offset of 0.7 centimeters looks OK to me, with a 12 point font, but you may wish to experiment if you don't like the placement. A3.8 Can Gri draw maps? Gri can draw maps, but it lacks builtin support for map projections. (A previous version had projections, but they were not working correctly and were removed.) Gri does not have builtin coastline files, either. Many good coastline files are on the web; see, for example, Rich Signell's site http://crusty.er.usgs.gov/coast/getcoast.html or the USGS mapping site http://www.usgs.gov or the Global Self-consistent Hierarchical High-resolution Shoreline site http://www.ngdc.noaa.gov/mgg/shorelines/gshhs.html _________________________________________________________________ A4 Gri and other programs A4.1 Is Gri better than Fortran/C/... plotting subroutines? Gri started out as a set of subroutines. The set is called `gr'; the name `gri' means gr-interactive. Although I wrote both `gr' and `gri', I haven't used gr in years. I am unaware of anybody else who ever used `gr'. Thus, in at least this case, the interpreted Gri language is superior to subroutines. In some applications the graphics are hard-wired into the computation so using Gri might not make sense. An example is the SPEM numerical model, which has builtin NCAR plotting calls. But this approach is inefficient in user-time and computer-time, because changing the format of the output may require re-running a model. The best approach is to decouple preparation of data from presentation of data. In highly interactive applications, such as many uses of matlab and statistical programs such as S and S-plus, it may make sense to use the builtin graphics routines because they are so tightly bound to the processing. A4.2 How can I include Gri plots in LaTeX files? This is done outside LaTeX (or TeX), with the program that converts from DVI format to PostScript format. This conversion is done differently on different computers; you'll have to enquire locally. With `dvips', you can use the `\special' command or the `\espfbox' command. The epsfbox command is smarter, since it figures the plot dimensions from the PostScript file itself. Unfortunately, old versions of Gri do not insert the correct plot dimensions in the PostScript file. Here's an example, for a 15cm tall figure, of how to insert a Gri PostScript file into a figure: \documentstyle{article} \begin{document} ... Figure \ref{fig1} shows ... \begin{figure} \vspace*{15cm} % MAKE ENOUGH SPACE \special{psfile=fig1.ps} % THIS INSERTS THE PLOT \caption[Short caption, which appears in list of figures.] {\label{fig1} Long caption, which appears with the figure.} \end{figure} \end{document} In other LaTeX and TeX dialects, of course (e.g. the lovely agu++ format), you'll do things differently; the above will give you enough of a guide. A4.3 How may I convert Gri output to GIF format? Conversion of the Gri PostScript output to GIF is normally done for inclusion in web-pages. For a discussion of the merits of various image formats, see Information Architecture. I have been told that GIF images suffer from both technical limitations (no gamma value is stored in the file) and license restrictions. The PNG format was designed to overcome these limitations, and is expected to replace GIF before the year 2000. It should also be noted that there is no generally acceptable way to convert PostScript to gif, especially when the PostScript is vector based. One problem is that of resolution: if the output GIF is low-resolution, then the text may be drawn roughly because of rasterization. In many convertors one may specify the size of the output image, which permits control over this resolution problem, giving the user the task of weighing file size against output quality. Note also that the colour table frequently gets reordered in the conversion, possibly leading to inaccurate results. Simply stated, PostScript is superior to GIF and other raster-based formats. That's why Gri chose PostScript for the output model. There are several ways to convert Gri PostScript into GIF images. * METHOD 1. Use the convert program, which is a part of the ImageMagick set of software. The convert software is quite powerful, being able to convert from almost any format into almost any other. The ImageMagick software is free, and available on the world-wide-web at URL http://www.wizards.dupont.com/cristy/ImageMagick.html * METHOD 2: The GNU program gs can also do this conversion. In newer versions, this conversion to GIF is builtin. Here is a shellscript #!/usr/bin/sh gri -y -p -b $1.gri gs -q -dNOPAUSE -sDEVICE=ppm -sOutputFile=$1.ppm $1.ps -c quit ppmtogif -interlace -transparent rgb:ff/ff/ff $1.ppm > $1.gif rm -f $1.ppm * METHOD 3: In older versions of gs, you must run a little program in the gs interpreter, by typing $ gs foo.ps GS> (pstoppm.ps)run GS> (foo) ppm1run GS> quit This creates a file called foo.ppm, in the so-called PPM format. Various programs exist for converting image types, e.g. convert. Availability of software: ImageMagick uses Aladdin Ghostscript, another free program, to rasterize the PostScript file created by gri. Ghostscript is available from http://www.cs.wisc.edu/~ghost/index.html and many other sites (including any CTAN archive). Older version of ghostscript are available under the GNU GPL. Speaking of GNU, gs and other GNU software are freely available at many locations on the web, e.g. ftp://prep.ai.mit.edu/pub/gnu Author's note: this answer was compiled with advice from Peter Galbraith, Toru Suzuki, and George White, to each of whom I am very grateful for the help. In fact, the answer is mostly a patchwork of their suggestions, and all the helpful pointers to information on the web are theirs, not mine. A4.4 Is there an Emacs mode for Gri? Yes. Peter Galbraith has written a very powerful mode for Gri commandfiles which is supplied with Gri and which is fully documented in the manual. The capabilities of the mode include the following. * Indents loops, if statements, newcommands, etc. * Uses built-in knowledge of Gri commands to 'complete' your commands. For example, typing 'drM-TAB' (where M-TAB is the completion keystroke) causes the mode to write 'draw' in place of the 'dr'. Pressing M-TAB again gives a list of all Gri commands starting with 'draw'. * Provides complete access to Gri help on commands, including the full Gri 'info' manual if your machine has that installed. There is even an 'apropos' feature to let you search for commands you're not sure even exist. * Lets you run Gri from within the buffer. If syntax or runtime Gri errors are encountered, the cursor (usually) moves to the offending line in the Gri editing buffer. * Lets you run Ghostview without leaving Emacs. _________________________________________________________________ A5 Evolution of Gri A5.1 Where can I get the latest version of Gri? Gri is available at the anonymous FTP site ftp://ftp.phys.ocean.dal.ca/users/kelley/gri Instructions there will tell you what to do, but it should be obvious if you've used FTP before. A5.2 How can I find out the most recent features of Gri? Do anonymous ftp to phys.ocean.dal.ca and cd to the directory /users/kelley/gri. Pick up the file ChangeLog. For more details, see the history chapter in the manual A5.3 Should I keep my copy of Gri up-to-date? The advantages of being up-do-date are: * You get new features. * There is a better chance of getting your bugs repaired, since all bug fixes are applied only to the current version.) The disadvantages of being up-to-date are: * You can get clobbered by new bugs. (You should avoid this by keeping your old versions of Gri. That means archiving both gri, the executable, and gri.cmd, the startup file.) * You can get clobbered by changes in the syntax. This is the penalty you pay for using a program under active development. To protect yourself, use the expecting version command, which will warn you of any incompatibilites between the version you expect and the version that is presently installed. Most people should not be more than 5-10 versions out of date. To keep in touch, subscribe to the gri maillist (...see Q2.3). Also, keep track of the file ChangeLog in the FTP location. As with most software, the supplier may be more enthusiastic about new versions than the users are. Other Gri users may therefore provide the best advice on whether it is worth upgrading. A5.4 How can I protect myself against changes to Gri? The most important thing is to save old versions of Gri. At hard-disk street prices of about a cent per megabyte, an archive will cost under a nickle. Archiving the source is just a matter of copying the files you've downloaded to a location of your choosing. Since the directory name is of the form gri-VERSION, keeping track of old sources is trivial. If you're using a prepackaged version of Gri (e.g. in RedHat or in Debian linux), then you'll probably know how to update Gri already. At any rate, you can skip some of the steps below, since rpm -ql gri will list all the relevant files, saving you the part of the steps below that involves locating files. Archiving the Gri binary and library file is quite easy, but archiving the documentation is complicated since there are a lot of documentation files, and they are scattered across your filesystem. For example, 'info' files go in the /usr/info directory, while 'manpage' files go in the /usr/man/man* directory, and the 'html' files go someplace else). This isn't specific to Gri; the filesystem is just defined that way, for historical reasons. Your first step is to determine whether you wish to archive the documentation. In most case you won't want to. The point is just that you have an old set of scripts that you need to work; you won't be writing new scripts, and if you wrote these ones, then you understand Gri well enough anyway. Besides, Gri doesn't change that much from version to version, and the changes mostly involve additions. If you do wish to archive the documentation and emacs files, locate the files and copy them. (If you do not, skip the remainder of this paragraph.) In Redhat linux, do rpm -ql gri to locate the files. In debian linux, do something similar. If 'locate' is working on your computer, do locate gri and examine the list that you get. If none of the above is true, look in the second-last paragraph above for directories where Gri documentation files are often found, and move them to wherever seems appropriate. You'll probably have to alter other things as well, to tell the info and man programs where to find the documentation. If you use the Emacs editing mode, move that appropriately and edit whatever dot-files and system configuration files that Emacs uses to locate mode files. (Note that all emacs modes understand about using different versions; see the C-c C-r or by calling the command M-x gri-version. If, as is likely, you're only archiving Gri for old scripts that you don't need to edit, you may not need to worry about changes to gri-mode and you may as well go ahead and install the new gri-mode and forget about the old one.) If you only wish to archive Gri itself, things are much easier! You need to copy only two files, the executable (often /usr/bin/gri) and a library file (often /usr/share/gri/gri.cmd) to a directory of your choosing, and then create a shell alias (or a shellscript), which uses these two files you've copied. Let me take it step by step. First, type gri -version and make note of the present version number. For concreteness, let's say it is version 2.6.0. Next, decide where you wish to keep this gri version. For concreteness, let's say that you'd like to keep it in a directory named /usr/local/gri/2.6.0. Create that directory if it doesn't exist already: mkdir -p /usr/local/gri/2.6.0 Next, type gri -directory_default to find out where the gri.cmd file is located. Let's say it's in the common location usr/share/gri, for concreteness; then you need to move this to your chosen directory: mv /usr/share/gri/gri.cmd /usr/local/gri/2.6.0 Now, we need to copy the executable. If you don't know where it is, type which gri to find out. Then move it also, e.g. if Gri is located in the /usr/bin directory, you'd type mv /usr/bin/gri /usr/local/gri/2.6.0 Now we just have to make an alias to run this particular copy of Gri, with this particular library file. In the Bash shell, just put the following line in your ~/.aliases file: alias gri2.6.0='/usr/local/gri/2.6.0/gri -directory /usr/local/gri/2.6.0' and then you have a new command, gri2.6.0 that runs this particular copy of Gri. Alternatively, you could create a shellscript to run this Gri, e.g. a script named gri2.6.0 that contains the lines: #!/usr/bin/sh # Run numbered version of gri /usr/local/gri/2.6.0/gri -directory /usr/local/gri/2.6.0 "$@" _________________________________________________________________ A6 Gri on various computers A6.1 What computers does Gri work on? Gri has been ported to several Unix machines (e.g. Sun solaris and sunOS; IBM RISC; HP RISC; SGI; DEC alpha; and x86 linux) and to x86 MS-DOS. An old version is available for DEC vax VMS. A6.2 What kind of compiler is required to compile gri? Gri requires a C++ compiler capable of handling the language feature called "templates," and it also needs the so-called "standard template library" (STL). Templates have been a feature of C++ since about 1994, and STL became part of the draft C++ library standard in early 1996. If your compiler vendor does not support templates or STL, you should obtain a newer compiler. The free C++ compiler called g++, available from the Free Software Foundation, is known to compile Gri on at least a half-dozen problems. The compiler version must be 2.7.2 or higher for success. A6.3 Why can't I link my compiled gri? (on HP computer) Unfortunately, I made a bad programming decision several versions ago -- I decided to start using the STL (the standard template library). The STL is part of the draft ANSI C++ standard, so I figured I'd be safe. And my tests on solaris and linux platforms indicated that STL worked as advertised, in g++ 2.7.x. However, I should have checked further. It turns out that g++ on some platforms (e.g. HP's unix and IBMRS's AIX unix) does not handle templates properly. The linker cannot locate templates defined in one file and used in another. This issue is discussed at some length in the g++ documentation, where three methods are presented for solving the problem. (In the info-format documentation, you can find the relevant parts by searching for the string "where's the template?") In Gri I've used what method 3 as defined in the g++ manual. Apparently this fails on some platforms. Although I'd welcome tests by users on the other two g++ methods, and I'd be happy to switch if one of them appeared to work more universally, I have to say that I'm not optimistic: from what I read on the newsgroups, nobody is having much success on this. The GNU folks say that g++ version 2.8 will handle templates much better, so I'm waiting for that. Unfortunately it's been, so far, a two-year wait. Almost certainly, commercial compilers handle templates better, but I lack resources to purchase these for the various platforms. I'd be happy, though, to act as a broker for anyone who is able to compile Gri on the problematic platforms, and who is willing to share their results. A6.4 Is there a Macintosh version of Gri? There once was a clicky-pointy Macintosh version of gri, but I got frustrated with modifying the code each time Apple upgraded the OS and stopped maintaining the code. After several years of living (happily) without the Macintosh, I flushed the Mac code down the drain. However a version for Macintosh unix is available . A6.5 Is there a DOS/Windows version of Gri? There is a version available for DOS, available at the normal Gri FTP site, ftp://ftp.phys.ocean.dal.ca/users/kelley/gri and copy another at the anonymous FTP site ftp://shiho.tokyo-u-fish.ac.jp/pub/msdos/gri with filename of the form gri2025b.zip where 2025 refers to the version name. This binary version was prepared and very kindly shared by Toru Suzuki toru@shiho.tokyo-u-fish.ac.jp Together with the distribution comes a file called README, which tells how to install and use Gri in an msdos context. Also, see the Gri manual under the heading Compilation on x86 (PC-style) Computers As for viewing the output, I recommend obtaining a copy of the Ghostview program (which is a general PostScript display program), in the version called GSview. A6.6 Is there a linux version of Gri? For non-RedHat versions of linux, one compiles and installs Gri in the usual way; see the manual for more details. Users of RedHat linux have it much easier though! A RPM (RedHat Program Manager) version of Gri exists, so that installing it takes just one line of typing, or one mouse-click in the RPM GUI-based installer called `glint'. requires just one line of typing. The RPM (RedHat Package Manager) version exists at FTP site ftp://ftp.phys.ocean.dal.ca/users/kelley/gri in a file with a name such as `gri-2.1.17-1.i386.rpm' (RedHat readers will know immediately what all the numbers and dots stand for!) Once you've downloaded this, install Gri by typing rpm -i gri-2.1.17-1.i386.rpm Later on, Gri may be uninstalled ('extracted') by typing rpm -e gri Knowledgeable RedHat users will know that RPM can also give information about Gri; for non-experts, here are a few examples: rpm -qa -- list all installed packages rpm -qi gri -- summarize gri capabilities (if it's installed) rpm -ql gri -- list all files related to gri _________________________________________________________________ A7 Gri bugs A7.1 What are known bugs in Gri? Gri is used daily by many users, including the author, so that it suffers few serious bugs. Generally, more recent versions of Gri suffer fewer bugs than earlier versions. This improvement owes much to the trial of daily usage by folks with differing working styles; and all users can thank those who send in bug reports (see Q7.2). One of the main problems with recent versions of Gri is that line numbers of syntax errors are reported inaccurately, if the error occured inside a new-command. A list of Gri bugs is maintained in the manual. A7.2 How can I report Gri bugs? The first step is to make sure it is actually a bug. You might try, for example, posting a question to the Gri newsgroup (see Q2.3), and getting advice from other users. Please be clear, so you don't waste others users' time. If you think you've found a bug, let the author know. Here's the advice from the manual (see especially item 4, for directions on emailing bug reports): Your bug reports help make Gri reliable and useful. Reporting bugs often results in quick changes to gri which will solve your problem. This is especially true if your version is reasonably up-to-date, for then you can simply get the corrected version and replace the version you were using. Here is how to report bugs. The details of how to report bugs is in the online documents , but the quick answer is to go to the Sourceforge Gri/bug site and use the slick GUI interface there. References 1. http://www.phys.ocean.dal.ca/~kelley 2. mailto:Dan.Kelley@Dal.Ca 3. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A1.1 4. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A1.2 5. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A1.3 6. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A1.4 7. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A2.1 8. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A2.2 9. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A2.3 10. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A2.4 11. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A2.5 12. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A3.1 13. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A3.2 14. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A3.3 15. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A3.4 16. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A3.5 17. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A3.6 18. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A3.7 19. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A3.8 20. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A4.1 21. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A4.2 22. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A4.3 23. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A4.4 24. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A5.1 25. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A5.2 26. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A5.3 27. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A5.4 28. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q6.1 29. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q6.2 30. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q6.3 31. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q6.4 32. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q6.5 33. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q6.6 34. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A7.1 35. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#A7.2 36. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q1.1 37. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q1.2 38. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q1.3 39. http://www.phys.ocean.dal.ca/~kelley/gre 40. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q1.4 41. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q2.1 42. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q2.3 43. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q2.1 44. ftp://ftp.phys.ocean.dal.ca/users/kelley/gri 45. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q2.2 46. ftp://ftp.phys.ocean.dal.ca/users/kelley/gri 47. http://gri.sourceforge.net/gridoc/html/index.html 48. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q2.3 49. http://gri.sourceforge.net/gri-cookbook/index.html 50. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q2.4 51. mailto:majordomo@phys.ocean.dal.ca 52. mailto:gri@phys.ocean.dal.ca 53. http://sourceforge.net/forum/?group_id=5511 54. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q2.5 55. ftp://ftp.phys.ocean.dal.ca/users/kelley/gri 56. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q3.1 57. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q3.2 58. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q3.3 59. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q3.4 60. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q3.5 61. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q3.6 62. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q3.7 63. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q3.8 64. http://crusty.er.usgs.gov/coast/getcoast.html 65. http://www.usgs.gov/ 66. http://www.ngdc.noaa.gov/mgg/shorelines/gshhs.html 67. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q4.1 68. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q4.2 69. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q4.3 70. http://www.lanl.gov/projects/ia 71. http://www.wizards.dupont.com/cristy/ImageMagick.html 72. http://www.cs.wisc.edu/~ghost/index.html 73. ftp://prep.ai.mit.edu/pub/gnu 74. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q4.4 75. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q5.1 76. ftp://ftp.phys.ocean.dal.ca/users/kelley/gri 77. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q5.2 78. http://gri.sourceforge.net/gridoc/html/History.html 79. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q5.3 80. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q2.3 81. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q5.4 82. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q6.1 83. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q6.2 84. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q6.3 85. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q6.4 86. http://gri.sourceforge.net/gridoc/html/mac-install.html#Mac-install 87. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q6.5 88. ftp://ftp.phys.ocean.dal.ca/users/kelley/gri 89. ftp://shiho.tokyo-u-fish.ac.jp/pub/msdos/gri 90. mailto:toru@shiho.tokyo-u-fish.ac.jp 91. http://gri.sourceforge.net/gridoc/html/msdos-install.html#Msdos-install 92. http://www.cs.wisc.edu/~ghost/index.html 93. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q6.6 94. http://gri.sourceforge.net/gridoc/html/index.html 95. ftp://ftp.phys.ocean.dal.ca/users/kelley/gri 96. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q7.1 97. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q7.2 98. http://gri.sourceforge.net/gridoc/html/KnownBugs.html#KnownBugs 99. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q7.2 100. file://localhost/home/kelley/GRI-work/gri/doc/FAQ.html#Q2.3 101. http://gri.sourceforge.net/gridoc/html/ReportingBugs.html#ReportingBugs 102. http://sourceforge.net/bugs/?group_id=5511 gri/doc/Makefile.am0000644000175000017500000001743713147560272012627 0ustar psgpsg## Process this file with automake to produce Makefile.in # gri: doc/Makefile.am srcdir = @srcdir@ VPATH = @srcdir@ info_TEXINFOS = gri.texi PACKAGE_VERSION = @PACKAGE_VERSION@ if OS_IS_LINUX_REDHAT MAN_DIR = $(DESTDIR)$(prefix)/share/man/man1 INFO_DIR = $(DESTDIR)$(prefix)/share/info DOC_DIR = $(DESTDIR)$(prefix)/share/doc/gri-${PACKAGE_VERSION} HTML_DIR = $(DOC_DIR)/html EXAMPLES_DIR = $(DOC_DIR)/examples else if OS_IS_LINUX_DEBIAN MAN_DIR = $(DESTDIR)$(prefix)/share/man/man1 INFO_DIR = $(DESTDIR)$(prefix)/share/info DOC_DIR = $(DESTDIR)$(prefix)/share/doc/gri HTML_DIR = $(DOC_DIR)/html EXAMPLES_DIR = $(DOC_DIR)/examples else if OS_IS_FINK MAN_DIR = $(DESTDIR)$(prefix)/share/man/man1 INFO_DIR = $(DESTDIR)$(prefix)/share/info DOC_DIR = $(DESTDIR)$(prefix)/share/doc/gri-${PACKAGE_VERSION} HTML_DIR = $(DOC_DIR)/html EXAMPLES_DIR = $(DOC_DIR)/examples else if OS_IS_FREEBSD MAN_DIR = $(DESTDIR)$(prefix)/man/man1 INFO_DIR = $(DESTDIR)$(prefix)/info DOC_DIR = $(DESTDIR)$(prefix)/share/doc/gri HTML_DIR = $(DOC_DIR)/html EXAMPLES_DIR = $(DESTDIR)$(prefix)/share/examples/gri else MAN_DIR = $(DESTDIR)$(prefix)/share/man/man1 INFO_DIR = $(DESTDIR)$(prefix)/share/info DOC_DIR = $(DESTDIR)$(prefix)/share/gri/doc HTML_DIR = $(DOC_DIR)/html EXAMPLES_DIR = $(DOC_DIR)/examples endif endif endif endif RM = rm -f # REFCARD = refcard # CMD_REFCARD = cmdrefcard HTML_LONG_NAME = gri-long # INFO_DIR_SOLARIS = $(DESTDIR)$(prefix)/info TEX = ${SHELL} ../missing --run tex TEXINDEX = ${SHELL} ../missing --run texindex SUBDIRS = examples resources screenshots tst_suite EXTRA_DIST = \ refcard.tex cmdrefcard.tex\ install-sh archive-to-html.pl cmdrefcard.tex refcard.tex\ FAQ.html\ gri-manpage.1 gri-manpage-redhat.1 gri-manpage-SunOS5.1\ gri_merge.1-skel gri_unpage.1-skel\ gri2texi texinfo2HTML gri2html HTML_subdivide\ make_html_index make_html_commandindex make_html_builtinindex\ mdate-sh html: $(srcdir)/gri.texi cd examples ; ${MAKE} cd tst_suite ; ${MAKE} # Make the info page (even if rewritten later) to get indices ... $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I$(srcdir) gri.texi # ... but this is clumsy and should be done with a dependency. cat $(srcdir)/gri.texi > TMP perl $(srcdir)/make_html_index >> TMP perl $(srcdir)/make_html_commandindex >> TMP perl $(srcdir)/make_html_builtinindex >> TMP cat TMP | perl $(srcdir)/texinfo2HTML > $(HTML_LONG_NAME) $(RM) TMP $(RM) gri[1-9]*.html perl $(srcdir)/HTML_subdivide $(HTML_LONG_NAME) "The Gri graphing language" $(RM) $(HTML_LONG_NAME) $(RM) *.pass2 if test ! -f index.html ; then ln -s gri1.html index.html ; fi touch html install-refcards: $(INSTALL_DATA) refcard.ps $(CARD_DIR) $(INSTALL_DATA) cmdrefcard.ps $(CARD_DIR) html-tar: ${MAKE} html-install DOC_DIR=./gridoc tar -c -f gridoc.tar ./gridoc gzip -f --best gridoc.tar html-install: # NB. Be careful in editing this target. Things that are # created during the building process do not have $(srcdir) # in their names; only things in the tarball have that prefix. ${INSTALL} -d $(HTML_DIR) ${INSTALL} -d $(HTML_DIR)/resources $(INSTALL_DATA) $(srcdir)/resources/*.gif $(HTML_DIR)/resources ${INSTALL} -d $(HTML_DIR)/tst_suite $(INSTALL_DATA) tst_suite/*html $(HTML_DIR)/tst_suite $(INSTALL_DATA) $(srcdir)/examples/*.gri $(HTML_DIR)/ $(INSTALL_DATA) examples/*.html $(HTML_DIR)/ $(INSTALL_DATA) examples/*.png $(HTML_DIR)/ ${INSTALL} -d $(HTML_DIR)/screenshots $(INSTALL_DATA) $(srcdir)/screenshots/*.png $(HTML_DIR)/screenshots $(INSTALL_DATA) *.html $(HTML_DIR) ${INSTALL} -d $(EXAMPLES_DIR) $(INSTALL_DATA) $(srcdir)/examples/model* $(EXAMPLES_DIR) $(INSTALL_DATA) $(srcdir)/examples/*.dat $(EXAMPLES_DIR) $(INSTALL_DATA) $(srcdir)/examples/*.gri $(EXAMPLES_DIR) $(INSTALL_DATA) $(srcdir)/examples/e*.ps $(EXAMPLES_DIR) $(INSTALL_SCRIPT) $(srcdir)/examples/FEM.pl $(EXAMPLES_DIR) (cd $(HTML_DIR); rm -rf examples ; ln -sf ../examples) # Sun Jun 8 11:40:52 UTC 2003 [Dan Kelley] # This is commented-out because it's not used. Later it will be deleted. #card-clean: # -$(RM) refcard.dvi refcard.log refcard.ps # -$(RM) cmdrefcard.dvi cmdrefcard.log cmdrefcard.ps # -$(RM) card # Sun Jun 8 11:40:52 UTC 2003 [Dan Kelley] # This is commented-out because it's not used. Later it will be deleted. #html-clean: # rm -rf HIDE_FILE # mkdir HIDE_FILE # mv FAQ.html HIDE_FILE # -$(RM) *.html *.png html # mv HIDE_FILE/FAQ.html . # rm -rf HIDE_FILE #info-install-solaris: # $(INSTALL) -d $(INFO_DIR_SOLARIS) # chmod 755 $(INFO_DIR_SOLARIS) # cp gri.info* $(INFO_DIR_SOLARIS) # chmod 644 $(INFO_DIR_SOLARIS)/gri.info* refcard.ps: refcard.tex $(TEX) $(srcdir)/refcard.tex dvips -o refcard.ps -t landscape -t letter refcard.dvi cmdrefcard.ps: cmdrefcard.tex $(TEX) $(srcdir)/cmdrefcard.tex dvips -o cmdrefcard.ps -t landscape -t letter cmdrefcard.dvi gri.ps: gri.texi cd examples ; ${MAKE} eps cd screenshots ; ${MAKE} eps cd tst_suite ; ${MAKE} texi $(TEX) gri.texi $(TEXINDEX) gri.cp $(TEX) gri.texi dvips -o gri.ps -t letter gri.dvi #ps-install: gri.ps # $(INSTALL) -d $(DOC_DIR) # chmod 755 $(DOC_DIR) # $(INSTALL) -m 644 gri.ps $(DOC_DIR) gri.pdf: gri.texi cd examples ; ${MAKE} pdf cd screenshots ; ${MAKE} pdf cd tst_suite ; ${MAKE} texi pdftex gri.texi $(TEXINDEX) gri.cp pdftex gri.texi pdftex gri.texi pdftex gri.texi # Add to some of the automake-created targets. all-local: refcard.ps cmdrefcard.ps ${MAKE} html if OS_IS_LINUX_REDHAT gri_manpage_name = gri-manpage-redhat.1 else gri_manpage_name = gri-manpage.1 endif install-data-local: ${MAKE} html-install $(MKDIR_P) $(DOC_DIR) $(INSTALL) -m 644 $(srcdir)/../license.txt $(DOC_DIR) if !OS_IS_LINUX_REDHAT # This is handled by gri.spec [2003-may-31 Dan Kelley] $(INSTALL_DATA) refcard.ps $(DOC_DIR) $(INSTALL_DATA) cmdrefcard.ps $(DOC_DIR) endif mkdir -m 755 -p $(MAN_DIR) cat $(srcdir)/../doc/$(gri_manpage_name) | sed -e s,VERSION,${PACKAGE_VERSION}, > tmp $(INSTALL_DATA) tmp $(MAN_DIR)/gri.1 $(RM) tmp # Install manpages manually; man_MANS puts them in /usr/man/man1, which is not where # they are supposed to go, at least on linux/redhat systems [2003-jun-8 Dan Kelley] $(INSTALL_DATA) $(srcdir)/../doc/gri_merge.1-skel $(MAN_DIR)/gri_merge.1 $(INSTALL_DATA) $(srcdir)/../doc/gri_unpage.1-skel $(MAN_DIR)/gri_unpage.1 mkdir -m 755 -p $(INFO_DIR) echo "INSTALLING INTO INFO_DIR WHICH IS [$(INFO_DIR)]" if !OS_IS_FINK $(INSTALL_DATA) $(srcdir)/../doc/gri.info* $(INFO_DIR) else @echo "DEBUG: The OS is fink" endif if !OS_IS_LINUX_REDHAT # This is handled by gri.spec [2003-may-31 Dan Kelley] gzip -f --best $(MAN_DIR)/gri_merge.1 gzip -f --best $(MAN_DIR)/gri_unpage.1 if !OS_IS_FINK cd $(INFO_DIR) ; gzip -f --best gri.info* endif endif uninstall-local: $(RM) `ls ../*ps ../license.txt *.html gri.info* $(HTML_DIR)/examples/* $(HTML_DIR)/resources/* $(HTML_DIR)/tst_suite/* $(HTML_DIR)/screenshots/* $(HTML_DIR)/*` $(RM) html $(RM) $(DOC_DIR)/license.txt $(DOC_DIR)/refcard.ps $(DOC_DIR)/cmdrefcard.ps $(RM) refcard* cmdrefcard* $(RM) $(MAN_DIR)/gri.* $(MAN_DIR)/gri_unpage.* $(MAN_DIR)/gri_merge.* $(RM) $(INFO_DIR)/gri.info* gri/doc/texim2texi0000755000175000017500000000367713147557614012632 0ustar psgpsg#!/usr/bin/perl -w # Convert macros into texi format. Macros are: # # @c EQUIVALENCE .* .* -> translate 1st string (one word) to 2nd (possibly several words) # @c SYNTAX .* -> make pretty list, establish link to 'how to read syntax' # @c EXAMPLE .* -> example with a title # @c QUIETEXAMPLE .* -> as EXAMPLE but no title # @c TESTFILE .* -> establish link to testfile # @c STYLE .* -> formatting for examples # @c CLICKABLE_SAMPLE .* .* -> for html, graph+code. First is gif, second code (normally as html). while(<>) { next if /\@c -\*- mode:/; foreach $target (keys (%equivalence)) { s/$target/$equivalence{$target}/g; } if (/\@c\s*EQUIVALENCE\s([^ ]*)\s*([^\n]*)/) { $equivalence{$1} = $2; print STDERR "Established Equivalance '$1' -> '$2'\n"; } elsif (/\@c\s*STYLE\s*(.*)/) { $item = $1; s,\@c\s*STYLE.*,\@noindent\n\@emph{Style $item} ---,; } elsif (/\@c\s*SYNTAX\s*(.*)/) { $item = $1; $item =~ s/\\N/\n/g; s,\@c\s*SYNTAX.*,\n\n\@c HTML \n\@emph{Syntax:}\n\@c HTML \n\@example\n$item\n\@end example,; } elsif (/\@c\s*EXAMPLE\s*(.*)/) { $item = $1; $item =~ s/\\N/\n/g; s,\@c\s*EXAMPLE.*,\n\@emph{Example:}\n\@example\n$item\n\@end example,; } elsif (/\@c\s*QUIETEXAMPLE\s*(.*)/) { $item = $1; $item =~ s/\\N/\n/g; #print STDERR; s,\@c\s*QUIETEXAMPLE.*,\@example\n$item\n\@end example,; #print STDERR; } elsif (/\@c\s*CLICKABLE_SAMPLE\s*([^\s]*)\s*([^\s]*)/) { print "\@c HTML (Click figure below to see the code that generated it.)\n"; print "\@c HTML
    \n"; next; # skip the command itself } elsif (/\@c\s*TESTFILE/) { s,\@c\s*TESTFILE\s(.*),\n\ \@c HTML Test file `$1.gri'.

    \ \@iftex\ \@sp 1\ \@noindent Test file \@file{$1.gri}:\ \ \@cartouche\ \@include tst_suite/$1.texi\ \@end cartouche\ \@end iftex,; } print; } gri/doc/favicon-gri.gri0000644000175000017500000000102313147557614013470 0ustar psgpsgset x size 5 set y size 5 set x axis 0 1 0.25 set y axis 0 20 10 set font size 0 \background_color = "hsb 0.60 0.24 1" \line_color = "red" \word_color = "black" read columns x y 0.0 12.5 0.25 19 0.5 12 0.75 15 1 13 draw axes none set color \background_color set line width axis rapidograph 6 draw curve filled to ..ybottom.. y set color black #draw axes frame set color \line_color set line width 10 draw curve set color \word_color set font size 100 set font to Helvetica draw label "Gri" at 0.05 1.3 gri/doc/make_html_index0000755000175000017500000000214213147557614013642 0ustar psgpsg#!/usr/local/bin/perl # Create HTML index from index of pre-installed info page. # Bug: the @code{} items get lost, too bad. $debug = 0; # change to 1 to get some debugging output open(IN, "info -f ./gri.info 'Concept Index' | ") || die "Cannot get 'Concept Index'\n"; print " \@c HTML \@c HTML

    Concept index

    \@node Concept Index, Index of Builtins, Index of Builtins, Top \@c HTML Navigation: \@c HTML next, \@c HTML previous, \@c HTML parent. \@itemize \@bullet "; # Skip header ... this may be brittle, since how do we know how it's defined? while() { chop; #print "SKIPPING ($_)\n"; last if /Menu:/; } # Process the body. while() { chop; print "BEFORE [$_]\n" if $debug; s/\s*\((line)\s*[0-9]+\)\s*//; s/\s*$//; print "AFTER [$_]\n" if $debug; next if /^$/; # ignores "(line #)" lines, which occur for long items. s/\* //; s/\.$//; s/:\s*/\n ... \@xref{/; s/$/}/; print "\@item\n $_\n"; } print "\@end itemize\n"; gri/doc/gri-manpage-SunOS5.10000644000175000017500000000604713147557614014137 0ustar psgpsg.TH GRI 1 .SH NAME gri \- scientific graphics language .SH SYNOPSIS .B gri [ .B OPTIONS ] [ .I CommandFile [ .I optional_arguments ]] .SH DESCRIPTION Gri is a programming language for scientific graphics. It can make x-y graphs, contour-graphs, and image graphs. In addition, Gri has a full suite of low-level graphical elements and sufficient programming capabilities (loops, subroutines, etc) to permit complex customization. Gri is not a point-click application. In some ways it is analogous to TeX. Extensive power rewards tolerance of a modest learning curve. .C For more information, please consult online .C .I info .C and .C .I html .C manuals. .C The .C .I info .C manual is normally accessed by typing .C .C .B info gri An online .I html manual is normally located at .B /opt/gri/doc/gri/html/index.html but it may be installed in a different place on this machine. .C The .C .I html .C FAQ is located at .C .B /usr/doc/gri-N.N.N/html/FAQ.html .C There is also a .C .I reference card .C in TeX and postscript formats. See .C .B /usr/doc/gri/refcard.* .C .C The .C .I examples .C in .C .B /usr/doc/gri/examples/ .C are shown in the manual, and are included as a quick start primer. .C .SH GRI_MERGE AND GRI_UNPAGE COMMANDS .C .C Two Perl scripts are provided with Gri to manipulate the PostScript .C output. .C .C .I gri_merge .C is used to merge multiple Gri output files into a single PostScript file. .C Type .C .B gri_merge -h .C for usage information. .C .C .I gri_unpage .C is used is split a multi-page Gri output file (in which the .C .B new page .C command was used) into separate PostScript files, one for each page. Type .C .B gri_unpage -h .C .SH EMACS SUPPORT .C .C An .C .I emacs .C mode is provided with Gri. .C .C Consult the primer .C .C .C .C .B /opt/gri/doc/gri/doc/README.gri-mode .C .C The mode may be installed automatically in Debian by the elisp file: .C .C .B /etc/emacs/site-start.d/50gri.el .C .C The emacs mode itself is .C .I gri-mode.el .C and is installed on Debian as .C .B /usr/share/emacs/site-lisp/gri-mode.el .C .C Byte-compiled versions of this file are produced for every flavour of Emacs .C that is installed, and are located in places like .C .B /usr/share/emacs/20.2/site-lisp/gri-mode.elc .C .SH INSTALLING MULTIPLE VERSIONS .C .C Since the way Gri works sometimes changes with new versions, you may want .C to keep old versions installed if an important script depends on it. The .C Debian packaging of Gri allows this. Installing the next gri package .C (named like gri_2.1.22-1_i386.deb) will replace your current version, but .C Debian i386 (and perhaps alpha) packages will be made for older versions .C which can be installed alongside the main gri package. Look for a package .C named like so: .C .C .B gri-2.1.21_2.1.21-1_i386.deb .C .C at the ftp site: .C .C .B ftp://ftp.phys.ocean.dal.ca/users/rhogee/gri/ .SH AUTHOR Gri (c) 1999-2002 Dan Kelley , released as GPL open-source software. This manual page is patterned on the Debian manual page by Peter S Galbraith gri/doc/tst_suite/0000755000175000017500000000000013147560320012574 5ustar psgpsggri/doc/tst_suite/tst_control.gri0000644000175000017500000000147613147557614015675 0ustar psgpsgshow "doc/tst_suite/tst_control.gri ..." ... # If statements if 0 assert 0 " failed test 1" end if if 1 else assert 0 " failed test 2" end if # Loops. # Loop with if inside .i. = 0 while {rpn .i. 3 >} .i. += 1 if 1 else assert 0 " failed test 3" end if end while assert {rpn .i. 3 ==} " failed test 4" # Loop inside if if 1 .i. = 0 while {rpn .i. 3 >} .i. += 1 end while assert {rpn .i. 3 ==} " failed test 5" else assert 0 " failed test 6" .i. = 0 while {rpn .i. 3 >} .i. += 1 end while assert 0 " failed test 7" end if # Nested loops .i. = 0 while {rpn .i. 2 >} .j. = 0 while {rpn .j. 4 >} .j. += 1 end while .i. += 1 end while assert {rpn .i. 2 ==} " failed test 8" assert {rpn .j. 4 ==} " failed test 9" show " passed" gri/doc/tst_suite/tst_var_syn.gri0000644000175000017500000002242013147557614015666 0ustar psgpsgshow "doc/tst_suite/tst_var_syn.gri ..." ... rpnfunction same - abs 1e-10 > # Are numbers virtually same? # New and delete (variables) .v. = 1 new .v. .v. = 2 assert {rpn .v. 2 same} " failed test 1.1" assert {rpn ".v." defined} " failed test 1.2" delete .v. assert {rpn .v. 1 same} " failed test 1.3" assert {rpn ".v." defined} " failed test 1.4" delete .v. assert {rpn ".v." defined !} " failed test 1.4" # New and delete (synonyms) \v = "hi" new \v \v = "hello" assert {rpn "\v" "hello" ==} " failed test 2.1" assert {rpn "\\v" defined} " failed test 2.2" delete \v assert {rpn "\v" "hi" ==} " failed test 2.3" assert {rpn "\\v" defined} " failed test 2.4" delete \v assert {rpn "\\v" defined !} " failed test 2.5" # Multi-word synonyms \h = "Hi there buddy" assert {rpn \[]h 3 ==} " failed test 3.1" .i. = \[]h assert {rpn .i. 3 ==} " failed test 3.2" assert {rpn "\[0]h" "Hi" ==} " failed test 3.3" assert {rpn "\[1]h" "there" ==} " failed test 3.4" assert {rpn "\[2]h" "buddy" ==} " failed test 3.5" \h = "Hi means \"hello\"" assert {rpn "\[0]h" "Hi" ==} " failed test 3.6" assert {rpn "\[1]h" "means" ==} " failed test 3.7" assert {rpn "\[2]h" "\"hello\"" ==} " failed test 3.8" .i. = 1 assert {rpn "\[.i.]h" "means" ==} " failed test 3.9" \i = "1" assert {rpn "\[\i]h" "means" ==} " failed test 3.10" # Setting by quoted name set ".var." to 10 assert {rpn .var. 10 ==} " failed test 4.1" set "\\syn" to "hi" assert {rpn "\syn" "hi" ==} " failed test 4.2" # Setting by quoted name, in a new command `hi pi "\\Greeting" ".Pi."' { set "\.word2." to "hi" set "\.word3." to 3.14 } hi pi "\\g" ".p." assert {rpn "\g" "hi" ==} " failed test 5.1" assert {rpn .p. 3.14 ==} " failed test 5.2" # Execution of synonyms \ret = "\string = \"Hello\"" \ret assert {rpn "\string" "Hello" ==} " failed test 6.1" # Parsing of individual words in synonyms (tests SourceForge bug 114983) `Newcommand "\pat"'' { \t = "A .2" assert {rpn "\[0].word1." "\[0]t" ==} " failed test 7.1" } Newcommand "A .2" # Test aliased synonyms # Part 1. check to see if can delete without either a # single or a double backslash, and either with # enclosing double-quotes, or not. \a = "HI" assert {rpn "\\a" defined } " failed test 8.1" delete \a assert {rpn "\\a" defined ! } " failed test 8.2" \a = "HI" delete \a assert {rpn "\\a" defined ! } " failed test 8.3" new \a assert {rpn "\\a" defined } " failed test 9.1" \a = "greeting" assert {rpn "\\a" defined } " failed test 9.2" delete \a assert {rpn "\\a" defined ! } " failed test 9.3" # Part 5. sprintf sprintf \a "%.1f" 10 assert {rpn "\a" "10.0" == } " failed test 10.1" \alias_for_a = "\\a" sprintf \@alias_for_a "%.1f" 20 assert {rpn "\a" "20.0" == } " failed test 10.2" # Part 6. Environment variables (SF bug 117415) \alias_for_a = "\\a" get env \@alias_for_a "SHELL" get env \b "SHELL" assert {rpn "\a" "\b" ==} " failed test 11.1" # Part 7 'read' (SF bug 117412) \TMPFILE = tmpname system echo "Hello" > \TMPFILE open "\TMPFILE" read \a assert {rpn "\a" "Hello" ==} " failed test 12.1" \a = "JUNK" \alias_for_a = "\\a" rewind read \\a assert {rpn "\a" "Hello" ==} " failed test 12.2" \a = "JUNK" \alias_for_a = "\\a" rewind read \@alias_for_a close assert {rpn "\a" "Hello" ==} " failed test 12.3" system rm -f \TMPFILE # Part 8 -- ensure not trying to evaluate inside 'false' if parts. \str = "Hello" \t = {rpn "\s" "tr" strcat} # construct a name if {rpn "\\t" defined} # test if defined .val. = 1 end if if {rpn "\\x" defined} # this one is not defined .val. = 2 end if assert {rpn .val. 1 ==} " failed test 12.4" # \a1 = "1" \b1 = "2" \a2 = "10" \b2 = "20" read columns x y \a1 \b1 \a2 \b2 assert {rpn x 0 @ 1 ==} " failed test 13.1" assert {rpn x 1 @ 10 ==} " failed test 13.2" assert {rpn y 0 @ 2 ==} " failed test 13.3" assert {rpn y 1 @ 20 ==} " failed test 13.4" `NC ...' { read columns x y \.word1 \.word2. } NC 1 10 assert {rpn x 0 @ 1 ==} " failed test 14.1" assert {rpn y 0 @ 10 ==} " failed test 14.2" \a = "1 2" \b = "10 20" \index = "0" read columns x y \[\index]a \[1]b assert {rpn x 0 @ 1 ==} " failed test 15.1" assert {rpn y 0 @ 20 ==} " failed test 15.2" `NC2 ...' { read columns x y \[0].word1. \[0].word2. \[1].word1. \[1].word2. } NC2 "1 2" "100 200" assert {rpn x 0 @ 1 ==} " failed test 16.1" assert {rpn x 1 @ 2 ==} " failed test 16.2" assert {rpn y 0 @ 100 ==} " failed test 16.3" assert {rpn y 1 @ 200 ==} " failed test 16.4" # Part 9. New commands with variables # Rvalue: synonyms/variables `ampersand_rvalue &.v. &\s' { new \syn \syn = "Shadow" new .a. .a. = 0 assert {rpn \.word1. 1 ==} " failed test 17.1" assert {rpn "\.word2." "Brightness" ==} " failed test 17.2" delete \syn delete .a. } .a. = 1 \syn = "Brightness" ampersand_rvalue &.a. &\syn # Rvalue + Lvalue: synonym `append &\s' { \.word1. = "\.word1. and bye" } \a = "hi" append &\a assert {rpn "\a" "hi and bye" ==} "failed test 18.3" # Rvalue + Lvalue: variable in the = form of assignment `double &.var.' { \.word1. = {rpn \.word1. 2 *} } .a. = 10 double &.a. assert {rpn .a. 20 ==} "failed test 18.4" `Double &.var.' { \.word1. *= 2 } .a. = 10 Double &.a. assert {rpn .a. 20 ==} " failed test 18.5" `halve &.var.' { \.word1. = {rpn \.word1. 2 /} } halve &.a. assert {rpn .a. 10 ==} " failed test 18.6" `NC3 &\friendly' { \.word1. = "Howdy" } \greeting = "Hi" NC3 &\greeting assert {rpn "\greeting" "Howdy" ==} " failed test 18.7" `postpend_dat &\filename' { \.word1. = {rpn "\.word1." ".dat" strcat} } \filename = "test" postpend_dat &\filename assert {rpn "test.dat" "\filename" ==} " failed test 18.8" # new `test_new &\s' { new \.word1. new \a \a = "This will dissapear" \.word1. = "Think locally" delete \a } \a = "Act globally" test_new &\a assert {rpn "\a" "Think locally" ==} " failed test 18.9" delete \a assert {rpn "\a" "Act globally" ==} " failed test 18.10" `test_new_delete &\s' { new \a \a = "Insurrection" assert {rpn "\.word1." "Act globally" ==} " failed test 18.11" delete \.word1. assert {rpn "\.word1." "Or else" ==} " failed test 18.12" delete \a } \a = "Or else" new \a \a = "Act globally" test_new_delete &\a # Nexting `nest2 &.v. &\s' { assert {rpn "\.word1." "HI" ==} " failed test 18.13" assert {rpn \.word2. 0.5 ==} " failed test 18.14" } `nest1 &.v. &\s' { nest2 &\.word2. &\.word1. # reversed } .a. = 0.5 \s = "HI" nest1 &.a. &\s # defined `check_defined &.v.' { assert {rpn "\\.word1." defined} " failed test 18.15" delete .a. assert {rpn "\\.word1." defined !} " failed test 18.16" } .a. = 100 check_defined &.a. # System \t = system perl <<"EOF" {print "Hi"}; EOF assert {rpn "\t" "Hi" ==} " failed test 19.1" \t = system perl <<"EOF" {print "Hello"}; EOF assert {rpn "\t" "Hello" ==} " failed test 19.2" `NC4' { \t = system perl <<"EOF" {print "Howdie"}; EOF } NC4 assert {rpn "\t" "Howdie" ==} " failed test 19.3" `NC5' { \t = system perl <<"EOF" {print "G'day"}; EOF } NC5 assert {rpn "\t" "G'day" ==} " failed test 19.4" ### BLOCK 20 ### # Alias as lvalue (e.g. \@ptr = ...) # (1) lvalue synonyms \greeting = "You say goodbye" \alias = "\\greeting" \@alias = "And I say hello" assert {rpn "\greeting" "And I say hello" ==} " failed test 20.1" # (2) lvalue variables .b. = 1 \bptr = ".b." \@bptr *= 2 assert {rpn .b. 2 ==} " failed test 20.2" \@bptr = 10 assert {rpn .b. 10 ==} " failed test 20.3" # Alias as rvalue (e.g. show "\@ptr") # (1) rvalue synonyms \a = "HI" \aptr = "\\a" assert {rpn "\@aptr" "HI" ==} " failed test 20.4" \@aptr = "BYE" assert {rpn "\@aptr" "BYE" ==} " failed test 20.5" \aa = "\@aptr" assert {rpn "\@aptr" "BYE" ==} " failed test 20.6" # (2) rvalue variables .a. = 1 \aptr = ".a." assert {rpn \@aptr 1 ==} " failed test 20.7" .aa. = {rpn .a. 1 +} assert {rpn .aa. 2 ==} " failed test 20.8" # Missing values set missing value 0 .x. = 0 assert {rpn .x. ismissing} " failed test 21.1" assert {rpn .x. 1 + ismissing} " failed test 21.2" set missing value 1e33 show " passed" gri/doc/tst_suite/Makefile.in0000644000175000017500000002727513147560320014656 0ustar psgpsg# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/tst_suite ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) VPATH = @srcdir@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS_TEMPLATE = @EXTRA_CFLAGS_TEMPLATE@ GREP = @GREP@ HAVE_CONVERT = @HAVE_CONVERT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PROGS = @PROGS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ # gri: doc/tst_suite/Makefile.am srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ the_texi = tst_IO.texi tst_control.texi tst_rpn.texi tst_var_syn.texi the_html = tst_IO.html tst_control.html tst_rpn.html tst_var_syn.html EXTRA_DIST = tst_IO.gri tst_IO_1.dat tst_IO_2.dat tst_control.gri\ tst_rpn.gri tst_var_syn.gri $(the_texi) DISTCLEANFILES = $(the_html) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/tst_suite/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/tst_suite/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am .PRECIOUS: Makefile %.texi : %.gri perl $(srcdir)/../gri2texi $< $@ %.html : %.gri perl $(srcdir)/../gri2html $< $@ all: texi html texi: $(the_texi) html: $(the_html) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gri/doc/tst_suite/tst_IO_2.dat0000644000175000017500000000001113147557614014714 0ustar psgpsg1 11 2 22gri/doc/tst_suite/Makefile.am0000644000175000017500000000106413147557614014645 0ustar psgpsg## Process this file with automake to produce Makefile.in # gri: doc/tst_suite/Makefile.am srcdir = @srcdir@ VPATH = @srcdir@ the_texi = tst_IO.texi tst_control.texi tst_rpn.texi tst_var_syn.texi the_html = tst_IO.html tst_control.html tst_rpn.html tst_var_syn.html EXTRA_DIST = tst_IO.gri tst_IO_1.dat tst_IO_2.dat tst_control.gri\ tst_rpn.gri tst_var_syn.gri $(the_texi) DISTCLEANFILES = $(the_html) %.texi : %.gri perl $(srcdir)/../gri2texi $< $@ %.html : %.gri perl $(srcdir)/../gri2html $< $@ all: texi html texi: $(the_texi) html: $(the_html) gri/doc/tst_suite/tst_rpn.gri0000644000175000017500000000706413147557614015013 0ustar psgpsgshow "doc/tst_suite/tst_rpn.gri ..." ... rpnfunction same - abs 1e-5 > # Are numbers virtually same? # Simple arithmetic .a. = 0 assert {rpn .a. !} " failed test 1.1" .a. += 1 assert .a. " failed test 1.2" .a. += 1 assert {rpn .a. 2 same} " failed test 1.3" .a. *= 2 assert {rpn .a. 4 same} " failed test 1.4" .a. /= 4 assert {rpn .a. 1 same} " failed test 1.5" assert {rpn 2 1 - 1 same} " failed test 1.6" assert {rpn 2 1 + 3 same} " failed test 1.7" assert {rpn 3 2 * 6 same} " failed test 1.8" assert {rpn 4 2 / 2 same} " failed test 1.9" # Conversions (lower-case ok on input, but output is upper-case) assert {rpn "aa" hex2dec 170 ==} " failed test 2.1" assert {rpn "AB" hex2dec 171 ==} " failed test 2.2" assert {rpn 63 dec2hex "3F" ==} " failed test 2.3" assert {rpn 193 dec2hex "C1" ==} " failed test 2.4" # Logic assert {rpn 1 0 or} " failed test 3.1" assert {rpn 0 1 or} " failed test 3.2" assert {rpn 1 0 |} " failed test 3.3" assert {rpn 0 1 |} " failed test 3.4" assert {rpn 1 0 and not} " failed test 3.5" assert {rpn 1 0 & !} " failed test 3.6" # Logs, powers .a. _= 10 assert {rpn .a. 0 same} " failed test 4.1" .a. = 2 .a. ^= 8 assert {rpn .a. 256 same} " failed test 4.2" assert {rpn -2 4 power 16 ==} " failed test 4.3" assert {rpn -2 3 power -8 ==} " failed test 4.4" assert {rpn -2 2 power 4 ==} " failed test 4.5" assert {rpn 2 3 power 8 ==} " failed test 4.6" # String operations \a = {rpn "file" ".dat" strcat} assert {rpn "\a" "file.dat" ==} " failed test 5.1" \sentence = "This sentence has five words" \w1 = word 0 of "\sentence " assert {rpn "\w1" "This" ==} " failed test 5.2" \w2 = word 1 of "\sentence " assert {rpn "\w2" "sentence" ==} " failed test 5.3" assert {rpn 0 4 "hello" substr "hell" ==} " failed test 5.4" # Q: will the below work on all OS????? # NB. better to switch with something more universal \six = system "date | wc | awk '{print $2}'" assert {rpn \six 6 ==} " failed test 6.1" # Statistical operations read columns x 1 3 2 9 3 assert {rpn x mean 3.6 same} " failed test 7.1" assert {rpn x stddev 3.1305 same} " failed test 7.2" assert {rpn x skewness 0.882432 same} " failed test 7.3" assert {rpn x kurtosis 1.88008 same} " failed test 7.4" # ----------- FILL IN LATER ----------------- # Math functions (e.g. sin, ...) # Stack operations push, pop, and exch. assert {rpn 45 cos 0.7071 same} " failed test 8.1" assert {rpn 45 sin 0.7071 same} " failed test 8.2" assert {rpn 45 tan 1 same} " failed test 8.3" # Missing-values set missing value -99 read .x. .y. 1 -99 assert {rpn .y. ismissing} " failed test 9.1" assert {rpn .y. -99 == } " failed test 9.2" assert {rpn .y. -99 != !} " failed test 9.3" assert {rpn .y. 0 != } " failed test 9.4" # some boolean tests need not check that both values exist assert {rpn .y. 0 & !} " failed test 9.5" assert {rpn 0 .y. & !} " failed test 9.6" assert {rpn .y. 1 & } " failed test 9.7" assert {rpn .y. 1 | } " failed test 9.8" assert {rpn 1 .y. | } " failed test 9.9" if {rpn .y. -99 !=} show " failed test 9.10" end if show " passed" gri/doc/tst_suite/tst_IO.gri0000644000175000017500000000464313147557614014523 0ustar psgpsgshow "doc/tst_suite/tst_IO.gri ..." ... # Test some I/O features. NOTE: this will make _no_ sense # to you unless you have a look at the test files! # Read columns from file with newline at the end ... open tst_IO_1.dat read columns x y close assert {rpn ..num_col_data.. 2 ==} " failed test 1-a" assert {rpn x 0 @ 1 ==} " failed test 1-b" assert {rpn x 1 @ 2 ==} " failed test 1-c" assert {rpn y 0 @ 11 ==} " failed test 1-d" assert {rpn y 1 @ 22 ==} " failed test 1-e" # ... as above, but from a file without newline at the end. open tst_IO_2.dat read columns x y close assert {rpn ..num_col_data.. 2 ==} " failed test 2-a" assert {rpn x 0 @ 1 ==} " failed test 2-b" assert {rpn x 1 @ 2 ==} " failed test 2-c" assert {rpn y 0 @ 11 ==} " failed test 2-d" assert {rpn y 1 @ 22 ==} " failed test 2-e" # Read a line into a synonym. open tst_IO_1.dat read line \s assert {rpn "\s" "1 11" ==} " failed test 3-a" read line \s assert {rpn "\s" "2 22" ==} " failed test 3-b" close open tst_IO_2.dat read line \s assert {rpn "\s" "1 11" ==} " failed test 3-c" read line \s assert {rpn "\s" "2 22" ==} " failed test 3-d" close # Read variable/synonym, in various orders. open tst_IO_1.dat read .a. .b. assert {rpn .a. 1 ==} " failed test 4-a" assert {rpn .b. 11 ==} " failed test 4-b" read \a \b assert {rpn "\a" "2" ==} " failed test 4-c" assert {rpn "\b" "22" ==} " failed test 4-d" rewind read .a. \b assert {rpn .a. 1 ==} " failed test 4-e" assert {rpn "\b" "11" ==} " failed test 4-f" read \a .b. assert {rpn "\a" "2" ==} " failed test 4-g" assert {rpn .b. 22 ==} " failed test 4-h" close open tst_IO_2.dat read .a. .b. assert {rpn .a. 1 ==} " failed test 4-i" assert {rpn .b. 11 ==} " failed test 4-j" read \a \b assert {rpn "\a" "2" ==} " failed test 4-k" assert {rpn "\b" "22" ==} " failed test 4-l" rewind read .a. \b assert {rpn .a. 1 ==} " failed test 4-m" assert {rpn "\b" "11" ==} " failed test 4-n" read \a .b. assert {rpn "\a" "2" ==} " failed test 4-o" assert {rpn .b. 22 ==} " failed test 4-p" close show " passed" gri/doc/tst_suite/tst_IO_1.dat0000644000175000017500000000001213147557614014714 0ustar psgpsg1 11 2 22 gri/doc/gri2html0000755000175000017500000000371413147557614012250 0ustar psgpsg#!/usr/bin/perl die "Usage: gri2html file.gri file.html" if ($#ARGV !=1); $filename_gri = $ARGV[0]; $filename_html = $ARGV[1]; open(IN, "$filename_gri") || die "Can't open `$filename_gri' for input\n"; open(OUT, ">$filename_html") || die "Can't open `$filename_html' for output\n"; print OUT "\n"; print OUT "\n"; print OUT "$ARGV[0]\n"; print OUT "\n"; print OUT "\n"; print OUT "# This html document was prepared by gri2html based on the Gri script named\n"; print OUT "
    # $ARGV[0]\n"; print OUT "
    # Gri is available for free at http://gri.sourceforge.net\n"; print OUT "
    \n";
    
    while() {
        s,<,<,g;
        s,>,>,g;
        s,//(.*),//$1,;
           
        if (/^[ ]*\#/) {
            s,(\#.*),$1,;
            print OUT "$_";
            next;
        }
        # #Comments
        s,(\#.*),$1,;
    
        # \.factor. =
        s,(\\\.[^.]+\. [\+\*/^-]?=),$1,;
        # .gulf_emphasisGSL. = 
        s,(\.[^.]+\. [\+\*/^-]?=),$1,;
        # \xl = 
        s,(\\[^\\]+ [\+\*/^-]?=),$1,;
    
        # \.factor.
        s,(\\\.[^ .]+\.),$1,g;
        # .factor.
        s,( \.[^ .]+\.),$1,g;
        # ..ysize..
        s,(\.\.[^ .]+\.\.),$1,g;
        # \xl
        s,( \\[^\ ]+),$1,g;
    
        # `newcommand'
        s,^(\`.*\')$,$1,;
    
        # system stuff
           s,system (.*),system $1,;
        # "strings"
        s,(".*"),$1,g;
    
        s,\b(quit|return|if|else( if)?|end (if|while)|break|while|rpn)\b,$1,g;
    
    #   s,"(.*)","$1",g;
        print OUT "$_";
    }
    print OUT "
    \n"; print OUT "\n"; print OUT "\n"; gri/doc/cmdrefcard.tex0000644000175000017500000005535313147557614013414 0ustar psgpsg% scp cmdrefcard.ps dankelley@gri.sourceforge.net:/home/groups/g/gr/gri/htdocs \def\griversion{2.8} \def\date{2001 July 30} % Reference Card for Gri %**start of header \hbadness=10000 \vbadness=10000 \newcount\columnsperpage % This file can be printed with 1, 2, or 3 columns per page (see below). % Specify how many you want here. Nothing else needs to be changed. \columnsperpage=3 % This file is intended to be processed by plain TeX (TeX82). % % The final reference card has six columns, three on each side. % This file can be used to produce it in any of three ways: % 1 column per page % produces six separate pages, each of which needs to be reduced to 80%. % This gives the best resolution. % 2 columns per page % produces three already-reduced pages. % You will still need to cut and paste. % 3 columns per page % produces two pages which must be printed sideways to make a % ready-to-use 8.5 x 11 inch reference card. % For this you need a dvi device driver that can print sideways, e.g., % lw -land griref.dvi % Which mode to use is controlled by setting \columnsperpage above. % % Author: % Dan Kelley (copied from a Unix reference card written by Steven Matheson) % Internet: matehson@open.dal.ca % % Note by Peter Galbraith, July 2001: It's pretty obvious to me that Steve % based his reference card on emacs' refcard written by Stephen Gildea. % Therefore, this file is a derived product and is licensed under the GPL. \def\shortnotice{\vskip 1ex plus 2 fill \centerline{\small Gri version \versionnumber}} \def\notice{ \vskip 1ex plus 2 fill\begingroup\small \centerline{(c) 2001, Dan E. Kelley} See also {\it refcard}, an overview of Gri. \endgroup} % make \bye not \outer so that the \def\bye in the \else clause below % can be scanned without complaint. \def\bye{\par\vfill\supereject\end} \newdimen\intercolumnskip \newbox\columna \newbox\columnb \def\ncolumns{\the\columnsperpage} \message{[\ncolumns\space V column\if 1\ncolumns\else s\fi\space per page]} \def\scaledmag#1{ scaled \magstep #1} % This multi-way format was designed by Stephen Gildea % October 1986. \if 1\ncolumns \hsize 4in \vsize 10in \voffset -.7in \font\titlefont=\fontname\tenbf \scaledmag3 \font\headingfont=\fontname\tenbf \scaledmag2 \font\smallfont=\fontname\sevenrm \font\smallsy=\fontname\sevensy \footline{\hss\folio} \def\makefootline{\baselineskip10pt\hsize6.5in\line{\the\footline}} \else \hsize 3.2in \vsize 7.95in \hoffset -.75in \voffset -.745in \font\titlefont=cmbx10 \scaledmag2 \font\headingfont=cmbx10 \scaledmag1 \font\subheadingfont=cmbx10 \scaledmag0 \font\smallfont=cmr6 \font\smallsy=cmsy6 \font\eightrm=cmr8 \font\eightbf=cmbx8 \font\eightit=cmti8 \font\eighttt=cmtt8 \font\eightsy=cmsy8 \textfont0=\eightrm \textfont2=\eightsy \def\rm{\eightrm} \def\bf{\eightbf} \def\it{\eightit} \def\tt{\eighttt} \normalbaselineskip=.8\normalbaselineskip \normallineskip=.8\normallineskip \normallineskiplimit=.8\normallineskiplimit \normalbaselines\rm %make definitions take effect \if 2\ncolumns \let\maxcolumn=b \footline{\hss\rm\folio\hss} \def\makefootline{\vskip 2in \hsize=6.86in\line{\the\footline}} \else \if 3\ncolumns \let\maxcolumn=c \nopagenumbers \else \errhelp{You must set \columnsperpage equal to 1, 2, or 3.} \errmessage{Illegal number of columns per page} \fi\fi \intercolumnskip=.46in \def\abc{a} \output={% % This next line is useful when designing the layout. %\immediate\write16{Column \folio\abc\space starts with \firstmark} \if \maxcolumn\abc \multicolumnformat \global\def\abc{a} \else\if a\abc \global\setbox\columna\columnbox \global\def\abc{b} %% in case we never use \columnb (two-column mode) \global\setbox\columnb\hbox to -\intercolumnskip{} \else \global\setbox\columnb\columnbox \global\def\abc{c}\fi\fi} \def\multicolumnformat{\shipout\vbox{\makeheadline \hbox{\box\columna\hskip\intercolumnskip \box\columnb\hskip\intercolumnskip\columnbox} \makefootline}\advancepageno} \def\columnbox{\leftline{\pagebody}} \def\bye{\par\vfill\supereject \if a\abc \else\null\vfill\eject\fi \if a\abc \else\null\vfill\eject\fi \end} \fi % we won't be using math mode much, so redefine some of the characters % we might want to talk about \catcode`\^=12 \catcode`\_=12 \chardef\\=`\\ \chardef\{=`\{ \chardef\}=`\} \hyphenation{mini-buf-fer} \parindent 0pt \parskip 1ex plus .5ex minus .5ex \def\small{\smallfont\textfont2=\smallsy\baselineskip=.8\baselineskip} \def\n{\hfil\break} \outer\def\newcolumn{\vfill\eject} \outer\def\title#1{{\titlefont\centerline{#1}}\vskip 1ex plus .5ex} \outer\def\section#1{\par\filbreak \vskip 3ex plus 2ex minus 2ex {\headingfont #1}\mark{#1}% \vskip 2ex plus 1ex minus 1.5ex} \outer\def\subsection#1{\par\filbreak \vskip 3ex plus 2ex minus 2ex {\subheadingfont #1}\mark{#1}% \vskip 2ex plus 1ex minus 1.5ex} \newdimen\keyindent \def\beginindentedkeys{\keyindent=1em} \def\endindentedkeys{\keyindent=0em} \endindentedkeys \def\paralign{\vskip\parskip\halign} \def\<#1>{$\langle${\rm #1}$\rangle$} \def\kbd#1{{\tt#1}\null} %\null so not an abbrev even if period follows \def\beginexample{\par\leavevmode\begingroup %17feb93 \obeylines\obeyspaces\parskip0pt\tt} \obeylines\obeyspaces\parskip0pt\vskip-12pt\tt} {\obeyspaces\global\let =\ } \def\endexample{\endgroup} \def\key#1#2{\leavevmode\hbox to \hsize{\vtop {\hsize=.65\hsize\rightskip=1em \hskip\keyindent\relax#1}\kbd{#2}\hfil}} \newbox\metaxbox \setbox\metaxbox\hbox{\kbd{M-x }} \newdimen\metaxwidth \metaxwidth=\wd\metaxbox \def\metax#1#2{\leavevmode\hbox to \hsize{\hbox to .75\hsize {\hskip\keyindent\relax#1\hfil}% \hskip -\metaxwidth minus 1fil \kbd{#2}\hfil}} \def\threecol#1#2#3{\hskip\keyindent\relax#1\hfil&\kbd{#2}\quad &\kbd{#3}\quad\cr} %**end of header \tolerance=10000 \title{Overview of Gri \griversion$\,$Commands} \raggedright \section{1\quad Introduction} This reference card describes the commands in version \griversion\ of the Gri plotting language. See also the companion ``Gri Reference Card'' and the online manuals. \section{2\quad Control Statements} \subsection{2.1\quad If Statements} The {\tt if} statement has ancillary {\tt else if} and {\tt else} statements, and is ended by the {\tt end if} statement, e.g. \beginexample if $\lbrace$rpn .x. 10 >$\rbrace$ show "The variable .x. is less than 10" else if $\lbrace$rpn .x. 20 >$\rbrace$ show "The variable .x. is between 10 and 20" else show "The variable .x. is greater than 20" end if \endexample \subsection{2.2\quad Loops} {\tt while} loops are provided. The statements between {\tt while} and {\tt end while} are repeated until the RPN expression on the {\tt while} commandline is false. Here is an infinite loop ended -- by a {\tt break} statement -- when the file contents are exhausted: \beginexample while 1 read .x. .y. if ..eof.. break end if show ".x. is " .x. end while \endexample Here is a loop that will print the numbers 0, 1, ..., 9. \beginexample .i. = 0 while $\lbrace$rpn .i. 10 >$\rbrace$ show .i. .i. += 1 end while \endexample \section{3\quad List of Gri Commands} What follows is a complete list of built-in Gri commands. For more help on a given command, see the full manual, or use the Gri online help facitilty (e.g., type {\tt gri} to launch Gri, then type {\tt help}; exit by typing The notation is as follows. $\bullet$ Items written within square brackets are optional. $\bullet$ Items written within dots are either raw numbers, RPN expressions, or variable names. $\bullet$ Items preceeded by backslashes are any given string. $\bullet$ Items separated by vertical bars are alternatives. $\bullet$ Curly brackets group words that must appear together. Thus, for example, the syntax \beginexample set dash [.n.$\mid$$\lbrace$.dash. .blank.$\rbrace$$\mid$off] \endexample means that {\tt set dash} is a possible Gri command (meaning use the default dash style). Several forms of optional items may be present also. For example, {\tt set dash 2} is legal; it means use the dash style numbered 2. Gri will check any single number presented in this place on this command against the list of acceptable {\tt .n.} values. If two numbers are present, Gri interprets the first as the length of dashes and the second as the length of blanks; notice the braces, indicating that these two parameters must appear together. Finally, the keyword {\tt off} is allowed (it means go back to a solid line). \bigskip Here are the commands: \smallskip \parindent -1ex \beginexample % INSERT stuff from cmdrefcard.pl schellscript here (to line 'end of INSERT') assert .condition. ["message"] cd [$\backslash$pathname] close [$\backslash$filename] convert columns to grid [neighbor $\mid$ $\lbrace$objective$\mid$boxcar .xr. .yr. [.n. .e.]$\rbrace$ $\mid$ $\lbrace$barnes [.xr. .yr. .gamma. .iter.]$\rbrace$] convert columns to spline [.gamma.] [.xmin. .xmax. .xinc.] convert grid to columns convert grid to image [size .width. .height.] [box .ll\_x. .ll\_y. .ur\_x. .ur\_y.] convert image to grid create columns from function create image grayscale banded .band. create image greyscale banded .band. debug [.n.] $\mid$ [clipped values in draw commands] $\mid$ off delete $\lbrace$.variable. $\mid$ $\backslash$synonym [...]$\rbrace$ $\mid$ columns [$\lbrace$randomly .fraction.$\rbrace$$\mid$$\lbrace$where missing$\rbrace$] $\mid$ grid $\mid$ $\lbrace$[x$\mid$y] scale$\rbrace$ differentiate $\lbrace$x$\mid$y wrt index$\mid$y$\mid$x$\rbrace$ $\mid$ $\lbrace$grid wrt x$\mid$y$\rbrace$ draw arrow from .x0. .y0. to .x1. .y1. [cm] draw arrows draw axes if needed draw axes [.style.$\mid$frame$\mid$none] draw border box [.ll\_x. .ll\_y. .ur\_x. .ur\_y. .width\_cm. .brightness.] draw box filled .ll\_x. .ll\_y. .ur\_x. .ur\_y. [cm] draw box .ll\_x. .ll\_y. .ur\_x. .ur\_y. [cm] draw circle with radius .r\_cm. at .x\_cm. .y\_cm. draw contour [$\lbrace$.value. [unlabelled$\mid$$\lbrace$labelled "$\backslash$label"$\rbrace$]$\rbrace$ $\mid$ $\lbrace$.min. .max. .inc. [.inc\_unlabelled.] [unlabelled]$\rbrace$] draw curve overlying draw curve filled [to $\lbrace$.y. y$\rbrace$ $\mid$ $\lbrace$.x. x$\rbrace$] draw curve draw essay "text"$\mid$reset draw gri logo .x\_cm. .y\_cm. .height\_cm. .style. $\backslash$fgcolor $\backslash$bgcolor draw grid draw image palette [axisleft$\mid$axisright$\mid$axistop$\mid$axisbottom] [left .left. right .right. [increment .inc.]] [box .ll\_x\_cm. .ll\_y\_cm. .ur\_x\_cm. .ur\_y\_cm.] draw image grayscale [left .left. right .right. [increment .inc.]] [box .ll\_x\_cm. .ll\_y\_cm. .ur\_x\_cm. .ur\_y\_cm.] draw image histogram [box .ll\_x\_cm. .ll\_y\_cm. .ur\_x\_cm. .ur\_y\_cm.] draw image draw isopycnal [unlabelled] .density. [.P\_sigma. [.P\_theta.]] draw isospice .spice. [unlabelled] draw label boxed "$\backslash$string" at .ll\_x. .ll\_y. [cm] draw label whiteunder "$\backslash$string" at .ll\_x. .ll\_y. [cm] draw label for last curve "label" draw label "$\backslash$string" [centered$\mid$rightjustified] at .x. .y. [cm] [rotated .deg.] draw line from .x0. .y0. to .x1. .y1. [cm] draw line legend "label" at .x. .y. [cm] [length .cm.] draw lines $\lbrace$vertically .left. .right. .inc.$\rbrace$ $\mid$ $\lbrace$horizontally .bottom. .top. .inc.$\rbrace$ draw patches .width. .height. [cm] draw polygon [filled] .x0. .y0. .x1. .y1. .x2. .y2. [...] draw regression line [clipped] draw symbol legend $\backslash$symbol\_name "label" at .x. .y. [cm] draw symbol [.code.$\mid$$\backslash$name [at .x. .y. [cm]] [graylevel z]$\mid$[color [hue z$\mid$.h.] [brightness z$\mid$.b.] [saturation z$\mid$.s.]]] draw time stamp [fontsize .points. [at .x\_cm. .y\_cm. cm [with angle .deg.]]] draw title "$\backslash$string" draw values [.dx. .dy.] [$\backslash$format] [separation .xcm. .ycm.] draw x axis [at bottom$\mid$top$\mid$$\lbrace$.y. [cm]$\rbrace$ [lower$\mid$upper]] draw x box plot at .y. [size .cm.] draw y axis [at left$\mid$right$\mid$$\lbrace$.x. cm$\rbrace$ [left$\mid$right]] draw y box plot at .x. [size .cm] draw zero line [horizontally$\mid$vertically] expecting version .n. filter column x$\mid$y$\mid$z$\mid$u$\mid$v recursively .a0. .a1. ... .b0. .b1. ... filter grid rows$\mid$columns recursively .a0. .a1. ... .b0. .b1. ... filter image highpass$\mid$lowpass flip grid$\mid$image x$\mid$y get env $\backslash$result $\backslash$environment\_variable heal columns$\mid$$\lbrace$grid along x$\mid$y$\rbrace$ help [*$\mid$command\_name$\mid$$\lbrace$- topic$\rbrace$] if $\lbrace$[!] .flag.$\rbrace$$\mid$$\backslash$flag$\mid$$\lbrace$$\lbrace$"string1" == "string2"$\rbrace$$\rbrace$ ignore last .n. input $\backslash$ps\_filename [.xcm. .ycm. [.xmag. .ymag. [.rot\_deg.]]] insert $\backslash$filename interpolate x$\mid$y grid to ... list $\backslash$command-syntax ls [$\backslash$file\_specification] mask image [to $\lbrace$uservalue .u.$\rbrace$$\mid$$\lbrace$imagevalue .i.$\rbrace$] new page new postscript file $\backslash$name new .variable\_name.$\mid$$\backslash$synonym\_name [.variable\_name.$\mid$$\backslash$synonym\_name [...]] open $\lbrace$$\backslash$filename$\rbrace$$\mid$$\lbrace$"system command$\mid$"$\rbrace$ $\lbrace$[binary [uchar$\mid$int$\mid$float$\mid$double$\mid$16bit]]$\rbrace$$\mid$$\lbrace$netCDF$\rbrace$ postscript $\backslash$string pwd query $\backslash$synonym$\mid$.variable ["$\backslash$prompt" [("$\backslash$default"$\mid$.default)]] quit [.exit\_status.] read colornames from RGB $\backslash$filename read columns ... read grid $\lbrace$x [.rows.$\mid$$\lbrace$="name"$\rbrace$]$\rbrace$$\mid$$\lbrace$y [.cols.]$\lbrace$="name"$\rbrace$$\rbrace$$\mid$$\lbrace$data $\lbrace$[spacers] [.rows. .cols.] [spacers] [bycolumns]$\rbrace$$\mid$$\lbrace$="name"$\rbrace$$\rbrace$ read grid x [.rows.] read grid y [.rows.] read grid data [spacers] [.rows. .cols.] [spacers] [bycolumns] read grid x = "variable name" read grid y = "variable name" read grid data = "variable name" set x grid', `set y grid read grid x' sets `$\backslash$.return\_value to `N cols read grid y' sets `$\backslash$.return\_value' to `N rows read grid data' sets `$\backslash$.return\_value to `N rows N cols read image colorscale [rgb$\mid$hsb] read image grayscale read image greyscale read image mask rasterfile read image mask .rows. .cols. read image pgm [box .ll\_x. .ll\_y. .ur\_x. .ur\_y.] read image rasterfile [box .ll\_x. .ll\_y. .ur\_x. .ur\_y.] read image .rows. .cols. [box .ll\_x. .ll\_y. .ur\_x. .ur\_y.] [bycolumns] read from $\backslash$filename read line [raw] $\backslash$synonym read [raw] [* [*...]] $\backslash$synonym$\mid$$\lbrace$.variable. [.variable. ...]$\rbrace$ read [* [*...]] $\backslash$synonym$\mid$$\lbrace$.variable. [.variable. ...]$\rbrace$ regress $\lbrace$y vs x [linear]$\rbrace$$\mid$$\lbrace$x vs y [linear]$\rbrace$ reorder columns randomly$\mid$$\lbrace$ascending in x$\mid$y$\mid$z$\rbrace$$\mid$$\lbrace$descending in x$\mid$y$\mid$z$\rbrace$ rpnfunction $\backslash$name "action" rescale resize x for maps resize x for maps resize y for maps resize y for maps return rewind [filename] set axes style .style. $\mid$ $\lbrace$offset [.dist\_cm.]$\rbrace$ $\mid$ rectangular $\mid$ none $\mid$ default set axes style 0 set axes style 1 set axes style 2 set axes style offset [.dist\_cm.] set axes style rectangular set axes style none set axes style default set arrow size .size.$\mid$$\lbrace$as .num. percent of length$\rbrace$$\mid$default set arrow size .size. set arrow size as .num. percent of length set arrow size default set arrow type .which. set beep on$\mid$off set bounding box .ll\_x. .ll\_y. .ur\_x. .ur\_y. [cm$\mid$pt] set clip [postscript] $\lbrace$on [.xleft. .xright. .ybottom. .ytop.]$\rbrace$$\mid$off set clip on set clip on .xleft. .xright. .ybottom. .ytop. set clip off set clip postscript on .xleft. .xright. .ybottom. .ytop. set clip postscript off set color $\backslash$name$\mid$$\lbrace$rgb .red. .green. .blue.$\rbrace$$\mid$$\lbrace$hsb .hue. .saturation. .brightness.$\rbrace$ set colour $\backslash$name$\mid$$\lbrace$rgb .red. .green. .blue.$\rbrace$$\mid$$\lbrace$hsb .hue. .saturation. .brightness.$\rbrace$ set colorname $\backslash$$\backslash$name $\lbrace$rgb .red. .green. .blue.$\rbrace$$\mid$$\lbrace$hsb .hue. .saturation. .brightness.$\rbrace$ set contour format $\backslash$style$\mid$default set contour label for lines exceeding .x. cm set contour label position $\lbrace$.start\_cm. .between\_cm.$\rbrace$$\mid$centered$\mid$default set contour labels rotated$\mid$horizontal$\mid$whiteunder$\mid$nowhiteunder set dash [.type.$\mid$$\lbrace$.dash\_cm. .blank\_cm. ...$\rbrace$$\mid$off] set environment set error action to core dump set flag $\backslash$name [off] set font color $\backslash$name$\mid$$\lbrace$rgb .red. .green. .blue.$\rbrace$$\mid$$\lbrace$hsb .hue. .saturation. .brightness.$\rbrace$ set font colour $\backslash$name$\mid$$\lbrace$rgb .red. .green. .blue.$\rbrace$$\mid$$\lbrace$hsb .hue. .saturation. .brightness.$\rbrace$ set font encoding PostscriptStandard $\mid$ isolatin1 set font size $\lbrace$.size. [cm]$\rbrace$$\mid$default set font size .size. set font size .size. cm set font size default set font to $\backslash$fontname set graylevel .brightness.$\mid$white$\mid$black set greylevel .brightness.$\mid$white$\mid$black set grid missing $\lbrace$above$\mid$below .intercept. .slope.$\rbrace$$\mid$$\lbrace$inside curve$\rbrace$ set grid missing above$\mid$below .intercept. .slope set grid missing inside curve set ignore initial newline [off] set ignore error eof set image colorscale ... set image colourscale ... set image grayscale using histogram [black .bl. white .wh.] set image greyscale using histogram [black .bl. white .wh.] set image grayscale [black .bl. white .wh. [increment .inc.]] set image greyscale [black .bl. white .wh. [increment .inc.]] set image missing value color to white$\mid$black$\mid$$\lbrace$graylevel .brightness.$\rbrace$$\lbrace$rgb .red. .green. .blue.$\rbrace$ set image missing value colour to white$\mid$black$\mid$$\lbrace$graylevel .brightness.$\rbrace$ set image range .min\_value. .max\_value. set input data window x$\mid$y $\lbrace$.min. .max.$\rbrace$$\mid$off set input data window x .min. .max. set input data window x off set input data window y .min. .max. set input data window y off set input data separator TAB$\mid$default set line cap .type. set line join .type. set line width [axis$\mid$symbol$\mid$all] .width\_pt.$\mid$$\lbrace$rapidograph $\backslash$name$\rbrace$$\mid$default set missing value .value. set postscript filename "$\backslash$string" set page size letter$\mid$legal$\mid$folio$\mid$tabloid$\mid$A0$\mid$A1$\mid$A2$\mid$A3$\mid$A4$\mid$A5 set page portrait$\mid$landscape$\mid$$\lbrace$factor .mag.$\rbrace$$\mid$$\lbrace$translate .xcm. .ycm.$\rbrace$ set panel .row. .col. set panels .rows. .cols. [.dx\_cm. .dy\_cm.] set path to "$\backslash$path"$\mid$default for data$\mid$commands set symbol size .diameter\_cm.$\mid$default set symbol size .diameter\_cm. set symbol size default set tic size .size.$\mid$default set tic size .size. set tic size default set tics in$\mid$out set trace [on$\mid$off] set trace set trace on set trace off set u scale .cm\_per\_unit.$\mid$$\lbrace$as x$\rbrace$ set u scale .cm\_per\_unit. set u scale as x set v scale .cm\_per\_unit.$\mid$$\lbrace$as y$\rbrace$ set v scale .cm\_per\_unit. set v scale as y set x axis top$\mid$bottom$\mid$increasing$\mid$decreasing$\mid$$\lbrace$.left. .right. [.incBig. [.incSml.]]$\rbrace$$\mid$unknown set x axis top set x axis bottom set x axis increasing set x axis decreasing set x axis .left. .right. set x axis .left. .right. .incBig. set x axis .left .right. .incBig. .incSml. set x format $\backslash$format$\mid$default$\mid$off %e' and `%g') are permitted. For example, `set x format %.1f set x grid .left. .right. .inc.$\mid$$\lbrace$/.cols.$\rbrace$ set x grid .left. .right. .inc. set x grid .left. .right. /.cols. set x margin $\lbrace$[bigger$\mid$smaller] .size.$\rbrace$ $\mid$ default set x margin .size. set x margin bigger .size. set x margin smaller .size. set x margin default set x name "$\backslash$name"$\mid$default set x size .width\_cm.$\mid$default set x size .width\_cm. set x size default set x type linear$\mid$log$\mid$$\lbrace$map E$\mid$W$\mid$N$\mid$S$\rbrace$ set y axis label horizontal$\mid$vertical set y axis label horizontal set y axis label vertical set y axis left$\mid$right$\mid$increasing$\mid$decreasing$\mid$$\lbrace$.bottom. .top. [.incBig. [.incSml.]]$\rbrace$$\mid$unknown set y axis left set y axis right set y axis increasing set y axis decreasing set y axis .bottom. .top. set y axis .bottom. .top. .incBig. set y axis .bottom. .top. .incBig. .incSml. set y format $\backslash$format$\mid$default$\mid$off %e' and `%g') are permitted. For example, `set y format %.1f set y grid .bottom. .top. .inc.$\mid$$\lbrace$/.rows.$\rbrace$ set y grid .bottom. .top. .inc. set y grid .bottom. .top. /.rows. set y margin $\lbrace$[bigger$\mid$smaller] .size.$\rbrace$ $\mid$ default set y margin .size. set y margin bigger .size. set y margin smaller .size. set y margin default set y name "$\backslash$name"$\mid$default set y size .height\_cm.$\mid$default set y size .height\_cm. set y size default set y type linear$\mid$log$\mid$$\lbrace$map N$\mid$S$\mid$E$\mid$W$\rbrace$ set z missing above$\mid$below .intercept. .slope. set "..." show all show axes show color show colornames show columns [statistics] show flags show grid [mask] show hint of the day show image show license show misc show next line show traceback show stopwatch show synonyms show time show variables show .value. $\mid$ $\lbrace$rpn ...$\rbrace$ $\mid$ "$\backslash$text" [.value.$\mid$$\lbrace$rpn ...$\rbrace$$\mid$text [...]] skip [forward$\mid$backward] [.n.] sleep .sec. smooth $\lbrace$x [.n.]$\rbrace$ $\mid$ $\lbrace$y [.n.]$\rbrace$ $\mid$ $\lbrace$grid data [.f.$\mid$$\lbrace$along x$\mid$y$\rbrace$]$\rbrace$ source $\backslash$filename sprintf $\backslash$synonym "format" .variable. [.variable. [...]] state save$\mid$restore$\mid$display superuser system $\backslash$system-command while .test.$\mid$$\lbrace$rpn ...$\rbrace$ write columns to $\backslash$filename write contour .value. to $\backslash$filename write grid to $\backslash$filename [bycolumns] write image colorscale to $\backslash$filename write image grayscale to $\backslash$filename write image greyscale to $\backslash$filename write image mask [pgm$\mid$rasterfile] to $\backslash$filename write image [pgm$\mid$rasterfile] to $\backslash$filename unlink $\backslash$filename ?draw axes exploded ?contour xyz data ?set axes ?draw image BW raster \endexample % end of INSERT \parindent 0ex \notice \bye gri/doc/gri_unpage.1-skel0000644000175000017500000000163313147557614013726 0ustar psgpsg.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.019. .TH GRI_UNPAGE "1" "2009" "gri_unpage " FSF .SH NAME gri_unpage \- split a multi-page Gri output file into separate files. .SH DESCRIPTION gri_unpage is used to split a multi-page Gri output file (in which the .B new page command was used) into separate PostScript files, one for each page. .SH USAGE # gri_unpage name.ps .IP Creates files name-1.ps, name-2.ps, etc, one for each page of name.ps. .TP .SH OPTIONS: The OPTIONS, available if your 'perl' has 'getopts' library, are: .HP \fB\-l\fR \fB\-\-\fR sets the bounding box to letter page size. .IP By default, the bounding box size is extracted from the original file, and is used for all newly created files. .HP .TP .SH BUGS: .PP 1. Bounding box is always the same size (grabbed from the original). 2. Assumes that all Gri fonts are used even if they aren't. .SH "SEE ALSO" .B gri(1), gri_merge(1) gri/doc/gri-manpage.10000644000175000017500000000543513147557614013045 0ustar psgpsg.TH GRI 1 .SH NAME gri \- scientific graphics language .SH SYNOPSIS .B gri [ .B OPTIONS ] [ .I CommandFile [ .I optional_arguments ]] .SH DESCRIPTION Gri is a programming language for scientific graphics. It can make x-y graphs, contour-graphs, and image graphs. In addition, Gri has a full suite of low-level graphical elements and sufficient programming capabilities (loops, subroutines, etc) to permit complex customization. Gri is not a point-click application. In some ways it is analogous to TeX. Extensive power rewards tolerance of a modest learning curve. For more information, please consult online .I info and .I html manuals. The .I info manual is normally accessed by typing .B info gri The .I html manual is located at .B /usr/doc/gri-N.N.N/html/index.html, where .B N.N.N is the version number. The .I html FAQ is located at .B /usr/doc/gri-N.N.N/html/FAQ.html .C There is also a .C .I reference card .C in TeX and postscript formats. See .C .B /usr/doc/gri/refcard.* .C .C The .C .I examples .C in .C .B /usr/doc/gri/examples/ .C are shown in the manual, and are included as a quick start primer. .SH GRI_MERGE AND GRI_UNPAGE COMMANDS Two Perl scripts are provided with Gri to manipulate the PostScript output. .I gri_merge is used to merge multiple Gri output files into a single PostScript file. Type .B gri_merge -h for usage information. .I gri_unpage is used is split a multi-page Gri output file (in which the .B new page command was used) into separate PostScript files, one for each page. Type .B gri_unpage -h .SH EMACS SUPPORT An .I emacs mode is provided with Gri. .C Consult the primer .C .C .B /opt/gri/doc/gri/doc/README.gri-mode The mode is installed automatically in Debian by the elisp file: .B /etc/emacs/site-start.d/50gri.el The emacs mode itself is .I gri-mode.el and is installed on Debian as .B /usr/share/emacs/site-lisp/gri-mode.el Byte-compiled versions of this file are produced for every flavour of Emacs that is installed, and are located in places like .B /usr/share/emacs/20.2/site-lisp/gri-mode.elc .C .SH INSTALLING MULTIPLE VERSIONS .C .C Since the way Gri works sometimes changes with new versions, you may want .C to keep old versions installed if an important script depends on it. The .C Debian packaging of Gri allows this. Installing the next gri package .C (named like gri_2.1.22-1_i386.deb) will replace your current version, but .C Debian i386 (and perhaps alpha) packages will be made for older versions .C which can be installed alongside the main gri package. Look for a package .C named like so: .C .C .B gri-2.1.21_2.1.21-1_i386.deb .C .C at the ftp site: .C .C .B ftp://ftp.phys.ocean.dal.ca/users/rhogee/gri/ .SH AUTHOR Gri (c) 1999-2002 Dan Kelley This manual page by Peter S Galbraith . gri/doc/make_html_builtinindex0000644000175000017500000000145113147557614015230 0ustar psgpsg#!/usr/local/bin/perl # Create HTML index from index of pre-installed info page. # Bug: the @code{} items get lost, too bad. open(IN, "info -f ./gri.info 'Index of Builtins' |") || die "Cannot get 'Index of Builtins'\n"; print " \@c HTML \@c HTML

    Builtin index

    \@node Index of Builtins, Concept Index, Index of Commands, Top \@c HTML Navigation: \@c HTML next, \@c HTML previous, \@c HTML parent. \@itemize \@bullet "; while() { next if (/\*\s*Menu:\s*$/); if (/\* .*\./) { s/\* //; s/\.$//; s/:\s*/\n ... \@xref{/; s/$/}./; print "\@item\n $_"; } } print "\n\@end itemize\n"; gri/doc/refcard.tex0000644000175000017500000004143013147557614012717 0ustar psgpsg% scp refcard.ps dankelley@gri.sourceforge.net:/home/groups/g/gr/gri/htdocs \def\griversion{2.8} \def\date{2001 Apr 11} % Reference Card for Gri %**start of header \hbadness=10000 \vbadness=10000 \newcount\columnsperpage % This file can be printed with 1, 2, or 3 columns per page (see below). % Specify how many you want here. Nothing else needs to be changed. \columnsperpage=3 % This file is intended to be processed by plain TeX (TeX82). % % The final reference card has six columns, three on each side. % This file can be used to produce it in any of three ways: % 1 column per page % produces six separate pages, each of which needs to be reduced to 80%. % This gives the best resolution. % 2 columns per page % produces three already-reduced pages. % You will still need to cut and paste. % 3 columns per page % produces two pages which must be printed sideways to make a % ready-to-use 8.5 x 11 inch reference card. % For this you need a dvi device driver that can print sideways, e.g., % lw -land griref.dvi % Which mode to use is controlled by setting \columnsperpage above. % % Author: % Dan Kelley (copied from a Unix reference card written by Steven Matheson) % Internet: matehson@open.dal.ca % % Note by Peter Galbraith, July 2001: It's pretty obvious to me that Steve % based his reference card on emacs' refcard written by Stephen Gildea. % Therefore, this file is a derived product and is licensed under the GPL. \def\version{\date} \def\shortnotice{\vskip 1ex plus 2 fill \centerline{\small Gri version \versionnumber}} \def\notice{ \vskip 1ex plus 2 fill\begingroup\small \centerline{(c) 2001, Dan E. Kelley} See also {\it cmdrefcard}, a companion reference card. \endgroup} % make \bye not \outer so that the \def\bye in the \else clause below % can be scanned without complaint. \def\bye{\par\vfill\supereject\end} \newdimen\intercolumnskip \newbox\columna \newbox\columnb \def\ncolumns{\the\columnsperpage} \message{[\ncolumns\space V column\if 1\ncolumns\else s\fi\space per page]} \def\scaledmag#1{ scaled \magstep #1} % This multi-way format was designed by Stephen Gildea % October 1986. \if 1\ncolumns \hsize 4in \vsize 10in \voffset -.7in \font\titlefont=\fontname\tenbf \scaledmag3 \font\headingfont=\fontname\tenbf \scaledmag2 \font\smallfont=\fontname\sevenrm \font\smallsy=\fontname\sevensy \footline{\hss\folio} \def\makefootline{\baselineskip10pt\hsize6.5in\line{\the\footline}} \else \hsize 3.2in \vsize 7.95in \hoffset -.75in \voffset -.745in \font\titlefont=cmbx10 \scaledmag2 \font\headingfont=cmbx10 \scaledmag1 \font\subheadingfont=cmbx10 \scaledmag0 \font\smallfont=cmr6 \font\smallsy=cmsy6 \font\eightrm=cmr8 \font\eightbf=cmbx8 \font\eightit=cmti8 \font\eighttt=cmtt8 \font\eightsy=cmsy8 \textfont0=\eightrm \textfont2=\eightsy \def\rm{\eightrm} \def\bf{\eightbf} \def\it{\eightit} \def\tt{\eighttt} \normalbaselineskip=.8\normalbaselineskip \normallineskip=.8\normallineskip \normallineskiplimit=.8\normallineskiplimit \normalbaselines\rm %make definitions take effect \if 2\ncolumns \let\maxcolumn=b \footline{\hss\rm\folio\hss} \def\makefootline{\vskip 2in \hsize=6.86in\line{\the\footline}} \else \if 3\ncolumns \let\maxcolumn=c \nopagenumbers \else \errhelp{You must set \columnsperpage equal to 1, 2, or 3.} \errmessage{Illegal number of columns per page} \fi\fi \intercolumnskip=.46in \def\abc{a} \output={% % This next line is useful when designing the layout. %\immediate\write16{Column \folio\abc\space starts with \firstmark} \if \maxcolumn\abc \multicolumnformat \global\def\abc{a} \else\if a\abc \global\setbox\columna\columnbox \global\def\abc{b} %% in case we never use \columnb (two-column mode) \global\setbox\columnb\hbox to -\intercolumnskip{} \else \global\setbox\columnb\columnbox \global\def\abc{c}\fi\fi} \def\multicolumnformat{\shipout\vbox{\makeheadline \hbox{\box\columna\hskip\intercolumnskip \box\columnb\hskip\intercolumnskip\columnbox} \makefootline}\advancepageno} \def\columnbox{\leftline{\pagebody}} \def\bye{\par\vfill\supereject \if a\abc \else\null\vfill\eject\fi \if a\abc \else\null\vfill\eject\fi \end} \fi % we won't be using math mode much, so redefine some of the characters % we might want to talk about \catcode`\^=12 \catcode`\_=12 \chardef\\=`\\ \chardef\{=`\{ \chardef\}=`\} \hyphenation{mini-buf-fer} \parindent 0pt \parskip 1ex plus .5ex minus .5ex \def\small{\smallfont\textfont2=\smallsy\baselineskip=.8\baselineskip} \def\n{\hfil\break} \outer\def\newcolumn{\vfill\eject} \outer\def\title#1{{\titlefont\centerline{#1}}\vskip 1ex plus .5ex} \outer\def\section#1{\par\filbreak \vskip 3ex plus 2ex minus 2ex {\headingfont #1}\mark{#1}% \vskip 2ex plus 1ex minus 1.5ex} \outer\def\subsection#1{\par\filbreak \vskip 3ex plus 2ex minus 2ex {\subheadingfont #1}\mark{#1}% \vskip 2ex plus 1ex minus 1.5ex} \newdimen\keyindent \def\beginindentedkeys{\keyindent=1em} \def\endindentedkeys{\keyindent=0em} \endindentedkeys \def\paralign{\vskip\parskip\halign} \def\<#1>{$\langle${\rm #1}$\rangle$} \def\kbd#1{{\tt#1}\null} %\null so not an abbrev even if period follows \def\beginexample{\leavevmode\begingroup \obeylines\obeyspaces\parskip0pt\tt} {\obeyspaces\global\let =\ } \def\endexample{\endgroup} \def\key#1#2{\leavevmode\hbox to \hsize{\vtop {\hsize=.65\hsize\rightskip=1em \hskip\keyindent\relax#1}\kbd{#2}\hfil}} \newbox\metaxbox \setbox\metaxbox\hbox{\kbd{M-x }} \newdimen\metaxwidth \metaxwidth=\wd\metaxbox \def\metax#1#2{\leavevmode\hbox to \hsize{\hbox to .75\hsize {\hskip\keyindent\relax#1\hfil}% \hskip -\metaxwidth minus 1fil \kbd{#2}\hfil}} \def\threecol#1#2#3{\hskip\keyindent\relax#1\hfil&\kbd{#2}\quad &\kbd{#3}\quad\cr} %**end of header \tolerance=10000 \title{Gri \griversion$\,$Reference Card} \section{1\quad What Gri Is} Gri is a language for drawing scientific diagrams such as x-y graphs, contours, vector fields, and images. The Gri language is extensible, well-tested and fully documented. The output is in the PostScript page description language. \section{2\quad How to Run Gri} Normally Gri is run non-interactively. At the system prompt, type {\tt gri foo.gri} to run Gri on the file {\tt foo.gri}, creating a PostScript file called {\tt foo.ps}. (If the script name ends in {\tt .gri}, then there is no need to type the suffix.) Several command-line options exist; type {\tt gri -help} to see them, or consult the manual. Occasionally you might want to run Gri interactively. To do this, type {\tt gri} at the system prompt, and then type Gri commands at the Gri prompt, using {\tt quit} to get out of Gri. \section{3\quad Overview of Gri Language} \subsection{3.1\quad Syntax} Commands normally appear one per line, although ending a line with back-slash causes Gri to scan the next line also. Comments may be inserted at the end of non-continued lines by preceeding the comment by a hash-code ({\tt \#}). Gri allows the usual suite of programming structures, such as loops and if-statements; additionally, new commands may be added to Gri easily (see section 3.7). \subsection{3.2\quad Built-in Commands} Here are the first words of the built-in Gri commands: \beginexample cd close convert create debug delete differentiate draw expecting filter flip get help if ignore input insert interpolate list ls mask move new open pwd query quit read regress reorder rescale resize return rewind set show skip smooth sprintf superuser system write \endexample To get more information on a given command, e.g. the {\tt open} command, type {\tt help open} in an interactive Gri session, or {\tt C-H i gri commands open} in an {\tt emacs} editing session, or {\tt info commands open} at the system level. \subsection{3.3\quad Mathematics} Wherever Gri expects to see a number in a command, one may substitute a mathematical expression written in reverse polish notation (RPN) notation. RPN expressions are enclosed in braces and preceeded by the word {\tt rpn}, e.g. \beginexample set x size $\lbrace$ rpn 5 2.54 * $\rbrace$ \# Make width be 5 inches x += $\lbrace$ rpn 1 2 /$\rbrace$ \# Add 0.5 to x values y -= $\lbrace$ rpn y mean $\rbrace$ \# De-mean y column x -= $\lbrace$ rpn x 0 @ $\rbrace$ \# Subtract first value \endexample \subsection{3.4\quad Variables (for Storing Numbers)} User-defined variables have names that begin and end with periods (like {\tt .offset.}); variables defined by gri (which you may alter if you wish) have names that begin and end with two periods (like {\tt ..xsize..}). To list the variables use {\tt show variables}. Each of the following commands accomplishes the same thing, making the plot 2 cm wider. (Gri uses {\tt ..xsize..} to store the width of the plot.) \beginexample ..xsize.. = $\lbrace$ rpn ..xsize.. 2.0 + $\rbrace$ ..xsize.. += 2 set x size $\lbrace$ rpn ..xsize.. 2.0 + $\rbrace$ set x size bigger 2 \endexample \subsection{3.5\quad Synonyms (for Storing Strings)} Synonyms have names which begin with backslash (like {\tt $\backslash$name}). To list the synonyms use {\tt show synonyms}. Synonyms can be embedded within strings or used raw, e.g. \beginexample \\dir = "mydir" query \\filename "What's the data file?" ("file.dat") open \\mydir/\\filename read columns x y draw curve draw title "Data in \\filename in dir \\mydir" \endexample \subsection{3.6\quad Strings and Math Symbols} Strings are enclosed in double quotes. As in \TeX, superscripts and subscripts are enclosed in dollar signs. Subscripts are preceeded by underscore, superscripts by carat. Superscripts or subscripts consisting of more than one character are enclosed in braces. Gri handles Greek letters and mathematical symbols as \TeX\ does: they are enclosed in dollar signs and have backslash as the first character. Most Greek letters are available, along with several mathematical symbols, but complicated La\TeX\ macros (like {\tt $\backslash$frac$\lbrace\rbrace\lbrace\rbrace$}) are not available. Examples: \beginexample set x name "x/x\$_0\$" draw title "y\$_$\lbrace$dim$\rbrace$\$ as fcn of \$\\alpha\$" \endexample \subsection{3.7\quad Extending Gri} You can create new Gri commands in your commandfile or in your {\tt $\sim$/.grirc} file. Commands in {\tt $\sim$/.grirc} can be used anywhere -- they are your personal extensions to gri. New commands defined in your commandfile exist only within that file. The example below defines a new command which is invoked by {\tt Landscape Big}. The command name (which should begin with upper case letters, to avoid clashing with future built-in commands in gri) is enclosed in angled single-quotes. Optional help lines follow. The body of the command starts after a line with an opening brace, and ends before a line with a closing brace. \beginexample `Landscape Big' Plot in landscape mode, big size $\lbrace$ set page landscape set x margin 2 set x size 25 set y margin 2 set y size 15 $\rbrace$ open file.dat read columns x y close Landscape Big draw curve quit \endexample \section{4\quad Editing Gri in GNU Emacs} A {\tt gri-mode} is available for editing Gri commandfiles in {\tt emacs}. It provides completion of Gri commands, a quick interface to the gri manual about the command being edited, useful pulldown menus, code fontification and the usual indentation, comment placement, etc. Consult the Gri manual for a full description. To use {\tt gri-mode}, put lines like the following in your {\tt $\sim$/.emacs} file. \beginexample ;;; Gri mode (autoload 'gri-mode "gri-mode" "Enter Gri-mode." t) (setq auto-mode-alist (cons '("\\.gri\$" . gri-mode) auto-mode-alist)) \endexample \section{5\quad Documentation and User Group} An {\tt info} manual is available at the system level and inside Emacs. A PostScript manual is also online, along with a cookbook of Gri examples. Since Unix has no standard place to store PostScript manuals, you must consult your system manager to find these files. A World Wide Web manual is available at {\it http://gri.sourceforge.net}. There are Gri mailing lists and discussion groups at this site as well. \section{6.\quad Example -- Linegraph} Suppose the file {\tt example1.dat} contains data in two columns separated by white space. The following shows how to plot data with lines connecting the points. To get symbols without lines, substitute {\tt draw symbols} for {\tt draw curve}; to get both symbols and lines, use both {\tt draw} commands. If you have several curves which cross, use {\tt draw curve overlying}, which whites out a border below each curve, yielding a visual cue that lets the eye trace the individual curves easily. \beginexample \# Example1.gri -- linegraph using data in a file open example1.dat \# Open the data file read columns x y \# Read (x,y) draw curve \# Draw curve stored in (x,y) \endexample You'll notice that there was no need to ask that axes be drawn. They will be automatically determined (based on the data that were read in) and drawn just after the {\tt draw curve} command. (Gri likes to draw axes, and you've got to ask it not to do so, if you don't want them.) Also, note that Gri was not instructed to close the datafile. This is done automatically at termination. One could insert a {\tt close} command after the {\tt read} command, if desired; this is helpful when you wish to work with many data files sequentially. The axes are labelled {\tt x} and {\tt y}. To change that, and to add a title, do as follows: \beginexample open example1.dat read columns x y set x name "Time, s" set y name "Distance, m" draw curve draw title "Trajectory of fluid motion" \endexample To get a thicker curve, say 2 points wide, you could do \beginexample open example1.dat read columns x y set line width 2 draw curve \endexample To get a dashed line, \beginexample open example1.dat read columns x y set dash draw curve \endexample To get a red line, \beginexample open example1.dat read columns x y draw axes set color red draw curve \endexample Note in the above that the axes were drawn before the color was set to red, so they will come out black. Otherwise both the curve and the axes would be red. \section{7.\quad Example -- Contour Graph} Gri can plot contour graphs of either gridded or ungridded data. Several methods are provided for gridding data. The following example shows how to grid randomly distributed (x,y,z) data and plot contours. \beginexample \# Example 5 - Contouring ungridded data, from figure \# 5 of Koch et al., 1983, J. Climate Appl. Met., \# volume 22, pages 1487-1503. open example5.dat read columns x y z close set x size 12 set x axis 0 12 2 set y size 10 set y axis 0 10 2 draw axes set line width symbol 0.2 set symbol size 0.2 draw symbol bullet set font size 8 draw values set x grid 0 12 0.25 set y grid 0 10 0.25 convert columns to grid \# Uncomment next line to smooth the grid: \#smooth grid data set font size 10 draw contour 0 40 2 set font size 12 draw title "Data from Fig 5 Koch et al., 1983" quit \endexample Note that a {\tt quit} command has been included, although it is not required, since Gri quits when it reaches the end of the commandfile anyway. \section{8.\quad Example -- Image Graph} Gri can draw images in BW and color. The following example shows how to plot a satellite image. \beginexample \# Example 6 -- Plot IR image of Gulf of Maine \# define characteristics of norda images \\0val = "5" \# 0 in image \\255val = "30.5" \# 255 in image .r. = 128 \# rows .c. = 128 \# cols .pixel_width. = 2 .km. = $\lbrace$rpn .c. .pixel_width. *$\rbrace$ \# get filenames query \\filename "Image file?" ("example6image.dat") query \\maskname "Mask file?" ("example6mask.dat") \# get data open \\filename binary set image range \\0val \\255val read image .r. .c. box 0 0 .km. .km. close open \\maskname binary read image mask .r. .c. close \# find out what grayscale method to use query \\histo "Flatten histogram?" ("no" "yes") query \\Tw "T/deg for white on page?" ("10") query \\Tb "T/deg for black on page?" ("15") \# set up scales. set x size 12.8 set y size 12.8 set x name "km" set y name "km" set x axis 0 .km. 32 set y axis 0 .km. 32 \# plot image, grayscale, and histogram if $\lbrace$rpn \\histo "yes" ==$\rbrace$ set image grayscale using histogram \\ black \\Tb white \\Tw else set image grayscale black \\Tb white \\Tw end if draw image draw image palette left \\Tw right \\Tb draw image histogram if $\lbrace$rpn \\histo "yes" == $\rbrace$ draw title "Grayscale histogram enhanced" else draw title "Grayscale linear \\Tw to \\Tb" end if \endexample \notice \bye gri/license.txt0000644000175000017500000000126013147557614012202 0ustar psgpsg Copyright 2009 Dan Kelley This file is part of Gri. Gri is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Gri is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Gri. If not, see . gri/README-SunOS50000644000175000017500000000273113147557614011775 0ustar psgpsgCompiling and Installing Gri ============================ To install Gri, type ./install and answer the questions. Basically, you'll be telling the installer where to put the Gri executable, various library files, and a long list of documention files. What Gri is =========== Gri is a language for scientific graphics applications. By 'language' I mean that it is a command-driven application, as opposed to a click/point application. It is analogous to latex or tex, and shares the property that extensive power is the reward for tolerating a modest learning curve. Gri output is in industry-standard PostScript, suitable for incorporation in documents prepared by various text processors. Gri can make x-y graphs, contour-graphs, and image graphs. In addition to high-level capabilities, it has enough low-level capabilities to allow users to achieve a high degree of customization. Precise control is extended to all aspects of drawing, including line-widths, colors, and fonts. Text includes a subset of the tex language, so that it is easy to incorporate Greek letters and mathematical symbols in labels. Copyright restrictions ====================== The Gri programming languages, and all manuals and online help-files, are (c) 1991-2009 Dan E. Kelley . The Gri Emacs mode (gri-mode.el) is (c) 1994-2009 Peter S. Galbraith Gri and gri-mode.el are distributed under GPLv3 license or later; see COPYING. gri/src/0000755000175000017500000000000013147560320010573 5ustar psgpsggri/src/insert.cc0000644000175000017500000000513113147557614012422 0ustar psgpsg/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include "gr.hh" #include "extern.hh" #include "private.hh" #include "superus.hh" bool insertCmd() { if (_nword != 2) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } std::string fname(_word[1]); if (!resolve_filename(fname, true, 'c')) { err("`source' cannot handle file named `\\", _word[1], "'", "\\"); return false; } //printf("Sourcing '%s'\n", fname.c_str()); FILE *fp = fopen(fname.c_str(), "r"); if (NULL == fp) { extern char _grTempString[]; sprintf(_grTempString, "`source' cannot open file `%s' (translated to `%s')", _word[1], fname.c_str()); err(_grTempString); return false; } #if 1 CmdFile cf; // as in file.cc cf.set(fname.c_str(), fp, false, 0, false); _cmdFILE.push_back(cf); #else //printf("DEBUG %s:%d insert on file '%s'\n",__FILE__,__LINE__,fname.c_str()); /* * Scan through the file, doing lines. */ while (!feof(fp)) { /* * See if hit EOF on a line with no text. */ if (NULL == fgets(_cmdLine, LineLength, fp)) break; if (feof(fp)) { warning("Missing newline at end of inserted file `\\", fname.c_str(), "'", "\\"); strcat(_cmdLine, "\n"); } _cmdFILE.back().increment_line(); // BUG line numbers wrong BUG if (((unsigned) superuser()) & FLAG_AUT1) { void insert_source_indicator(char *cl); // in doline.cc insert_source_indicator(_cmdLine); } massage_command_line(_cmdLine); //printf("DEBUG %s:%d massaged line is '%s'\n",__FILE__,__LINE__,_cmdLine); // Kludge if (is_create_new_command(_cmdLine)) insert_cmd_in_ps(_cmdLine/*, "insert.cc:66"*/); if (_nword > 0 && !strcmp(_word[0], "return") && !skipping_through_if()) break; if (!perform_command_line(fp, false)) { return false; } } #endif return true; } gri/src/image_ex.hh0000644000175000017500000000303613147557614012710 0ustar psgpsg/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* declare some extern things, which are defined in image.c */ #if !defined(_image_extern_h_) #define _image_extern_h_ #include "gr.hh" extern double _image0, _image255; /* uservalue <-> [0,255] scale */ extern double _image_missing_color_red; /* for missing data */ extern double _image_missing_color_green; /* for missing data */ extern double _image_missing_color_blue; /* for missing data */ extern double _image_llx, _image_lly, _image_urx, _image_ury; /* coords */ extern double *_imageHist; extern gr_color_model _image_color_model; extern bool _imageTransform_exists; extern bool _imageHist_exists; extern IMAGE _image, _imageMask; extern unsigned char *_imageTransform; #endif /* not _image_extern_h_ */ gri/src/read.cc0000644000175000017500000027147413147557614012050 0ustar psgpsg// vim: noexpandtab tabstop=8 softtabstop=8 /* Gri - A language for scientific graphics programming Copyright (C) 2011 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ //#define DEBUG_READ 1 // Debug // #define REMOVE_COMMENTS_FROM_DATA 1 // Uncomment the preceding line to make Gri remove comments // from data lines. It used to do this by default, but // E.N. pointed out that it was a silly idea from the get-go. #include #include // for reverse #include #include #include #include "gr.hh" #include "extern.hh" #include "image_ex.hh" #include "defaults.hh" #include "gr_coll.hh" #include "files.hh" #include "errors.hh" #include "DataFile.hh" #if defined(HAVE_LIBNETCDF) #include "netcdf.h" #endif unsigned int chars_read = 0; unsigned int offset_for_read = 0; bool read_colornamesCmd(void); bool read_columnsCmd(void); void skip_hash_headers(FILE * fp); bool record_number_unclipped_data(void); bool read_gridCmd(void); bool read_grid_xCmd(void); static double vector_repeats(double *v, int n); bool read_grid_yCmd(void); bool read_grid_dataCmd(void); bool read_image_pgmCmd(void); bool read_image_mask_rasterfileCmd(void); bool read_image_rasterfileCmd(void); static bool read_pgm_image(FILE * fp, IMAGE *im, IMAGE *imMask); static bool read_raster_image(FILE * fp, IMAGE *im); bool read_imageCmd(void); bool read_image_colorscaleCmd(void); bool read_image_grayscaleCmd(void); bool read_image_maskCmd(void); #if defined(HAVE_LIBNETCDF) static bool read_netCDF_column(unsigned int iword, GriColumn *col, int *expected_length, bool append); #endif bool read_synonym_or_variableCmd(void); bool read_lineCmd(); static eof_status get_next_data_line(const char *prompt, unsigned int expected_fields); static bool get_next_data_word(void); // Defined elsewhere extern bool ignore_initial_newline(void); extern char _grTempString[]; // following defined in set.c extern double _input_data_window_x_min; extern double _input_data_window_x_max; extern double _input_data_window_y_min; extern double _input_data_window_y_max; extern bool _input_data_window_x_exists; extern bool _input_data_window_y_exists; static bool maybe_make_grids(void); static GriString inLine(128); // Start short static double tmpf, tmpf2; static int colu, colv, colx, coly, colz, colweight; bool read_from_filenameCmd() { if (_nword == 3) { std::string fname(_word[2]); un_double_quote(fname); if (!push_data_file_to_top(fname.c_str())) { err("Must `open \\", fname.c_str(), "' before doing `read from", fname.c_str(), "'", "\\"); return false; } else { return true; } } else { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } } // `read colornames from RGB "\filename"' bool read_colornamesCmd() { chars_read = 0; FILE *fp; char name[100]; // should be long enough ?? std::string fname; if (_nword == 4) { fname = _lib_directory.c_str(); fname.append("rgb.txt"); } else fname = _word[4]; un_double_quote(fname); //printf("fname='%s'\n", fname.c_str()); fp = fopen(fname.c_str(), "r"); Require(fp != NULL, err("`read colornames' cannot open file `\\", fname.c_str(), "'", "\\")); while(!feof(fp)) { unsigned num; char name2[100], name3[100], name4[100]; int rr, gg, bb, line_len; double r, g, b; if (NULL == fgets(_grTempString, _grTempStringLEN - 1, fp)) break; if (_grTempString[skip_space(_grTempString)] != '#') { // FIXME: what does this test do? line_len = (int)strlen(_grTempString); if (line_len > 3) { num = sscanf(_grTempString, "%d %d %d %s %s %s %s", &rr, &gg, &bb, name, name2, name3, name4); if (num > 0) { switch (num - 3) { case 1: break; case 2: strcat(name, " "); strcat(name, name2); break; case 3: strcat(name, " "); strcat(name, name2); strcat(name, " "); strcat(name, name3); break; case 4: strcat(name, " "); strcat(name, name2); strcat(name, " "); strcat(name, name3); strcat(name, " "); strcat(name, name4); break; default: printf("[%s] num=%d\n", _grTempString, num); warning("`read colornames' found too many words in RGB colorname; truncating to `\\", name, "'", "\\"); } r = rr / 255.0; g = gg / 255.0; b = bb / 255.0; //printf("COLOR '%s' %f %f %f\n",name,r,g,b); create_color(name, r, g, b); } } } else { //printf("HEADER <%s>\n",_grTempString); } } return true; } #if defined(HAVE_LIBNETCDF) static bool read_netCDF_column(unsigned int iword, GriColumn *col, int *expected_length, bool append) { if (iword + 1 < _nword && !strcmp(_word[iword + 1], "=")) { // ASSUME have 2 more words long start[1], edges[1]; long length; // Length of column int var_id, dim_ids[10], dims; std::string varname(_word[iword + 2]); un_double_quote(varname); var_id = ncvarid(_dataFILE.back().get_netCDF_id(), varname.c_str()); Require(var_id != -1, err("Cannot find netCDF variable `\\", varname.c_str(), "'", "\\")); nc_type type; Require(-1 != ncvarinq(_dataFILE.back().get_netCDF_id(), var_id, (char *) 0, &type, &dims, dim_ids, (int *) 0), err("Cannot find info on netCDF variable `\\", varname.c_str(), "'", "\\")); Require(dims == 1, err("Cannot `read columns ... x=\"\\", varname.c_str(), "\" since it is not a vector", "\\")); Require(-1 != ncdiminq(_dataFILE.back().get_netCDF_id(), dim_ids[0], (char *)0, &length), err("Cannot determine length of netCDF variable `\\", varname.c_str(), "'", "\\")); Require(length > 0, err("netCDF variable `\\", varname.c_str(), "' has zero length", "\\")); if (*expected_length && length != *expected_length) { err("Length of netCDF variable `\\", varname.c_str(), "' disagrees with length of a previously scanned column", "\\"); return false; } *expected_length = int(length); unsigned int old_length; if (append) { old_length = col->size(); col->setDepth((unsigned int) (length + old_length)); } else { old_length = 0; col->setDepth((unsigned int)length); } start[0] = 0; edges[0] = length; switch(type) { case NC_FLOAT: { float *tmp = (float*)NULL; GET_STORAGE(tmp, float, (size_t)length); if (-1 == ncvarget(_dataFILE.back().get_netCDF_id(), var_id, start, edges, (void *)tmp)) { err("Error reading variable `\\", varname.c_str(), "' from netCDF file", "\\"); } for (unsigned int ii = 0; ii < (unsigned int) length; ii++) (*col)[ii + old_length] = tmp[ii]; free(tmp); } break; case NC_DOUBLE: { double *tmp = (double*)NULL; GET_STORAGE(tmp, double, (size_t)length); if (-1 == ncvarget(_dataFILE.back().get_netCDF_id(), var_id, start, edges, (void *)tmp)) { err("Error reading variable `\\", varname.c_str(), "' from netCDF file", "\\"); } for (unsigned int ii = 0; ii < (unsigned int) length; ii++) (*col)[ii + old_length] = tmp[ii]; free(tmp); } break; default: err("Cannot handle the type of netCDF variable `\\", varname.c_str(), "'", "\\"); } _columns_exist = true; return true; } else { err("Cannot parse command"); return false; } } #endif static int figure_column(const char *w, int def) { const char *ptr = strstr(w, "="); if (ptr == NULL) return def; double res; if (!getdnum(ptr + 1, &res)) err("Cannot read column number in `\\", w, "'", "\\"); return int(floor(res + 0.5)); } bool read_columnsCmd() { chars_read = 0; int lines_with_missing_data = 0; double missing = gr_currentmissingvalue(); // call once to speed unsigned int i; bool last_point_was_inside = false; int number_to_read, number_read = 0; bool number_specified; int maxCol, row; eof_status end_of_data = no_eof; // flag for end of data int number_outside_window = 0, number_made_missing = 0; bool old = _ignore_error; bool append = false; // appending to end of existing? if (word_is(_nword - 1, "appending")) { _nword--; // will undo later append = true; } if (_nword < 3) { err("`read columns' must specify columns [eg `read columns x y']"); if (append) _nword++; return false; } // Figure out how many lines to read, if user specified it _ignore_error = true; if (getdnum(_word[2], &tmpf)) { if (_dataFILE.back().get_type() == DataFile::bin_netcdf) { demonstrate_command_usage(); err("You may not specify number of data with netCDF files."); if (append) _nword++; return false; } number_specified = true; number_to_read = (int) floor(0.5 + fabs((double) tmpf)); } else { number_specified = false; number_to_read = 0; // irrelevant; prevent compiler warnings } _ignore_error = old; if (number_specified) { if (number_to_read == 0) { warning("`read columns 0 ...' is legal but suspicious"); if (append) _nword++; RETURN_VALUE("0 rows 0 non-missing 0 inside-clip-region"); return true; } else if (number_to_read < 0) { NO_NEGATIVE_ERROR(".n."); if (append) _nword++; return false; } } // Zero out columns, unless appending if (!append) { _colX.setDepth(0); _colY.setDepth(0); _colZ.setDepth(0); _colU.setDepth(0); _colV.setDepth(0); _colWEIGHT.setDepth(0); } // // Handle netCDF as special case if (_dataFILE.back().get_type() == DataFile::bin_netcdf) { #if defined(HAVE_LIBNETCDF) int expected_length = 0; for (i = 2 + (int) number_specified; i < _nword; i += 3) { if (!strcmp(_word[i], "u")) { if (!read_netCDF_column(i, &_colU, &expected_length, append)) { if (append) _nword++; return false; } } else if (!strcmp(_word[i], "v")) { if (!read_netCDF_column(i, &_colV, &expected_length, append)) { if (append) _nword++; return false; } } else if (!strcmp(_word[i], "x")) { if (!read_netCDF_column(i, &_colX, &expected_length, append)) { if (append) _nword++; return false; } } else if (!strcmp(_word[i], "y")) { if (!read_netCDF_column(i, &_colY, &expected_length, append)) { if (append) _nword++; return false; } } else if (!strcmp(_word[i], "z")) { if (!read_netCDF_column(i, &_colZ, &expected_length, append)) { if (append) _nword++; return false; } } else if (!strcmp(_word[i], "weight")) { if (!read_netCDF_column(i, &_colWEIGHT, &expected_length, append)) { if (append) _nword++; return false; } } else { err("unknown item `\\", _word[i], "' in `read columns'", "\\"); if (append) _nword++; return false; } } #else err("Not compiled with netCDF library"); #endif } else { // Data in a normal ascii or binary file // Find what cols are data in. colu = colv = colx = coly = colz = colweight =-1; for (i = 2 + (int) number_specified; i < _nword; i++) { if (!strncmp(_word[i], "u", 1)) { colu = figure_column(_word[i], i - 1 - number_specified); } else if (!strncmp(_word[i], "v", 1)) { colv = figure_column(_word[i], i - 1 - number_specified); } else if (!strncmp(_word[i], "x", 1)) { colx = figure_column(_word[i], i - 1 - number_specified); } else if (!strncmp(_word[i], "y", 1)) { coly = figure_column(_word[i], i - 1 - number_specified); } else if (!strncmp(_word[i], "z", 1)) { colz = figure_column(_word[i], i - 1 - number_specified); } else if (!strncmp(_word[i], "weight", 5)) { colweight = figure_column(_word[i], i - 1 - number_specified); } else if (!strcmp(_word[i], "*")) { // should this have something? } else { err("unknown item `\\", _word[i], "' in `read columns'\n", " Possibly you meant to read a named vector from a netCDF\n file? If so, you should have opened file using netCDF keyword", "\\"); if (append) _nword++; return false; } } // // Figure out column numbers. maxCol = colu; if (colv > maxCol) maxCol = colv; if (colx > maxCol) maxCol = colx; if (coly > maxCol) maxCol = coly; if (colz > maxCol) maxCol = colz; if (colweight > maxCol) maxCol = colweight; // Read data. row = 0; while (end_of_data == no_eof && (!number_specified || number_read < number_to_read)) { unsigned int numCols; // Keep an eye on storage space. char prompt[20]; sprintf(prompt, "row %3d: ", row); // Dump data into inLine. end_of_data = get_next_data_line(prompt, maxCol); number_read++; #if 0 if (end_of_data == eof_after_data) { warning("Got EOF on end of data line; should have a newline there"); } #endif #if 0 printf("DEBUG %s:%d. 'read columns' got [%s]\n",__FILE__,__LINE__,inLine.getValue()); #endif //unsigned int this_line_len = strlen(inLine.getValue()) + 1; #ifdef REMOVE_COMMENTS_FROM_DATA remove_comment(inLine.getValue()); #endif chop_into_data_words(inLine.getValue(), _word, &numCols, MAX_nword); #if 0 printf("%s:%d LINE IS:\n", __FILE__,__LINE__); for (int iii = 0; iii < numCols; iii++) { printf("<%s> ", _word[iii]); } printf("\n"); #endif PUT_VAR("..words_in_dataline..", double(numCols)); if (numCols < 1) { // blank line means done end_of_data = eof_before_data; // trick break; } //printf("numCols= %d maxCol= %d\n", numCols, maxCol); if (maxCol > int(numCols)) { sprintf(_grTempString, "`read columns' -- line %d has %d columns but need %d columns", _dataFILE.back().get_line() - 1, numCols, maxCol); warning(_grTempString); if (append) _nword++; lines_with_missing_data++; } if (colx <= 0) { _colX.push_back((double)row); } else { if (*_word[colx-1] == '\0' || colx > int(numCols)) { _colX.push_back(missing); } else { if (!getdnum(_word[colx - 1], &tmpf)) { err("Can't read x"); continue; } _colX.push_back(tmpf); //printf("pushing back %lf (missing= %lf)\n",tmpf,missing); } } if (coly > 0) { if (*_word[coly-1] == '\0' || coly > int(numCols)) { _colY.push_back(missing); } else { if (!getdnum(_word[coly - 1], &tmpf)) { err("Can't read y"); continue; } _colY.push_back(tmpf); } } if (colu > 0) { if (*_word[colu-1] == '\0' || colu > int(numCols)) { _colU.push_back(missing); } else { if (!getdnum(_word[colu - 1], &tmpf)) { err("Can't read u"); continue; } _colU.push_back(tmpf); } } if (colv > 0) { if (*_word[colv-1] == '\0' || colv > int(numCols)) { _colV.push_back(missing); } else { if (!getdnum(_word[colv - 1], &tmpf)) { err("Can't read v"); continue; } _colV.push_back(tmpf); } } if (colz > 0) { if (*_word[colz-1] == '\0' || colz > int(numCols)) { _colZ.push_back(missing); } else { if (!getdnum(_word[colz - 1], &tmpf)) { err("Can't read z"); continue; } _colZ.push_back(tmpf); } } if (colweight > 0) { if (*_word[colweight-1] == '\0' || colweight > int(numCols)) { _colWEIGHT.push_back(missing); } else { if (!getdnum(_word[colweight - 1], &tmpf)) { err("Can't read weight"); continue; } _colWEIGHT.push_back(tmpf); } } // Check whether this is outside a x or y data window if (_input_data_window_x_exists) { // If an input window exists, check the point to see if it is // inside. tmpf = _colX.topElement(); if (tmpf < _input_data_window_x_min || tmpf > _input_data_window_x_max) { // The current point is outside. Insert a missing value if // last point was inside; if not, though, simply skip this // datum altogether, since the last point will have been // flagged as missing anyway. This keeps storage low. number_outside_window++; if (last_point_was_inside) { if (colx > 0) { _colX.pop_back(); _colX.push_back(missing); } if (coly > 0) { _colY.pop_back(); _colY.push_back(missing); } if (colu > 0) { _colU.pop_back(); _colU.push_back(missing); } if (colv > 0) { _colV.pop_back(); _colV.push_back(missing); } if (colz > 0) { _colZ.pop_back(); _colZ.push_back(missing); } if (colweight > 0) { _colWEIGHT.pop_back(); _colWEIGHT.push_back(missing); } row++; last_point_was_inside = false; number_made_missing++; continue; } else { if (colx > 0) _colX.pop_back(); if (coly > 0) _colY.pop_back(); if (colu > 0) _colU.pop_back(); if (colv > 0) _colV.pop_back(); if (colz > 0) _colZ.pop_back(); last_point_was_inside = false; continue; //row will not be incremented } } else { // The current point is inside. Set flag and continue with // the normal processing. last_point_was_inside = true; } } if (_input_data_window_y_exists) { // If an input window exists, check the point to see if it is // inside. tmpf = _colY.topElement(); if (tmpf < _input_data_window_y_min || tmpf > _input_data_window_y_max) { // The current point is outside. Insert a missing value // if last point was inside; if not, though, simply skip // this datum altogether, since the last point will have // been flagged as missing anyway. This keeps storage // low. number_outside_window++; if (last_point_was_inside) { if (colx > 0) { _colX.pop_back(); _colX.push_back(missing); } if (coly > 0) { _colY.pop_back(); _colY.push_back(missing); } if (colu > 0) { _colU.pop_back(); _colU.push_back(missing); } if (colv > 0) { _colV.pop_back(); _colV.push_back(missing); } if (colz > 0) { _colZ.pop_back(); _colZ.push_back(missing); } if (colweight > 0) { _colWEIGHT.pop_back(); _colWEIGHT.push_back(missing); } row++; last_point_was_inside = false; number_made_missing++; continue; } else { if (colx > 0) _colX.pop_back(); if (coly > 0) _colY.pop_back(); if (colu > 0) _colU.pop_back(); if (colv > 0) _colV.pop_back(); if (colz > 0) _colZ.pop_back(); last_point_was_inside = false; continue; // row will not be incremented } } else { // The current point is inside. Set flag and continue // with the normal processing. last_point_was_inside = true; } } row++; } } if (lines_with_missing_data > 0) { sprintf(_grTempString, "`read columns' encountered %d %s with missing data", lines_with_missing_data, lines_with_missing_data == 1 ? "line" : "lines"); warning(_grTempString); } // All done reading. PUT_VAR("..num_col_data..", double(_colX.size())); PUT_VAR("..num_col_data_missing..", double(number_missing_cols())); if (end_of_data == eof_before_data && _colX.size() == 0 && !batch()) warning("`read columns' found EOF or blank line before finding data."); if (number_specified) { double trace = 0.0; get_var("..trace..", &trace); // number was specified if (end_of_data != no_eof) { sprintf(_grTempString, "%sOnly found %d rows\n", _margin.c_str(), int(_colX.size())); gr_textput(_grTempString); } else if (trace) { sprintf(_grTempString, "%sRead %d data points into columns.\n", _margin.c_str(), int(_colX.size())); gr_textput(_grTempString); if (_input_data_window_x_exists || _input_data_window_y_exists) { sprintf(_grTempString, "\ %sIgnored %d data outside window, yielding %d missing values in columns.\n", _margin.c_str(), number_outside_window, number_made_missing); gr_textput(_grTempString); } } } else { double trace = 0.0; get_var("..trace..", &trace); // number not specified if (trace) { sprintf(_grTempString, "%sRead %d data points into columns.\n", _margin.c_str(), int(_colX.size())); gr_textput(_grTempString); if (_input_data_window_x_exists || _input_data_window_y_exists) { sprintf(_grTempString, "\ %sIgnored %d data outside window, yielding %d missing values in columns.\n", _margin.c_str(), number_outside_window, number_made_missing); gr_textput(_grTempString); } } } if (_colX.size() > 0) { _columns_exist = true; //printf("%s:%d _xscale_exists= %d\n",__FILE__,__LINE__,_xscale_exists); if (!_xscale_exists) { if (!create_x_scale()) { warning("Problem autoscaling -- no data or all x values equal"); } } } if (_colY.size() > 0) { _columns_exist = true; if (!_yscale_exists) { if (!create_y_scale()) { warning("Problem autoscaling -- no data or all y values equal"); } } } // Recover unused space _colX.compact(); _colY.compact(); _colZ.compact(); _colU.compact(); _colV.compact(); _colWEIGHT.compact(); if (append) _nword++; sprintf(_grTempString, "%d rows %d non-missing %d inside-clip-region", int(_colX.size()), int(_colX.size() - number_missing_cols()), int(_colX.size() - number_outside_window++)); RETURN_VALUE(_grTempString); return true; } // read_gridCmd() -- navigate `read grid' command bool read_gridCmd() { chars_read = 0; if (_nword < 3) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (!strcmp(_word[2], "x")) { return read_grid_xCmd(); } else if (!strcmp(_word[2], "y")) { return read_grid_yCmd(); } else if (!strcmp(_word[2], "data")) { return read_grid_dataCmd(); } else { err("`Valid format: `read grid x|y|data'"); return false; } } // read_grid_xCmd() -- read x-values for contour matrix bool read_grid_xCmd() { chars_read = 0; double repeat = 0.0; unsigned int i; unsigned int number_to_read; eof_status end_of_data = no_eof; // flag for end of data bool number_specified; // was number given? if (_dataFILE.back().get_type() == DataFile::bin_netcdf) { #if defined(HAVE_LIBNETCDF) long start[1], edges[1]; long length; int var_id, dim_ids[10], dims; if (_nword > 5) { demonstrate_command_usage(); err("Extra words in command. Expect e.g `read grid x = \"name\"'"); return false; } if (_nword != 5 || !word_is(3, "=") || !quoted(_word[4])) { demonstrate_command_usage(); err("Must specify variable name for a netCDF file"); return false; } char *varname = new char [strlen(_word[4])]; // skip first char if (!varname) OUT_OF_MEMORY; strcpy(varname, 1 + _word[4]); varname[strlen(varname) - 1] = '\0'; var_id = ncvarid(_dataFILE.back().get_netCDF_id(), varname); if (var_id == -1) { err("Cannot find netCDF variable `\\", varname, "'", "\\"); return false; } nc_type type; if (-1 == ncvarinq(_dataFILE.back().get_netCDF_id(), var_id, (char *) 0, &type, &dims, dim_ids, (int *) 0)) { err("Cannot find info on netCDF variable `\\", varname, "'", "\\"); return false; } if (dims != 1) { err("Cannot `read grid x' from variable `\\", varname, "' since it is not a vector", "\\"); return false; } if (-1 == ncdiminq(_dataFILE.back().get_netCDF_id(), dim_ids[0], (char *)0, &length)) { err("Cannot determine length of netCDF variable `\\", varname, "'", "\\"); return false; } start[0] = 0; edges[0] = length; if (!allocate_xmatrix_storage((int)length)) gr_Error("ran out of storage"); switch(type) { case NC_FLOAT: { float *tmp = (float*)NULL; GET_STORAGE(tmp, float, (size_t)length); if (-1 == ncvarget(_dataFILE.back().get_netCDF_id(), var_id, start, edges, (void *)tmp)) { err("Error reading variable `\\", varname, "' from netCDF file", "\\"); } for (unsigned int ii = 0; ii < (unsigned int) length; ii++) _xmatrix[ii] = tmp[ii]; free(tmp); } break; case NC_DOUBLE: { double *tmp = (double*)NULL; GET_STORAGE(tmp, double, (size_t)length); if (-1 == ncvarget(_dataFILE.back().get_netCDF_id(), var_id, start, edges, (void *) tmp)) { err("Error reading variable `\\", varname, "' from netCDF file", "\\"); } for (unsigned int ii = 0; ii < (unsigned int) length; ii++) _xmatrix[ii] = tmp[ii]; free(tmp); } break; default: err("Cannot handle the type of netCDF variable `\\", varname, "'", "\\"); } delete [] varname; _num_xmatrix_data = (int)length; _xgrid_exists = true; #else demonstrate_command_usage(); err("Gri internal error: attempting to use nonexistent netCDF library"); #endif } else { // Figure out how many lines to read; check against existing grid if // possible switch (_nword) { case 3: // make initial guess number_specified = false; _num_xmatrix_data = number_to_read = COLUMN_LEN_DEFAULT; break; case 4: if (!getdnum(_word[3], &tmpf)) { demonstrate_command_usage(); READ_WORD_ERROR(".cols."); return false; } number_to_read = (int) floor(0.5 + fabs((double) tmpf)); if (number_to_read <= 1) { err("Need .cols. > 1"); return false; } if (_grid_exists && number_to_read != _num_xmatrix_data) { sprintf(_errorMsg, "\ Grid width %d disagrees with existing x-grid (%d); first `delete grid'", number_to_read, _num_xmatrix_data); err(_errorMsg); return false; } else { _num_xmatrix_data = number_to_read; } number_specified = true; break; default: demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } // Get storage if (!allocate_xmatrix_storage(number_to_read)) gr_Error("ran out of storage"); // Read data i = 0; while (end_of_data == no_eof && (!number_specified || i < number_to_read)) { // Keep an eye on storage space. if (i >= _num_xmatrix_data) { _num_xmatrix_data += COLUMN_LEN_DEFAULT; _xmatrix = (double *) realloc((char *) _xmatrix, (unsigned) _num_xmatrix_data * sizeof(double)); if (!_xmatrix) gr_Error("ran out of storage"); } char prompt[20]; sprintf(prompt, "row %3d: ", i); end_of_data = get_next_data_line(prompt, 1); #if 0 if (end_of_data == eof_after_data) { warning("Got EOF on end of data line; should have a newline there"); } #endif #ifdef REMOVE_COMMENTS_FROM_DATA remove_comment(inLine.getValue()); #endif unsigned int numCols_ui; chop_into_data_words(inLine.getValue(), _word, &numCols_ui, MAX_nword); PUT_VAR("..words_in_dataline..", double(numCols_ui)); if (numCols_ui < 1) { // blank line means done end_of_data = eof_before_data; // trick break; } if (!getdnum(_word[0], _xmatrix + i)) continue; i++; } if (i <= 0) { err("`read grid x' found no data"); return false; } _num_xmatrix_data = i; } // All done reading. //printf("DEBUG [read_grid_xCmd() %s:%d] _xscale_exists=%d\n",__FILE__,__LINE__,_xscale_exists); if (!_xscale_exists) if (!create_x_scale()) { warning("Problem autoscaling -- no data or all x values equal"); } _xgrid_exists = true; if (_xmatrix[1] > _xmatrix[0]) _xgrid_increasing = true; else _xgrid_increasing = false; if ((repeat = vector_repeats(_xmatrix, _num_xmatrix_data))) { sprintf(_errorMsg, "\ x-grid has some adjacent values equal (e.g., value %f)", repeat); warning(_errorMsg); } sprintf(_grTempString, "%d cols\n", _num_xmatrix_data); RETURN_VALUE(_grTempString); return true; } // check for approximately equal adjacent values static double vector_repeats(double *v, int n) { if (n <= 1) return 0.0; double range = fabs(v[0] - v[n - 1]) / 1.0e10; if (range == 0.0) return v[0]; for (int i = 1; i < n; i++) if (fabs(v[i] - v[i - 1]) < range) return v[i]; return 0.0; } // read_grid_yCmd() -- read y-values for contour matrix bool read_grid_yCmd() { chars_read = 0; double repeat = 0.0; unsigned int number_to_read; eof_status end_of_data = no_eof; // flag for end of data bool number_specified; // was number given? unsigned int i, n; if (_dataFILE.back().get_type() == DataFile::bin_netcdf) { #if defined(HAVE_LIBNETCDF) long start[1], edges[1]; long length; int var_id, dim_ids[10], dims; if (_nword > 5) { demonstrate_command_usage(); err("Extra words in command. Expect e.g `read grid y = \"name\"'"); return false; } if (_nword != 5 || !word_is(3, "=") || !quoted(_word[4])) { demonstrate_command_usage(); err("Must specify variable name for a netCDF file"); return false; } char *varname = new char [strlen(_word[4])]; // skip first char if (!varname) OUT_OF_MEMORY; strcpy(varname, 1 + _word[4]); varname[strlen(varname) - 1] = '\0'; var_id = ncvarid(_dataFILE.back().get_netCDF_id(), varname); if (var_id == -1) { err("Cannot find netCDF variable `\\", varname, "'", "\\"); return false; } nc_type type; if (-1 == ncvarinq(_dataFILE.back().get_netCDF_id(), var_id, (char *) 0, &type, &dims, dim_ids, (int *) 0)) { err("Cannot find info on netCDF variable `\\", varname, "'", "\\"); return false; } if (dims != 1) { err("Cannot `read grid x' from variable `\\", varname, "' since it is not a vector", "\\"); return false; } if (-1 == ncdiminq(_dataFILE.back().get_netCDF_id(), dim_ids[0], (char *)0, &length)) { err("Cannot determine length of netCDF variable `\\", varname, "'", "\\"); return false; } start[0] = 0; edges[0] = length; if (!allocate_ymatrix_storage((int)length)) gr_Error("ran out of storage"); switch(type) { case NC_FLOAT: { float *tmp = (float*)NULL; GET_STORAGE(tmp, float, (size_t)length); if (-1 == ncvarget(_dataFILE.back().get_netCDF_id(), var_id, start, edges, (void *)tmp)) { err("Error reading variable `\\", varname, "' from netCDF file", "\\"); } for (unsigned int ii = 0; ii < (unsigned int) length; ii++) _ymatrix[ii] = tmp[ii]; free(tmp); } break; case NC_DOUBLE: { double *tmp = (double*)NULL; GET_STORAGE(tmp, double, (size_t)length); if (-1 == ncvarget(_dataFILE.back().get_netCDF_id(), var_id, start, edges, (void *)tmp)) { err("Error reading variable `\\", varname, "' from netCDF file", "\\"); } for (unsigned int ii = 0; ii < (unsigned int) length; ii++) _ymatrix[ii] = tmp[ii]; free(tmp); } break; default: err("Cannot handle the type of netCDF variable `\\", varname, "'", "\\"); } delete [] varname; _num_ymatrix_data = (int)length; // Reverse order of vector, because Gri normally reads // from top down std::reverse(_ymatrix, _ymatrix + _num_ymatrix_data); _ygrid_exists = true; #else demonstrate_command_usage(); err("Gri internal error: attempting to use nonexistent netCDF library"); #endif } else { // Figure out how many lines to read; check against existing grid if // possible switch (_nword) { case 3: // make initial guess number_specified = false; _num_ymatrix_data = number_to_read = COLUMN_LEN_DEFAULT; break; case 4: if (!getdnum(_word[3], &tmpf)) { demonstrate_command_usage(); READ_WORD_ERROR(".cols."); return false; } number_to_read = (int) floor(0.5 + fabs((double) tmpf)); if (number_to_read <= 1) { err("Need .cols. > 1"); return false; } if (_grid_exists && number_to_read != _num_ymatrix_data) { sprintf(_errorMsg, "\ Grid height %d disagrees with existing y-grid (%d); first `delete grid'", number_to_read, _num_ymatrix_data); err(_errorMsg); return false; } else { _num_ymatrix_data = number_to_read; } number_specified = true; break; default: demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } // Get storage if (!allocate_ymatrix_storage(number_to_read)) gr_Error("ran out of storage"); // Read data i = 0; while (end_of_data == no_eof && (!number_specified || i < number_to_read)) { // Keep an eye on storage space. if (i >= _num_ymatrix_data) { _num_ymatrix_data += COLUMN_LEN_DEFAULT; _ymatrix = (double *) realloc((char *) _ymatrix, (unsigned) _num_ymatrix_data * sizeof(double)); if (!_ymatrix) gr_Error("ran out of storage"); } char prompt[20]; sprintf(prompt, "row %3d: ", i); end_of_data = get_next_data_line(prompt, 1); #if 0 if (end_of_data == eof_after_data) { warning("Got EOF on end of data line; should have a newline there"); } #endif #ifdef REMOVE_COMMENTS_FROM_DATA remove_comment(inLine.getValue()); #endif unsigned int numCols_ui; chop_into_data_words(inLine.getValue(), _word, &numCols_ui, MAX_nword); PUT_VAR("..words_in_dataline..", double(numCols_ui)); if (numCols_ui < 1) { // blank line means done end_of_data = eof_before_data; // trick break; } if (!getdnum(_word[0], _ymatrix + i)) continue; i++; } if (i <= 0) { err("`read grid y' found no data"); return false; } _num_ymatrix_data = i; } // Now flip them, since reading in from top to bottom. n = _num_ymatrix_data / 2; for (i = 0; i < n; i++) { double tmpd = _ymatrix[i]; _ymatrix[i] = _ymatrix[_num_ymatrix_data - i - 1]; _ymatrix[_num_ymatrix_data - i - 1] = tmpd; } // All done reading. if (!_yscale_exists) if (!create_y_scale()) { warning("Problem autoscaling -- no data or all y values equal"); } _ygrid_exists = true; if (_ymatrix[1] > _ymatrix[0]) _ygrid_increasing = true; else _ygrid_increasing = false; if ((repeat = vector_repeats(_ymatrix, _num_ymatrix_data))) { sprintf(_errorMsg, "\ y-grid has some adjacent values equal (e.g., value %f)", repeat); warning(_errorMsg); } sprintf(_grTempString, "%d rows\n", _num_ymatrix_data); RETURN_VALUE(_grTempString); return true; } bool read_grid_binary(bool bycolumns, char bintype) { chars_read = 0; if (bycolumns) { err("`read grid data' cannot use `bycolumn' with binary data."); return false; } if (_nword == 5) { // gave .cols. and .rows. double tmp; if (!getdnum(_word[3], &tmp)) return false; if (tmp <= 0) { NO_NEGATIVE_ERROR("rows"); return false; } _num_ymatrix_data = (unsigned int)floor(0.5 + tmp); if (!getdnum(_word[4], &tmp)) return false; if (tmp <= 0) { NO_NEGATIVE_ERROR("cols"); return false; } _num_xmatrix_data = (unsigned int)floor(0.5 + tmp); } else { // Ensure that dimensions are known if (_num_xmatrix_data == 0) { err("Cannot `read grid data' unless grid dimensions are known\n First specify x grid by `set x grid' or `read grid x',\n or specify `.cols.' and `.rows.' in present `read grid data' command"); return false; } if (_num_ymatrix_data == 0) { err("Cannot `read grid data' unless grid dimensions are known\n First specify x grid by `set y grid' or `read grid y',\n or specify `.cols.' and `.rows.' in present `read grid data' command"); return false; } } if (!allocate_grid_storage(_num_xmatrix_data, _num_ymatrix_data)) { err("Insufficient space for matrix"); return false; } unsigned int row = _num_ymatrix_data - 1; FILE *the_file = _dataFILE.back().get_fp(); do { double value_d; // for data float value_f; int value_i; unsigned char value_uc; unsigned short int value_16bit; for (unsigned int col = 0; col < _num_xmatrix_data; col++) { int items; double value; if (bintype == 'f') { items = fread((char *)& value_f, sizeof(value_f), 1, the_file); value = value_f; } else if (bintype == 'd') { items = fread((char *)& value_d, sizeof(value_d), 1, the_file); value = value_d; } else if (bintype == 'i') { items = fread((char *)& value_i, sizeof(value_i), 1, the_file); value = value_i; } else if (bintype == 'u') { items = fread((char *)& value_uc, sizeof(value_uc), 1, the_file); value = value_uc; } else if (bintype == 'U') { items = fread((char *)& value_16bit, sizeof(value_16bit), 1, the_file); value = value_16bit; } else { gr_Error("Internal error in read_grid_binary(). Please report to author\n"); return false; } if (items != 1) { char msg[100]; sprintf(msg, "Can't read grid datum at col=%d, row=%d", col, row); err(msg); return false; } _f_xy(col, row) = value; #if 0 // BUG: what was I doing w/ this _f_xy printing? if (value < 0.0) printf("_f_xy(col=%d, row=%d)=%f\n",col,row,value); #endif _legit_xy(col, row) = gr_missing(value) ? false : true; } if (_chatty > 1) printf("Read row %d of grid data\n", row); } while (row-- != 0); return true; // ok } // read_grid_dataCmd() -- read grid data bool read_grid_dataCmd() { chars_read = 0; bool bycolumns = false; if (!strcmp(_word[_nword - 1], "bycolumns")) { bycolumns = true; _nword--; } if (_dataFILE.back().get_type() == DataFile::bin_netcdf) { #if defined(HAVE_LIBNETCDF) long start[2], edges[2]; int var_id, grid_dim_ids[10]; // only need 2 int grid_dims; // Dimensionality (should be 2) long grid_height, grid_width; if (_nword > 5) { demonstrate_command_usage(); err("Extra words in command. Expect e.g `read grid data = \"name\"'"); return false; } if (_nword != 5 || !word_is(3, "=") || !quoted(_word[4])) { demonstrate_command_usage(); err("Must specify variable name for a netCDF file"); return false; } char *varname = new char [strlen(_word[4])]; // skip first char if (!varname) OUT_OF_MEMORY; strcpy(varname, 1 + _word[4]); varname[strlen(varname) - 1] = '\0'; var_id = ncvarid(_dataFILE.back().get_netCDF_id(), varname); if (var_id == -1) { err("Cannot find netCDF variable `\\", varname, "'", "\\"); return false; } nc_type type; if (-1 == ncvarinq(_dataFILE.back().get_netCDF_id(), var_id, (char *) 0, &type, &grid_dims, grid_dim_ids, (int *) 0)) { err("Cannot determine dimensions of `grid data' in netCDF file"); return false; } if (grid_dims != 2) { err("The dimension of netCDF variable `\\", varname, "' is not 2 as required", "\\"); return false; } if (-1 == ncdiminq(_dataFILE.back().get_netCDF_id(), grid_dim_ids[0], (char *)0, &grid_height)) { err("Cannot determine height of grid from netCDF file"); return false; } if (-1 == ncdiminq(_dataFILE.back().get_netCDF_id(), grid_dim_ids[1], (char *)0, &grid_width)) { err("Cannot determine height of grid from netCDF file"); return false; } if (_xgrid_exists && _num_xmatrix_data != (unsigned int)grid_width) { sprintf(_errorMsg, "\ Grid width %ld disagrees with existing x-grid, which is %d long", grid_width, _num_xmatrix_data); err(_errorMsg); return false; } if (_ygrid_exists && _num_ymatrix_data != (unsigned int)grid_height) { sprintf(_errorMsg, "\ Grid height %ld disagrees with existing y-grid, which is %d high", grid_height, _num_ymatrix_data); err(_errorMsg); return false; } start[0] = 0; start[1] = 0; edges[0] = grid_height; edges[1] = grid_width; if (!allocate_grid_storage(int(grid_width), int(grid_height))) { err("Insufficient space for matrix"); return false; } #if 0 if (-1 == ncvarget(_dataFILE.back().get_netCDF_id(), var_id, start, edges, (void *) f_xy_tmp)) { err("Error reading grid data from variable `\\", varname, "' from netCDF file", "\\"); return false; } #else switch(type) { case NC_FLOAT: { float *f_xy_tmp = (float*)NULL; GET_STORAGE(f_xy_tmp, float, (size_t)(grid_width * grid_height)); if (-1 == ncvarget(_dataFILE.back().get_netCDF_id(), var_id, start, edges, (void *) f_xy_tmp)) { err("Error reading grid data from variable `\\", varname, "' from netCDF file", "\\"); return false; } for (int row = grid_height - 1; row > -1; row--) { double val; for (int col = 0; col < grid_width; col++) { val = f_xy_tmp[col + grid_width * row]; _f_xy(col, row) = val; _legit_xy(col, row) = gr_missing(val) ? false : true; } } free(f_xy_tmp); } break; case NC_DOUBLE: { float *f_xy_tmp = (float*)NULL; GET_STORAGE(f_xy_tmp, float, (size_t)(grid_width * grid_height)); if (-1 == ncvarget(_dataFILE.back().get_netCDF_id(), var_id, start, edges, (void *) f_xy_tmp)) { err("Error reading grid data from variable `\\", varname, "' from netCDF file", "\\"); return false; } for (int row = grid_height - 1; row > -1; row--) { double val; for (int col = 0; col < grid_width; col++) { val = f_xy_tmp[col + grid_width * row]; _f_xy(col, row) = val; _legit_xy(col, row) = gr_missing(val) ? false : true; } } free(f_xy_tmp); } break; default: err("Cannot handle the type of netCDF variable `\\", varname, "'", "\\"); } #endif delete [] varname; #else gr_Error("Gri internal error: attempting to use nonexistent netCDF library"); return false; #endif } else if (_dataFILE.back().get_type() == DataFile::bin_unknown) { // If not supplied in `open', assume 32 bit float if (!read_grid_binary(bycolumns, 'f')) return false; } else if (_dataFILE.back().get_type() == DataFile::bin_uchar) { if (!read_grid_binary(bycolumns, 'u')) return false; } else if (_dataFILE.back().get_type() == DataFile::bin_16bit) { if (!read_grid_binary(bycolumns, 'U')) return false; } else if (_dataFILE.back().get_type() == DataFile::bin_int) { if (!read_grid_binary(bycolumns, 'i')) return false; } else if (_dataFILE.back().get_type() == DataFile::bin_double) { if (!read_grid_binary(bycolumns, 'd')) return false; } else if (_dataFILE.back().get_type() == DataFile::bin_float) { if (!read_grid_binary(bycolumns, 'f')) return false; } else if (_dataFILE.back().get_type() == DataFile::ascii || _dataFILE.back().get_type() == DataFile::from_cmdfile) { int cantread = 0; unsigned int startcol = 0, skip_at_end = 0; unsigned int row, col, nrow, ncol, nx, ny; // // Check for 'by columns', a common error if (word_is(_nword - 1, "columns")) { err("Correct usage is `read grid data ... bycolumns', not `... by columns'"); return false; } // Find out how many initial columns to skip, if any if (_nword > 3) { while (*_word[3 + startcol] == '*') { if (startcol + 5 > _nword) { demonstrate_command_usage(); err("Can't understand command."); return false; } startcol++; } while (*_word[_nword - 1 - skip_at_end] == '*') { skip_at_end++; } } // Read .nrow. and .ncol. if supplied; otherwise use // pre-existing or give error. if ((startcol + 5) == _nword) { // Cmdline has .nrow. and .ncol. if (!getdnum(_word[3 + startcol], &tmpf) || !getdnum(_word[4 + startcol], &tmpf2)) { return false; } // Check for crazy numbers nrow = (int) floor(0.5 + tmpf); if (nrow < 1) { err("Need .rows. > 1"); return false; } ncol = (int) floor(0.5 + tmpf2); if (ncol < 1) { err("Need .cols. > 1"); return false; } // Check for agreement with existing grid if (bycolumns) { nx = nrow; ny = ncol; } else { nx = ncol; ny = nrow; } if (_ygrid_exists && _num_ymatrix_data != ny) { if (bycolumns) { sprintf(_errorMsg, "\ .cols. %d disagrees with existing y-grid (%d); first `delete grid'", ny, _num_ymatrix_data); } else { sprintf(_errorMsg, "\ .rows. %d disagrees with existing y-grid (%d); first `delete grid'", ny, _num_ymatrix_data); } err(_errorMsg); return false; } if (_xgrid_exists && _num_xmatrix_data != nx) { if (bycolumns) { sprintf(_errorMsg, "\ .rows. %d disagrees with existing x-grid (%d); first `delete grid'", nx, _num_xmatrix_data); } else { sprintf(_errorMsg, "\ .cols. %d disagrees with existing x-grid (%d); first `delete grid'", nx, _num_xmatrix_data); } err(_errorMsg); return false; } } else if ((startcol + 3) == _nword) { // Using pre-existing .nrow. and .ncol. if (_xgrid_exists && _ygrid_exists) { if (bycolumns) { ncol = _num_ymatrix_data; nrow = _num_xmatrix_data; nx = nrow; ny = ncol; } else { ncol = _num_xmatrix_data; nrow = _num_ymatrix_data; nx = ncol; ny = nrow; } } else { demonstrate_command_usage(); err("Must set/read x-grid and y-grid first"); return false; } } else { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } // Finally know geometry. Now allocate storage, then read data. if (!allocate_grid_storage(nx, ny)) { err("Insufficient space for matrix"); return false; } for (row = 0; row < nrow; row++) { int expected_words = ncol + startcol + skip_at_end; eof_status end_of_data = no_eof; // flag for end of data char prompt[20]; sprintf(prompt, "row %3d: ", row); end_of_data = get_next_data_line(prompt, expected_words); #ifdef REMOVE_COMMENTS_FROM_DATA remove_comment(inLine.getValue()); #endif chop_into_data_words(inLine.getValue(), _word, &_nword, MAX_nword); PUT_VAR("..words_in_dataline..", double(_nword)); if (end_of_data == eof_before_data || _nword == 0) { char msg[100]; sprintf(msg, "\ `read grid data' encountered early blank-line or end-of-file while\n\ trying to read line %d of grid data.", row + 1); err(msg); _grid_exists = true; return false; } if (expected_words != int(_nword)) { char msg[1024]; if (bycolumns) { sprintf(msg, "Want %d data but line %d has %d numbers.\n", _num_ymatrix_data, row + 1, _nword); } else { sprintf(msg, "Want %d data but line %d has %d numbers\n", _num_xmatrix_data, row + 1, _nword); } err(msg); _grid_exists = false; return false; } if (bycolumns) { for (col = 0; col < ncol; col++) { if (getdnum(_word[col + startcol], &tmpf)) { _f_xy(row, col) = tmpf; _legit_xy(row, col) = gr_missing(tmpf) ? false : true; } else { cantread++; _legit_xy(row, col) = false; } } } else { int j = _num_ymatrix_data - row - 1; for (col = 0; col < ncol; col++) { if (getdnum(_word[col + startcol], &tmpf)) { _f_xy(col, j) = tmpf; _legit_xy(col, j) = gr_missing(tmpf) ? false : true; } else { cantread++; _legit_xy(col, j) = false; } } } } if (_chatty > 0 && cantread) { sprintf(_errorMsg, "%d elements couldn't be read", cantread); warning(_errorMsg); } } else { gr_Error("Unrecognized file type"); } matrix_limits(&_f_min, &_f_max); // Figure grid limits _grid_exists = true; sprintf(_grTempString, "%d rows %d cols\n", _num_ymatrix_data, _num_xmatrix_data); RETURN_VALUE(_grTempString); return true; } bool read_image_mask_rasterfileCmd() { chars_read = 0; if (!_dataFILE.back().get_type()) { err("Can only read images from binary files"); demonstrate_command_usage(); return false; } if (!read_raster_image(_dataFILE.back().get_fp(), &_imageMask)) { blank_image(); return false; } else { return true; } } bool read_image_pgmCmd() { #ifdef DEBUG_READ printf("in read image pgm\n"); #endif chars_read = 0; // get scale and box specifications if they exist if (!image_range_exists()) { err("First `set image range'"); return false; } #if 0 // removed 14/05/96; couldn't have worked anyway if (!_dataFILE.back().get_type()) { err("Can only read images from binary files"); demonstrate_command_usage(); return false; } #endif switch (_nword) { case 3: if (!read_pgm_image(_dataFILE.back().get_fp(), &_image, &_imageMask)) { blank_image(); blank_imageMask(); return false; } else { PUT_VAR("..image_width..", double(_image.ras_width)); PUT_VAR("..image_height..", double(_image.ras_height)); return maybe_make_grids(); } // NOT REACHED case 8: if (4 == get_cmd_values(_word, _nword, "box", 4, _dstack)) { define_image_scales(_dstack[0], _dstack[1], _dstack[2], _dstack[3]); } else { err("Cannot read `box' parameters"); demonstrate_command_usage(); return false; } if (!read_pgm_image(_dataFILE.back().get_fp(), &_image, &_imageMask)) { blank_image(); blank_imageMask(); return false; } else { PUT_VAR("..image_width..", double(_image.ras_width)); PUT_VAR("..image_height..", double(_image.ras_height)); return maybe_make_grids(); } // NOT REACHED default: NUMBER_WORDS_ERROR; demonstrate_command_usage(); return false; } // NOT REACHED } // Create integral grids if they don't exist static bool maybe_make_grids() { if (_xgrid_exists || _ygrid_exists) return true; _num_xmatrix_data = _image.ras_width; // get storage space if (!allocate_xmatrix_storage(_num_xmatrix_data)) { err("Insufficient space for grid x data"); return false; } // set up x grid unsigned int i; for (i = 0; i < _num_xmatrix_data; i++) _xmatrix[i] = i; _xgrid_exists = true; _xgrid_increasing = true; if (!_ygrid_exists) { _num_ymatrix_data = _image.ras_height; // get storage space if (!allocate_ymatrix_storage(_num_ymatrix_data)) { err("Insufficient space for grid y data"); return false; } // set up y grid for (i = 0; i < _num_ymatrix_data; i++) _ymatrix[i] = i; _ygrid_exists = true; _ygrid_increasing = true; } define_image_scales(0, 0, _num_xmatrix_data, _num_ymatrix_data); return true; } bool read_image_rasterfileCmd() { chars_read = 0; // get scale and box specifications if they exist if (!image_range_exists()) { err("First `set image range'"); return false; } if (!_dataFILE.back().get_type()) { err("Can only read images from binary files"); demonstrate_command_usage(); return false; } switch (_nword) { case 3: if (!read_raster_image(_dataFILE.back().get_fp(), &_image)) { blank_imageMask(); return false; } else { PUT_VAR("..image_width..", double(_image.ras_width)); PUT_VAR("..image_height..", double(_image.ras_height)); return maybe_make_grids(); } // NOT REACHED case 8: if (4 == get_cmd_values(_word, _nword, "box", 4, _dstack)) define_image_scales(_dstack[0], _dstack[1], _dstack[2], _dstack[3]); if (!read_raster_image(_dataFILE.back().get_fp(), &_image)) { blank_imageMask(); return false; } else { PUT_VAR("..image_width..", double(_image.ras_width)); PUT_VAR("..image_height..", double(_image.ras_height)); return maybe_make_grids(); } // NOT REACHED default: NUMBER_WORDS_ERROR; demonstrate_command_usage(); return false; } // NOT REACHED } // REF: man 3 pgm. I'm confused on P4, P5, etc, and I've changed the // code back and forth, from the looks of it. // // 14/5/96: found http://cephag.observ-gv.fr/documentation/man_pbmplus.html // and am now moving to it. enum FILE_TYPE { P2_type, // ascii portable graymap: B values 14/5/96 working P3_type, // ascii portable pixmap: RGB triplets P4_type, // cannot do P5_type, // binary portable graymap: B values 14/5/96 working P6_type // as P3 but binary 14/5/96 not working }; // WARNING: this code is pretty tangled ... if bugs crop up, it would make sense to clean it. static bool read_pgm_image(FILE * fp, IMAGE *im, IMAGE *imMask) { #ifdef DEBUG_READ printf("in read_pgm_image\n"); #endif chars_read = 0; FILE_TYPE file_type; //int i, j; int width, height, max_gray; unsigned char tmpB; char type[3]; skip_hash_headers(fp); if (1 != fscanf(fp, "%2s", type)) { err("Cannot read MAGIC on this pgm file"); return false; } skip_hash_headers(fp); if (!strcmp(type, "P2")) file_type = P2_type; // can do else if (!strcmp(type, "P3")) file_type = P3_type; else if (!strcmp(type, "P4")) file_type = P4_type; // cannot do else if (!strcmp(type, "P5")) file_type = P5_type; // can do else if (!strcmp(type, "P6")) file_type = P6_type; // cannot do else { sprintf(_grTempString, "\ This is not a PGM file, since the first 2 characters\n\ are \"%s\", not \"P2\", \"P3\", \"P4\", \"P5\", \"P6\"as they must be for a PGM file.", type); err(_grTempString); return false; } // Next few tests are for later ... I'll fill in the code // as I add support. // Presently, support P2 and P5. if (file_type == P3_type) { err("Cannot read P3-type images"); return false; } if (file_type == P4_type) { err("Cannot read P4-type images"); return false; } if (file_type == P6_type) { err("Cannot read binary portable-pixmap P6-type images"); return false; } skip_hash_headers(fp); if (1 != fscanf(fp, "%d", &width)) { err("Cannot read `width' of pgm file"); return false; } skip_hash_headers(fp); if (1 != fscanf(fp, "%d", &height)) { err("Cannot read `height' of pgm file"); return false; } skip_hash_headers(fp); max_gray = 255; if (file_type == P2_type || file_type == P5_type) { if (1 != fscanf(fp, "%d", &max_gray)) { err("Cannot read `maximum-gray-value' of pgm file"); return false; } if (_image_color_model != bw_model) { warning("'read image pgm' is switching from a color scale to a black/white scale.\n If you issue a 'read image colorscale' or 'set image colorscale'\n command after the present command, though, you can over-ride this\n and get a color image."); } for (unsigned int i = 0; i < 256; i++) _imageTransform[i] = (unsigned char)floor(0.5 + i*255/max_gray); _imageTransform_exists = true; _image_color_model = bw_model; } skip_hash_headers(fp); if (max_gray != 255) { err("Can only do pgm files with maximum-graylevel equal to 255"); return false; } im->ras_width = width; im->ras_height = height; im->ras_depth = 8; im->ras_length = width * height; im->ras_type = RT_STANDARD; im->ras_maptype = RMT_NONE; im->ras_maplength = 0; if (im->ras_width < 1 || im->ras_height < 1) { err("Cannot read image with negative or zero width or height"); return false; } if (im->storage_exists) { //printf("%s:%d freeing image storage at %x\n",__FILE__,__LINE__,(int)im->image); free(im->image); imMask->storage_exists = false; } if (imMask->storage_exists) { printf("%s:%d freeing imageMask storage at %lx\n",__FILE__,__LINE__,(long unsigned int)imMask->image); free(imMask->image); imMask->storage_exists = false; } imMask->ras_width = imMask->ras_height = 0; GET_STORAGE(im->image, unsigned char, (im->ras_width * im->ras_height)); im->storage_exists = true; //printf("%s:%d got new image storage at %x size %d by %d\n",__FILE__,__LINE__,(int)(im->image), im->ras_width, im->ras_height); #if 1 // fixing SF bug 664388 if (_dataFILE.back().get_type() == DataFile::from_cmdfile) { err("Cannot 'read image' from a commandfile; use a data file instead"); return false; } #ifdef DEBUG_READ printf("DEBUG: %s:%d image_width=%d image_height=%d\n",__FILE__,__LINE__,im->ras_width,im->ras_height); #endif if (file_type == P2_type) { for (int j = int(im->ras_height - 1); j > -1; j--) { for (int i = 0; i < int(im->ras_width); i++) { int tmp_int; if (1 != fscanf(fp, "%d", &tmp_int)) { printf("Cannot read datum at i=%d and j=%d (i.e. the %d-th point)\n", i, j, i*j); err("Cannot read P2 image"); return false; } *(im->image + i * im->ras_height + j) = tmp_int; #ifdef DEBUG_READ if (j==(im->ras_height-1) && i< 25) {printf("Debug test: datum[%d][%d] is %d\n", i, j, tmp_int);} #endif } } return true; } else if (file_type == P5_type) { for (int j = int(im->ras_height - 1); j > -1; j--) { for (int i = 0; i < int(im->ras_width); i++) { if (1 != fread((char *) & tmpB, sizeof(tmpB), 1, fp)) { sprintf(_grTempString, "Could not read all PGM image data. Ran out after reading %d bytes", (im->ras_height - 1 - j) * im->ras_width + i); err(_grTempString); return false; } *(im->image + i * im->ras_height + j) = tmpB; #ifdef DEBUG_READ printf("i=%d j=%d ... value %x_hex = %d_dec\n",i,j,tmpB,tmpB); #endif } } } else { err("Sorry, only 'P2' and 'P5' types of PGM image are handled by gri."); return false; } #else if (_dataFILE.back().get_type() != DataFile::from_cmdfile &&_dataFILE.back().get_type() != DataFile::ascii) { // It's binary -- check for correct type if (file_type != P5_type) { err("A binary `pgm' image needs first 2 chars to be \"P5\""); return false; } // Read byte by byte //printf("DEBUG: %s:%d image_width=%d image_height=%d\n",__FILE__,__LINE__,im->ras_width,im->ras_height); for (int j = int(im->ras_height - 1); j > -1; j--) { for (int i = 0; i < int(im->ras_width); i++) { if (1 != fread((char *) & tmpB, sizeof(tmpB), 1, fp)) { sprintf(_grTempString, "Could not read all PGM image data. Ran out after reading %d bytes", (im->ras_height - 1 - j) * im->ras_width + i); err(_grTempString); return false; } *(im->image + i * im->ras_height + j) = tmpB; //printf("i=%d j=%d ... value %x_hex = %d_dec\n",i,j,tmpB,tmpB); } } } else { // It's ascii -- check for correct type char nextWord[50]; if (file_type == P2_type /* || file_type == P3_type */) { for (int j = im->ras_height - 1; j > -1; j--) { for (int i = 0; i < int(im->ras_width); i++) { // Get 1 ascii datum. if (1 != fscanf(fp, "%s", nextWord)) { sprintf(_grTempString, "Could not read all PGM image data. Ran out after reading %d bytes", (im->ras_height - 1 - j) * im->ras_width + i); err(_grTempString); return false; } if (!getdnum(nextWord, &tmpf)) { tmpB = 0; } tmpB = (int) floor((double) (0.5 + tmpf)); *(im->image + i * im->ras_height + j) = tmpB; } } } else if (file_type == P5_type) { err("Mixed up -- it's a P5 type file but data are ascii"); return false; } else { err("Can only handle P2 and P5 subtypes of the PGM type"); return false; } } #endif return true; } // If the very next character is '#', skip rest of this line void skip_hash_headers(FILE * fp) { int c; // Skip initial whitespace (left from previous read) while (1) { do { c = getc(fp); } while (c == ' ' || c == '\n' || c == '\t'); if (c == '#') { while ('\n' != (c = getc(fp))) { ; } } else { ungetc(c, fp); return; } } } // REF: man 5 rasterfile; /usr/include/rasterfile.h on a sun computer static bool read_raster_image(FILE * fp, IMAGE * im) { chars_read = 0; int i, j; unsigned char tmpB; unsigned char b0, b1, b2, b3; // The "man rasterfile" page on solaris suggests to check the // first word against "#define RAS_MAGIC 0x59a66a95" but // we have to check it byte by byte (0x59 0xa6 0x6a 0x95) // because of endian issues. An ugly issue. if (1 != fread((char*)&b0, sizeof(unsigned char), 1, fp)) { err("Cannot read the first 'magic' byte at start of image"); return false; } if (1 != fread((char*)&b1, sizeof(unsigned char), 1, fp)) { err("Cannot read the second 'magic' byte at start of image"); return false; } if (1 != fread((char*)&b2, sizeof(unsigned char), 1, fp)) { err("Cannot read the third 'magic' byte at start of image"); return false; } if (1 != fread((char*)&b3, sizeof(unsigned char), 1, fp)) { err("Cannot read the fourth 'magic' byte at start of image"); return false; } // Sun is big endian; intel is little endian. bool big_endian = false; if (b0 == 0x59 && b1 == 0xa6 && b2 == 0x6a && b3 == 0x95) big_endian = true; else if (b3 == 0x59 && b2 == 0xa6 && b1 == 0x6a && b0 == 0x95) big_endian = false; else { sprintf(_grTempString, "This is not a Sun rasterfile, since first bytes are %x,%x,%x,%x instead of the expected %x,%x,%x,%x or %x,%x,%x,%x\n", b0, b1, b2, b3, 0x59, 0xa6, 0x6a, 0x95, 0x95, 0x6a, 0xa6, 0x59); err(_grTempString); } bool switch_bytes = false; #if defined(__GNUC__) // BUG: should do this endian work a lot more cleanly if ((!GRI_IS_BIG_ENDIAN && big_endian) || (GRI_IS_BIG_ENDIAN && ! big_endian)) { switch_bytes = true; #if defined(DEBUG_READ) printf("DEBUG: %s:%d must switch bytes\n",__FILE__,__LINE__); #endif } #endif #if defined(DEBUG_READ) printf("DEBUG. %s:%d endian status = %s\n",__FILE__,__LINE__,big_endian? "BIG":"LITTLE"); #endif if (1 != fread((char *) & im->ras_width, sizeof(unsigned int), 1, fp)) { err("Cannot read image width"); return false; } #if defined(DEBUG_READ) printf("DEBUG: %s:%d switch raster width from %d to ", __FILE__,__LINE__,im->ras_width); #endif if (switch_bytes) im->ras_width = endian_swap_uint(im->ras_width); #if defined(DEBUG_READ) printf("%d\n", im->ras_width); #endif bool need_zero_padding = (im->ras_width == 2 * (im->ras_width / 2)) ? false : true; if (1 != fread((char *) & im->ras_height, sizeof(unsigned int), 1, fp)) { err("Cannot read image height"); return false; } if (switch_bytes) im->ras_height = endian_swap_uint(im->ras_height); if (1 != fread((char *) & im->ras_depth, sizeof(unsigned int), 1, fp)) { err("Cannot read image depth"); return false; } if (switch_bytes) im->ras_depth = endian_swap_uint(im->ras_depth); if (1 != fread((char *) & im->ras_length, sizeof(unsigned int), 1, fp)) { err("Cannot read image length"); return false; } if (switch_bytes) im->ras_length = endian_swap_uint(im->ras_length); if (1 != fread((char *) & im->ras_type, sizeof(unsigned int), 1, fp)) { err("Cannot read image type"); return false; } if (switch_bytes) im->ras_type = endian_swap_uint(im->ras_type); if (1 != fread((char *) & im->ras_maptype, sizeof(unsigned int), 1, fp)) { err("Cannot read image maptype"); return false; } if (switch_bytes) im->ras_maptype = endian_swap_uint(im->ras_maptype); if (1 != fread((char *) & im->ras_maplength, sizeof(unsigned int), 1, fp)) { err("Cannot read image maplength"); return false; } if (switch_bytes) im->ras_maplength = endian_swap_uint(im->ras_maplength); if (need_zero_padding) if (im->ras_length != (need_zero_padding ? 1 + im->ras_width : im->ras_width) * im->ras_height) { sprintf(_grTempString, "Cannot read compressed images. This seems to be compressed, since it's %d wide and %d tall, but the length is %d\n", im->ras_width, im->ras_height, im->ras_length); err(_grTempString); return false; } if (im->ras_depth != 8) { err("Can only read 8 bit images"); return false; } if (im->ras_type != RT_STANDARD) { sprintf(_grTempString, "Can only read images of type RT_STANDARD (%d) but this is type %d\n", RT_STANDARD, im->ras_type); err(_grTempString); return false; } // Skip colormap if there is one BUG: should use it switch (im->ras_maptype) { case RMT_NONE: break; case RMT_RAW: warning("Skipping image map of type RMT_RAW."); for (i = 0; i < int(im->ras_maplength); i++) if (0 == fread((char *) & tmpB, sizeof(tmpB), 1, fp)) break; break; case RMT_EQUAL_RGB: // raw warning("Skipping image map of type RMT_RGB."); for (i = 0; i < int(im->ras_maplength); i++) if (0 == fread((char *) & tmpB, sizeof(tmpB), 1, fp)) break; break; default: err("Can only read images of maptype RMT_NONE or RMT_RAW"); return false; } if (im->ras_width < 1 || im->ras_height < 1) { err("Cannot read image with negative or zero width or height"); return false; } GET_STORAGE(im->image, unsigned char, (im->ras_width * im->ras_height)); for (j = int(im->ras_height - 1); j > -1; j--) { for (i = 0; i < int(im->ras_width); i++) { if (1 != fread((char *) & tmpB, sizeof(tmpB), 1, fp)) { sprintf(_grTempString, "Could not read all RasterFile image data. Ran out after reading %d bytes", (im->ras_height - 1 - j) * im->ras_width + i); err(_grTempString); return false; } //printf("i=%d j=%d ... value %x_hex = %d_dec\n",i,j,tmpB,tmpB); *(im->image + i * im->ras_height + j) = tmpB; } if (need_zero_padding) { if (0 == fread((char *) & tmpB, sizeof(tmpB), 1, fp)) break; } } return true; } // read_imageCmd() -- read image data bool read_imageCmd() { chars_read = 0; bool bycolumns = false; int i, j, nrow, ncol; unsigned int nx, ny; unsigned char tmpB; char nextWord[50]; if (!image_range_exists()) { err("First `set image range'"); return false; } if (!_dataFILE.back().get_type()) { err("Can only read images from binary files"); demonstrate_command_usage(); return false; } // Figure out if reading by columns (by rows is default). if (!strcmp(_word[_nword - 1], "bycolumns")) { bycolumns = true; _nword--; } // get box specifications if it exists if (4 == get_cmd_values(_word, _nword, "box", 4, _dstack)) define_image_scales(_dstack[0], _dstack[1], _dstack[2], _dstack[3]); if (2 == get_cmd_values(_word, _nword, "image", 2, _dstack)) { nrow = (int) floor(0.5 + _dstack[0]); ncol = (int) floor(0.5 + _dstack[1]); } else { demonstrate_command_usage(); err("Can't understand command."); return false; } if (nrow < 0 || ncol < 0) { NO_NEGATIVE_ERROR(".rows., .cols."); return false; } if (bycolumns) { nx = (unsigned int)nrow; ny = (unsigned int)ncol; } else { nx = (unsigned int)ncol; ny = (unsigned int)nrow; } // Check for agreement with existing mask grid. if (_imageMask.storage_exists && (_imageMask.ras_width != nx || _imageMask.ras_height != ny)) { sprintf(_errorMsg, "%dx%d grid contradicts existing %dx%d mask grid\n", nx, ny, _imageMask.ras_width, _imageMask.ras_height); err(_errorMsg); return false; } if (_image.storage_exists && (_image.ras_width != nx || _image.ras_height != ny)) { sprintf(_errorMsg, "%dx%d grid contradicts existing %dx%d grid\n", nx, ny, _imageMask.ras_width, _imageMask.ras_height); err(_errorMsg); return false; } // Allocate storage for image and mask if (!allocate_image_storage(nx, ny)) { err("No space for image"); return false; } if (!allocate_imageMask_storage(nx, ny)) { err("No space for image mask"); return false; } // Don't allow reading from cmd-file right now. if (_dataFILE.back().get_type() == DataFile::from_cmdfile) { err("Can't read images from command-file"); if (_cmdFILE.back().get_interactive()) return false; } // Read in the data, number by number. char emessage[200]; FILE *imfile = _dataFILE.back().get_fp(); DataFile::type imtype = _dataFILE.back().get_type(); for (j = int(ny - 1); j > -1; j--) { for (i = 0; i < int(nx); i++) { tmpB = 0; if (imtype == DataFile::bin_unknown || imtype == DataFile::bin_uchar) { // Get 1 binary datum. if (1 != fread((char *) & tmpB, 1, 1, imfile)) { sprintf(emessage, "Cannot read whole %dx%d 8-bit image. Only read %d bytes of the %d bytes expected in image", nx, ny, (i + j * nx), (nx * ny)); err(emessage); return false; } } else if (imtype == DataFile::bin_16bit) { unsigned short int v; if (1 != fread((char *) & v, sizeof(v), 1, imfile)) { sprintf(emessage, "Cannot read whole %dx%d 16-bit image.\n Only read %d bytes of the %d bytes expected in image", nx, ny, 2*(i + j * nx), 2*(nx * ny)); err(emessage); return false; } else { tmpB = (unsigned char)v; } } else if (imtype == DataFile::bin_int) { unsigned int v; if (1 != fread((char *) & v, sizeof(v), 1, imfile)) { sprintf(emessage, "Cannot read whole %dx%d 32-bit image.\n Only read %d bytes of the %d bytes expected in image", nx, ny, 4*(i + j * nx), 4*(nx * ny)); err(emessage); return false; } else { tmpB = (unsigned char)v; } } else if (imtype == DataFile::bin_float) { float v; if (1 != fread((char *) & v, sizeof(v), 1, imfile)) { sprintf(emessage, "Cannot read whole %dx%d 32-bit image.\n Only read %d bytes of the %d bytes expected in image", nx, ny, 4*(i + j * nx), 4*(nx * ny)); err(emessage); return false; } else { tmpB = (unsigned char)v; } } else if (imtype == DataFile::bin_double) { double v; if (1 != fread((char *) & v, sizeof(v), 1, imfile)) { sprintf(emessage, "Cannot read whole %dx%d 64-bit image.\n Only read %d bytes of the %d bytes expected in image", nx, ny, 8*(i + j * nx), 8*(nx * ny)); err(emessage); return false; } else { tmpB = (unsigned char)v; } } else if (imtype == DataFile::ascii) { // Get 1 ascii datum. if (1 != fscanf(imfile, "%s", nextWord)) { sprintf(emessage, "Cannot read whole %dx%d ascii image.\n Only read %d bytes of the %d values expected in image", nx, ny, (i + j * nx), (nx * ny)); err(emessage); return false; } if (!getdnum(nextWord, &tmpf)) { sprintf(emessage, "Cannot read whole %dx%d ascii image.\n Only read %d bytes of the %d values expected in image", nx, ny, (i + j * nx), (nx * ny)); err(emessage); return false; } tmpB = (int) floor((double) (0.5 + tmpf)); // Ignore comments. if (!strcmp(nextWord, "//")) while (fgetc(imfile) != '\n') ; } else { err("Internal error -- unknown image type."); return false; } // Now have 1 datum. Store it into image. if (bycolumns) { *(_image.image + j * nx + i) = tmpB; } else { *(_image.image + i * ny + j) = tmpB; } } } return true; } // read_image_colorscaleCmd() -- read image colorscale as 256 lines of // (R,G,B), clipped to range 0,1 `read image colorscale' `read image // colorscale rgb' `read image colorscale hsb' bool read_image_colorscaleCmd() { chars_read = 0; double R, G, B; double H, S, V; bool using_rgb = true; if (_nword == 3) { using_rgb = true; } else if (_nword == 4) { if (word_is(3, "rgb")) { using_rgb = true; } else if (word_is(3, "hsb")) { using_rgb = false; } else { demonstrate_command_usage(); err("Fourth word must be `rgb' or `hsb'"); return false; } } else { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } // Table must have 256 lines for (int i = 0; i < 256; i++) { if (get_next_data_line("Image colorscale", 3)) { err("Can't read image grayscale; found EOF on line."); return false; } #ifdef REMOVE_COMMENTS_FROM_DATA remove_comment(inLine.getValue()); #endif unsigned int nword; chop_into_data_words(inLine.getValue(), _Words2, &nword, MAX_nword); if (using_rgb) { getdnum(_Words2[0], &R); getdnum(_Words2[1], &G); getdnum(_Words2[2], &B); } else { getdnum(_Words2[0], &H); getdnum(_Words2[1], &S); getdnum(_Words2[2], &V); H = pin0_1(H); S = pin0_1(S); B = pin0_1(B); gr_hsv2rgb(H, S, V, &R, &G, &B); } _imageTransform[i] = (int) (floor(0.5 + pin0_255(255.0 * R))); _imageTransform[i + 256] = (int) (floor(0.5 + pin0_255(255.0 * G))); _imageTransform[i + 512] = (int) (floor(0.5 + pin0_255(255.0 * B))); } _imageTransform_exists = true; _image_color_model = rgb_model; return true; } // read_image_grayscaleCmd() -- read image grayscale (clipped to range 0-1) bool read_image_grayscaleCmd() { chars_read = 0; // Get data into inLine. if (get_next_data_line("Image grayscale", 256)) { err("Can't read image grayscale; found EOF on line."); return false; } #ifdef REMOVE_COMMENTS_FROM_DATA remove_comment(inLine.getValue()); #endif unsigned int nword; chop_into_data_words(inLine.getValue(), _Words2, &nword, MAX_nword); PUT_VAR("..words_in_dataline..", double(nword)); if (nword == 256) { // Table all on 1 line (required before version 1.049) for (int i = 0; i < 256; i++) { getdnum(_Words2[i], &tmpf); _imageTransform[i] = (int) (floor(0.5 + pin0_255(255.0 * tmpf))); } } else { // Table has 256 lines getdnum(_Words2[0], &tmpf); _imageTransform[0] = (int) (floor(0.5 + pin0_255(255.0 * tmpf))); for (int i = 1; i < 256; i++) { if (get_next_data_line("Image grayscale", 1)) { err("Can't read image grayscale; found EOF on line."); return false; } #ifdef REMOVE_COMMENTS_FROM_DATA remove_comment(inLine.getValue()); #endif chop_into_data_words(inLine.getValue(), _Words2, &nword, MAX_nword); PUT_VAR("..words_in_dataline..", double(nword)); getdnum(_Words2[0], &tmpf); _imageTransform[i] = (int) (floor(0.5 + pin0_255(255.0 * tmpf))); } } _imageTransform_exists = true; return true; } // read_image_maskCmd() -- read image mask bool read_image_maskCmd() { chars_read = 0; bool bycolumns = false, outbounds = false; int cantread = 0; int i, j, nrow, ncol; unsigned int nx, ny; unsigned char tmpB; char nextWord[50]; // Figure out if reading by columns (by rows is default). if (!strcmp(_word[_nword - 1], "bycolumns")) { bycolumns = true; _nword--; } // Do initial check for bad command. if (_nword != 5) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (!getdnum(_word[3], &tmpf)) { demonstrate_command_usage(); err("Can't read .rows. PROPER: `read image mask .rows. .cols.'"); return false; } nrow = (int) floor(0.5 + tmpf); if (!getdnum(_word[4], &tmpf)) { demonstrate_command_usage(); err("Can't read .cols. PROPER: `read image mask .rows. .cols.'"); return false; } ncol = (int) floor(0.5 + tmpf); if (nrow < 0 || ncol < 0) { NO_NEGATIVE_ERROR(".rows., .cols."); return false; } if (bycolumns) { nx = (unsigned int)nrow; ny = (unsigned int)ncol; } else { nx = (unsigned int)ncol; ny = (unsigned int)nrow; } // Check for agreement with existing grid. if (_imageMask.storage_exists && (_imageMask.ras_width != nx || _imageMask.ras_height != ny)) { sprintf(_errorMsg, "%dx%d grid contradicts existing %dx%d mask grid\n", nx, ny, _imageMask.ras_width, _imageMask.ras_height); err(_errorMsg); return false; } if (_image.storage_exists && (_image.ras_width != nx || _image.ras_height != ny)) { sprintf(_errorMsg, "%dx%d grid contradicts existing %dx%d grid\n", nx, ny, _imageMask.ras_width, _imageMask.ras_height); err(_errorMsg); return false; } // Allocate storage. if (!allocate_imageMask_storage(nx, ny)) { err("No space for image mask"); return false; } // Don't allow reading from cmd-file right now. if (_dataFILE.back().get_type() == DataFile::from_cmdfile) { demonstrate_command_usage(); err("Can't read images from command-file"); if (!_cmdFILE.back().get_interactive()) return false; } // Read in the data, number by number. for (j = int(ny - 1); j > -1; j--) { for (i = 0; i < int(nx); i++) { if (_dataFILE.back().get_type()) { // Get 1 binary datum. if (1 != fread((char *) & tmpB, 1, 1, _dataFILE.back().get_fp())) { cantread++; tmpB = 0; } } else { // Get 1 ascii datum. if (1 != fscanf(_dataFILE.back().get_fp(), "%s", nextWord)) { err("Ran out of data"); return false; } if (!getdnum(nextWord, &tmpf)) { cantread++; tmpB = 0; } tmpB = (int) floor((double) (0.5 + tmpf)); // Ignore comments. if (!strcmp(nextWord, "//")) while (fgetc(_dataFILE.back().get_fp()) != '\n'); } // Now have 1 datum. Store it into imageMask or into image. if (bycolumns) { *(_imageMask.image + j * nx + i) = tmpB; } else { *(_imageMask.image + i * ny + j) = tmpB; } } } if (cantread) { sprintf(_errorMsg, "%d elements unreadable", cantread); err(_errorMsg); return false; } if (outbounds) { sprintf(_errorMsg, "%d elements <0 or >255", outbounds); err(_errorMsg); return false; } return true; } bool read_synonym_or_variableCmd() { //printf("dd IN READ SYN/VAR\n"); chars_read = 0; if (_nword < 2) { demonstrate_command_usage(); err("`read' what? (Need more words on command line.)"); return false; } unsigned int start = 0; #ifdef REMOVE_COMMENTS_FROM_DATA bool read_raw_flag = false; if (strEQ(_word[1], "raw")) { read_raw_flag = true; start = 1; } #endif if (_dataFILE.back().get_type() == DataFile::bin_netcdf) { #if defined(HAVE_LIBNETCDF) // For netCDF files, only allow `read \name' (with one synonym) int len = strlen(_word[1 + start]) - 1;// NB: skipping first char char *varname = new char [1 + len]; if (!varname) OUT_OF_MEMORY; char *varname_base; varname_base = varname; // for later deletion strcpy(varname, _word[1 + start] + 1); #if 1 // 2.060 // // Remove '{' and '}' if present if (varname[0] == '{') { varname++; len--; } if (varname[len - 1] == '}') { varname[len - 1] = '\0'; len--; } #endif bool has_colon = false; int i, where_colon = -1; for (i = 0; i < len; i++) { if (varname[i] == ':') { has_colon = true; where_colon = i; } } struct ncatt { int var; char name[MAX_NC_NAME]; nc_type type; int len; void *val; }; struct ncatt att; int varid; if (has_colon && where_colon != 0) { // Attribute of a variable varname[where_colon] = '\0'; varid = ncvarid(_dataFILE.back().get_netCDF_id(), varname); if (varid == -1) { err("No netCDF variable `\\", varname, "' exists", "\\"); delete [] varname_base; return false; } varname += where_colon + 1; } else { varid = NC_GLOBAL; if (where_colon == 0) varname++; } if (-1 == ncattinq(_dataFILE.back().get_netCDF_id(), varid, varname, &att.type, &att.len)) { err("No netCDF attribute `\\", varname, "' exists", "\\"); return false; } att.val = (void *) malloc((unsigned)att.len*nctypelen(att.type)); Require(att.val, OUT_OF_MEMORY); if (-1 == ncattget(_dataFILE.back().get_netCDF_id(), varid, varname, att.val)) { err("Cannot get netCDF attribute `\\", varname, "'", "\\"); return false; } switch(att.type) { case NC_FLOAT: { float *tf = (float *) att.val; sprintf(_grTempString, "%f", *tf); } break; case NC_DOUBLE: { double *td = (double *) att.val; sprintf(_grTempString, "%f", *td); } break; case NC_LONG: { long *tl = (long *) att.val; sprintf(_grTempString, "%ld", *tl); } break; case NC_CHAR: { char *tc = (char *) att.val; int i; for (i = 0; i < att.len; i++) _grTempString[i] = *(tc + i); _grTempString[i] = '\0'; } break; case NC_SHORT: { short *ts = (short *) att.val; sprintf(_grTempString, "%d", *ts); } break; default: warning("Unknown attribute type for `\\", varname, "'", "\\"); strcpy(_grTempString, ""); } if (!put_syn(_word[1 + start], _grTempString, true)) { err("Synonym stack exhausted"); delete [] varname_base; return false; } delete [] varname_base; return true; #else err("Not compiled with netCDF library"); return false; #endif } else if (_dataFILE.back().get_type() == DataFile::bin_uchar) { gr_Error("Cannot read unsigned char grid data yet"); } else if (_dataFILE.back().get_type() == DataFile::bin_16bit) { gr_Error("Cannot read 16-bit grid data yet"); } else if (_dataFILE.back().get_type() == DataFile::bin_int) { gr_Error("Cannot read int grid data yet"); } else if (_dataFILE.back().get_type() == DataFile::bin_float) { for (unsigned int w = 1 + start; w < _nword; w++) { std::string the_word(_word[w]); un_double_quote(the_word); un_double_slash(the_word); de_reference(the_word); if (the_word == "*") { if (is_var(the_word)) { float tmp; if (1 == fread((char *)&tmp, sizeof(float), 1, _dataFILE.back().get_fp())) { PUT_VAR(the_word.c_str(), tmp); } else { err("Can't read \\", _word[w], "'", "\\"); } } else if (is_syn(the_word)) { err("Cannot read synonyms from binary file"); return false; } else { // Probably impossible to get here anyway. err("`read' what? (Item `\\", _word[w], "' is neither a synonym-name nor a variable-name.)", "\\"); return false; } } } } else if (_dataFILE.back().get_type() == DataFile::bin_double) { gr_Error("Cannot read double grid data yet"); } else { // Ascii file [in read_synonym_or_variableCmd()] for (unsigned int w = 1 + start; w < _nword; w++) { if (true == get_next_data_word()) { PUT_VAR("..words_in_dataline..", 0.0); if (_ignore_eof) { warning("`read synonym|variable' hit end-of-file"); return false; } else { //printf("DEBUG 1\n"); return true; } } #ifdef REMOVE_COMMENTS_FROM_DATA if (!read_raw_flag) if (remove_comment(inLine.getValue())) return true; #endif std::string the_word(_word[w]); un_double_quote(the_word); un_double_slash(the_word); de_reference(the_word); if (the_word == "*") { continue; } else if (is_var(the_word)) { if (0 < strlen(inLine.getValue())) { double tmp; if (getdnum(inLine.getValue(), &tmp)) { PUT_VAR(the_word.c_str(), tmp); } else { err("Can't read \\", _word[w], " in `", inLine.getValue(), "'", "\\"); } } else { PUT_VAR(the_word.c_str(), gr_currentmissingvalue()); } } else if (is_syn(the_word)) { char *copy = new char [1 + strlen(inLine.getValue())]; if (!copy) OUT_OF_MEMORY; strcpy(copy, inLine.getValue()); if (copy[strlen(copy) - 1] == '\n') copy[strlen(copy) - 1] = '\0'; if (!put_syn(the_word.c_str(), copy, true)) { delete [] copy; err("Synonym stack exhausted"); return false; } delete [] copy; } else { err("`read' what? (Item `\\", _word[w], "' is neither a synonym-name nor a variable-name.)", "\\"); demonstrate_command_usage(); return false; } } //?????_dataFILE.back().increment_line(); // BUG: should only do this if reading from datafile } // flush to end of line, skipping comment if any int c = 0; while (c != '\n' && !feof(_dataFILE.back().get_fp())) c = getc(_dataFILE.back().get_fp()); return true; } // `read line [raw] \syn' bool read_lineCmd() { chars_read = 0; Require (_nword > 2, err("`read line' what?")); int start = 0; #ifdef REMOVE_COMMENTS_FROM_DATA bool read_raw_flag = false; if (strEQ(_word[2], "raw")) { read_raw_flag = true; start = 1; } #endif Require(is_syn(_word[2 + start]), err("`read line' what?")); eof_status end_of_data = no_eof; // flag for end of data end_of_data = get_next_data_line("", 1); //printf("\n %s:%d (read_lineCmd) <%s> end_of_data= %d\n",__FILE__,__LINE__,inLine.getValue(),end_of_data); if (end_of_data == eof_before_data) { if (_ignore_eof) { warning("`read line' hit end-of-file"); return false; } else { set_eof_flag_on_data_file(); return false; } } else { char *s = inLine.getValue(); #ifdef REMOVE_COMMENTS_FROM_DATA if (!read_raw_flag) { remove_comment(s); } else { // remove trailing newlines int len = strlen(s); while (len > 1 && (s[len - 1] == '\n' || s[len - 1] == '\r')) s[--len] = '\0'; } #else // remove trailing newlines int len = strlen(s); while (len > 1 && (s[len - 1] == '\n' || s[len - 1] == '\r')) s[--len] = '\0'; #endif if (!put_syn(_word[2 + start], s, true)) { err("Synonym stack exhausted"); return false; } } return true; } // get next data line, giving the indicated prompt // if interactive, and store the result in the global string inLine. // // If expected_fields > 0 then, for binary files, that number of items will be // read and put into inLine; for ascii files, the parameter will be ignored. // // RETURN VALUE: 0 if didn't hit EOF // 1 if hit EOF before anything else // 2 if hit EOF after some material on the line // Thus, an return value of 2 means that the data line was not terminated // with newline, but that data were found nonetheless. static eof_status get_next_data_line(const char *prompt, unsigned int expected_fields) { //printf("DEBUG %s:%d (get_next_data_line) interactive=%d (from_cmdfile = %d)\n",__FILE__,__LINE__,int(_dataFILE.back().get_type()),DataFile::from_cmdfile); eof_status got_eof = no_eof; // Get line from either commandfile, data-file, or new-command. extern bool _store_cmds_in_ps; // startup.c if (_dataFILE.back().get_type() == DataFile::from_cmdfile) { // Get line from cmd-file. if (_cmdFILE.back().get_interactive()) { // Interactive case: write prompt and then get line. if (!batch()) gr_textput(prompt); gr_textget(inLine.getValue(), inLine.getCapacity() - 1); _cmdFILE.back().increment_line(); } else { #if 1 // TRYING to get 'read columns' to work in blocks extern std::vector bsStack; //printf("DEBUG %s:%d non-interactive case. bsStack.size %d ***\n",__FILE__,__LINE__,bsStack.size()); // If not in block, use file; if in block, read from it. if (bsStack.size() == 0) { got_eof = inLine.line_from_FILE(_cmdFILE.back().get_fp()); if (got_eof != no_eof) { set_eof_flag_on_data_file(); return got_eof; } _cmdFILE.back().increment_line(); // Take care of special case of data files created by VAX // FORTRAN; they have a spurious newline at the start. if (_dataFILE.back().get_line() == 1 && *(inLine.getValue()) == '\n' && ignore_initial_newline()) { warning("Skipping initial empty line in data file"); got_eof = inLine.line_from_FILE(_cmdFILE.back().get_fp()); if (got_eof != no_eof) { set_eof_flag_on_data_file(); return got_eof; } } } else { extern bool get_line_in_block(const char *block, unsigned int *offset); unsigned int offset = offset_for_read + chars_read; //printf("READ has offset= %d for block\n||%s||\n",offset,bsStack.back().get_start()+offset); if (!get_line_in_block(bsStack.back().get_start(), &offset)) { set_eof_flag_on_data_file(); return got_eof; } bsStack.back().move_offset(strlen(_cmdLine) + 1); //printf("DEBUG %s:%d think line is [%s]\n",__FILE__,__LINE__,_cmdLine); inLine.fromSTR(_cmdLine); chars_read += strlen(_cmdLine) + 1; //printf("DEBUG %s:%d inLine is [%s]; chars_read now %d since adding %d\n",__FILE__,__LINE__,inLine.getValue(),chars_read,strlen(_cmdLine) + 1); return no_eof; } #endif } // Display the line as a comment in PostScript file. if (_store_cmds_in_ps) { strcpy(_grTempString, "gri:"); gr_comment(strcat(_grTempString, inLine.getValue())); } } else { // Get line from data-file. if (_dataFILE.back().get_type() == DataFile::ascii) { // ASCII file, non interactive got_eof = inLine.line_from_FILE(_dataFILE.back().get_fp()); //printf("get_next_data_line %s:%d got_eof=%d\n",__FILE__,__LINE__,got_eof); } else { // binary file unsigned int i; char achar[LineLength]; inLine.fromSTR(""); switch (_dataFILE.back().get_type()) { case DataFile::bin_uchar: for (i = 0; i < expected_fields; i++) { unsigned char a; if (1 != fread((char *) & a, sizeof(a), 1, _dataFILE.back().get_fp())) { set_eof_flag_on_data_file(); return i == 0 ? eof_before_data : eof_after_data; } sprintf(achar, "%f ", double(a)); inLine.catSTR(achar); } break; case DataFile::bin_16bit: for (i = 0; i < expected_fields; i++) { unsigned short int a; if (1 != fread((char *) & a, sizeof(a), 1, _dataFILE.back().get_fp())) { set_eof_flag_on_data_file(); return i == 0 ? eof_before_data : eof_after_data; } sprintf(achar, "%f ", double(a)); inLine.catSTR(achar); } break; case DataFile::bin_int: for (i = 0; i < expected_fields; i++) { int a; if (1 != fread((char *) & a, sizeof(a), 1, _dataFILE.back().get_fp())) { set_eof_flag_on_data_file(); return i == 0 ? eof_before_data : eof_after_data; } sprintf(achar, "%f ", double(a)); inLine.catSTR(achar); } break; case DataFile::bin_float: for (i = 0; i < expected_fields; i++) { float a; if (1 != fread((char *) & a, sizeof(a), 1, _dataFILE.back().get_fp())) { set_eof_flag_on_data_file(); return i == 0 ? eof_before_data : eof_after_data; } sprintf(achar, "%f ", double(a)); inLine.catSTR(achar); } break; case DataFile::bin_double: for (i = 0; i < expected_fields; i++) { double a; if (1 != fread((char *) & a, sizeof(a), 1, _dataFILE.back().get_fp())) { set_eof_flag_on_data_file(); return i == 0 ? eof_before_data : eof_after_data; } sprintf(achar, "%f ", double(a)); inLine.catSTR(achar); } break; default: fatal_err("`read' confused about binary file type. Check `open'"); } } // If ran out of data, set a flag and return. if (got_eof != no_eof) { //printf("get_next_data_line %s:%d setting eof flag.\n",__FILE__,__LINE__); set_eof_flag_on_data_file(); return got_eof; } } #if 0 // SF bug 669303 _dataFILE.back().increment_line(); // BUG: should only do this if reading from datafile printf("incremeing line ... is now %d\n",_dataFILE.back().get_line()); #endif // If no newline, over-ran buffer. // Check that newline-terminated; note already checked for EOF if (inLine.size() > 0 && inLine[inLine.size() - 1] != '\n') { err("Internal bug with inLine buffer: please report to author."); return eof_before_data; } // Return flag that didn't run out of data. return no_eof; } // get next word from datafile. Fail if file not open. Return true if EOF static bool get_next_data_word() { // Get line from cmd-file. if (_dataFILE.back().get_type() == DataFile::from_cmdfile) { // from get_next_data_line() if (_cmdFILE.back().get_interactive()) { err("cannot `read variable/synonym' from interactive cmdfile\n"); } else { // from get_next_data_line() unsigned int eol; bool status = inLine.word_from_FILE(_cmdFILE.back().get_fp(), &eol); for (unsigned int e = 0; e < eol; e++) { //printf("DEBUG: %s:%d incrementing line number in command file\n", __FILE__, __LINE__); _cmdFILE.back().increment_line(); } if (status) { set_eof_flag_on_data_file(); return true; } } return false; } else { // Get line from data-file. if (_dataFILE.back().get_type() == DataFile::ascii) { // ASCII file, non interactive if (1 == inLine.word_from_DataFile(_dataFILE.back())) { set_eof_flag_on_data_file(); return true; } } else { // binary file char achar[LineLength]; inLine.fromSTR(""); switch (_dataFILE.back().get_type()) { case DataFile::bin_uchar: { unsigned char a; if (1 != fread((char *) & a, sizeof(a), 1, _dataFILE.back().get_fp())) { set_eof_flag_on_data_file(); return true; } sprintf(achar, "%f ", ((double) a)); inLine.catSTR(achar); } break; case DataFile::bin_16bit: { unsigned short int a; if (1 != fread((char *) & a, sizeof(a), 1, _dataFILE.back().get_fp())) { set_eof_flag_on_data_file(); return true; } sprintf(achar, "%f ", ((double) a)); inLine.catSTR(achar); } break; case DataFile::bin_int: { int a; if (1 != fread((char *) & a, sizeof(a), 1, _dataFILE.back().get_fp())) { set_eof_flag_on_data_file(); return true; } sprintf(achar, "%f ", (double) a); inLine.catSTR(achar); } break; case DataFile::bin_float: { float a; if (1 != fread((char *) & a, sizeof(a), 1, _dataFILE.back().get_fp())) { set_eof_flag_on_data_file(); return true; } sprintf(achar, "%f ", (double) a); inLine.catSTR(achar); } break; case DataFile::bin_double: { double a; if (1 != fread((char *) & a, sizeof(a), 1, _dataFILE.back().get_fp())) { set_eof_flag_on_data_file(); return true; } sprintf(achar, "%f ", (double) a); inLine.catSTR(achar); } break; default: fatal_err("`read' confused about binary file type. Check `open'"); } } #if 0 // 2.065: should have been caught anyway *** // If ran out of data, set a flag and return. if (feof(_dataFILE.back().get_fp())) { set_eof_flag_on_data_file(); return true; } #endif #if 0 // SF bug 669303 _dataFILE.back().increment_line(); #endif // Return flag that didn't run out of data. return false; } // NOT REACHED } void set_eof_flag_on_data_file() { PUT_VAR("..eof..", 1.0); } void clear_eof_flag_on_data_file() { PUT_VAR("..eof..", 0.0); } gri/src/help.cc0000644000175000017500000002036313147557614012052 0ustar psgpsg/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include "gr.hh" #include "extern.hh" #include "files.hh" bool give_overall_help_message(void); bool give_help_on_topic(void); bool helpCmd() { if (_nword == 1) { (void) give_overall_help_message(); return true; } // Give help on topic if (_nword == 3 && !strcmp(_word[1], "-")) { give_help_on_topic(); return true; } else { // Must be `help item ...' int i = 0, cmd; bool found = false; std::string tmpname_file(tmp_file_name()); FILE *fp; if (!(fp = fopen(tmpname_file.c_str(), "w"))) { printf("buffer filename is '%s'\n",tmpname_file.c_str()); err("Sorry, error opening buffer-file for `help'"); return false; } // Figure out what command, and give help for it. while (*(_cmdLine + i) != ' ') i++; while (*(_cmdLine + i) == ' ') i++; strcat(_cmdLine, " *"); for (cmd = 0; cmd < _num_command; cmd++) { if (same_syntax(_cmdLine + i, _command[cmd].syntax, 1)) { found = true; fprintf(fp, "%s\n", _command[cmd].help); } } if (found) { fclose(fp); more_file_to_terminal(tmpname_file.c_str()); delete_file(tmpname_file.c_str()); return true; } else { fclose(fp); delete_file(tmpname_file.c_str()); err("Sorry, can't understand 'help' request."); give_overall_help_message(); return false; } } } bool give_overall_help_message() { ShowStr("\ Type `help' followed by a command-name:\n\ assert cd close convert\n\ create debug delete differentiate\n\ draw expecting filter flip\n\ get help if ignore\n\ input insert interpolate list\n\ ls mask move new\n\ open pwd query quit\n\ read regress reorder rescale\n\ resize return rewind set\n\ show skip sleep smooth\n\ source sprintf state superuser\n\ system write\n\ Or type `help -' followed by a topic from this list:\n\ example extending files math\n\ strings synonyms variables manual\n\ To exit, type `quit'.\n\ "); return true; } bool give_help_on_topic() { FILE *fp; std::string tmpname_file(tmp_file_name()); if (!(fp = fopen(tmpname_file.c_str(), "w"))) { err("Sorry, error opening buffer-file for `help -'"); return false; } else if (!strcmp(_word[2], "example")) { fprintf(fp, "\ // Example of plot with 2 curves on it:\n\ // Note: the `//' symbol means rest of line is a comment\n\ open filename1 // open 1st data-file\n\ read columns x y // read columnar xy data\n\ draw curve // draw 1st data curve\n\ close // close 1st data-file\n\ open filename2 // open 2nd data-file\n\ read columns x y\n\ close\n\ set dash // make this line dashed\n\ draw curve // superimpose 2nd curve\n\ quit // end of plot\n\ "); fclose(fp); } else if (!strcmp(_word[2], "extending")) { fprintf(fp, "\ Extending gri by defining new commands:\n\ You can define new commands as in this example:\n\n\ \n\ `New Command'\n\ This is help for this new command. Any lines between the new\n\ command name and the opening brace are made into the help for the\n\ command. Note that the new command has the name New Command, and\n\ can be invoked just by naming it. By convention, you should name\n\ new commands with UPPER CASE as the first characters, to distinguish\n\ them from normal commands. Also by convention, the body of \n\ the command should be indented 4 spaces.\n\ {\n\ show \"You've called `New Command'\"\n\ }\n\ "); fclose(fp); } else if (!strcmp(_word[2], "files")) { fprintf(fp, "\ Data-file operations:\n\ open\n\ close\n\ show next line\n\ read columns\n\ read grid x\n\ read grid y\n\ read grid data\n\ skip forward\n\ skip backward\n\ "); fclose(fp); } else if (!strcmp(_word[2], "math")) { fprintf(fp, "\ Math operations:\n\ Simple format:\n\ `item += #', `item -= #', `item *= #', `item /= #'\n\ where item is a column or a variable. For variables only (eg, `.a.'),\n\ there is also the form\n\ `.variable. = #'\n\ In all forms, # may be a number:\n\ `x += 2'\n\ or a variable:\n\ `x += .offset.'\n\ or a reverse-polish expression in numbers/variables:\n\ `x += { rpn .phase. 30 + 10 / sin }\n\ "); fclose(fp); } else if (!strcmp(_word[2], "strings")) { fprintf(fp, "\ MATH SYMBOLS: get these by imbedding in dollar signs as in TeX.\n\ Example \"$\\alpha$\".\n\ SUPERSCRIPTS & SUBSCRIPTS: Within this `math mode', get superscripts with\n\ ^c for a single character (c) or ^{ccc} for several characters (ccc);\n\ for subscripts use _c and _{ccc}.\n\ \n\ SPECIAL CHARACTERS: You get \\ using \\\\, ^ using \\^, and _ using \\^.\n\ Outside math mode, things are different; ^ and _ are just ordinary\n\ characters with no special meaning, and \\ is used for synonyms.\n\ \n\ SYNONYMS: Thus you may define \\file as a filename with \n\ `query \\filename \"give filename\" {\"input.dat\"}'\n\ \n\ Then whenever \\filename occurs in a string, gri will substitute \n\ whatever string you've supplied. Finally, you may at any time get gri \n\ to print a $ by using \\$.\n\ "); fclose(fp); } else if (!strcmp(_word[2], "synonyms")) { fprintf(fp, "\ Synonyms store character strings. You may use them in place of any\n\ normal Gri command word, and also within quoted strings.\n\ \n\ Examples of assigning to synonyms:\n\ \\synonym = \"Text to store in synonym\" // store that text\n\ \\synonym = system \"date\" // store the date\n\ // (Note that above form limits \\synonym to 8192 characters)\n\ query \\synonym \"Prompt string\" (\"default\") // get user input\n\ \n\ Examples of using synonyms:\n\ // Making filenames be flexible and interactive:\n\ open \\file\n\ draw title \"Data from file \\file\"\n\ // Extracting words from within synonyms\n\ \\sentence = \"This synonym has several words\"\n\ \\first_word = word 0 from \"\\sentence\"\n\ \\second_word = word 1 from \"\\sentence\"\n\ "); fclose(fp); } else if (!strcmp(_word[2], "variables")) { fprintf(fp, "\ Variables store numbers. You may use them in place of any numbers\n\ in any Gri command.\n\ \n\ Examples of assigning to variables:\n\ .time. = 10\n\ .time. += 1\n\ .time. = {rpn .time. 2 *}\n\ read .time.\n\ \n\ Examples of using variables:\n\ read columns .number. x y\n\ draw label \"hello\" at .xcm. .ycm.\n\ sprintf \\title \"x is %%f and y is %%f (centimeters)\" .x. .y.\n\ draw label \"\\title\" at .x. .y. cm\n\ "); fclose(fp); } else if (word_is(2, "manual")) { fprintf(fp, "\ The Gri manual should be available online through the unix command\n\ info gri\n\ and this same manual should be available inside emacs. Peter Galbraith\n\ emacs editing mode for Gri yields easy access to this manual, with the\n\ ability to look up help on the command where the editing cursor resides.\n\ \n\ Normally a PostScript manual is also available. See your system manager.\n\ \n\ Also, a world-wide-web manual is available; as of November 1994, this\n\ is at the location http://www.cs.dal.ca/users/kelley/gri/gri1.html.\n\ "); fclose(fp); } else { err("Sorry, no help on that topic"); give_overall_help_message(); return false; } more_file_to_terminal(tmpname_file.c_str()); delete_file(tmpname_file.c_str()); return true; } gri/src/variable.cc0000644000175000017500000002177113147557614012713 0ustar psgpsg/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include "gr.hh" #include "extern.hh" #include "private.hh" #include "Variable.hh" std::vector variableStack; // Get index of variable // RETURN non-negative integer if 'name' is an existing variable, or -1 if not. // BUG: only finds single-dotted variables (stored in the stack) int index_of_variable(const char *name, int mark) { if (!is_var(name)) return -1; unsigned int stackLen = variableStack.size(); // Look up normally (global scope) or privately (with mark >= 0) if (mark == -1) { for (int i = stackLen - 1; i >= 0; i--) if (!strcmp(name, variableStack[i].get_name())) return i; return -1; } else { int mark_above = mark + 1; unsigned int index; int this_mark = 0; for (index = 0; index < stackLen; index++) { const char *n = variableStack[index].get_name(); if (*n == '\0') if (++this_mark == mark_above) break; } if (this_mark != mark_above) { //printf("DEBUG %s:%d no match for <%s>\n",__FILE__,__LINE__,name); return -1; } //printf("DEBUG %s:%d index %d\n",__FILE__,__LINE__,index); for (int i = index - 1; i >= 0; i--) { //printf("check <%s> to see if <%s>\n",variableStack[i].get_name(),name); if (!strcmp(variableStack[i].get_name(), name)) { return i; } } return -1; } return -1; } // Make new variable bool create_variable(const char *name, double value) { GriVariable newVariable(name, value); variableStack.push_back(newVariable); return true; } bool show_variablesCmd() { bool have_some = false; ShowStr("Variables...\n"); int n = variableStack.size(); for (int i = 0; i < n; i++) { const char *n = variableStack[i].get_name(); if (*n == '\0') { printf(" ------------------------------------------------\n"); } else { extern char _grTempString[]; sprintf(_grTempString, " %-25s = %g\n", variableStack[i].get_name(), variableStack[i].get_value()); ShowStr(_grTempString); have_some = true; } } if (!have_some) ShowStr(" ... none exist\n"); return true; } // display unused user variables void display_unused_var() { unsigned int stackLen = variableStack.size(); extern char _grTempString[]; if (stackLen > 0) { for (int i = stackLen - 1; i >= 0; i--) { if (0 == variableStack[i].getCount()) { const char* name = variableStack[i].get_name(); if (*(name + 1) != '.') { // avoid builtins sprintf(_grTempString, "\ Warning: variable `%s' defined but not used\n", name); ShowStr(_grTempString); } } } } } // is_var - return 0 if not a variable, or 1 if is bool is_var(const char *w) { int len = strlen(w); return (len > 2 && w[0] == '.' && w[-1 + len] == '.' ? true : false); } // is_var - return 0 if not a variable, or 1 if is bool is_var(const std::string& w) { int len = w.size(); return (len > 2 && w[0] == '.' && w[-1 + len] == '.' ? true : false); } // for internal debugging void show_var_stack() { unsigned stackLen = variableStack.size(); if (stackLen > 0) { printf("Variable stack [\n"); for (int i = stackLen - 1; i >= 0; i--) { printf(" %s = %f\n", variableStack[i].get_name(), variableStack[i].get_value()); } printf("]\n"); } } // Delete variable, searching from end of stack bool delete_var(const std::string& name) { unsigned stackLen = variableStack.size(); for (int i = stackLen - 1; i >= 0; i--) { if (name == variableStack[i].get_name()) { //printf("DEBUG %s:%d DELETING var %d named <%s>\n",__FILE__,__LINE__,i,name.c_str()); for (unsigned int j = i; j < stackLen - 1; j++) variableStack[j] = variableStack[j + 1]; variableStack.pop_back(); //printf("DEBUG %s:%d after handling 'delete var', the list is...\n",__FILE__,__LINE__); return true; } } return false; } // get_var() - get value of variable (incrementing the 'uses' flag) // // RETURN true if variable is defined and has a value // RETURN false otherwise bool get_var(const char *name, double *value) { *value = 0.0; // store something in case not found if (!is_var(name)) return false; // Following are special cases. They are not stored in the stack because // it would take far too much time. // // If more variables are added to this list, be sure to make changes to // gri.cc and extern.h, under comments which appear as follows: // // The following globals have symbolic names associated with them, and // MUST be updated whenever these names are assigned to. See the note in // put_var() in variable.c. The reason for the parallel C storage is // that the following are accessed for every data point plotted. Certain // other symbolic variables (like ..publication.. for example) are not // accessed frequently, and hence have no parallel C storage as the // following do. Thus they are safe against breakage. if (!strcmp(name, "..trace..")) { *value = (int) _griState.trace(); return true; } else if (!strcmp(name, "..use_default_for_query..")) { *value = (int) _use_default_for_query; return true; } else if (!strcmp(name, "..linewidth..")) { *value = _griState.linewidth_line(); return true; } else if (!strcmp(name, "..linewidthaxis..")) { *value = _griState.linewidth_axis(); return true; } else if (!strcmp(name, "..linewidthsymbol..")) { *value = _griState.linewidth_symbol(); return true; } else if (!strcmp(name, "..superuser..")) { *value = double(_griState.superuser()); return true; } else { // Look it up in stack int i; unsigned stackLen = variableStack.size(); if (stackLen > 0) { for (i = stackLen - 1; i >= 0; i--) { #ifdef DEBUG_VARIABLE printf("debug: check [%s] vs %d-th [%s]\n", name, i, variableStack[i].get_name()); #endif if (!strcmp(name, variableStack[i].get_name())) { *value = variableStack[i].get_value(); variableStack[i].incrementCount(); // record the usage return true; } } } } return false; } // put_var() -- assign value to name, creating new variable if necessary. // If replace_existing=0 replace existing value. // If replace_existing=1 create a new variable with the old name. // RETURN NULL if can't do it. bool put_var(const char *name, double value, bool replace_existing) { void reset_top_of_plot(void); int i; unsigned stackLen = variableStack.size(); // put_var (): Certain special cases are stored in C variables too, // for speed. (An example is ..xleft.., which is stored as _xleft and // used all over the code.) Capture these and store the values. Also, // some operations should be intercepted for general use later: e.g. // changing ..ymargin.. requires calling reset_top_of_plot(). Note // that this code fragment is easy to break, because addition of new // internals means addition of code here. See also the note in gri.cc, // where the internals are segmented. if (!strcmp(name, "..trace..")) { _griState.set_trace((floor(0.5 + value)) ? true : false); } else if (!strcmp(name, "..use_default_for_query..")) { _use_default_for_query = int(floor(0.5 + value)) ? true : false; } else if (!strcmp(name, "..linewidth..")) { _griState.set_linewidth_line(value); } else if (!strcmp(name, "..linewidthaxis..")) { _griState.set_linewidth_axis(value); } else if (!strcmp(name, "..linewidthsymbol..")) { _griState.set_linewidth_symbol(value); } else if (!strcmp(name, "..superuser..")) _griState.set_superuser((unsigned int)(floor(0.5 + value))); else if (!strcmp(name, "..missingvalue..")) gr_set_missing_value(value); else if (!strcmp(name, "..xleft..")) _xleft = value; else if (!strcmp(name, "..xright..")) _xright = value; else if (!strcmp(name, "..xinc..")) _xinc = value; else if (!strcmp(name, "..ybottom..")) _ybottom = value; else if (!strcmp(name, "..ytop..")) _ytop = value; else if (!strcmp(name, "..yinc..")) _yinc = value; // Replace if on stack already. if (replace_existing) { if (stackLen) { for (i = stackLen - 1; i >= 0; i--) { if (!strcmp(name, variableStack[i].get_name())) { variableStack[i].set_value(value); return true; } } } } // Store on end of stack. GriVariable newVariable(name, value); variableStack.push_back(newVariable); if (!strcmp(name, "..ymargin..") || !strcmp(name, "..ysize..")) reset_top_of_plot(); return true; } gri/src/CmdFile.hh0000644000175000017500000000543613147557614012443 0ustar psgpsg/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // Object for command files #if !defined(_CmdFile_hh_) #define _CmdFile_hh_ #include #include #include #include #include "types.hh" #include "macro.hh" #include "superus.hh" unsigned int superuser(void); class CmdFile { public: CmdFile() { name.assign(""); fp = (FILE*)NULL; // for now anyway interactive = true; save2ps = false; line = 0; } CmdFile(const CmdFile& c) { name.assign(c.get_name()); fp = c.get_fp(); if (fp == (FILE*)NULL) { printf("ERROR at %s:%d -- try to CmdFile copy null '%s' from %lx this %lx\n", __FILE__,__LINE__,name.c_str(),(long unsigned int)(&c),(long unsigned int)this); exit(1); } interactive = c.get_interactive(); save2ps = c.get_save2ps(); line = c.get_line(); } ~CmdFile() { #if 0 // BUG 2001-feb-17 -- not sure on next 2 lines name.string::~string(); // not executed #endif } CmdFile& operator=(const CmdFile& c) { name.assign(c.get_name()); fp = c.get_fp(); if (fp == (FILE*)NULL) { printf("%s:%d try to CmdFile operator= null file this %lx\n",__FILE__,__LINE__,(long unsigned int)this); exit(1); } interactive = c.get_interactive(); save2ps = c.get_save2ps(); line = c.get_line(); return *this; } void set(const char *n, FILE *f, bool i, int l, bool save_in_ps = true) { name.assign(n); fp = f; if (fp == (FILE*)NULL) { printf("ERROR at %s:%d -- try to CmdFile set null file this %lx\n",__FILE__,__LINE__,(long unsigned int)this); exit(1); } interactive = i; save2ps = save_in_ps; line = l; } void increment_line() { line++; } const char *get_name() const { return name.c_str(); } FILE *get_fp() const { return fp; } bool get_interactive() const { return interactive; } int get_line() const { return line; } bool get_save2ps() const { return save2ps; } private: FILE *fp; std::string name; bool interactive; bool save2ps; int line; }; #endif gri/src/source.cc0000644000175000017500000000477013147557614012426 0ustar psgpsg/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include "gr.hh" #include "extern.hh" #include "private.hh" #include "superus.hh" bool sourceCmd() { if (_nword != 2) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } std::string fname(_word[1]); if (!resolve_filename(fname, false, 'c')) { err("`source' cannot handle file named `\\", _word[1], "'", "\\"); return false; } //printf("Sourcing '%s'\n", fname.c_str()); FILE *fp = fopen(fname.c_str(), "r"); if (NULL == fp) { extern char _grTempString[]; sprintf(_grTempString, "`source' cannot open file `%s' (translated to `%s')", _word[1], fname.c_str()); err(_grTempString); return false; } #if 1 if (((unsigned) superuser()) & FLAG_AUT1) { CmdFile cf; // as in file.cc cf.set(fname.c_str(), fp, false, 0); _cmdFILE.push_back(cf); } #endif /* * Scan through the file, doing lines. */ while (!feof(fp)) { /* * See if hit EOF on a line with no text. */ if (NULL == fgets(_cmdLine, LineLength, fp)) break; if (feof(fp)) { warning("Missing newline at end of inserted file `\\", fname.c_str(), "'", "\\"); strcat(_cmdLine, "\n"); } _cmdFILE.back().increment_line(); // BUG line numbers wrong BUG if (((unsigned) superuser()) & FLAG_AUT1) { void insert_source_indicator(char *cl); // in doline.cc insert_source_indicator(_cmdLine); } massage_command_line(_cmdLine); //printf("[%s]\n",_cmdLine); if (_nword > 0 && !strcmp(_word[0], "return") && !skipping_through_if()) break; if (!perform_command_line(fp, false)) { return false; } } _done = 0; fclose(fp); if (((unsigned) superuser()) & FLAG_AUT1) { _cmdFILE.pop_back(); } return true; } gri/src/gr_coll.hh0000644000175000017500000001401013147557614012545 0ustar psgpsg/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // Some classes for Gri //#define DEBUG 1 #if !defined(_gr_coll_hh_) #define _gr_coll_hh_ // GriString: -- string // GriDvector: -- vector of doubles // GriColumn: -- column (e.g., "x", "y") // BlockSource: -- used by command.cc // RpnItem: -- used by rpncalc.cc // Some things used in gr.hh also #include #include //#include "gr.hh" #include "errors.hh" #include "types.hh" #include "CmdFile.hh" #include "DataFile.hh" #include "GCounter.hh" #include "GriColor.hh" // EOF indicator. enum eof_status { no_eof, eof_after_data, eof_before_data }; class GriString { public: GriString(const char *s = ""); GriString(const GriString& n); GriString(unsigned int len); ~GriString() {delete [] value;} void convert_slash_to_MSDOS(); eof_status line_from_FILE(FILE *fp); // Get Line from file, true if EOF bool word_from_FILE(FILE *fp, unsigned int *eol); // Get word from file, true if EOF bool word_from_DataFile(DataFile& f); // Get word from file, true if EOF void fromSTR(const char *s); // Grow if necessary void catSTR(const char *s); // Grow if necessary char *getValue() const {return value; } unsigned int size(void) const {return strlen(value);} unsigned int getCapacity() const {return capacity;} #if 0 void sed(const char *cmd); // Modify by (limited) sed command BUG #endif char& operator[](unsigned int offset); // Access element if it exists void draw(double xcm, double ycm, gr_textStyle s, double angle) const; private: char *value; // The string, null-term unsigned int capacity; // Can hold capacity - 1 chars }; class GriDvector { public: GriDvector(); GriDvector(unsigned int length); ~GriDvector(); void expand(); // Get more space void expand(unsigned int capacity); // Get more space void compact(); // Remove things beyond depth void push_back(double value); // Store on top void pop_back(); // Remove top element double topElement(); // Retrieve top void erase(double *pos_); // Remove element double& operator[](unsigned int offset); // Retrieve at index double min(void); // Min of non-missing double max(void); // Max of non-missing double median(void); // Median of non-missing double skewness(void); // skewness of non-missing double kurtosis(void); // skewness of non-missing double mean(void); // Mean of non-missing double stddev(void); // Std-deviation of non-mis double *begin(void); // Pointer to contents void setDepth(unsigned int theDepth); // Set depth size_t size(); // Get depth unsigned int size_legit(); // Number of good values unsigned int capacity(); // Get total capacity private: size_t the_depth; // Number stored size_t the_capacity; // Number storable double *contents; // Contents }; class GriColumn : public GriDvector { public: GriColumn(); ~GriColumn(); void setName(const char *theName); // Set name of column char *getName(); // Get name of column private: char *name; }; // Keep track of the file:line sources for commandline blocks class BlockSource { public: BlockSource() { filename.assign(""); line = 0; start = NULL; } BlockSource& operator=(const BlockSource& n) { #if defined(DEBUG) printf("DEBUG:gr_coll.hh BlockSource operator=() [line now is %d]\n",n.get_line()); #endif filename = n.get_filename(); line = n.get_line(); start = n.get_start(); offset = n.get_offset(); return *this; } BlockSource(const BlockSource& n) { #if defined(DEBUG) printf("DEBUG:gr_coll.hh BlockSource(BlockSource) [line now is %d]\n",n.get_line()); #endif filename = n.get_filename(); line = n.get_line(); start = n.get_start(); } BlockSource(const char* the_start, const char *the_filename, unsigned int the_line) { #if defined(DEBUG) printf("DEBUG:gr_coll.hh BlockSource([see below],%s,%d)\n[%s]\n",the_filename,the_line,the_start); #endif start = the_start; filename = the_filename; line = the_line; } ~BlockSource() { //filename.string::~string(); 2001-feb-17 } void increment_line(unsigned int line_length) { line++; offset += line_length + 1; // the 1 is for newline } const char *get_filename() const {return filename.c_str(); } unsigned int get_line() const {return line; } const char *get_start() const {return start; } unsigned int get_offset() const {return offset; } void move_offset(unsigned int o) {offset += o; } private: std::string filename; // Name of file containing this src unsigned int line; // Which line we're executing that file const char* start; // Points to next line to execute unsigned int offset; // Next line is at (start+offset) }; // Operand types. enum operand_type { UNKNOWN, VARIABLE_WITH_MISSING_VALUE, NOT_OPERAND, NUMBER, STRING, COLUMN_NAME, FUNCTION }; class RpnItem { private: char *name; double value; bool valid; operand_type type; public: RpnItem(); RpnItem(const RpnItem& n); ~RpnItem() {delete name;} void set(const char *the_name, double the_value, operand_type the_type, bool the_valid = true); char *getName() const {return name;} double getValue() const {return value;} operand_type getType() const {return type;} bool getValid() const {return valid;} RpnItem& operator=(const RpnItem& n); }; #endif // ifdef _gr_coll_hh_ gri/src/rpncalc.cc0000644000175000017500000017157513147557614012560 0ustar psgpsg/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // Do rpn math static bool permit_missing_value_in_comparisons = 0; #define STRING_END(S) ((S) + strlen((S)) - 1) #include #include #include #include #include #if defined(HAVE_ACCESS) #include #endif #ifdef HAVE_STAT #include #include #endif #include "gr.hh" #include "extern.hh" #include "private.hh" #ifdef __DECXX extern "C" double acosh(double x); // DEC-cxx needs this extern "C" double asinh(double x); // DEC-cxx needs this extern "C" double atanh(double x); // DEC-cxx needs this #endif static std::vector rS; void erase_rpn_stack() { rS.erase(rS.begin(), rS.end()); } // ******************************************* // *** Macros to simplify stack operations *** // ******************************************* // Require index i to be type t. #define NEED_IS_TYPE(i,t) \ { \ if (rS[rS.size() - (i)].getType() != (t)) { \ RpnError = ILLEGAL_TYPE; \ return false; \ } \ } // Retrieve name (i-1) from top of stack (i=1 means top) #define NAME(i) (rS[rS.size() - (i)].getName()) // Retrieve value (i-1) from top of stack (i=1 means top) #define VALUE(i) (rS[rS.size() - (i)].getValue()) // Retrieve validity (i-1) from top of stack (i=1 means top) #define VALID(i) (rS[rS.size() - (i)].getValid()) // Retrieve type (i-1) from top of stack (i=1 means top) #define TYPE(i) (rS[rS.size() - (i)].getType()) // Set (i-1) from top of stack (i=1 means top) #define SET(i, n, value, t, valid) (rS[rS.size() - (i)].set((n), (value), (t), (valid))) #define Ee 2.7182818284590452354 // rpn - reverse polish notation calculator // // RETURN VALUE: see defines below // // Return codes: #define NO_ERROR 0 // everything is OK #define BAD_WORD 1 // not operator, operand, column, function #define STACK_UNDERFLOW 2 // missing operators #define STACK_OVERFLOW 3 // extra stuff #define DIV_BY_ZERO 4 // cannot divide by zero #define OUT_OF_STORAGE 5 // computer limitation #define ILLEGAL_TYPE 6 // cannot do with given operand(s) #define NEED_GE_0 7 // need operand >= 0 #define NEED_GT_0 8 // need operand > 0 #define RANGE_1 9 // need operand in range -1 to 1 #define NEED_GT_1 10 // need operand > 1 #define COMPUTER_LIMITATION 11 // can't do on this machine #define GENERAL_ERROR 12 // some other error // Operator types. typedef enum { ADD = 1, SUBTRACT, MULTIPLY, DIVIDE, POWER, AGE, // of a file ASINE, ACOSINE, ATANGENT, SINE, COSINE, TANGENT, ACOSH, ASINH, ATANH, COSH, SINH, TANH, SQRT, LOG, LN, EXP, EXP10, CEIL, FLOOR, REMAINDER, ABS, LESS_THAN, LESS_THAN_EQUAL, GREATER_THAN, GREATER_THAN_EQUAL, EQUAL, NOT_EQUAL, AND, OR, NOT, CMTOPT, PTTOCM, DUP, POP, EXCH, ROLL_LEFT, ROLL_RIGHT, PSTACK, CLEAR, STRCAT, STRLEN, SUBSTR, ATOF, SYSTEM, SUP, INF, ASSIGN, XYCMTOUSER, XYUSERTOCM, XCMTOUSER, XPTTOUSER, XUSERTOCM, XUSERTOPT, YCMTOUSER, YPTTOUSER, YUSERTOCM, YUSERTOPT, AREA, VAL, MIN, MAX, MEDIAN, MEAN, STDDEV, SKEWNESS, KURTOSIS, SIZE, STRINGWIDTH, STRINGASCENT, STRINGDESCENT, SED, DEFINED, ISMISSING, INTERPOLATE, RAND, NOT_OPERATOR, DIRECTORY_EXISTS, FILE_EXISTS, HEX2DEC, DEC2HEX, ARGC, ARGV, WORDC, WORDV } operator_name; // Rpn functions. typedef struct { char *op_name; unsigned int chars; // for speeding lookup operator_name op_id; } RPN_DICT; #define RPN_FCN_CAPACITY 100 #define RPN_W_CAPACITY 100 unsigned int rpn_fcn_filled = 0; typedef struct { char * name; char * w[RPN_W_CAPACITY]; unsigned int nw; } RPN_FCN; RPN_FCN rpn_fcn[RPN_FCN_CAPACITY]; // Operators, with common (algebraic) ones first to speed lookup. RPN_DICT rpn_dict[] = { {(char *)"+", 1, ADD}, {(char *)"-", 1, SUBTRACT}, {(char *)".", 1, MULTIPLY}, {(char *)"*", 1, MULTIPLY}, {(char *)"/", 1, DIVIDE}, {(char *)"power", 5, POWER}, {(char *)"age", 3, AGE}, {(char *)"asin", 4, ASINE}, {(char *)"acos", 4, ACOSINE}, {(char *)"atan", 4, ATANGENT}, {(char *)"sin", 3, SINE}, {(char *)"cos", 3, COSINE}, {(char *)"tan", 3, TANGENT}, {(char *)"asinh", 5, ASINH}, {(char *)"acosh", 5, ACOSH}, {(char *)"atanh", 5, ATANH}, {(char *)"cosh", 4, COSH}, {(char *)"sinh", 4, SINH}, {(char *)"tanh", 4, TANH}, {(char *)"sqrt", 4, SQRT}, {(char *)"log", 3, LOG}, {(char *)"ln", 2, LN}, {(char *)"exp", 3, EXP}, {(char *)"exp10", 5, EXP10}, {(char *)"ceil", 4, CEIL}, {(char *)"dec2hex", 7, DEC2HEX}, // cf hex2dec {(char *)"floor", 5, FLOOR}, {(char *)"hex2dec", 7, HEX2DEC}, // cf dec2hex {(char *)"remainder", 9, REMAINDER}, {(char *)"abs", 3, ABS}, {(char *)"<", 1, LESS_THAN}, {(char *)"<=", 2, LESS_THAN_EQUAL}, {(char *)">", 1, GREATER_THAN}, {(char *)">=", 2, GREATER_THAN_EQUAL}, {(char *)"==", 2, EQUAL}, {(char *)"!=", 2, NOT_EQUAL}, {(char *)"&", 1, AND}, {(char *)"and", 3, AND}, {(char *)"|", 1, OR}, {(char *)"or", 2, OR}, {(char *)"!", 1, NOT}, {(char *)"not", 3, NOT}, {(char *)"cmtopt", 6, CMTOPT}, {(char *)"pttocm", 6, PTTOCM}, {(char *)"dup", 3, DUP}, {(char *)"pop", 3, POP}, {(char *)"exch", 4, EXCH}, {(char *)"roll_left", 9, ROLL_LEFT}, {(char *)"roll_right", 10, ROLL_RIGHT}, {(char *)"pstack", 6, PSTACK}, {(char *)"strcat", 6, STRCAT}, {(char *)"strlen", 6, STRLEN}, {(char *)"substr", 6, SUBSTR}, {(char *)"atof", 4, ATOF}, {(char *)"system", 6, SYSTEM}, {(char *)"sup", 3, SUP}, {(char *)"inf", 3, INF}, {(char *)"=", 1, ASSIGN}, {(char *)"xcmtouser", 9, XCMTOUSER}, {(char *)"xpttouser", 9, XPTTOUSER}, {(char *)"xycmtouser", 10, XYCMTOUSER}, {(char *)"xyusertocm", 10, XYUSERTOCM}, {(char *)"xusertocm", 9, XUSERTOCM}, {(char *)"xusertopt", 9, XUSERTOPT}, {(char *)"ycmtouser", 9, YCMTOUSER}, {(char *)"ypttouser", 9, YPTTOUSER}, {(char *)"yusertocm", 9, YUSERTOCM}, {(char *)"yusertopt", 9, YUSERTOPT}, {(char *)"area", 4, AREA}, {(char *)"@", 1, VAL}, {(char *)"min", 3, MIN}, {(char *)"max", 3, MAX}, {(char *)"median", 6, MEDIAN}, {(char *)"mean", 4, MEAN}, {(char *)"stddev", 6, STDDEV}, {(char *)"skewness", 8, SKEWNESS}, {(char *)"kurtosis", 8, KURTOSIS}, {(char *)"size", 4, SIZE}, {(char *)"directory_exists", 16, DIRECTORY_EXISTS}, {(char *)"file_exists", 11, FILE_EXISTS}, {(char *)"argc", 4, ARGC}, {(char *)"argv", 4, ARGV}, {(char *)"sed", 3, SED}, {(char *)"width", 5, STRINGWIDTH}, {(char *)"ascent", 6, STRINGASCENT}, {(char *)"descent", 7, STRINGDESCENT}, {(char *)"defined", 7, DEFINED}, {(char *)"ismissing", 9, ISMISSING}, {(char *)"interpolate", 11, INTERPOLATE}, {(char *)"rand", 4, RAND}, {(char *)"wordc", 5, WORDC}, {(char *)"wordv", 5, WORDV}, {(char *)NULL, 0, NOT_OPERATOR} }; int RpnError; #define PT_PER_IN 72.27 // points per inch #define PT_PER_CM 28.45 // points per centimetre #define deg_per_rad (57.29577951) void gr_usertocm(double x, double y, double *x_cm, double *y_cm); void gr_cmtouser(double x_cm, double y_cm, double *x, double *y); static operator_name is_oper(const char *w); static operand_type is_operand(const char *w, double *operand); bool rpn_create_function(char *name, char ** w, unsigned int nw); static unsigned int rpn_which_function(const char *w); int rpn(unsigned int nw, char **w, char ** result); static bool do_operation(operator_name oper); int rpn(unsigned int nw, char **w, char ** result) { if (((unsigned) superuser()) & FLAG_RPN) { printf("%s:%d called rpn(", __FILE__,__LINE__); for (unsigned int i=0; i < nw - 1; i++) printf(" '%s',",w[i]); printf(" '%s')\n", w[nw-1]); } unsigned int NW; char *W[MAX_nword]; operator_name oper; double operand_value = 0.0; // should be set below, actually (remove warning) *result = new char[1]; strcpy(*result, ""); if (nw < 1) { if (((unsigned) superuser()) & FLAG_RPN) printf("rpn() go stack underflow\n"); return STACK_UNDERFLOW; } RpnError = 0; // Dump into new array (so can manipulate for funtions) NW = nw; if (NW < MAX_nword) for (unsigned int i = 0; i < NW; i++) W[i] = w[i]; else return OUT_OF_STORAGE; // Now, scan through list, pushing operands onto stack and obeying // operators immediately. for (unsigned int i = 0; i < NW; i++) { if (((unsigned) superuser()) & FLAG_RPN) printf(" rpn scanning item '%s'\n",W[i]); if (NOT_OPERATOR != (oper = is_oper((const char*)W[i]))) { // Do indicated operation. do_operation(oper); } else { // Must be an operand unsigned int which; char *Wnew[MAX_nword]; // for function case operand_type type = is_operand((const char*)W[i], &operand_value); if (((unsigned) superuser()) & FLAG_RPN) printf(" rpn operand type %d (variable with missing value code = %d)\n", type, VARIABLE_WITH_MISSING_VALUE); RpnItem item; switch (type) { case VARIABLE_WITH_MISSING_VALUE: if (_debugFlag & 0x01) printf("rpn trying to use variable '%s' but its value equals the current \"missing value\"", W[i]); item.set("", gr_currentmissingvalue(), NUMBER, false); rS.push_back(item); break; case NUMBER: item.set("", operand_value, type, true); rS.push_back(item); break; case COLUMN_NAME: item.set(W[i], operand_value, type, true); rS.push_back(item); break; case FUNCTION: which = rpn_which_function((const char*)W[i]) - 1; if ((NW + rpn_fcn[which].nw) >= MAX_nword) { fatal_err("Ran out of space in RPN expression"); } // Shuffle words up. // Copy words up to function name for (unsigned int ii = 0; ii < i; ii++) { Wnew[ii] = W[ii]; } // Copy the function contents for (unsigned int ii = 0; ii < rpn_fcn[which].nw; ii++) { Wnew[i + ii] = rpn_fcn[which].w[ii]; } // Copy rest (skip the function name itself) for (unsigned int ii = 0; ii < NW - i - 1; ii++) { Wnew[i + ii + rpn_fcn[which].nw] = W[i + ii + 1]; } // Now dump back into W[] NW += rpn_fcn[which].nw - 1; for (unsigned int ii = 0; ii < NW; ii++) { W[ii] = Wnew[ii]; } i--; // Must reexamine i-th word break; case STRING: item.set(W[i], 0.0 , type, true); rS.push_back(item); break; case NOT_OPERAND: default: RpnError = BAD_WORD; break; } } if (RpnError) return RpnError; } if (rS.size() > 1) return STACK_OVERFLOW; // If stack is empty, return nothing if (rS.size() == 0) { return NO_ERROR; } // Otherwise, save final result into the string //printf("missing code %d\n",rS[0].getValid()); switch (TYPE(1)) { case NUMBER: if (_debugFlag & 0x01 && !rS[0].getValid()) { warning("Rpn result is 'missing' since it contained a variable equal to 'missing' value"); } *result = new char[50]; sprintf(*result, "%.20g", VALUE(1)); rS.pop_back(); break; case STRING: *result = new char[1 + strlen(NAME(1))]; strcpy(*result, NAME(1)); rS.pop_back(); break; case FUNCTION: // I think cannot arrive here anyway err("Not allowed to end up with function on stack"); return GENERAL_ERROR; case COLUMN_NAME: case NOT_OPERAND: case VARIABLE_WITH_MISSING_VALUE: case UNKNOWN: break; } return NO_ERROR; } static operator_name is_oper(const char *w) { int i; #if 0 i = 0; while (rpn_dict[i].op_name) { if (strlen(rpn_dict[i].op_name) != rpn_dict[i].chars) { printf("ERROR in rpn_dict on '%s' ... %d vs %d\n",rpn_dict[i].op_name, strlen(rpn_dict[i].op_name), rpn_dict[i].chars); } i++; } #endif i = 0; unsigned int chars_in_w = strlen(w); // checking first speeds a bit while (rpn_dict[i].op_name) { if (chars_in_w == rpn_dict[i].chars && !strcmp(rpn_dict[i].op_name, w)) return (operator_name) (rpn_dict[i].op_id); i++; } return NOT_OPERATOR; } static operand_type is_operand(const char *w, double *operand_value) { double value; if (w[0] == '"' && w[strlen(w) - 1] == '"') { return STRING; } else if (rpn_which_function(w)) { return FUNCTION; } else if (!strcmp(w, "x") || !strcmp(w, "y") || !strcmp(w, "z") || !strcmp(w, "u") || !strcmp(w, "v") || !strcmp(w, "grid")) { return COLUMN_NAME; } else if (is_var(w)) { if (getdnum(w, &value)) *operand_value = value; else return VARIABLE_WITH_MISSING_VALUE; if (gr_missing(value)) return VARIABLE_WITH_MISSING_VALUE; else return NUMBER; } else if (getdnum(w, &value)) { // BUG - if can't scan, will die *operand_value = value; return NUMBER; } else { return NOT_OPERAND; } } bool rpn_create_function(char *name, char *w[], unsigned int nw) { unsigned int i; rpn_fcn[rpn_fcn_filled].name = new char[1 + strlen(name)]; if (!rpn_fcn[rpn_fcn_filled].name) OUT_OF_MEMORY; strcpy(rpn_fcn[rpn_fcn_filled].name, name); if (nw > 0) { if (nw >= RPN_W_CAPACITY) { fatal_err("internal error: too many words in rpn def"); } for (i = 0; i < nw; i++) { rpn_fcn[rpn_fcn_filled].w[i] = new char[1 + strlen(w[i])]; if (!rpn_fcn[rpn_fcn_filled].w[i]) OUT_OF_MEMORY; strcpy(rpn_fcn[rpn_fcn_filled].w[i], w[i]); } } rpn_fcn[rpn_fcn_filled].nw = nw; rpn_fcn_filled++; return true; } // Return 1 + index of function, or 0 if unknown static unsigned int rpn_which_function(const char *name) { if (isdigit(name[0])) return 0; for (unsigned int i = 0; i < rpn_fcn_filled; i++) if (!strcmp(rpn_fcn[i].name, name)) return (i + 1); return 0; } #define NEED_ON_STACK(num) \ { \ if (rS.size() < (num)) { \ RpnError = STACK_UNDERFLOW; \ return false; \ } \ } #define GET_COL_VAL(COL_NAME, I) \ { \ if ((COL_NAME).size() <= 0 || (I) > ((COL_NAME).size() - 1)) { \ SET(2, "", gr_currentmissingvalue(),NUMBER,false); \ } else { \ SET(2, "", (COL_NAME)(I), NUMBER, true); \ } // Area under y-x curve double curve_area() { double sum = 0; int n = _colX.size(); for (int i = 1; i < n; i++) { if (!gr_missingx(_colX[i]) && !gr_missingx(_colX[i - 1]) && !gr_missingy(_colY[i]) && !gr_missingy(_colY[i - 1])) { sum += 0.5 * (_colY[i] + _colY[i - 1]) * (_colX[i] - _colX[i - 1]); } } return sum; } #define GET_GRID_MIN() \ { \ unsigned int i, j; \ bool first = true; \ double min_val = gr_currentmissingvalue(); \ if (!_grid_exists) { \ err("No data in grid yet."); \ RpnError = GENERAL_ERROR; \ return false; \ } \ for (j = 0; j < _num_ymatrix_data; j++) { \ for (i = 0; i < _num_xmatrix_data; i++) { \ if (inside_box(_xmatrix[i], _ymatrix[j]) && !gr_missing((double)_f_xy(i, j))) { \ if (first) { \ min_val = _f_xy(i, j); \ first = false; \ } else { \ if (_f_xy(i, j) < min_val) { \ min_val = _f_xy(i, j); \ } \ } \ } \ } \ } \ SET(1, "", min_val, NUMBER, true); \ } #define GET_GRID_MAX() \ { \ unsigned int i, j; \ bool first = true; \ double max_val = gr_currentmissingvalue(); \ if (!_grid_exists) { \ err("No data in grid yet."); \ RpnError = GENERAL_ERROR; \ return false; \ } \ for (j = 0; j < _num_ymatrix_data; j++) { \ for (i = 0; i < _num_xmatrix_data; i++) { \ if (inside_box(_xmatrix[i], _ymatrix[j]) && !gr_missing((double)_f_xy(i, j))) { \ if (first) { \ max_val = _f_xy(i, j); \ first = false; \ } else { \ if (_f_xy(i, j) > max_val) { \ max_val = _f_xy(i, j); \ } \ } \ } \ } \ } \ SET(1, "", max_val, NUMBER, true); \ } #define GET_GRID_MEAN() \ { \ unsigned int i, j; \ double mean_val = 0.0; \ int num = 0; \ if (!_grid_exists) { \ err("No data in grid yet."); \ RpnError = GENERAL_ERROR; \ return false; \ } \ for (j = 0; j < _num_ymatrix_data; j++) { \ for (i = 0; i < _num_xmatrix_data; i++) { \ if (inside_box(_xmatrix[i], _ymatrix[j]) && _legit_xy(i, j)) { \ mean_val += _f_xy(i, j); \ num++; \ } \ } \ } \ if (num > 0) { \ mean_val = mean_val / num; \ } else { \ mean_val = gr_currentmissingvalue(); \ } \ SET(1, "", mean_val, NUMBER, true); \ } #define GET_GRID_STDDEV() \ { \ unsigned int i, j; \ double stddev_val = 0.0; \ double mean_val = 0.0; \ int num = 0; \ if (!_grid_exists) { \ err("No data in grid yet."); \ RpnError = GENERAL_ERROR; \ return false; \ } \ for (j = 0; j < _num_ymatrix_data; j++) { \ for (i = 0; i < _num_xmatrix_data; i++) { \ if (_legit_xy(i, j)) { \ mean_val += _f_xy(i, j); \ num++; \ } \ } \ } \ if (num > 0) { \ mean_val = mean_val / num; \ for (j = 0; j < _num_ymatrix_data; j++) { \ for (i = 0; i < _num_xmatrix_data; i++) { \ if (_legit_xy(i, j)) { \ stddev_val += (_f_xy(i, j)-mean_val)*(_f_xy(i, j)-mean_val);\ } \ } \ } \ if (num > 1) { \ stddev_val = sqrt(stddev_val / (num - 1)); \ } else { \ stddev_val = gr_currentmissingvalue(); \ } \ } else { \ stddev_val = gr_currentmissingvalue(); \ } \ SET(1, "", stddev_val, NUMBER, true); \ } #define GET_GRID_SIZE() \ { \ unsigned int i, j; \ unsigned int num = 0; \ if (!_grid_exists) { \ err("No data in grid yet."); \ RpnError = GENERAL_ERROR; \ return false; \ } \ for (j = 0; j < _num_ymatrix_data; j++) { \ for (i = 0; i < _num_xmatrix_data; i++) { \ if (_legit_xy(i, j)) { \ num++; \ } \ } \ } \ SET(1, "", num, NUMBER, true); \ } static bool do_operation(operator_name oper) { //printf("do_operation(%d) vs %d\n",int(oper),int(ARGV)); if (oper == NOT_OPERATOR) { RpnError = BAD_WORD; return false; } double missing = gr_currentmissingvalue(); double res; // holds result if (oper == ADD) { NEED_ON_STACK(2); NEED_IS_TYPE(1, NUMBER); NEED_IS_TYPE(2, NUMBER); if (VALID(1) && VALID(2)) SET(2, "", (VALUE(1)+VALUE(2)), NUMBER, true); else SET(2, "", missing, NUMBER, false); rS.pop_back(); return true; } if (oper == SUBTRACT) { NEED_ON_STACK(2); NEED_IS_TYPE(1, NUMBER); NEED_IS_TYPE(2, NUMBER); if (VALID(1) && VALID(2)) SET(2, "", ((VALUE(2))-(VALUE(1))), NUMBER, true); else SET(2, "", missing, NUMBER, false); rS.pop_back(); return true; } if (oper == GREATER_THAN) { NEED_ON_STACK(2); NEED_IS_TYPE(1, NUMBER); NEED_IS_TYPE(2, NUMBER); if (permit_missing_value_in_comparisons) { // fix SF bug 641406 if (VALID(1) && VALID(2)) SET(2, "", (VALUE(1)>VALUE(2)?1.0:0.0), NUMBER, true); else SET(2, "", missing, NUMBER, false); } else { SET(2, "", (VALUE(1)>VALUE(2)?1.0:0.0), NUMBER, true); } rS.pop_back(); return true; } if (oper == GREATER_THAN_EQUAL) { NEED_ON_STACK(2); NEED_IS_TYPE(1, NUMBER); NEED_IS_TYPE(2, NUMBER); if (permit_missing_value_in_comparisons) { // fix SF bug 641406 if (VALID(1) && VALID(2)) SET(2, "", (VALUE(1)>=VALUE(2)?1:0), NUMBER, true); else SET(2, "", missing, NUMBER, false); } else { SET(2, "", (VALUE(1)>=VALUE(2)?1:0), NUMBER, true); } rS.pop_back(); return true; } if (oper == EQUAL) { NEED_ON_STACK(2); if (TYPE(1) == STRING && TYPE(2) == STRING) { SET(2, "", !strcmp(NAME(2), NAME(1)) ? 1.0 : 0.0, NUMBER, true); rS.pop_back(); } else if (TYPE(1) == NUMBER && TYPE(2) == NUMBER) { if (permit_missing_value_in_comparisons) { // fix SF bug 641406 if (VALID(1) && VALID(2)) SET(2, "", (VALUE(1)==VALUE(2)?1.0:0.0), NUMBER, true); else SET(2, "", missing, NUMBER, false); } else { SET(2, "", (VALUE(1)==VALUE(2)?1.0:0.0), NUMBER, true); } rS.pop_back(); } else { err("RPN operator `==' cannot handle the items currently on stack."); RpnError = ILLEGAL_TYPE; return false; } return true; } if (oper == NOT_EQUAL) { NEED_ON_STACK(2); if (TYPE(1) == STRING && TYPE(2) == STRING) { SET(2, "", !strcmp(NAME(2), NAME(1)) ? 0.0 : 1.0, NUMBER, true); rS.pop_back(); } else if (TYPE(1) == NUMBER && TYPE(2) == NUMBER) { if (permit_missing_value_in_comparisons) { // fix SF bug 641406 if (VALID(1) && VALID(2)) SET(2, "", (VALUE(1)!=VALUE(2)?1.0:0.0), NUMBER, true); else SET(2, "", missing, NUMBER, false); } else { SET(2, "", (VALUE(1)!=VALUE(2)?1.0:0.0), NUMBER, true); } rS.pop_back(); } else { err("Rpn operator `!=' cannot handle items on stack."); RpnError = ILLEGAL_TYPE; return false; } return true; } if (oper == AND) { NEED_ON_STACK(2); NEED_IS_TYPE(1, NUMBER); NEED_IS_TYPE(2, NUMBER); // if EITHER on stack is 0, result is 0 if (VALID(1) && !VALUE(1)) { SET(2, "", 0.0, NUMBER, true); rS.pop_back(); return true; } if (VALID(2) && !VALUE(2)) { SET(2, "", 0.0, NUMBER, true); rS.pop_back(); return true; } if (VALID(1) && VALID(2)) { SET(2, "", (VALUE(1)&&VALUE(2)?1.0:0.0), NUMBER, true); } else { SET(2, "", missing, NUMBER, false); } rS.pop_back(); return true; } if (oper == OR) { NEED_ON_STACK(2); NEED_IS_TYPE(1, NUMBER); NEED_IS_TYPE(2, NUMBER); // if EITHER on stack is 1, result is 1 if (VALID(1) && VALUE(1)) { SET(2, "", 1.0, NUMBER, true); rS.pop_back(); return true; } if (VALID(2) && VALUE(2)) { SET(2, "", 1.0, NUMBER, true); rS.pop_back(); return true; } if (VALID(1) && VALID(2)) SET(2, "", (VALUE(1)||VALUE(2)?1.0:0.0), NUMBER, true); else SET(2, "", missing, NUMBER, false); rS.pop_back(); return true; } if (oper == NOT) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (VALID(1)) SET(1, "", (VALUE(1) ? 0.0 : 1.0), NUMBER, true); else SET(1, "", missing, NUMBER, false); return true; } if (oper == LESS_THAN) { NEED_ON_STACK(2); NEED_IS_TYPE(1, NUMBER); NEED_IS_TYPE(2, NUMBER); if (permit_missing_value_in_comparisons) { // fix SF bug 641406 if (VALID(1) && VALID(2)) SET(2, "", (VALUE(1) 0.0) { SET(2, "", pow(x, p), NUMBER, true); rS.pop_back(); return true; } // If x<0 and p is even integer, ok; // If x<0 and p is odd integer, ok; // Otherwise, we're out of luck. if (x < 0.0) { if (is_even_integer(p)) { SET(2, "", pow(-x, p), NUMBER, true); rS.pop_back(); return true; } else if (is_odd_integer(p)) { SET(2, "", -pow(-x, p), NUMBER, true); rS.pop_back(); return true; } else { RpnError = NEED_GE_0; rS.pop_back(); // no need, since will die return false; } } // Cannot get here. return true; } if (oper == ACOSINE) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (VALID(1)) { if (VALUE(1) > 1.0 || VALUE(1) < -1.0) { RpnError = RANGE_1; return false; } SET(1, "", (acos(VALUE(1)) * deg_per_rad), NUMBER, true); } else SET(1, "", missing, NUMBER, false); return true; } if (oper == AGE) { NEED_ON_STACK(1); NEED_IS_TYPE(1, STRING); static time_t present_time; time(&present_time); //printf("DEBUG: B. present_time %d\n", (unsigned int)(present_time)); string filename(NAME(1)); #ifdef HAVE_STAT struct stat buf; un_double_quote(filename); //printf("BEFORE... [%s]\n",filename.c_str()); extern bool full_path_name(std::string& f); full_path_name(filename); //printf("AFTER... [%s]\n",filename.c_str()); if (0 == stat(filename.c_str(), &buf)) { double seconds = buf.st_ctime; SET(1, "", present_time - seconds, NUMBER, true); } else { SET(1, "", present_time, NUMBER, true); //warning("warning: cannot find age of file named `\\", filename.c_str(), "' so using an 'infinite' age", "\\"); } #else SET(1, "", present_time, NUMBER, true); warning("This computer cannot do stat() on file named `\\", filename.c_str(), "' so using an 'infinite' age'", "\\"); #endif return true; } if (oper == ASINE) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (VALID(1)) { if (VALUE(1) > 1.0 || VALUE(1) < -1.0) { RpnError = RANGE_1; return false; } SET(1, "", (asin(VALUE(1)) * deg_per_rad), NUMBER, true); } else SET(1, "", missing, NUMBER, false); return true; } if (oper == ATANGENT) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (VALID(1)) { if (VALUE(1) > 1.0 || VALUE(1) < -1.0) { RpnError = RANGE_1; return false; } SET(1, "", (atan(VALUE(1)) * deg_per_rad), NUMBER, true); } else SET(1, "", missing, NUMBER, false); return true; } if (oper == SINE) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (VALID(1)) { SET(1, "", (sin(VALUE(1)/deg_per_rad)), NUMBER, true); } else SET(1, "", missing, NUMBER, false); return true; } if (oper == COSINE) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (VALID(1)) { SET(1, "", (cos(VALUE(1)/deg_per_rad)), NUMBER, true); } else SET(1, "", missing, NUMBER, false); return true; } if (oper == TANGENT) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (VALID(1)) { SET(1, "", (tan(VALUE(1)/deg_per_rad)), NUMBER, true); } else SET(1, "", missing, NUMBER, false); return true; } if (oper == SINH) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (VALID(1)) { SET(1, "", (sinh(VALUE(1))), NUMBER, true); } else SET(1, "", missing, NUMBER, false); return true; } if (oper == ACOSH) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (!VALID(1)) { SET(1, "", missing, NUMBER, false); return true; } if (VALUE(1) < 1.0) { RpnError = NEED_GT_1; return false; } #if defined(HAVE_ACOSH) SET(1, "", (acosh(VALUE(1))), NUMBER, true); return true; #else RpnError = COMPUTER_LIMITATION; return false; #endif } if (oper == ATANH) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (!VALID(1)) { SET(1, "", missing, NUMBER, false); return true; } if (VALUE(1) > 1.0 || VALUE(1) < -1.0) { RpnError = RANGE_1; return false; } #if defined(HAVE_ACOSH) SET(1, "", (atanh(VALUE(1))), NUMBER, true); return true; #else RpnError = COMPUTER_LIMITATION; return false; #endif } if (oper == ASINH) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (!VALID(1)) { SET(1, "", missing, NUMBER, false); return true; } #if defined(HAVE_ACOSH) SET(1, "", (asinh(VALUE(1))), NUMBER, true); return true; #else RpnError = COMPUTER_LIMITATION; return false; #endif } if (oper == COSH) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (!VALID(1)) { SET(1, "", missing, NUMBER, false); return true; } SET(1, "", (cosh(VALUE(1))), NUMBER, true); return true; } if (oper == TANH) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (!VALID(1)) { SET(1, "", missing, NUMBER, false); return true; } SET(1, "", (tanh(VALUE(1))), NUMBER, true); return true; } if (oper == SQRT) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (!VALID(1)) { SET(1, "", missing, NUMBER, false); return true; } if (VALUE(1) < 0.0) { RpnError = NEED_GE_0; return false; } SET(1, "", (sqrt(VALUE(1))), NUMBER, true); return true; } if (oper == LOG) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (!VALID(1)) { SET(1, "", missing, NUMBER, false); return true; } if (VALUE(1) <= 0.0) { RpnError = NEED_GT_0; return false; } SET(1, "", (log10(VALUE(1))), NUMBER, true); return true; } if (oper == LN) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (!VALID(1)) { SET(1, "", missing, NUMBER, false); return true; } if (VALUE(1) <= 0) { RpnError = NEED_GT_0; return false; } SET(1, "", (log(VALUE(1))), NUMBER, true); return true; } if (oper == EXP) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (!VALID(1)) { SET(1, "", missing, NUMBER, false); return true; } SET(1, "", (pow(Ee, VALUE(1))), NUMBER, true); return true; } if (oper == EXP10) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (!VALID(1)) { SET(1, "", missing, NUMBER, false); return true; } SET(1, "", (pow(10.0, VALUE(1))), NUMBER, true); return true; } if (oper == HEX2DEC) { NEED_ON_STACK(1); NEED_IS_TYPE(1, STRING); if (!VALID(1)) { SET(1, "", missing, NUMBER, false); return true; } std::string hex = NAME(1); un_double_quote(hex); unsigned int r; if (1 == sscanf(hex.c_str(), "%x", &r)) { res = floor(0.5 + r); } else { res = gr_currentmissingvalue(); err("hex2dec cannot decode \\", hex.c_str(), "\\"); RpnError = GENERAL_ERROR; return false; } SET(1, "", res, NUMBER, true); return true; } if (oper == DEC2HEX) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (!VALID(1)) { SET(1, "", missing, NUMBER, false); return true; } if (VALUE(1) < -0.5) { SET(1, "", 0.0, STRING, true); RpnError = NEED_GE_0; return false; } char hex[20]; // BUG: may not be long enough unsigned int chars = snprintf(hex, -1 + sizeof(hex), "%X", (unsigned int)floor(0.5 + VALUE(1))); if (chars > -1 + sizeof(hex)) { err("dec2hex buffer overflow [internal error in rpncalc.cc, please contact developer]"); return false; } if (chars < 1) { SET(1, "", 0.0, STRING, true); err("dec2hex cannot convert number"); RpnError = GENERAL_ERROR; return false; } std::string qhex = "\""; qhex.append(hex); qhex.append("\""); SET(1, qhex.c_str(), 0.0, STRING, true); return true; } if (oper == FLOOR) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (!VALID(1)) { SET(1, "", missing, NUMBER, false); return true; } SET(1, "", (floor(VALUE(1))), NUMBER, true); return true; } if (oper == REMAINDER) { NEED_ON_STACK(2); NEED_IS_TYPE(1, NUMBER); NEED_IS_TYPE(2, NUMBER); if (!VALID(1)) { SET(1, "", missing, NUMBER, false); return true; } SET(2, "", (fmod(VALUE(2), VALUE(1))), NUMBER, true); rS.pop_back(); return true; } if (oper == CEIL) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (!VALID(1)) { SET(1, "", missing, NUMBER, false); return true; } SET(1, "", (ceil(VALUE(1))), NUMBER, true); return true; } if (oper == ABS) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (!VALID(1)) { SET(1, "", missing, NUMBER, false); return true; } SET(1, "", (fabs(VALUE(1))), NUMBER, true); return true; } if (oper == CMTOPT) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (!VALID(1)) { SET(1, "", missing, NUMBER, false); return true; } SET(1, "", (VALUE(1) * PT_PER_CM), NUMBER, true); return true; } if (oper == PTTOCM) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); if (!VALID(1)) { SET(1, "", missing, NUMBER, false); return true; } SET(1, "", (VALUE(1) / PT_PER_CM), NUMBER, true); return true; } if (oper == DUP) { NEED_ON_STACK(1); RpnItem item; item.set(NAME(1), VALUE(1), TYPE(1), true); rS.push_back(item); return true; } if (oper == POP) { if (rS.size() < 2) { warning("An 'RPN' pop is leaving a blank stack. Do you want this?"); } rS.pop_back(); return true; } if (oper == EXCH) { NEED_ON_STACK(2); RpnItem old; // cannot do old=... here old = rS[rS.size() - 1]; rS[rS.size() - 1] = rS[rS.size() - 2]; rS[rS.size() - 2] = old; return true; } if (oper == ROLL_LEFT) { NEED_ON_STACK(2); RpnItem old; // cannot do old=... here old = rS[0]; for (unsigned int i = 0; i < rS.size() - 1; i++) rS[i] = rS[i + 1]; rS[rS.size() - 1] = old; return true; } if (oper == ROLL_RIGHT) { NEED_ON_STACK(2); RpnItem old; // cannot do old=... here old = rS[rS.size() - 1]; for (unsigned int i = rS.size() - 1; i > 0; i--) rS[i] = rS[i - 1]; rS[0] = old; return true; } if (oper == PSTACK) { return print_rpn_stack(); } if (oper == STRLEN) { NEED_ON_STACK(1); NEED_IS_TYPE(1, STRING); SET(1, "", double(strlen(NAME(1))), NUMBER, true); return true; } if (oper == SUBSTR) { NEED_ON_STACK(3); NEED_IS_TYPE(1, STRING); NEED_IS_TYPE(2, NUMBER); NEED_IS_TYPE(3, NUMBER); std::string s(NAME(1)), ss; un_double_quote(s); int stop = int(VALUE(2)); int start = int(VALUE(3)); if (stop < 0 || start < 0) { RpnError = NEED_GE_0; return false; } rS.pop_back(); rS.pop_back(); rS.pop_back(); RpnItem item; ss = "\""; ss.append(s.substr(start, stop)); ss.append("\""); item.set(ss.c_str(), 0.0, STRING, true); rS.push_back(item); return true; } if (oper == STRCAT) { // Need to remove the last quote (") of first and first quote of second. NEED_ON_STACK(2); NEED_IS_TYPE(1, STRING); NEED_IS_TYPE(2, STRING); std::string res(NAME(2)); res.STRINGERASE(res.size()-1, 1); res.append(NAME(1) + 1); SET(2, res.c_str(), 0.0, STRING, true); rS.pop_back(); return true; } if (oper == ATOF) { NEED_ON_STACK(1); NEED_IS_TYPE(1, STRING); double tmp; sscanf(NAME(1), "\"%lf\"", &tmp); SET(1, "", tmp, NUMBER, true); return true; } if (oper == SYSTEM) { NEED_ON_STACK(1); NEED_IS_TYPE(1, STRING); #if !defined(HAVE_POPEN) err("This computer can't do `system' in RPN, since no popen() subroutine."); return false; #else { char *output_lines = new char[LineLength]; if (!output_lines) OUT_OF_MEMORY; char *thisline = new char[LineLength]; if (!thisline) OUT_OF_MEMORY; FILE *pipefile; // double duty for this strcpy(output_lines, 1 + NAME(1)); if (*STRING_END(output_lines) == '"') *STRING_END(output_lines) = '\0'; pipefile = (FILE *) popen(output_lines, "r"); if (!pipefile) { err("Sorry, cannot do `system' in RPN; failed popen() call"); delete [] thisline; delete [] output_lines; return false; } strcpy(output_lines, ""); // BUG -- should check for overwrite! while (NULL != fgets(thisline, LineLength_1, pipefile)) strcat(output_lines, thisline); pclose(pipefile); if (*STRING_END(output_lines) == '\n') { *STRING_END(output_lines) = '\0'; } std::string tmp("\""); tmp.append(output_lines); tmp.append("\""); SET(1, tmp.c_str(), 0.0, STRING, true); delete [] thisline; delete [] output_lines; } return true; #endif } if (oper == SUP) { NEED_ON_STACK(2); NEED_IS_TYPE(1, NUMBER); NEED_IS_TYPE(2, NUMBER); if (VALID(1) && VALID(2)) SET(2, "", (VALUE(1)>VALUE(2)?VALUE(1):VALUE(2)), NUMBER, true); else SET(2, "", missing, NUMBER, false); rS.pop_back(); return true; } if (oper == INF) { NEED_ON_STACK(2); NEED_IS_TYPE(1, NUMBER); NEED_IS_TYPE(2, NUMBER); if (VALID(1) && VALID(2)) SET(2, "", (VALUE(1) -1; cmd--) if (!strcmp(_command_word[cmd], _command_word_separator)) break; //printf("DEBUG cmd %d num %d stacksize %d\n",cmd,_num_command_word,rS.size()); RpnItem item; if (cmd > -1) item.set("", double(_num_command_word - cmd - 1), NUMBER, true); else item.set("", 0.0, NUMBER, true); rS.push_back(item); return true; } if (oper == WORDV) { if (rS.size() < 1) { err("`wordv' needs an argument, e.g. {rpn 0 wordv} gives first word of command\n."); return false; } NEED_IS_TYPE(1, NUMBER); int index = int(VALUE(1)); if (index < 0) { printf("`wordv' needs index >= 0\n"); RpnError = NEED_GT_1; return false; } extern int _num_command_word; extern char *_command_word[MAX_cmd_word]; extern char *_command_word_separator; int cmd; // Trace back through the stack until at next level deep, then // move forward to indicated word. for (cmd = _num_command_word - 1; cmd > -1; cmd--) { //printf("\t%d of %d <%s>\n",cmd,_num_command_word,_command_word[cmd]); if (!strcmp(_command_word[cmd], _command_word_separator)) break; } //printf("cmd is %d max is %d ... value '%s'\n",cmd,_num_command_word,_command_word[cmd+index+1]); std::string rv; if (*_command_word[cmd + index + 1] == '\"') { rv.append(_command_word[cmd + index + 1]); } else { rv.append("\""); rv.append(_command_word[cmd + index + 1]); rv.append("\""); } SET(1, rv.c_str(), 0.0, STRING, true); //printf("\t\trv is '%s'\n",rv.c_str()); return true; } if (oper == ARGC) { extern std::vector_gri_argv; RpnItem item; item.set("", double(_gri_argv.size()), NUMBER, true); rS.push_back(item); return true; } if (oper == ARGV) { NEED_ON_STACK(1); NEED_IS_TYPE(1, NUMBER); int index = int(VALUE(1)); if (index < 0) { printf("'argv' needs index >= 0\n"); RpnError = NEED_GT_1; return false; } extern std::vector_gri_argv; if (index >= int(_gri_argv.size())) { SET(1, "\" \"", 0.0, STRING, true); return true; } std::string rv("\""); rv.append(_gri_argv[index]); rv.append("\""); SET(1, rv.c_str(), 0.0, STRING, true); return true; } if (oper == FILE_EXISTS) { NEED_ON_STACK(1); if (TYPE(1) != STRING) { err("RPN string operator `file_exists' needs a string to be top item on stack."); RpnError = ILLEGAL_TYPE; return false; } else { #if defined(HAVE_ACCESS) std::string fname(NAME(1)); un_double_quote(fname); if (fname[0] == '~') { fname.STRINGERASE(0, 1); std::string home(egetenv("HOME")); home.append(fname); fname = home; } //printf("DEBUG: should check if file named '%s' or '%s' exists\n",NAME(1),fname.c_str()); if (0 == access(fname.c_str(), R_OK)) SET(1, "", 1.0, NUMBER, true); else SET(1, "", 0.0, NUMBER, true); #else warning("Can't determine whether file exists (no 'access' subroutine on this system) so guessing answer is yes."); SET(1, "", 1.0, NUMBER, true); #endif } return true; } if (oper == DEFINED) { NEED_ON_STACK(1); NEED_IS_TYPE(1, STRING); std::string n1(NAME(1)); un_double_quote(n1); // It's either a synonym or a variable, or not defined if (is_syn(n1)) { //printf("\n"); //printf("DEBUG %s:%d defined on <%s>\n",__FILE__,__LINE__,n1.c_str()); int w_index = -1; if (1 == sscanf(n1.c_str(), "\\.word%d.", &w_index)) { std::string w(""); if (get_cmdword(w_index, w)) { // If such a \.word?. exists, look up pointed-to item //printf("DEBUG %s:%d w= <%s>\n",__FILE__,__LINE__,w.c_str()); std::string coded_name; int coded_level; if (is_coded_string(w, coded_name, &coded_level)) { //printf("DEBUG %s:%d encoded `%s' at level %d\n",__FILE__,__LINE__, coded_name.c_str(), coded_level); std::string value; if (get_coded_value(coded_name, coded_level, value)) { //printf(" ** YES [%s] is defined\n", coded_name.c_str()); SET(1, "", 1.0, NUMBER, true); } else { //printf(" ** NO [%s] is NOT defined\n", coded_name.c_str()); SET(1, "", 0.0, NUMBER, true); } } else { // Nothing pointed-to, so \.word?. existence enough SET(1, "", 1.0, NUMBER, true); } } else { // If no such \.word?., certainly nothing pointed-to. SET(1, "", 0.0, NUMBER, true); } } else { //printf("CASE 2. n1 is [%s]\n",n1.c_str()); bool exists; std::string syn_value; // not used, actually if (n1[1] == '@') { std::string d("\\"); d.append(n1.substr(2, n1.size())); exists = get_syn(d.c_str(), syn_value); //printf("CASE 2B d is [%s] returning %d\n",d.c_str(),exists); } else { exists = get_syn(n1.c_str(), syn_value); //printf("CASE 2B. n1 is [%s] returning %d\n",n1.c_str(),exists); } if (exists) SET(1, "", 1.0, NUMBER, true); else SET(1, "", 0.0, NUMBER, true); } } else if (is_var(n1)) { double tmp; bool exists = get_var(n1.c_str(), &tmp); if (exists) SET(1, "", 1.0, NUMBER, true); else SET(1, "", 0.0, NUMBER, true); } else { err("Can only use `defined' on a variable or synonym (e.g., `.var.' or `\\syn'), not on `\\", NAME(1), "' as found", "\\"); RpnError = ILLEGAL_TYPE; return false; } return true; } if (oper == ISMISSING) { //printf("\noperator ISMISSING.\n"); //printf("value on stack: %f\n",VALUE(1)); NEED_IS_TYPE(1, NUMBER); SET(1, "", gr_missing(VALUE(1)) == true ? 1.0 : 0.0, NUMBER, true); //printf("ste value to %f\n",VALUE(1)); return true; } if (oper == INTERPOLATE) { // Next 2 functions in convert.cc NEED_ON_STACK(3); NEED_IS_TYPE(3, COLUMN_NAME); // must be `grid', actually NEED_IS_TYPE(2, NUMBER); // x NEED_IS_TYPE(1, NUMBER); // y int i, j; double x = VALUE(2), y = VALUE(1), grid_value; if (!locate_i_j(x, y, &i, &j)) { SET(3, "", gr_currentmissingvalue(), NUMBER, true); } else { #if defined(OLD_IMAGE_INTERPOLATION) value_i_j(i, j, x, y, &grid_value); #else value_i_j(i, j, x, y, &grid_value); #endif SET(3, "", grid_value, NUMBER, true); } rS.pop_back(); rS.pop_back(); return true; } if (oper == RAND) { RpnItem item; #if defined(HAVE_DRAND48) item.set("", drand48(), NUMBER, true); #else item.set("", rand(), NUMBER, true); #endif rS.push_back(item); return true; } if (oper == VAL) { extern char _grTempString[]; NEED_ON_STACK(2); NEED_IS_TYPE(2, COLUMN_NAME); int index = (int) (floor(0.5 + VALUE(1))); if (index < 0) { err("Can't take negative index of the `\\", NAME(1), "' column.", "\\"); RpnError = GENERAL_ERROR; return false; } if (!strcmp(NAME(2), "x")) { if (index > int(_colX.size() - 1)) { sprintf(_grTempString, "Cannot index %d-th value of x column; valid range is 0 to %d", index, int(_colX.size() - 1)); err(_grTempString); RpnError = GENERAL_ERROR; return false; } SET(2, "", _colX[index], NUMBER, true); rS.pop_back(); } else if (!strcmp(NAME(2), "y")) { if (index > int(_colY.size() - 1)) { sprintf(_grTempString, "Cannot index %d-th value of y column; valid range is 0 to %d", index, int(_colY.size() - 1)); err(_grTempString); RpnError = GENERAL_ERROR; return false; } SET(2, "", _colY[index], NUMBER, true); rS.pop_back(); } else if (!strcmp(NAME(2), "z")) { if (index > int(_colZ.size() - 1)) { sprintf(_grTempString, "Cannot index %d-th value of z column; valid range is 0 to %d", index, int(_colZ.size() - 1)); err(_grTempString); RpnError = GENERAL_ERROR; return false; } SET(2, "", _colZ[index], NUMBER, true); rS.pop_back(); } else if (!strcmp(NAME(2), "u")) { if (index > int(_colU.size() - 1)) { sprintf(_grTempString, "Cannot index %d-th value of u column; valid range is 0 to %d", index, int(_colU.size() - 1)); err(_grTempString); RpnError = GENERAL_ERROR; return false; } SET(2, "", _colU[index], NUMBER, true); rS.pop_back(); } else if (!strcmp(NAME(2), "v")) { if (index > int(_colV.size() - 1)) { sprintf(_grTempString, "Cannot index %d-th value of v column; valid range is 0 to %d", index, int(_colV.size() - 1)); err(_grTempString); RpnError = GENERAL_ERROR; return false; } SET(2, "", _colV[index], NUMBER, true); rS.pop_back(); } else if (!strcmp(NAME(2), "weight")) { if (index > int(_colWEIGHT.size() - 1)) { sprintf(_grTempString, "Cannot index %d-th value of weight column; valid range is 0 to %d", index, int(_colWEIGHT.size() - 1)); err(_grTempString); RpnError = GENERAL_ERROR; return false; } SET(2, "", _colWEIGHT[index], NUMBER, true); rS.pop_back(); } else { err("Column `\\", NAME(2), "' is invalid", "\\"); RpnError = GENERAL_ERROR; return false; } return true; } if (oper == AREA) { NEED_ON_STACK(2); NEED_IS_TYPE(1, COLUMN_NAME); NEED_IS_TYPE(2, COLUMN_NAME); if (!(!strcmp(NAME(2), "y") && !strcmp(NAME(1), "x"))) { err("To get area under curve, must use syntax `y x area'"); RpnError = GENERAL_ERROR; return false; } SET(2, "", curve_area(), NUMBER, true); rS.pop_back(); return true; } if (oper == MIN) { NEED_ON_STACK(1); NEED_IS_TYPE(1, COLUMN_NAME); if (!strcmp(NAME(1), "x")) { SET(1, "", _colX.min(), NUMBER, true); } else if (!strcmp(NAME(1), "y")) { SET(1, "", _colY.min(), NUMBER, true); } else if (!strcmp(NAME(1), "z")) { SET(1, "", _colZ.min(), NUMBER, true); } else if (!strcmp(NAME(1), "u")) { SET(1, "", _colU.min(), NUMBER, true); } else if (!strcmp(NAME(1), "v")) { SET(1, "", _colV.min(), NUMBER, true); } else if (!strcmp(NAME(1), "grid")) { GET_GRID_MIN(); } else { err("Can't find min of item `\\", NAME(1), "'", "\\"); RpnError = GENERAL_ERROR; return false; } return true; } if (oper == MAX) { NEED_ON_STACK(1); NEED_IS_TYPE(1, COLUMN_NAME); if (!strcmp(NAME(1), "x")) { SET(1, "", _colX.max(), NUMBER, true); } else if (!strcmp(NAME(1), "y")) { SET(1, "", _colY.max(), NUMBER, true); } else if (!strcmp(NAME(1), "z")) { SET(1, "", _colZ.max(), NUMBER, true); } else if (!strcmp(NAME(1), "u")) { SET(1, "", _colU.max(), NUMBER, true); } else if (!strcmp(NAME(1), "v")) { SET(1, "", _colV.max(), NUMBER, true); } else if (!strcmp(NAME(1), "grid")) { GET_GRID_MAX(); } else { err("Can't find max of item `\\", NAME(1), "'", "\\"); RpnError = GENERAL_ERROR; return false; } return true; } if (oper == MEDIAN) { NEED_ON_STACK(1); NEED_IS_TYPE(1, COLUMN_NAME); if (!strcmp(NAME(1), "x")) { SET(1, "", _colX.median(), NUMBER, true); } else if (!strcmp(NAME(1), "y")) { SET(1, "", _colY.median(), NUMBER, true); } else if (!strcmp(NAME(1), "z")) { SET(1, "", _colZ.median(), NUMBER, true); } else if (!strcmp(NAME(1), "u")) { SET(1, "", _colU.median(), NUMBER, true); } else if (!strcmp(NAME(1), "v")) { SET(1, "", _colV.median(), NUMBER, true); } else if (!strcmp(NAME(1), "grid")) { err("This version of Gri cannot do 'median' of grid yet."); RpnError = GENERAL_ERROR; return false; } else { err("Column `\\", NAME(1), "' is invalid", "\\"); RpnError = GENERAL_ERROR; return false; } return true; } if (oper == MEAN) { NEED_ON_STACK(1); NEED_IS_TYPE(1, COLUMN_NAME); if (!strcmp(NAME(1), "x")) { SET(1, "", _colX.mean(), NUMBER, true); } else if (!strcmp(NAME(1), "y")) { SET(1, "", _colY.mean(), NUMBER, true); } else if (!strcmp(NAME(1), "z")) { SET(1, "", _colZ.mean(), NUMBER, true); } else if (!strcmp(NAME(1), "u")) { SET(1, "", _colU.mean(), NUMBER, true); } else if (!strcmp(NAME(1), "v")) { SET(1, "", _colV.mean(), NUMBER, true); } else if (!strcmp(NAME(1), "grid")) { GET_GRID_MEAN(); } else { err("Column `\\", NAME(1), "' is invalid", "\\"); RpnError = GENERAL_ERROR; return false; } return true; } if (oper == SKEWNESS) { NEED_ON_STACK(1); NEED_IS_TYPE(1, COLUMN_NAME); if (!strcmp(NAME(1), "x")) { SET(1, "", _colX.skewness(), NUMBER, true); } else if (!strcmp(NAME(1), "y")) { SET(1, "", _colY.skewness(), NUMBER, true); } else if (!strcmp(NAME(1), "z")) { SET(1, "", _colZ.skewness(), NUMBER, true); } else if (!strcmp(NAME(1), "u")) { SET(1, "", _colU.skewness(), NUMBER, true); } else if (!strcmp(NAME(1), "v")) { SET(1, "", _colV.skewness(), NUMBER, true); } else if (!strcmp(NAME(1), "grid")) { err("Cannot do skewness of a grid. Ask author if you need this to be added to Gri"); } else { err("Column `\\", NAME(1), "' is invalid", "\\"); RpnError = GENERAL_ERROR; return false; } return true; } if (oper == KURTOSIS) { NEED_ON_STACK(1); NEED_IS_TYPE(1, COLUMN_NAME); if (!strcmp(NAME(1), "x")) { SET(1, "", _colX.kurtosis(), NUMBER, true); } else if (!strcmp(NAME(1), "y")) { SET(1, "", _colY.kurtosis(), NUMBER, true); } else if (!strcmp(NAME(1), "z")) { SET(1, "", _colZ.kurtosis(), NUMBER, true); } else if (!strcmp(NAME(1), "u")) { SET(1, "", _colU.kurtosis(), NUMBER, true); } else if (!strcmp(NAME(1), "v")) { SET(1, "", _colV.kurtosis(), NUMBER, true); } else if (!strcmp(NAME(1), "grid")) { err("Cannot do kurtosis of a grid. Ask author if you need this to be added to Gri"); } else { err("Column `\\", NAME(1), "' is invalid", "\\"); RpnError = GENERAL_ERROR; return false; } return true; } if (oper == STDDEV) { NEED_ON_STACK(1); NEED_IS_TYPE(1, COLUMN_NAME); if (!strcmp(NAME(1), "x")) { SET(1, "", _colX.stddev(), NUMBER, true); } else if (!strcmp(NAME(1), "y")) { SET(1, "", _colY.stddev(), NUMBER, true); } else if (!strcmp(NAME(1), "z")) { SET(1, "", _colZ.stddev(), NUMBER, true); } else if (!strcmp(NAME(1), "u")) { SET(1, "", _colU.stddev(), NUMBER, true); } else if (!strcmp(NAME(1), "v")) { SET(1, "", _colV.stddev(), NUMBER, true); } else if (!strcmp(NAME(1), "grid")) { GET_GRID_STDDEV(); } else { err("Column `\\", NAME(1), "' is invalid", "\\"); RpnError = GENERAL_ERROR; return false; } return true; } if (oper == SIZE) { NEED_ON_STACK(1); NEED_IS_TYPE(1, COLUMN_NAME); if (!strcmp(NAME(1), "x")) { SET(1, "", _colX.size_legit(), NUMBER, true); } else if (!strcmp(NAME(1), "y")) { SET(1, "", _colY.size_legit(), NUMBER, true); } else if (!strcmp(NAME(1), "z")) { SET(1, "", _colZ.size_legit(), NUMBER, true); } else if (!strcmp(NAME(1), "u")) { SET(1, "", _colU.size_legit(), NUMBER, true); } else if (!strcmp(NAME(1), "v")) { SET(1, "", _colV.size_legit(), NUMBER, true); } else if (!strcmp(NAME(1), "grid")) { GET_GRID_SIZE(); } else { err("Column `\\", NAME(1), "' is invalid", "\\"); RpnError = GENERAL_ERROR; return false; } return true; } gr_Error("Internal error: should not be able to get to\n this line. Please email bug report to author"); return true; } // Used by rpn.cc also, in case of stack overflow bool print_rpn_stack(const char *msg) { int i; int stack_len = rS.size(); if (strlen(msg) > 0) ShowStr(msg); // printf("stack types UNKNOWN, VARIABLE_WITH_MISSING_VALUE, NOT_OPERAND, NUMBER, STRING, COLUMN_NAME, FUNCTION\n"); ShowStr("Operands on rpn stack: ("); for (i = 0; i < stack_len; i++) { char str[100]; //printf("type[%d] = %d\n", i, TYPE(stack_len - i)); if (TYPE(stack_len - i) == NUMBER) { sprintf(str, "%.20g", VALUE(stack_len - i)); ShowStr(str); } else if (TYPE(stack_len - i) == COLUMN_NAME) { //ShowStr("colname:"); ShowStr(NAME(stack_len - i)); //printf("[%s]\n",NAME(stack_len - i)); } else { ShowStr(NAME(stack_len - i)); } if (i != (stack_len - 1)) ShowStr(", "); } ShowStr(")\n"); return true; } #undef NEED_IS_TYPE #undef NEED_ON_STACK #undef GET_COL_VAL #undef GET_COL_MIN #undef GET_COL_MAX #undef GET_COL_MEAN #undef GET_COL_STDDEV #undef VALUE #undef NAME #undef VALUE #undef TYPE gri/src/group.cc0000644000175000017500000000311613147557614012253 0ustar psgpsg/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "extern.hh" extern FILE *_grSVG; static std::vector group_name; bool groupCmd() { printf("DEBUG: in 'group'\n"); return group_start(); } bool end_groupCmd() { printf("DEBUG: in 'end group'\n"); return group_end(); } bool group_start(const char *id) { if (_output_file_type == svg) { std::string name = id; if (strlen(id) > 0) fprintf(_grSVG, " \n", id); else fprintf(_grSVG, " \n"); group_name.push_back(name); } return true; } bool group_end() { if (_output_file_type == svg) { if (group_name.size() > 0) { fprintf(_grSVG, " \n", group_name.back().c_str()); group_name.pop_back(); } else { fprintf(_grSVG, " \n"); } } return true; } gri/src/startup.cc0000644000175000017500000013515213147557614012627 0ustar psgpsg/* Gri - A language for scientific graphics programming Copyright (C) 2008-2017 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ //#define TEST_POPT // uncomment this to test the POPT library #include #include #include #include #ifdef TEST_POPT #if defined(HAVE_OLD_POPT) extern "C" { #include } #else #include #endif #endif #include "gr.hh" #include "extern.hh" #include "private.hh" #include "defaults.hh" #include "files.hh" #include "gr_coll.hh" #include "macro.hh" #include "GriColor.hh" #include "superus.hh" // The next few lines are trying to get around an intermittent // problem with Solaris compilation. I don't compile on Solaris // often, and every time I do, I have to either comment-out, // or to uncomment, the declaration below. I guess I could put // in a few more lines here, checking for this or that version of // this or that compiler, but that would be ugly. Maybe this // should go into the configure.in file, but it is difficult for // me to do that, without access to solaris machines that behave // differently from one another. Besides, the error message on // this is pretty clear, and this is a reported bug on // gri.sourceforge.net (number 618041), at // http://sourceforge.net/tracker/index.php?func=detail&aid=618041&group_id=5511&atid=105511 // and so I'll just leave this here for now, half-broken on // Solaris. #if defined(HAVE_GETHOSTNAME) #if defined(IS_SUN) //extern "C" unsigned int gethostname(char *name, int namelen); #endif #endif #if defined(OS_IS_BEOS) #include #endif static std::vector colorStack; static const char** argv_leftover; typedef struct { unsigned int code; char *action; } superuser_flag; static superuser_flag sflag[] = { {FLAG_SYN, (char *)"Print cmdline before/after sub synonyms"}, {FLAG_RPN, (char *)"Print cmdline before/after sub rpn"}, {FLAG_NEW, (char *)"Print new commands being defined"}, {FLAG_SYS, (char *)"Print system commands before passing"}, {FLAG_FLOW, (char *)"Indicate program flow"}, {FLAG_AUT2, (char *)"Variable; for use by developers only"}, {FLAG_AUT1, (char *)"Variable; for use by developers only"}, {0, NULL} }; static std::string psname(""); static bool user_gave_directory = false; extern char _grTempString[]; bool display_colors(); static void create_builtin_colors(void); bool _no_startup_message = false; bool _contour_label_rotated = false; // <-> draw.c set.c bool _contour_label_whiteunder = true; // <-> draw.c set.c bool _store_cmds_in_ps = true; // <-> read.c bool _private = true; // "-private" and "-no_private" commandline options bool initialize_image(); bool initialize_imageMask(); bool create_arrays(void); static void create_builtin_variables(void); static void create_builtin_synonyms(void); static void set_defaults(void); const char** interpret_optional_arguments(int argc, char *argv[]); static void get_input_simulation(int argc, const char *argv[]); static void insert_creator_name_in_PS(int argc, char *argv[], const std::string&psname); static void dogrirc(void); #if 0 static void show_startup_msg(void); #endif int last_optional_arg = 0; // RETURN 1 if found color and dumped RGB into red, green, blue bool look_up_color(const char *name, double *red, double *green, double *blue) { int i, num = colorStack.size(); for (i = 0; i < num; i++) { if (!strcmp(name, colorStack[i].get_name().c_str())) { *red = colorStack[i].getR(); *green = colorStack[i].getG(); *blue = colorStack[i].getB(); return true; } } return false; } bool create_color(const char *name, double r, double g, double b) { GriNamedColor color(name, r, g, b); colorStack.push_back(color); return true; } #if 0 // RETURN value contents of s following the last ',' in s, or all of s static char* last_name(char *s) { int len = strlen(s); int i; for (i = len - 1; i > -1; i--) { if (s[i] == ',') { if (i != len - 1) i++; break; } } char *return_value; if (i < 0) { // no comma return_value = new char[1 + len]; if (!return_value) OUT_OF_MEMORY; strcpy(return_value, s); } else { return_value = new char[1 + len - i]; if (!return_value) OUT_OF_MEMORY; strcpy(return_value, s + i); } return return_value; } #endif bool start_up(int argc, char **argv) { extern rectangle _page_size; _page_size.set(0.0, 0.0, 0.0, 0.0); /* #if defined(TEST_POPT) printf("DEBUG: %s:%d: FYI, start_up() found the raw args to be:\n",__FILE__,__LINE__); for (int i = 0; i < argc; i++) printf("DEBUG: '%s'\n", argv[i]); #endif */ #ifdef OSX_BUNDLE // printf("%s:%d OSX_BUNDLE being used\n",__FILE__,__LINE__); #endif _output_file_type = postscript; // Record version number int major_version, minor_version, minor_minor_version; extern char _input_data_separator; // defined in gri.cc _input_data_separator = ' '; extern char _gri_number[]; sscanf(_gri_number, "%d.%d.%d", &major_version, &minor_version, &minor_minor_version); _version = major_version + minor_version / 100.0 + minor_minor_version / 10000.0; _arrow_type = 0; // default // Get storage space for arrays, variables, synonyms, etc initialize_image(); initialize_imageMask(); create_arrays(); create_builtin_variables(); create_builtin_synonyms(); set_up_command_word_buffer(); set_defaults(); // Initialize some globals. _nword = 0; // Prevent problems. _contour_label_rotated = false; // see `set contour labels rotated' _contour_label_whiteunder = true; // see `set contour labels whiteunder _axes_offset = 0.0; _use_default_for_query = false; _warn_offpage = true; PUT_VAR("..use_default_for_query..", 0.0); PUT_VAR("..words_in_dataline..", 0.0); // just in case tested PUT_VAR("..batch..", 0.0); _debugFlag = 0; PUT_VAR("..debug..", 0.0); PUT_VAR("..eof..", 0.0); PUT_VAR("..landscape..", 0.0); PUT_VAR("..publication..", 0.0); PUT_VAR("..xlast..", 0.0); PUT_VAR("..ylast..", 0.0); PUT_VAR("..image_width..", 0.0); PUT_VAR("..image_height..", 0.0); PUT_VAR("..q1..",0.0); PUT_VAR("..q2..",0.0); PUT_VAR("..q3..",0.0); #ifdef OSX_BUNDLE extern std::string _lib_directory; _lib_directory.assign(argv[0]); std::string::size_type last_slash = _lib_directory.rfind("/"); if (last_slash != STRING_NPOS) { _lib_directory.STRINGERASE(last_slash, _lib_directory.length()); } else { fatal_err("OSX error: cannot find slash in argv[0]\n"); } // printf("%s:%d: OSX_BUNDLE using _lib_directory '%s'\n", __FILE__, __LINE__, _lib_directory.c_str()); #endif // Get leftover (non-optional) arguments argv_leftover = interpret_optional_arguments(argc, argv); unsigned int argc_leftover = 0; //printf("%s:%d argc_leftover= %d:\n",__FILE__,__LINE__,argc_leftover); while (argv_leftover && argv_leftover[argc_leftover] != NULL) { std::string thisarg = argv_leftover[argc_leftover]; //printf("\t<%s>\n", argv_leftover[argc_leftover]); int thisarglen = thisarg.length(); if (thisarglen > 3 && '.' == thisarg[thisarg.length()-3] && 'p' == thisarg[thisarg.length()-2] && 's' == thisarg[thisarg.length()-1]) { psname = thisarg; } argc_leftover++; } //printf("end. LEFTOVER. have %d\n",argc_leftover); if (argc_leftover == 0) { _margin.assign(" "); push_cmd_file("stdin", batch() ? false : true, true, "r"); Require(put_syn("\\.command_file.", "stdin", true), OUT_OF_MEMORY); } else { std::string fname(argv_leftover[0]); Require(put_syn("\\.command_file.", fname.c_str(), true), OUT_OF_MEMORY); //printf("FILENAME '%s'\n",fname.c_str()); // If filename shorter than 4 characters, cannot have .gri suffix, // so append it. std::string::size_type p = fname.rfind(".gri"); if (fname.size() < 4 || p != -4 + fname.size()) fname.append(".gri"); // If user didn't give psname, create it. First, must trim the // ".gri" suffix (which is sure to be there). Then, must remove // any filename path, since we want the .ps or .eps // file to be created in this local directory . //printf("psname.empty() %d\n", psname.empty()); if (psname.empty()) { psname = fname; int l = psname.size(); psname.STRINGERASE(l - 4, l - 1); std::string::size_type last_slash = psname.rfind("/"); if (last_slash != STRING_NPOS) psname.STRINGERASE(0, last_slash + 1); psname.append(".ps"); } if (!push_cmd_file(fname.c_str(), false, false, "r")) { fprintf(stderr, "Gri cannot open commandfile `%s'\n", fname.c_str()); delete_ps_file(); gri_exit(1); } #if 0 // Possibly they gave a ps filename ... if (argc > last_optional_arg + 2) { std::string tmp(argv[last_optional_arg+2]); std::string::size_type p = tmp.rfind(".ps"); if (p != STRING_NPOS && p == -3 + tmp.size()) { warning("\ first argument looks like a PostScript filename. Older versions\n\ of Gri allowed you to specify the PostScript name that way,\n\ but now you must use the \"-output\" option, as for example:\n\ gri ... -output \\", tmp.c_str(), " ...\n\ As it is, Gri is using the filename `", psname.c_str(), "'.", "\\"); //psname = tmp; } } #endif gr_setup_ps_filename(psname.c_str()); } //printf("DEBUG2 separator= %d\n", separator); get_input_simulation(argc_leftover, argv_leftover); insert_creator_name_in_PS(argc, argv, psname); // Finally, ready to begin plot. gr_begin(1); // Embed info on how gri was invoked. if (!_private) { extern FILE *_grPS; char host[BUFSIZ]; #if defined(HAVE_GETHOSTNAME) if (0 != gethostname(host, BUFSIZ - 1)) strcpy(host, "unknown"); #else strcpy(host, "unknown"); #endif fprintf(_grPS, "%%gri:# Gri was invoked by user named\n%%gri:# %s\n%%gri:# on host named\n%%gri:# %s\n%%gri:# using the command\n%%gri:# ", egetenv("USER"), host); for (int i = 0; i < argc; i++) fprintf(_grPS, " %s", argv[i]); SECOND_TYPE sec; time(&sec); sprintf(_grTempString, "%s", asctime(localtime(&sec))); _grTempString[-1 + strlen(_grTempString)] = '\0'; // trim newline fprintf(_grPS, "\n%%gri:# at local time %s.\n", _grTempString); } put_syn("\\.ps_file.", gr_currentPSfilename(), true); // Disable tracing during startup phase, unless in superuser mode. double trace_old; get_var("..trace..", &trace_old); PUT_VAR("..trace..", 0.0); // Do the gri.cmd file. Note that 'create_commands()' will take care of // the searching for the gri.cmd file. bool tmp = _store_cmds_in_ps; _store_cmds_in_ps = false; if (superuser() & FLAG_AUT2) printf("Processing gri.cmd ..."); create_commands(GRI_COMMANDS_FILE, user_gave_directory); if (superuser() & FLAG_AUT2) printf(" done\n"); create_builtin_colors(); // Define default paths char* griinputs = egetenv("GRIINPUTS"); if (griinputs != NULL && strlen(griinputs) > 0) { warning("Your GRIINPUTS environment variable has been IGNORED.\n In this version of gri, you must put the line\n set path \"\\", griinputs, "\" for commands\n in your ~/.grirc file to get the same effect.\n", "\\"); } put_syn("\\.path_data.", ".", true); put_syn("\\.path_commands.", ".", true); // Do user's ~/.grirc file. _store_cmds_in_ps = tmp; dogrirc(); // Re-enable tracing PUT_VAR("..trace..", trace_old); // DataFile stack DataFile new_data_file; if (superuser() & FLAG_AUT1)printf("\nDEBUG: %s:%d pushing back a datafile at address %lx\n",__FILE__,__LINE__,(long unsigned int)(&new_data_file)); _dataFILE.push_back(new_data_file); _first = true; _bounding_box.set(0.0, 0.0, 0.0, 0.0); //printf("At end of start_up, _cmdLine is <%s>\n",_cmdLine); return true; } static void create_builtin_colors() { GriNamedColor color; color.setNameRGB("white", 1.000, 1.000, 1.000); colorStack.push_back(color); color.setNameRGB("LightGray", 0.827, 0.827, 0.827); colorStack.push_back(color); color.setNameRGB("darkslategray", 0.184, 0.310, 0.310); colorStack.push_back(color); color.setNameRGB("black", 0.000, 0.000, 0.000); colorStack.push_back(color); color.setNameRGB("red", 1.000, 0.000, 0.000); colorStack.push_back(color); color.setNameRGB("brown", 0.647, 0.165, 0.165); colorStack.push_back(color); color.setNameRGB("tan", 0.824, 0.706, 0.549); colorStack.push_back(color); color.setNameRGB("orange", 1.000, 0.647, 0.000); colorStack.push_back(color); color.setNameRGB("yellow", 1.000, 1.000, 0.000); colorStack.push_back(color); color.setNameRGB("green", 0.000, 1.000, 0.000); colorStack.push_back(color); color.setNameRGB("ForestGreen", 0.133, 0.545, 0.133); colorStack.push_back(color); color.setNameRGB("cyan", 0.000, 1.000, 1.000); colorStack.push_back(color); color.setNameRGB("blue", 0.000, 0.000, 1.000); colorStack.push_back(color); color.setNameRGB("skyblue", 0.529, 0.808, 0.922); colorStack.push_back(color); color.setNameRGB("magenta", 1.000, 0.000, 1.000); colorStack.push_back(color); } bool display_colors() { char msg[200]; for (unsigned int i = 0; i < colorStack.size(); i++) { sprintf(msg, "Color `%s' has RGB = (%f,%f,%f)\n", colorStack[i].get_name().c_str(), colorStack[i].getR(), colorStack[i].getG(), colorStack[i].getB()); ShowStr(msg); } return true; } #if 0 // get full filename, searching through directory list char * file_in_list(const char *name, bool show_nonlocal_files, bool show_local_files) { //printf("file_in_list(%s,...)\n", name); char * return_name; #if defined(VMS) || defined(MSDOS) // BUG -- Cannot search list yet return_name = new char[1 + strlen(name)]; if (!return_name) OUT_OF_MEMORY; strcpy(return_name, name); return return_name; #else // Obey absolute filenames if (*name == '/') { return_name = new char[1 + strlen(name)]; if (!return_name) OUT_OF_MEMORY; strcpy(return_name, name); return return_name; } else { // Filename from list char* tmp = egetenv("GRIINPUTS"); if (!tmp || !strlen(tmp)) tmp = GRIINPUTS; char* griinputs = new char[1 + strlen(tmp)]; if (!griinputs) OUT_OF_MEMORY; char* to_free = griinputs; strcpy(griinputs, tmp); return_name = new char[2 + strlen(griinputs) + strlen(name)]; if (!return_name) OUT_OF_MEMORY; griinputs = strtok(griinputs, ":"); do { FILE *fp; sprintf(return_name, "%s/%s", griinputs, name); if ((fp = fopen(return_name, "r"))) { if ((return_name[0] == '.' && show_local_files) || (return_name[0] != '.' && show_nonlocal_files)) { if (!batch()) { ShowStr("Will use commandfile `"); ShowStr(return_name); ShowStr("'\n"); } } fclose(fp); delete [] to_free; return return_name; } } while ((griinputs = (char *) strtok(NULL, ":"))); // Could not find commandfile. ShowStr("FATAL ERROR: could not locate the commandfile named\n "); ShowStr(name); ShowStr("\n in the current directory, nor in any directory"); ShowStr("\n specified in the colon-separated directory list\n "); ShowStr(tmp); ShowStr("\n (To change this directory list, you may modify the"); ShowStr("\n GRIINPUTS environment variable.)\n"); extern FILE *_grPS; fclose(_grPS); #ifdef VMS char tmp[1024]; sprintf(tmp, "DEL %s;*", gr_currentPSfilename()); call_the_OS(tmp, __FILE__, __LINE__); #else sprintf(tmp, "rm -f %s", gr_currentPSfilename()); call_the_OS(tmp, __FILE__, __LINE__); #endif gri_exit(1); return NULL; // never done, actually } #endif } #endif static void // save extra words get_input_simulation(int argc_leftover, const char *argv_leftover[]) { if (argc_leftover < 1) return; extern std::vector _gri_argv; for (int i = 0; i < argc_leftover; i++) { //printf("\t push %d <%s>\n",i,argv_leftover[i]); #if 0 // 2001-feb-23 vsn 2.6.0 (alpha) gr_textsave(argv_leftover[i]); #endif _gri_argv.push_back(argv_leftover[i]); } } static void set_defaults() { extern char _xtype_map, _ytype_map; _contourFmt.assign(CONTOUR_FMT_DEFAULT); _current_directory.assign("."); // Set up various other defaults _xFmt.assign(X_FMT_DEFAULT); _yFmt.assign(Y_FMT_DEFAULT); _colU.setName("u"); _colV.setName("v"); _colX.setName("x"); _colY.setName("y"); _colZ.setName("z"); _colWEIGHT.setName("weight"); _prompt.assign("gri: "); PUT_VAR("..arrowsize..", ARROWSIZE_DEFAULT); PUT_VAR("..exit_status..", 0.0); _axesStyle = 0; _braceLevel = 0; _gri_beep = false; _chatty = 1; // Fonts PUT_VAR("..fontsize..", FONTSIZE_PT_DEFAULT); gr_setfontsize_pt(FONTSIZE_PT_DEFAULT); gr_setfont(FONT_DEFAULT); _clipData = 0; _columns_exist = false; _done = 0; _drawingstarted = false; _error_in_cmd = false; _exit_value = 0; PUT_VAR("..graylevel..", 0.0); _ignore_eof = false; _ignore_error = false; _dash.erase(_dash.begin(), _dash.end()); // go to solid PUT_VAR("..linewidth..", LINEWIDTH_DEFAULT); PUT_VAR("..linewidthaxis..", LINEWIDTHAXIS_DEFAULT); PUT_VAR("..linewidthsymbol..", LINEWIDTHSYMBOL_DEFAULT); _grid_exists = false; _xgrid_exists = false; _ygrid_exists = false; // gr_set_missing_value(MISSING_VALUE); PUT_VAR("..missingvalue..", gr_currentmissingvalue()); { char tmp[100]; sprintf(tmp, "%f", gr_currentmissingvalue()); put_syn("\\.missingvalue.", tmp, true); } _f_min = _f_max = gr_currentmissingvalue(); // BUG: what if not using missing values? #if 1 // version > 2.12.7 gr_set_missing_value_none(); #endif _need_x_axis = true; _need_y_axis = true; _num_xmatrix_data = 0; _num_ymatrix_data = 0; PUT_VAR("..symbolsize..", SYMBOLSIZE_DEFAULT); _top_of_plot = 0.0; _uscale_exists = false; _vscale_exists = false; _xatbottom = true; PUT_VAR("..xmargin..", XMARGIN_DEFAULT); _xscale_exists = false; _xsubdiv = 1; _xtype = gr_axis_LINEAR; _xtype_map = ' '; PUT_VAR("..xsize..", XSIZE_DEFAULT); PUT_VAR("..xleft..", 0.0); PUT_VAR("..xright..", XSIZE_DEFAULT); PUT_VAR("..xinc..", XSIZE_DEFAULT); PUT_VAR("..xlabelling..", 0.0); _yatleft = true; PUT_VAR("..ymargin..", YMARGIN_DEFAULT); PUT_VAR("..ysize..", YSIZE_DEFAULT); PUT_VAR("..ybottom..", 0.0); PUT_VAR("..ytop..", YSIZE_DEFAULT); PUT_VAR("..yinc..", YSIZE_DEFAULT); PUT_VAR("..ylabelling..", 0.0); _yscale_exists = false; _ysubdiv = 1; _ytype = gr_axis_LINEAR; _ytype_map = ' '; } static void create_builtin_synonyms() { extern char _gri_number[]; char * user; char * os; char * wd; char * home; // Use this for return codes if (!put_syn("\\.return_value.", "", true)) OUT_OF_MEMORY; // \.version. (version number) if (!put_syn("\\.version.", _gri_number, true)) OUT_OF_MEMORY; // \.pid. (process ID) sprintf(_grTempString, "%d", int(getpid())); if (!put_syn("\\.pid.", _grTempString, true)) OUT_OF_MEMORY; // \.wd. (working directory) wd = pwd(); if (!put_syn("\\.wd.", wd, true)) OUT_OF_MEMORY; // \.time. (time) SECOND_TYPE sec; time(&sec); strcpy(_grTempString, asctime(localtime(&sec))); _grTempString[-1 + strlen(_grTempString)] = '\0'; // trim newline if (!put_syn("\\.time.", _grTempString, true)) OUT_OF_MEMORY; // \.user. (user name) user = egetenv("USER"); if (user) { if (!put_syn("\\.user.", user, true)) OUT_OF_MEMORY; } else { if (!put_syn("\\.user.", "unknown", true)) OUT_OF_MEMORY; } // \.host. (host computer name) #if defined(HAVE_GETHOSTNAME) char host[BUFSIZ]; if (0 == gethostname(host, BUFSIZ - 1)) { if (!put_syn("\\.host.", host, true)) OUT_OF_MEMORY; } else { if (!put_syn("\\.host.", "unknown", true)) OUT_OF_MEMORY; } #else if (!put_syn("\\.host.", "unknown", true)) OUT_OF_MEMORY; #endif // \.os. (operating system) os = egetenv("SYSTEM"); if (os) { if (!put_syn("\\.system.", os, true)) OUT_OF_MEMORY; } else { if (!put_syn("\\.system.", "unknown", true)) OUT_OF_MEMORY; } // \.home. (home directory) home = egetenv("HOME"); if (home) { if (!put_syn("\\.home.", home, true)) OUT_OF_MEMORY; } else { if (!put_syn("\\.home.", "unknown", true)) OUT_OF_MEMORY; } } static void create_builtin_variables() { // create `..name..' variables PUT_VAR("..num_col_data..", _colX.size()); PUT_VAR("..num_col_data_missing..", 0); PUT_VAR("..arrowsize..", ARROWSIZE_DEFAULT); PUT_VAR("..batch..", 0.0); _debugFlag = 0; PUT_VAR("..debug..", 0.0); PUT_VAR("..fontsize..", FONTSIZE_PT_DEFAULT); PUT_VAR("..graylevel..", 0.0); _dash.erase(_dash.begin(), _dash.end()); // go to solid PUT_VAR("..linewidth..", LINEWIDTH_DEFAULT); PUT_VAR("..linewidthaxis..", LINEWIDTHAXIS_DEFAULT); PUT_VAR("..linewidthsymbol..", LINEWIDTHSYMBOL_DEFAULT); PUT_VAR("..missingvalue..", gr_currentmissingvalue()); { char tmp[100]; sprintf(tmp, "%f", gr_currentmissingvalue()); put_syn("\\.missingvalue.", tmp, true); } PUT_VAR("..symbolsize..", SYMBOLSIZE_DEFAULT); PUT_VAR("..superuser..", 0.0); PUT_VAR("..trace..", 0.0); PUT_VAR("..tic_direction..", 0.0); // out PUT_VAR("..tic_size..", TICSIZE_DEFAULT); PUT_VAR("..xmargin..", XMARGIN_DEFAULT); PUT_VAR("..xsize..", XSIZE_DEFAULT); PUT_VAR("..ymargin..", YMARGIN_DEFAULT); PUT_VAR("..ysize..", YSIZE_DEFAULT); PUT_VAR("..red..", 0.0); PUT_VAR("..blue..", 0.0); PUT_VAR("..green..", 0.0); } #if defined(HAVE_LIBPOPT) && defined(TEST_POPT) const char** interpret_optional_arguments(int argc, char *argv[]) { #define FLAG_DIRECTORY 1000 #define FLAG_DIRECTORY_DEFAULT 1001 #define FLAG_CREATOR 1002 #define FLAG_NO_BOUNDING_BOX 1003 #define FLAG_NO_CMD_IN_PS 1004 #define FLAG_NO_EXPECTING 1005 #define FLAG_NO_STARTUP_MESSAGE 1006 #define FLAG_NO_WARN_OFFPAGE 1007 #define FLAG_OUTPUT 1008 #define FLAG_PUBLICATION 1009 #define FLAG_SUPERUSER 1010 #define FLAG_WARN_OFFPAGE 1011 // I use the 'FLAG_...' numbers for options that lack single-character abbreviations. static struct poptOption optionsTable[] = { { "batch", 'b', POPT_ARG_NONE | POPT_ARGFLAG_ONEDASH, NULL, 'b' }, { "chatty", 'c', POPT_ARG_INT | POPT_ARGFLAG_ONEDASH, NULL, 'c' }, { "creator", '\0', POPT_ARG_STRING | POPT_ARGFLAG_ONEDASH, NULL, FLAG_CREATOR }, { "debug", 'd', POPT_ARG_NONE | POPT_ARGFLAG_ONEDASH, NULL, 'd' }, { "directory", '\0', POPT_ARG_STRING | POPT_ARGFLAG_ONEDASH, NULL, FLAG_DIRECTORY }, { "directory_default", '\0', POPT_ARG_NONE | POPT_ARGFLAG_ONEDASH, NULL, FLAG_DIRECTORY_DEFAULT}, { "help", 'h', POPT_ARG_NONE | POPT_ARGFLAG_ONEDASH, NULL, 'h' }, { "output", '\0', POPT_ARG_STRING | POPT_ARGFLAG_ONEDASH, NULL, FLAG_OUTPUT }, { "no_bounding_box", '\0', POPT_ARG_NONE | POPT_ARGFLAG_ONEDASH, NULL, FLAG_NO_BOUNDING_BOX }, { "no_cmd_in_ps", '\0', POPT_ARG_NONE | POPT_ARGFLAG_ONEDASH, NULL, FLAG_NO_CMD_IN_PS }, { "no_startup_message",'\0', POPT_ARG_NONE | POPT_ARGFLAG_ONEDASH, NULL, FLAG_NO_STARTUP_MESSAGE}, { "no_warn_offpage", '\0', POPT_ARG_NONE | POPT_ARGFLAG_ONEDASH, NULL, FLAG_NO_WARN_OFFPAGE }, { "private", '\0', POPT_ARG_NONE | POPT_ARGFLAG_ONEDASH, NULL, FLAG_PRIVATE }, { "no_private", '\0', POPT_ARG_NONE | POPT_ARGFLAG_ONEDASH, NULL, FLAG_NO_PRIVATE }, { "publication", '\0', POPT_ARG_NONE | POPT_ARGFLAG_ONEDASH, NULL, FLAG_PUBLICATION }, { "superuser", '\0', POPT_ARG_STRING | POPT_ARGFLAG_ONEDASH, NULL, FLAG_SUPERUSER }, { "trace", 't', POPT_ARG_NONE | POPT_ARGFLAG_ONEDASH, NULL, 't' }, { "version", 'v', POPT_ARG_NONE | POPT_ARGFLAG_ONEDASH, NULL, 'v' }, { "warn_offpage", '\0', POPT_ARG_NONE | POPT_ARGFLAG_ONEDASH, NULL, FLAG_WARN_OFFPAGE }, { "yes", 'y', POPT_ARG_NONE | POPT_ARGFLAG_ONEDASH, NULL, 'y' }, { 0, 0, 0, 0, 0 } }; const poptContext optCon = poptGetContext("gri", argc, #if !defined(HAVE_OLD_POPT) (const char**) #endif argv, optionsTable, 0); poptReadDefaultConfig(optCon, 0); // for aliasing ... this seems broken though int arg; extern char _gri_number[]; #ifndef OSX_BUNDLE _lib_directory.assign(DEFAULT_GRI_DIR); #endif #ifdef OSX_BUNDLE printf("%s:%d _lib_directory is '%s'\n",__FILE__,__LINE__,_lib_directory.c_str()); #endif while ((arg = poptGetNextOpt(optCon)) > 0) { const char *optArg = poptGetOptArg(optCon); int ival; switch (arg) { case 'b': PUT_VAR("..batch..", 1.0); //printf("DEBUG: %s:%d set to 'batch' mode\n",__FILE__,__LINE__); break; case 'c': //printf("DEBUG: %s:%d <%s>\n",__FILE__,__LINE__,optArg); if (1 == sscanf(optArg, "%d", &ival)) _chatty = ival; else _chatty = 1; //printf("DEBUG: %s:%d set to 'chatty' level %d\n",__FILE__,__LINE__, _chatty); break; case 'd': //printf("DEBUG: %s:%d set to 'debug' mode\n",__FILE__,__LINE__); PUT_VAR("..debug..", 1); _debugFlag = 1; break; case 'h': give_help(); //printf("DEBUG: %s:%d set the 'help' flag\n",__FILE__,__LINE__); gri_exit(0); break; // never executed case 't': //printf("DEBUG: %s:%d set the 'trace' flag\n",__FILE__,__LINE__); PUT_VAR("..trace..", 1.0); break; case 'v': gr_textput("gri version "); gr_textput(_gri_number); gr_textput("\n"); gri_exit(0); break; // never done case 'y': _use_default_for_query = true; PUT_VAR("..use_default_for_query..", 1.0); break; case FLAG_DIRECTORY: user_gave_directory = true; _lib_directory.assign(optArg); //printf("DEBUG: %s:%d got directory as '%s'\n",__FILE__,__LINE__,optArg); break; case FLAG_DIRECTORY_DEFAULT: gr_textput(_lib_directory.c_str()); gr_textput("\n"); gri_exit(0); break; // never done case FLAG_OUTPUT: { std::string o(optArg); std::string::size_type suffix_index = o.rfind("."); if (suffix_index != STRING_NPOS) { if (strEQ(o.c_str() + suffix_index, ".ps")) { psname.assign(optArg); gr_setup_ps_filename(psname.c_str()); } else if (strEQ(o.c_str() + suffix_index, ".eps")) { psname.assign(optArg); gr_setup_ps_filename(psname.c_str()); } else if (strEQ(o.c_str() + suffix_index, ".gif")) { fprintf(stderr, "%s:%d: GIF output does not work yet\n", __FILE__,__LINE__); _output_file_type = gif; } else if (strEQ(o.c_str() + suffix_index, ".svg")) { extern FILE *_grSVG; fprintf(stderr, "%s:%d: SVG output to file '%s' does not work yet\n", __FILE__,__LINE__, o.c_str()); _output_file_type = svg; psname.assign(optArg); gr_setup_ps_filename(o.c_str()); _grSVG = fopen(o.c_str(), "w"); if (!_grSVG) { fatal_err("Cannot open SVG file named `\\", o.c_str(), "'", "\\"); } fprintf(_grSVG, "\n\n"); //fprintf(stderr, "%s:%d: SVG error: assuming height and width both 500 pixels, for now\n", __FILE__,__LINE__); extern rectangle _page_size; _page_size.set(0.0, 0.0, 8.5, 11.0); // BUG: SVG setting fixed paper size _page_size.scale(CM_PER_IN); fprintf(_grSVG, "\n", int(8.5*PT_PER_IN), int(11.0*PT_PER_IN)); } else { warning("Sorry, cannot determine type of output file; using default postscript filename instead"); } } else { // Assume to be (an odd) ps name psname.assign(optArg); gr_setup_ps_filename(psname.c_str()); } } break; case FLAG_WARN_OFFPAGE: _warn_offpage = true; break; case FLAG_NO_BOUNDING_BOX: { extern bool _no_bounding_box; _no_bounding_box = true; } break; case FLAG_NO_CMD_IN_PS: _store_cmds_in_ps = false; // <-> read.c break; case FLAG_NO_STARTUP_MESSAGE: _no_startup_message = true; break; case FLAG_NO_WARN_OFFPAGE: _warn_offpage = false; break; case FLAG_PRIVATE: _private = true; break; case FLAG_NO_PRIVATE: _private = false; break; case FLAG_PUBLICATION: PUT_VAR("..publication..", 1.0); break; case FLAG_CREATOR: { FILE *fp; if (NULL == (fp = fopen(optArg, "r"))) fatal_err("`gri -creator' cannot open file `\\", optArg, "'", "\\"); GriString inLine(128); // Start short while (!inLine.line_from_FILE(fp)) { if (!strncmp(inLine.getValue(), "%gri:", 5)) { ShowStr(inLine.getValue() + 5); } } } gri_exit(0); break; // never executed case FLAG_SUPERUSER: if ('?' == *optArg) { superuser_flag *sf = sflag; printf("Superuser flags, with actions:\n"); while (sf->action != NULL) { printf(" -superuser %d\t => %s\n", sf->code, sf->action); sf++; } gri_exit(0); } if (1 == sscanf(optArg, "%d", &ival)) { PUT_VAR("..superuser..", double(ival)); printf("got superuser as %d\n",ival); } else { PUT_VAR("..superuser..", 1.0); printf("Gri cannot read in '%s'\n",optArg); } break; default: printf("Unknown option\n"); break; } } const char *last_option = poptBadOption(optCon,arg); //printf("DEBUG %s:%d last_option = '%s' arg=%d\n",__FILE__,__LINE__,last_option,arg); if (arg <= 0 && *last_option == '-') { fprintf(stderr, "Unknown option `%s'. Type `gri -h' for valid options\n", last_option); gri_exit(1); } put_syn("\\.lib_dir.", _lib_directory.c_str(), true); return (const char**) poptGetArgs(optCon); //printf("DEBUG: %s:%d last_option [%s]\n",__FILE__,__LINE__,last_option); } #else // #if defined(HAVE_LIBPOPT) && defined(TEST_POPT) const char** interpret_optional_arguments(int argc, char *argv[]) { // BUG: REMOVE THIS (LONG) BLOCK WHEN POPT IS FINALLY WORKING! extern char _gri_number[]; int number_optional_arg = 0; #ifndef OSX_BUNDLE _lib_directory.assign(DEFAULT_GRI_DIR); #endif #ifdef OSX_BUNDLE //printf("%s:%d _lib_directory is '%s'\n",__FILE__,__LINE__,_lib_directory.c_str()); #endif // Interpret optional [-] arguments if they exist. if (argc > 1) { int i; for (i = 1; i < argc; i++) { #if 0 printf("argv[%d] = '%s'\n", i, argv[i]); #endif // `gri -creator PostScript_filename' is a special case. It now // replaces the old (unix-only) system command grilog. if (!strcmp(argv[i], "-creator")) { FILE *fp; if (i + 1 > argc - 1) fatal_err("`gri -creator' needs a filename"); if (NULL == (fp = fopen(argv[i + 1], "r"))) fatal_err("`gri -creator' cannot open file `\\", argv[2], "'", "\\"); GriString inLine(128); // Start short while (!inLine.line_from_FILE(fp)) { if (!strncmp(inLine.getValue(), "%gri:", 5)) { ShowStr(inLine.getValue() + 5); } } gri_exit(0); } // First character tells whether optional arg if (*argv[i] == '-') { int val; extern bool _no_bounding_box; if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "-version")) { gr_textput("gri version "); gr_textput(_gri_number); gr_textput("\n"); gri_exit(0); } else if (!strcmp(argv[i], "-no_bounding_box")) { _no_bounding_box = true; } else if (!strcmp(argv[i], "-no_startup_message")) { _no_startup_message = true; } else if (!strcmp(argv[i], "-no_cmd_in_ps")) { _store_cmds_in_ps = false; // <-> read.c } else if (!strcmp(argv[i], "-b") || !strcmp(argv[i], "-batch")) { PUT_VAR("..batch..", 1.0); } else if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "-debug")) { PUT_VAR("..debug..", 1); _debugFlag = 1; } else if (!strcmp(argv[i], "-warn_offpage")){ _warn_offpage = true; } else if (!strcmp(argv[i], "-nowarn_offpage")){ _warn_offpage = false; } else if (!strcmp(argv[i], "-directory")) { user_gave_directory = true; number_optional_arg++; i++; if (i < argc) _lib_directory.assign(argv[i]); else { err("`-directory' needs an argument."); gri_exit(1); } } else if (!strcmp(argv[i], "-output")) { number_optional_arg++; i++; if (i < argc) { std::string o(argv[i]); std::string::size_type suffix_index = o.rfind("."); if (suffix_index != STRING_NPOS) { if (strEQ(o.c_str() + suffix_index, ".ps")) { psname.assign(argv[i]); gr_setup_ps_filename(psname.c_str()); } else if (strEQ(o.c_str() + suffix_index, ".eps")) { psname.assign(argv[i]); gr_setup_ps_filename(psname.c_str()); } else if (strEQ(o.c_str() + suffix_index, ".gif")) { fprintf(stderr, "%s:%d: GIF output does not work yet\n", __FILE__,__LINE__); _output_file_type = gif; } else if (strEQ(o.c_str() + suffix_index, ".svg")) { extern FILE *_grSVG; _output_file_type = svg; _grSVG = fopen(o.c_str(), "w"); if (!_grSVG) { fatal_err("Cannot open SVG file named `\\", o.c_str(), "'", "\\"); } psname.assign(o.c_str()); gr_setup_ps_filename(o.c_str()); fprintf(_grSVG, "\n\n"); //fprintf(stderr, "%s:%d: SVG error: assuming height and width both 500 pixels, for now\n", __FILE__,__LINE__); extern rectangle _page_size; _page_size.set(0.0, 0.0, 8.5, 11.0); // BUG: SVG setting fixed paper size _page_size.scale(CM_PER_IN); fprintf(_grSVG, "\n", int(8.5*PT_PER_IN), int(11.0*PT_PER_IN)); } else { warning("Sorry, cannot determine type of output file; using default postscript filename instead"); } } else { // Assume to be (an odd) ps name psname.assign(argv[i]); gr_setup_ps_filename(psname.c_str()); } } else { err("`gri ... -output FILENAME' needs the FILENAME!"); gri_exit(1); } } else if (!strcmp(argv[i], "-directory_default")) { gr_textput(_lib_directory.c_str()); gr_textput("\n"); gri_exit(0); } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "-help")) { give_help(); gri_exit(0); } else if (!strcmp(argv[i], "-private")) { _private = true; } else if (!strcmp(argv[i], "-no_private")) { _private = false; } else if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "-publication")) { PUT_VAR("..publication..", 1.0); } else if (!strncmp(argv[i], "-c", 2)) { if (1 == sscanf(argv[i], "-c%d", &val)) { _chatty = val; } else if (1 == sscanf(argv[i + 1], "%d", &val)) { _chatty = val; number_optional_arg++; i++; } else { _chatty = 1; } } else if (!strcmp(argv[i], "-chatty")) { if (1 == sscanf(argv[i], "-chatty%d", &val)) { _chatty = val; } else if (1 == sscanf(argv[i + 1], "%d", &val)) { _chatty = val; number_optional_arg++; i++; } else { _chatty = 1; } } else if (!strcmp(argv[i], "-no_expecting")) { warning("Gri no longer demands to find an `expecting' command, so the `-no_expecting' option can be dropped."); } else if (!strncmp(argv[i], "-superuser", 10)) { if ('?' == *(argv[i] + 10)) { superuser_flag *sf = sflag; printf("Superuser flags:\n"); while (sf->action != NULL) { printf("-superuser%d -- %s\n", sf->code, sf->action); sf++; } gri_exit(0); } if (1 == sscanf(argv[i], "-superuser%d", &val)) { PUT_VAR("..superuser..", ((double) val)); } else { PUT_VAR("..superuser..", ((double) 1.0)); } } else if (!strcmp(argv[i], "-t") || !strcmp(argv[i], "-trace")) { PUT_VAR("..trace..", 1.0); } else if (!strcmp(argv[i], "-y") || !strcmp(argv[i], "-yes")) { _use_default_for_query = true; PUT_VAR("..use_default_for_query..", 1.0); #if 0 } else if (!strcmp(argv[i], "-e")) { // User wants to do cmd in argv[i+1] if (argc < i + 2) fatal_err("\n The -e switch needs a command to do."); printf("SHOULD BE EXECUTING `%s'\n", argv[i + 1]); i++; number_optional_arg++; #endif } else { fatal_err("unknown commandline flag `\\", argv[i], "'.\n Type 'gri -help' to see how to run Gri.", "\\"); } number_optional_arg++; } else { //printf("%s:%d DEBUG last option was argv[%d] = '%s'\n",__FILE__,__LINE__,i,argv[i]); break; } } } return (const char**)(&argv[1 + number_optional_arg]); } #endif // #if defined(HAVE_LIBPOPT) && defined(TEST_POPT) void give_help() { gr_textput("NAME\n"); gr_textput(" gri - draw scientific graphs\n"); gr_textput("\n"); gr_textput("SYNOPSIS\n"); gr_textput(" gri [OPTIONS] [command_file [optional_arguments]]\n"); gr_textput("\n"); gr_textput("DESCRIPTION\n"); gr_textput(" If a command file (command_file) is named, commands are read from that file;\n"); gr_textput(" otherwise they are read from the keyboard. If a command_file is named, then\n"); gr_textput(" a file in which to store the PostScript output may also be named; otherwise\n"); gr_textput(" it is stored in a file named gr-00.ps (or gr-01.ps if gr-00.ps exists, etc).\n"); gr_textput("\n"); gr_textput(" There are 3 special forms that do no graphing:\n"); gr_textput(" `gri -creator postscript_file'\n"); gr_textput(" Extracts the Gri commands that created the Gri PostScript file,\n"); gr_textput(" but only if the Gri invocation that created the PostScript file\n"); gr_textput(" had used the -no_private commandline option, or if the version of\n"); gr_textput(" Gri that produced the file was earlier than 2.12.10.\n"); gr_textput(" `gri -help' or `gri -h'\n"); gr_textput(" Prints this help message.\n"); gr_textput(" `gri -version' or `gri -v'\n"); gr_textput(" Prints the version number of Gri.\n"); gr_textput("\n"); gr_textput(" In normal usage, where drawing is expected, Gri takes these options:\n"); gr_textput(" -batch or -b\n"); gr_textput(" Stops printing of prompts and hints.\n"); gr_textput(" -chatty[N] or -c[N]\n"); gr_textput(" Let gri print info messages\n"); gr_textput(" -debug or -d\n"); gr_textput(" Turns debugging on (sets variable ..debug.. to value 1).\n"); gr_textput(" -warn_offpage\n"); gr_textput(" Warn if any item is drawn far off a 8.5x11\" page.\n"); gr_textput(" (This is the default.)\n"); gr_textput(" -no_warn_offpage\n"); gr_textput(" Don't warn if any item is drawn far off a 8.5x11\" page\n"); gr_textput(" -directory pathname\n"); gr_textput(" Specifies the directory where Gri looks for startup files;\n"); gr_textput(" otherwise it looks in /opt/gri/lib or at whatever\n"); gr_textput(" directory is defined in configure shellscript, at compile time.\n"); gr_textput(" -directory_default\n"); gr_textput(" Reports directory where gri.cmd should be found,\n"); gr_textput(" if not supplied by -directory.\n"); gr_textput(" -no_bounding_box\n"); gr_textput(" Make bounding-box be full page.\n"); gr_textput(" -no_expecting\n"); gr_textput(" Prevent warning message if `expecting version .n.'\n"); gr_textput(" command is missing.\n"); gr_textput(" -no_startup_message\n"); gr_textput(" Stops printing of startup message.\n"); gr_textput(" -output file_name\n"); gr_textput(" Specify the name of the file to hold the graphical output. If\n"); gr_textput(" this flag is not specified, the file will be PostScript,\n"); gr_textput(" and its name will be derived from the name of the\n"); gr_textput(" commandfile, e.g. `mygraph.gri'\n"); gr_textput(" will produce `mygraph.ps'), or, for interactive use,\n"); gr_textput(" it will have a name like `gri-00.ps', or\n"); gr_textput(" `gri-01.ps' if the former file exists, etc.\n"); gr_textput(" -private\n"); gr_textput(" Prevents inserting any information about the user into\n"); gr_textput(" the PostScript file (see -no_private, next). As of\n"); gr_textput(" version 2.12.10, this privacy option is assumed by default.\n"); gr_textput(" -no_private\n"); gr_textput(" Instructs Gri to include comments in the PostScript file that\n"); gr_textput(" identify the user, state the commandline arguments used in\n"); gr_textput(" invoking Gri, and that list all the commands that were executed.\n"); gr_textput(" This information can be recovered by calling Gri on the\n"); gr_textput(" PostScript file, with the -creator commandline argument.\n"); gr_textput(" Until version 2.12.10, the default was to include this \n"); gr_textput(" information, but a change was made out of privacy concerns.\n"); gr_textput(" -publication or -p\n"); gr_textput(" Sets the builtin variable ..publication.. to 1; normally it is 0.\n"); gr_textput(" One might use if statements (`if !..publication..' ...) on drafts.\n"); gr_textput(" -superuser\n"); gr_textput(" Used mainly by Gri programmers (who can check the value with the\n"); gr_textput(" C function `superuser()'.) An optional value can be supplied\n"); gr_textput(" without spaces (e.g. `-s2') to set the debugging level.\n"); gr_textput(" The flags are as follows:\n"); gr_textput(" 1: print cmdline before/after substituting synonyms\n"); gr_textput(" 2: print cmdline before/after substituting rpn expressions\n"); gr_textput(" 4: print new commands being defined\n"); gr_textput(" 8: print system commands and `open \"... | \"'\n"); gr_textput(" commands before they are passed to the system\n"); gr_textput(" 128: for author's use only\n"); gr_textput(" 256: for author's use only\n"); gr_textput(" Note that all flags are equal to 2 raised to an\n"); gr_textput(" integer power. Since the flag values are detected by\n"); gr_textput(" a bitwise OR, you can combine flags by adding; thus\n"); gr_textput(" specifying a flag of 5 yields flags 1 and 4 together; specifying\n"); gr_textput(" 15 yields flags 1, 2, 4 and 8.\n"); gr_textput(" -trace or -t\n"); gr_textput(" Makes Gri print out command lines as they are executed.\n"); gr_textput(" -true or -y\n"); gr_textput(" Makes Gri think the answer to all `query's is RETURN.\n"); #if 0 gr_textput(" -e cmd\n"); gr_textput(" BUG: NOT IMPLEMENTED YET!\n"); gr_textput(" Makes Gri perform indicated command after\n"); gr_textput(" doing any commands in the ~/.grirc file.\n"); #endif } // Insert Creator info in PS file static void insert_creator_name_in_PS(int argc, char *argv[], const std::string& psname) { extern char _gri_release_time[]; extern char _gri_number[]; // see version.c gr_setup_creatorname("Gri"); gr_setup_creatorname(_gri_number); gr_setup_creatorname(" (released "); gr_setup_creatorname(_gri_release_time); if (_private) gr_setup_creatorname(")"); else gr_setup_creatorname("). User="); if (egetenv("USER")) gr_setup_creatorname(egetenv("USER")); #if 0 // SF bug 711354 if (argc > 1 + last_optional_arg) { // Commandfile name was supplied on cmdline. Require2(put_syn("\\.command_file.", filename_sans_dir(argv[last_optional_arg + 1]), true), OUT_OF_MEMORY); Require2(put_syn("\\.readfrom_file.", filename_sans_dir(argv[last_optional_arg + 1]), true), OUT_OF_MEMORY); gr_setup_creatorname(", commandfile="); printf("argc=%d last_optional_arg=%d [%s] [%s]\n",argc,last_optional_arg,argv[last_optional_arg],argv[last_optional_arg+1]); gr_setup_creatorname(argv[last_optional_arg + 1]); Require2(put_syn("\\.ps_file.", psname.c_str(), true), OUT_OF_MEMORY); } else { // No commandfile supplied on cmdline. Require2(put_syn("\\.command_file.", "stdin", true), OUT_OF_MEMORY); Require2(put_syn("\\.readfrom_file.", "stdin", true), OUT_OF_MEMORY); } #endif } static void dogrirc() { char grircname[100]; _done = 0; _margin.assign("| "); #if defined(HAVE_GETENV) char *home = egetenv("HOME"); if (!home) { warning("Cannot getenv(HOME), so cannot perform grirc file"); return; } sprintf(grircname, "%s/%s", home, GRIRC_FILE); #else strcpy(grircname, GRIRC_FILE); #endif if (push_cmd_file(grircname, false, false, "r")) { gr_comment("gri:#\n"); gr_comment("gri:# The user's ~/.grirc file ...\n"); while (do_command_line()){ ; } _done = 0; gr_comment("gri:# ... end of users ~/.grirc file.\n"); gr_comment("gri:\n"); } } #if 0 static void show_startup_msg() { std::string fullfilename(_lib_directory.c_str()); // Must check for '/' as file separator, on some machines. #if !defined(VMS) #if defined(MSDOS) // Insert a '\' if required if (fullfilename[fullfilename.length() - 1] != '\\') { fullfilename += "\\"; } #else // Insert a '/' if required if (fullfilename[fullfilename.length() - 1] != '/') { fullfilename += "/"; } #endif #endif fullfilename += "startup.msg"; FILE *fp = fopen(fullfilename.c_str(), "r"); if (fp) { GriString inLine(128); while (!inLine.line_from_FILE(fp)) { ShowStr(inLine.getValue()); } fclose(fp); } } #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/gri.cc��������������������������������������������������������������������������������������0000644�0001750�0001750�00000014240�13147557614�011700� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include "gr.hh" #include "defaults.hh" #include "private.hh" #include "types.hh" #include "gr_coll.hh" #include "GMatrix.hh" #include "GriState.hh" #include "Synonym.hh" #include "Variable.hh" using namespace std; // needed for g++-3 char source_indicator[256]; // BUG: length not checked // Globals from gr. extern char _grTempString[]; /* String available to all code. */ /* * The following globals have symbolic names associated with * them, and MUST be updated whenever these names are assigned to. See * the note in put_var() in variable.c. The reason for the parallel C * storage is that the following are accessed for every data point * plotted. Certain other symbolic variables (like ..publication.. for * example) are not accessed frequently, and hence have no parallel C * storage as the following do. Thus they are safe against breakage. */ output_file_type _output_file_type; GriState _griState; // present state bool _user_set_x_axis = false; bool _user_set_y_axis = false; double _xleft; /* ..xleft.. */ double _xright; /* ..xright.. */ double _x_labelling; /* ..xlabelling.. */ bool _x_gave_labelling; double _ybottom; /* ..ybottom.. */ double _ytop; /* ..ytop.. */ double _y_labelling; /* ..ylabelling.. */ bool _y_gave_labelling; // Globals used elsewhere (variables begin with _). int _arrow_type; bool _warn_offpage; std::vector _dash; std::vector _dataFILE; std::vector _cmdFILE; std::vector _gri_argv; char _input_data_separator; // ' ' (general whitespace) or '\t' char * _cmd_being_done_IP[cmd_being_done_LEN]; int _cmd_being_done_code[cmd_being_done_LEN]; int _cmd_being_done = 0; char * _cmdLine; char * _cmdLineCOPY; std::string _contourFmt; std::string _current_directory; int _error_action = 0; // 0=message/exit(1), 1=message/dump core/exit(1) char * _errorMsg; std::string _lib_directory; std::string _margin; std::string _prompt; char *_word[MAX_nword]; char *_Words2[MAX_nword]; char *_Words3[MAX_nword]; std::string _xFmt; std::string _yFmt; double _clipxleft, _clipxright, _clipybottom, _clipytop; double _cm_per_u, _cm_per_v; double *_dstack; double _gri_eof = 0.0; double _top_of_plot; GriMatrix _f_xy; double _f_min, _f_max, *_xmatrix, *_ymatrix; double _xinc; double _yinc; double _zinc; double _axes_offset = 0.0; int _axesStyle; bool _gri_beep = false; bool _user_gave_bounding_box = false; rectangle _page_size; rectangle _bounding_box_user; rectangle _bounding_box; // in cm on page int _braceLevel = 0; int _chatty; int _clipData = 0; int _debugFlag = 0; // used in debugging int _done = 0; // 1=`quit'; 2=`return' bool _drawingstarted = false; bool _error_in_cmd; int _exit_value = 0; gr_font _font; bool _first; bool _ignore_eof = false; bool _ignore_error; GriMatrix _legit_xy; bool _need_x_axis = true; bool _need_y_axis = true; unsigned int _nword; bool _xatbottom; bool _xincreasing = true; int _xsubdiv = 1; vector _x_label_positions; vector _x_labels; gr_axis_properties _xtype; char _xtype_map = ' '; // could be "EWNS " gr_axis_properties _ytype; char _ytype_map = ' '; // could be "EWNS " bool _yatleft; bool _yincreasing = true; int _ysubdiv = 1; vector _y_labels; vector _y_label_positions; /* numbers of items existing */ int _num_command = 0; /* commands */ unsigned int _num_xmatrix_data; unsigned int _num_ymatrix_data; /* Version number */ double _version; /* this version */ double _version_expected = 0.0; /* expected version (if any) */ /* flags for whether things exist yet (set in */ bool _columns_exist; bool _grid_exists; bool _uscale_exists; bool _vscale_exists; bool _xgrid_exists; bool _xgrid_increasing; bool _xscale_exists; bool _ygrid_exists; bool _ygrid_increasing; bool _yscale_exists; bool _use_default_for_query = false; /* * Matrices */ GriColumn _colU; GriColumn _colV; GriColumn _colX; GriColumn _colY; GriColumn _colZ; GriColumn _colWEIGHT; // Command stack #define COMMAND_STACK_SIZE 1000 typedef struct { char *syntax; // The 'name' of command char *help; // Help, if any char *procedure; // Commands to do char *filename; // Where defined int fileline; // Where defined } GRI_COMMAND; GRI_COMMAND _command[COMMAND_STACK_SIZE]; int _function_indent = 4; int gri_main(int argc, char **argv) { start_up(argc, argv); do { do_command_line(); } while (!_done); warning("\\\\"); // notify of pending repeated warnings end_up(); return _exit_value; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/superus.hh����������������������������������������������������������������������������������0000644�0001750�0001750�00000002753�13147557614�012645� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * Define flags for superuser * * To get combination flags, simply add them; thus a flag of 5 gives * flags 1 and 4 together. * * NOTE: for flag meanings, see startup.cc, where strings are defined; * just search for e.g. FLAG_SYN in that file. */ #define FLAG_SYN 0x0001 // 1 print cmdline before/after sub synonyms #define FLAG_RPN 0x0002 // 2 print cmdline before/after sub rpn #define FLAG_NEW 0x0004 // 4 print new commands being defined #define FLAG_SYS 0x0008 // 8 print system commands before passing #define FLAG_FLOW 0x0010 // 16 indicate program flow #define FLAG_AUT2 0x0080 // 128 flag for author's use #define FLAG_AUT1 0x0100 // 256 flag for author's use ���������������������gri/src/unlink.cc�����������������������������������������������������������������������������������0000644�0001750�0001750�00000002106�13147557614�012415� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include "extern.hh" // 'unlink \filename' bool unlinkCmd() { if (_nword != 2) { NUMBER_WORDS_ERROR; demonstrate_command_usage(); return false; } std::string filename(_word[1]); un_double_quote(filename); return delete_file(filename.c_str()); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/write.cc������������������������������������������������������������������������������������0000644�0001750�0001750�00000031050�13147557614�012247� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include "private.hh" #include "extern.hh" #include "image_ex.hh" #include "gr.hh" extern char _grTempString[]; bool writeCmd(void); bool write_columnsCmd(const char *filename); bool write_contourCmd(const char *filename); bool write_gridCmd(const char *filename); bool write_imageCmd(const char *filename, int image_type); bool write_image_maskCmd(const char *filename, int image_type); bool write_image_colorscaleCmd(const char *filename); bool write_image_grayscaleCmd(const char *filename); // image types #define IMAGE_RAW 0 // no header #define IMAGE_RASTER 1 // sun rasterfile header #define IMAGE_PGM 2 // pgm 'rawbits' header // `write contour .value. to \filename' bool write_contourCmd(const char *filename) { double dlevel; FILE *fp; // Decode command if (_nword == 5) { if (!getdnum(_word[2], &dlevel)) return false; } else { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } std::string fname(filename); un_double_quote(fname); if (!strcmp(fname.c_str(), "stdout")) fp = stdout; else if (!strcmp(fname.c_str(), "stderr")) fp = stderr; else if (NULL == (fp = fopen(fname.c_str(), "a+"))) { err("Sorry, `write columns \\file' can't open file named in next line"); err(fname.c_str()); return false; } // Check that data exist if (!grid_exists()) return false; if (!scales_defined()) { no_scales_error(); return false; } // Do contour(s) set_environment(); gr_contour(_xmatrix, _ymatrix, _f_xy, _legit_xy, _num_xmatrix_data, _num_ymatrix_data, dlevel, NULL, false, false, false, _griState.color_line(), _griState.color_text(), 0.0, 0.0, 0.0, fp); _drawingstarted = true; draw_axes_if_needed(); fclose(fp); return true; } bool write_image_header(IMAGE im, FILE * fp) { fwrite((char *) & im.ras_magic, sizeof(int), 1, fp); fwrite((char *) & im.ras_width, sizeof(int), 1, fp); fwrite((char *) & im.ras_height, sizeof(int), 1, fp); fwrite((char *) & im.ras_depth, sizeof(int), 1, fp); fwrite((char *) & im.ras_length, sizeof(int), 1, fp); fwrite((char *) & im.ras_type, sizeof(int), 1, fp); fwrite((char *) & im.ras_maptype, sizeof(int), 1, fp); fwrite((char *) & im.ras_maplength, sizeof(int), 1, fp); return true; } // ?? BUG -- should check for "to" in words bool writeCmd() { int image_type = IMAGE_RAW; char * filename; if (_nword < 4) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } filename = _word[_nword - 1]; if (word_is(1, "image")) { if (word_is(2, "rasterfile")) return write_imageCmd(filename, 1); else if (word_is(2, "pgm")) return write_imageCmd(filename, 2); else if (word_is(2, "colorscale")) return write_image_colorscaleCmd(filename); else if (word_is(2, "colourscale")) return write_image_colorscaleCmd(filename); else if (word_is(2, "grayscale")) return write_image_grayscaleCmd(filename); else if (word_is(2, "greyscale")) return write_image_grayscaleCmd(filename); else if (word_is(2, "mask")) return write_image_maskCmd(filename, image_type); else return write_imageCmd(filename, image_type); } else if (!strcmp(_word[1], "columns")) { write_columnsCmd(_word[_nword - 1]); } else if (!strcmp(_word[1], "contour")) { write_contourCmd(_word[_nword - 1]); } else if (!strcmp(_word[1], "grid")) { write_gridCmd(_word[_nword - 1]); } else { demonstrate_command_usage(); err("Can't understand command."); return false; } return true; } bool write_gridCmd(const char *filename) { bool bycolumns = false; FILE *fp; double missing_value = gr_currentmissingvalue(); if (!grid_exists()) { err("No grid yet"); return false; } // Special case std::string fname; unsigned int i, j; switch (_nword) { case 4: // `write grid to filename' fname.assign(filename); un_double_quote(fname); if (!strcmp(fname.c_str(), "stdout")) fp = stdout; else if (!strcmp(fname.c_str(), "stderr")) fp = stderr; else if (NULL == (fp = fopen(fname.c_str(), "a+"))) { err("Sorry, `write grid to \\file' can't open the file named in next line"); err(fname.c_str()); return false; } break; case 5: // `write grid to filename bycolumns' if (word_is(4, "bycolumns")) { fname.assign(_word[_nword - 2]); un_double_quote(fname); bycolumns = true; if (!strcmp(fname.c_str(), "stdout")) fp = stdout; else if (!strcmp(fname.c_str(), "stderr")) fp = stderr; else if (NULL == (fp = fopen(fname.c_str(), "a+"))) { err("Sorry, `write grid to \\file' can't open the file named in next line"); err(fname.c_str()); return false; } } else { demonstrate_command_usage(); err("Fourth word must be `bycolumns'"); return false; } break; default: demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (bycolumns == true) { for (i = 0; i < _num_xmatrix_data; i++) { for (j = 0; j < _num_ymatrix_data; j++) { if (_legit_xy(i, j) == true) { fprintf(fp, "%f ", _f_xy(i, j)); } else { fprintf(fp, "%f ", missing_value); } } fprintf(fp, "\n"); } } else { j = _num_ymatrix_data - 1; do { for (i = 0; i < _num_xmatrix_data; i++) { if (_legit_xy(i, j) == true) { fprintf(fp, "%f ", _f_xy(i, j)); } else { fprintf(fp, "%f ", missing_value); } } fprintf(fp, "\n"); } while (j-- != 0); } fclose(fp); return true; } bool write_columnsCmd(const char *filename) { unsigned int num = _colX.size(); if (num < 1) { err("Can't `write columns \\file' since no columns exist yet\n"); return false; } std::string fname(filename); un_double_quote(fname); FILE *fp; if (!strcmp(fname.c_str(), "stdout")) fp = stdout; else if (!strcmp(fname.c_str(), "stderr")) fp = stderr; else if (NULL == (fp = fopen(fname.c_str(), "a+"))) { err("Sorry, `write columns \\file' can't open file named in next line"); err(fname.c_str()); return false; } // print label line fprintf(fp, "//"); if (_colX.size() > 0) fprintf(fp, "%20s\t", "x"); if (_colY.size() > 0) fprintf(fp, "%20s\t", "y"); if (_colU.size() > 0) fprintf(fp, "%15s\t", "u"); if (_colV.size() > 0) fprintf(fp, "%15s\t", "v"); if (_colZ.size() > 0) fprintf(fp, "%15s\t", "z"); fprintf(fp, "\n"); for (unsigned int i = 0; i < num; i++) { fprintf(fp, "%15g\t%15g\t", _colX[i], _colY[i]); if (_colU.size() > 0) fprintf(fp, "%15g\t", _colU[i]); if (_colV.size() > 0) fprintf(fp, "%15g\t", _colV[i]); if (_colZ.size() > 0) fprintf(fp, "%15g\t", _colZ[i]); fprintf(fp, "\n"); } fclose(fp); return true; } // write image [pgm] to filename bool write_imageCmd(const char *filename, int image_type) { unsigned char zero = 0; int ii; register int i, j; FILE *fp; if (!_image.storage_exists) { err("No image exists yet\n"); return false; } std::string fname(filename); un_double_quote(fname); if (!strcmp(fname.c_str(), "stdout")) fp = stdout; else if (!strcmp(fname.c_str(), "stderr")) fp = stderr; else if (NULL == (fp = fopen(fname.c_str(), "a+"))) { err("Sorry, `write image \\file' can't open file named in next line"); err(filename); return false; } if (_num_xmatrix_data < 1 || _num_xmatrix_data < 1) { err("First create x/y grids, e.g. `read grid x' or `set x grid', ..."); return false; } // kludge because sun wants even number of bytes / row ii = _image.ras_width; if (ii % 2) ii++; // write header (maybe) switch (image_type) { case IMAGE_RAW: break; case IMAGE_RASTER: write_image_header(_image, fp); break; case IMAGE_PGM: fprintf(fp, "P5\n%d %d\n255\n", _image.ras_width, _image.ras_height); break; } if (_imageTransform_exists) { for (j = int(_image.ras_height - 1); j >= 0; j--) { for (i = 0; i < int(_image.ras_width); i++) fwrite((char *) (_imageTransform + *(_image.image + _image.ras_height * i + j)), sizeof(unsigned char), 1, fp); if (ii != i) fwrite((char *) & zero, sizeof(unsigned char), 1, fp); } } else { for (j = int(_image.ras_height - 1); j >= 0; j--) { for (i = 0; i < int(_image.ras_width); i++) fwrite((char *) (_image.image + _image.ras_height * i + j), sizeof(unsigned char), 1, fp); if (ii != i) { fwrite((char *) & zero, sizeof(unsigned char), 1, fp); } } } fclose(fp); return true; } bool write_image_maskCmd(const char *filename, int image_type) { unsigned char zero = 0; int ii; register int i, j; FILE *fp; if (!_imageMask.storage_exists) { err("No image mask exists yet\n"); return false; } if (_num_xmatrix_data < 1 || _num_xmatrix_data < 1) { err("Sorry, `write image mask to \\file' can't figure out nx or ny"); return false; } std::string fname(filename); un_double_quote(fname); if (!strcmp(fname.c_str(), "stdout")) fp = stdout; else if (!strcmp(fname.c_str(), "stderr")) fp = stderr; else if (NULL == (fp = fopen(fname.c_str(), "a+"))) { err("Sorry, `write image mask \\file' can't open file named in next line"); err(filename); return false; } // kludge because sun wants even number of bytes / row ii = _num_xmatrix_data; if (ii % 2) ii++; // write header (maybe) switch (image_type) { case IMAGE_RAW: break; case IMAGE_RASTER: { IMAGE im; im.ras_magic = RAS_MAGIC; im.ras_width = _num_xmatrix_data; im.ras_height = _num_ymatrix_data; im.ras_depth = 8; im.ras_length = im.ras_width * im.ras_height; im.ras_type = RT_STANDARD; im.ras_maptype = RMT_NONE; im.ras_maplength = 0; im.storage_exists = true; // has no effect (just get rid of warning on ia64/debian) im.image = (unsigned char*)NULL; // has no effect (just get rid of warning on ia64/debian) im.map = (unsigned char*)NULL; // has no effect (just get rid of warning on ia64/debian) write_image_header(im, fp); } break; case IMAGE_PGM: fprintf(fp, "P5\n%d %d\n255\n", _image.ras_width, _image.ras_height); break; } for (j = int(_image.ras_height - 1); j > -1; j--) { for (i = 0; i < int(_image.ras_width); i++) fwrite((char *) (_imageMask.image + _imageMask.ras_height * i + j), sizeof(unsigned char), 1, fp); if (ii != i) fwrite((char *) & zero, sizeof(unsigned char), 1, fp); } fclose(fp); return true; } bool write_image_colorscaleCmd(const char *filename) { extern unsigned char *_imageTransform; int i; FILE *fp; if (!_imageTransform_exists) { err("First `set image grayscale'"); return false; } std::string fname(filename); un_double_quote(fname); if (!strcmp(fname.c_str(), "stdout")) fp = stdout; else if (!strcmp(fname.c_str(), "stderr")) fp = stderr; else if (NULL == (fp = fopen(fname.c_str(), "a+"))) { err("Sorry, `write image grayscale to \\file' can't open file named in next line"); err(filename); return false; } for (i = 0; i < 256; i++) fprintf(fp, "%g %g %g\n", *(_imageTransform + i) / 255.0, *(_imageTransform + i + 256) / 255.0, *(_imageTransform + i + 512) / 255.0); fclose(fp); return true; } bool write_image_grayscaleCmd(const char *filename) { extern unsigned char *_imageTransform; int i; FILE *fp; if (!_imageTransform_exists) { err("First `set image grayscale'"); return false; } std::string fname(filename); un_double_quote(fname); if (!strcmp(fname.c_str(), "stdout")) fp = stdout; else if (!strcmp(fname.c_str(), "stderr")) fp = stderr; else if (NULL == (fp = fopen(fname.c_str(), "a+"))) { err("Sorry, `write image grayscale to \\file' can't open file named in next line"); err(fname.c_str()); return false; } for (i = 0; i < 256; i++) fprintf(fp, "%g\n", *(_imageTransform + i) / 255.0); fclose(fp); return true; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/convert.cc����������������������������������������������������������������������������������0000644�0001750�0001750�00000215034�13147557614�012603� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2010 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include #include "gr.hh" #include "extern.hh" #include "image_ex.hh" #include "defaults.hh" #include "GriTimer.hh" #include "GMatrix.hh" extern char _grTempString[]; #define USE_APPROX_EXP #ifdef USE_APPROX_EXP // Compute exp(-x) approximately, as efficiency measure. // See [97/1/25] for demonstration of factor of 3 speedup, with // 1000 column data and a 10 by 10 grid, and demonstration // that error is < 0.1% in the final grid. inline double exp_approx(double x) { return 1.0 / (0.999448 + x * (1.023820 + x * (0.3613967 + x * (0.4169646 + x * (-0.1292509 + x * 0.0499565))))); } #endif #if 0 static void display_f_xy(const char *msg); #endif static bool create_grid_barnes(double xr, double yr, double gamma, unsigned int iter, const std::vector &xgood, const std::vector &ygood, const std::vector &zgood, const std::vector &wgood); static bool create_grid_barnes_cv(double xr, double yr, double gamma, unsigned int iter, const std::vector &xgood, const std::vector &ygood, const std::vector &zgood, const std::vector &wgood); static unsigned int create_grid_objectiveCmd(double xr, double yr, const std::vector &xgood, const std::vector &ygood, const std::vector &zgood); static double interpolate_barnes(double xx, double yy, double zz, int skip, unsigned int n_k, const std::vector &x, const std::vector &y, const std::vector &z, const std::vector &weight, const std::vector &z_last, double xr, double yr); static int create_grid_boxcarCmd(double xr, double yr, const std::vector &x, const std::vector &y, const std::vector &z); static int create_grid_neighborCmd(const std::vector &xgood, const std::vector &ygood, const std::vector &zgood); bool convert_col_to_gridCmd(void); bool convert_col_to_splineCmd(void); bool convert_grid_to_columnsCmd(void); bool convert_grid_to_imageCmd(void); bool convert_image_to_gridCmd(void); bool image_range_exists(void); bool locate_i_j(double xx, double yy, int *ii, int *jj); int number_good_xyz(double x[], double y[], double f[], int n); bool value_i_j(unsigned int ii, unsigned int jj, double xx, double yy, double *value); // Spline things static inline double dmin(double a, double b); int interv(double *xt, int *lxt, double *x, int *left, int *mflag); double ppvalu(double *break_, double *coef, int *l, int *k, double *x, int *jderiv); int tautsp(double *x, double *y, unsigned int n, double *gamma, double *scrtch, double *break_, double *coef, int *l, int *k, int *iflag); #if 0 static void display_f_xy(const char *msg) { printf("%s\n", msg); for (unsigned int j = _num_ymatrix_data - 1; j > -1; j--) { for (unsigned int i = 0; i < _num_xmatrix_data; i++) printf("%f ", _f_xy(i,j)); printf("\n"); } } #endif #define DEFAULT_GRID_LENGTH 20 bool create_default_xgrid() { double xmin = _colX.min(); double xmax = _colX.max(); unsigned int nx = DEFAULT_GRID_LENGTH; double xinc = (xmax - xmin) / (nx - 1); Require(allocate_xmatrix_storage(nx), err("Insufficient space for grid x data")); for (unsigned int i = 0; i < nx; i++) _xmatrix[i] = xmin + double(i) * xinc; _xgrid_exists = true; if (!_xscale_exists) create_x_scale(); if (_xmatrix[1] > _xmatrix[0]) _xgrid_increasing = true; else _xgrid_increasing = false; return true; } bool create_default_ygrid() { double ymin = _colY.min(); double ymax = _colY.max(); unsigned int ny = DEFAULT_GRID_LENGTH; double yinc = (ymax - ymin) / (ny - 1); Require(allocate_ymatrix_storage(ny), err("Insufficient space for grid y data")); for (unsigned int i = 0; i < ny; i++) _ymatrix[i] = ymin + double(i) * yinc; _ygrid_exists = true; if (!_yscale_exists) create_y_scale(); if (_ymatrix[1] > _ymatrix[0]) _ygrid_increasing = true; else _ygrid_increasing = false; return true; } #undef DEFAULT_GRID_LENGTH bool convert_col_to_gridCmd() { int found = 0; Require(_colZ.size() > 0, err("No z data exist yet. First `read columns ... z'")); Require(_colX.size() == _colY.size() && _colX.size() == _colZ.size(), err("The x, y, and z columns are of unequal lengths")); if (!_xgrid_exists) { Require(create_default_xgrid(), err("Cannot create default x grid")); } if (!_ygrid_exists) { Require(create_default_ygrid(), err("Cannot create default y grid")); } // Check for archaic usage if (word_is(4, "planar")) { err("Sorry, `convert columns to grid planar' no longer available.\nTry using the `boxcar' method, which is virtually identical"); return 0; } // Seem to have data. Now proceed, first checking to see if neighbor // method (which takes no extra params). But first dump to // vectors known to be nonmissing std::vector xgood; xgood.reserve(_colX.size()); std::vector ygood; ygood.reserve(_colX.size()); std::vector zgood; zgood.reserve(_colX.size()); std::vector wgood; wgood.reserve(_colX.size()); unsigned int num = _colX.size(); bool have_weights = (_colWEIGHT.size() == _colX.size()); for (unsigned int g = 0; g < num; g++) { if (!gr_missingx(_colX[g]) && !gr_missingy(_colY[g]) && !gr_missing(_colZ[g])) { xgood.push_back(_colX[g]); ygood.push_back(_colY[g]); zgood.push_back(_colZ[g]); if (have_weights) wgood.push_back(_colWEIGHT[g]); else wgood.push_back(1.0); } } if (!xgood.size()) return true; // no data if (word_is(4, "neighbor")) { if (_nword != 5) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return 0; } found = create_grid_neighborCmd(xgood, ygood, zgood); } else { bool use_default = _nword == 4; // Not neighbor method. Must be one of below // //`convert columns to grid' //`convert columns to grid boxcar [.xr. .yr. [.n. .e.]]' //`convert columns to grid objective [.xr. .yr. [.n. .e.]]' //`convert columns to grid barnes [.xr. .yr. .gamma. .iter.]' //`convert columns to grid barnes_cross_validate [.xr. .yr. .gamma. .iter.]' // 0 1 2 3 4 5 6 7 8 if (_chatty > 0 && !word_is(4, "barnes_cross_validate")) ShowStr("`convert columns to grid' diagnostics:\n"); if (word_is(4, "barnes") || word_is(4, "barnes_cross_validate") || word_is(4, "boxcar") || word_is(4, "objective") || use_default) { double xr = 0.0, yr = 0.0; double gamma = 0.5; // .gamma. int iter = 2; // .iter. // Figure out (xr, yr), either automatically or from cmd if (_nword >= 7) { // Get from cmdline if (!getdnum(_word[5], &xr)) { READ_WORD_ERROR(".xr."); demonstrate_command_usage(); return 0; } if (!getdnum(_word[6], &yr)) { READ_WORD_ERROR(".yr."); demonstrate_command_usage(); return 0; } } if (word_is(4, "barnes") || word_is(4, "barnes_cross_validate")) { switch(_nword) { case 5: gamma = 0.5; iter = 2; break; case 9: if (!getdnum(_word[7], &gamma)) { READ_WORD_ERROR(".gamma."); demonstrate_command_usage(); return 0; } if (gamma < 0) { warning("\ `convert columns to grid barnes' changing sign of .gamma. to be >0"); gamma = -gamma; } if (gamma > 1) { warning("\ `convert columns to grid barnes' clipping .gamma. to max value of1"); gamma = 1.0; } if (!getinum(_word[8], &iter)) { READ_WORD_ERROR(".iter."); demonstrate_command_usage(); return 0; } break; default: demonstrate_command_usage(); NUMBER_WORDS_ERROR; return 0; } } // Now proceed to calculate // If .xr. < 0, of if not supplied calculate .xr./.yr. unsigned int numgood = xgood.size(); if (_nword == 4 || _nword == 5 || xr < 0.0) { double dx, dy; dx = (_colX.max() - _colX.min()) / sqrt(double(numgood)); dy = (_colY.max() - _colY.min()) / sqrt(double(numgood)); if (_chatty > 0) { sprintf(_grTempString, "\ Data spacing, computed from areal fraction, is dx=%f, dy=%f).\n", dx, dy); ShowStr(_grTempString); } // Either use fabs(xr) to get real xr, or use 1.4*dx if (xr < 0.0) { xr = GRI_ABS(xr) * dx; yr = GRI_ABS(yr) * dy; } else { // REF on why using 1.4: Equation 13 in S. E. Koch and M. // DesJardins and P. J. Kocin, 1983. ``An interactive // Barnes objective map anlaysis scheme for use with // satellite and conventional data,'', J. Climate Appl. // Met., vol 22, p. 1487-1503. xr = 1.4 * dx; yr = 1.4 * dy; } if (_chatty > 0) { sprintf(_grTempString, "\ Therefore Gri will use smoothing scales xr=%f, yr=%f. To resolve the small scale\n\ features, the (x,y) grid spacing should be 1/3 to 1/2 of these values.\n\n", xr, yr); ShowStr(_grTempString); } } // had to calculate (xr,yr) // OK, now do the gridding if (word_is(4, "barnes") || use_default) { // Barnes fills whole grid for now, anyway. create_grid_barnes(xr, yr, gamma, (unsigned int)iter, xgood, ygood, zgood, wgood); found = _num_xmatrix_data * _num_ymatrix_data; } else if (word_is(4, "barnes_cross_validate")) { // Barnes fills whole grid for now, anyway. create_grid_barnes_cv(xr, yr, gamma, (unsigned int)iter, xgood, ygood, zgood, wgood); found = _num_xmatrix_data * _num_ymatrix_data; } else if (word_is(4, "boxcar")) { found = create_grid_boxcarCmd(xr, yr, xgood, ygood, zgood); } else if (word_is(4, "objective")) { found = create_grid_objectiveCmd(xr, yr, xgood, ygood, zgood); } else { err("Method must be `boxcar', `objective', `barnes' or `barnes_cross_validate'"); return 0; } } else { err("Method must be `boxcar', `objective', `barnes' or `barnes_cross_validate'"); return 0; } } // method if (_chatty > 0 && !word_is(4, "barnes_cross_validate")) { sprintf(_grTempString, "\ Filled %.3f%% of the %d row, %d col grid.\n", 100.0 * (double) found / (double) (_num_xmatrix_data * _num_ymatrix_data), _num_ymatrix_data, _num_xmatrix_data); ShowStr(_grTempString); } // Locate and flag missing values for (unsigned int i = 0; i < _num_xmatrix_data; i++) for (unsigned int j = 0; j < _num_ymatrix_data; j++) if (gr_missing(_f_xy(i, j))) _legit_xy(i, j) = false; matrix_limits(&_f_min, &_f_max); if (get_flag("jinyu1")) { const char *name = "tmp.dat"; printf("Flag 'jinyu1' set, so writing x, y, z, zpredicted to file '%s'\n", name); FILE *tmp = fopen (name, "w"); Require(tmp, err("Cannot open the file")); unsigned int num = _colX.size(); for (unsigned int i = 0; i < num; i++) { double zpred; grid_interp(_colX[i], _colY[i], &zpred); if (!gr_missing(zpred)) { fprintf(tmp, "%f %f %f %f\n", _colX[i], _colY[i], _colZ[i], zpred); } else { fprintf(tmp, "%f %f %f %f\n", _colX[i], _colY[i], _colZ[i], gr_currentmissingvalue()); } fclose(tmp); } } return found; } static inline double dmin(double a, double b) { if (a > b) return b; else return a; } int interv(double *xt, int *lxt, double *x, int *left, int *mflag) { static int ilo = 1; static int istep, middle, ihi; // Parameter adjustments --xt; // from * a practical guide to splines * by C. de Boor // computes left = max( i : xt(i) .lt. xt(lxt) .and. xt(i) .le. x ) // // ****** i n p u t ****** // xt.....a double sequence, of length lxt , assumed to be nondecreasing // lxt.....number of terms in the sequence xt // x.....the point whose location with respect to the sequence xt is // to be determined // // ****** o u t p u t ****** // left, mflag.....both integers, whose value is // // 1 -1 if x .lt. xt(1) // i 0 if xt(i) .le. x .lt. xt(i+1) // i 0 if xt(i) .lt. x .eq. xt(i+1) .eq. xt(lxt) // i 1 if xt(i) .lt. xt(i+1) .eq. xt(lxt) .lt. x // // In particular, mflag = 0 is the 'usual' case. mflag .ne. 0 // // indicates that x lies outside the CLOSED interval // xt(1) .le. y .le. xt(lxt) . The asymmetric treatment of the // intervals is due to the decision to make all pp functions // continuous from the right, but, by returning mflag = 0 even if // x = xt(lxt), there is the option of having the computed pp // function continuous from the left at xt(lxt). // // ****** m e t h o d ****** // The program is designed to be efficient in the common situation that // it is called repeatedly, with x taken from an increasing or decrea- // sing sequence. This will happen, e.g., when a pp function is to be // graphed. The first guess for left is therefore taken to be the val- // ue returned at the previous call and stored in the l o c a l varia- // ble ilo . A first check ascertains that ilo .lt. lxt (this is nec- // essary since the present call may have nothing to do with the previ- // ous call). Then, if xt(ilo) .le. x .lt. xt(ilo+1), we set // left = ilo and are done after just three comparisons // Otherwise, we repeatedly double the difference istep = ihi - ilo // while also moving ilo and ihi in the direction of x , until // xt(ilo) .le. x .lt. xt(ihi), // after which we use bisection to get, in addition, // ilo+1 = ihi. left = ilo is then returned ihi = ilo + 1; if (ihi < *lxt) { goto L20; } if (*x >= xt[*lxt]) { goto L110; } if (*lxt <= 1) { goto L90; } ilo = *lxt - 1; ihi = *lxt; L20: if (*x >= xt[ihi]) { goto L40; } if (*x >= xt[ilo]) { goto L100; } // **** now x .lt. xt(ilo) . decrease ilo to capture x . istep = 1; L31: ihi = ilo; ilo = ihi - istep; if (ilo <= 1) { goto L35; } if (*x >= xt[ilo]) { goto L50; } istep <<= 1; goto L31; L35: ilo = 1; if (*x < xt[1]) { goto L90; } goto L50; // **** now x .ge. xt(ihi) . increase ihi to capture x . L40: istep = 1; L41: ilo = ihi; ihi = ilo + istep; if (ihi >= *lxt) { goto L45; } if (*x < xt[ihi]) { goto L50; } istep <<= 1; goto L41; L45: if (*x >= xt[*lxt]) { goto L110; } ihi = *lxt; // Now xt(ilo) .le. x .lt. xt(ihi) . narrow the interval. L50: middle = (ilo + ihi) / 2; if (middle == ilo) { goto L100; } // Note. it is assumed that middle = ilo in case ihi = ilo+1 if (*x < xt[middle]) { goto L53; } ilo = middle; goto L50; L53: ihi = middle; goto L50; // Set output and return. L90: *mflag = -1; *left = 1; return 0; L100: *mflag = 0; *left = ilo; return 0; L110: *mflag = 1; if (*x == xt[*lxt]) { *mflag = 0; } *left = *lxt; L111: if (*left == 1) { return 0; } --(*left); if (xt[*left] < xt[*lxt]) { return 0; } goto L111; } double ppvalu(double *break_, double *coef, int *l, int *k, double *x, int *jderiv) { int coef_dim1, coef_offset, i_1; double ret_val; static double h; static int i, m; static double fmmjdr; static int ndummy; // Parameter adjustments --break_; coef_dim1 = *k; coef_offset = coef_dim1 + 1; coef -= coef_offset; // Function Body // from * a practical guide to splines * by c. de boor // calls interv // calculates value at x of jderiv-th derivative of pp fct from pp-rep // ****** i n p u t ****** // break, coef, l, k.....forms the pp-representation of the function f // to be evaluated. specifically, the j-th derivative of f is // given by // (d**j)f(x) = coef(j+1,i) + h*(coef(j+2,i) + h*( ... (coef(k-1,i) + // + h*coef(k,i)/(k-j-1))/(k-j-2) ... )/2)/1 // with h = x - break(i), and // i = max( 1 , max( j , break(j) .le. x , 1 .le. j .le. l ) ). // x.....the point at which to evaluate. // jderiv.....int giving the order of the derivative to be evaluat- // ed. a s s u m e d to be zero or positive. // ****** o u t p u t ****** // ppvalu.....the value of the (jderiv)-th derivative of f at x. // ****** m e t h o d ****** // the interval index i , appropriate for x , is found through a // call to interv . the formula above for the jderiv-th derivative // of f is then evaluated (by nested multiplication). ret_val = 0.0; fmmjdr = (double) (*k - *jderiv); // derivatives of order k or higher are identically zero. if (fmmjdr <= 0.0) { goto L99; } // find index i of largest breakpoint to the left of x . i_1 = *l + 1; interv(&break_[1], &i_1, x, &i, &ndummy); // Evaluate jderiv-th derivative of i-th polynomial piece at x . h = *x - break_[i]; m = *k; L9: ret_val = ret_val / fmmjdr * h + coef[m + i * coef_dim1]; --m; fmmjdr += -1.0; if (fmmjdr > 0.0) { goto L9; } L99: return ret_val; } // Use iflag to indicate if call was ok #define SAVE double *sORIG = s; double *break_ORIG = break_; double *coefORIG = coef; double *gtauORIG = gtau; double *tauORIG = tau; #define RESTORE s = sORIG; break_ = break_ORIG; coef = coefORIG; gtau = gtauORIG; tau = tauORIG; int tautsp(double *tau, // input data, x, of length ntau double *gtau, // input data, y, of length ntau unsigned int ntau, // number data double *gamma, // tension parameter double *s, // length 6*ntau double *break_, // knot locations, length=l double *coef, // coefficients, length=4l int *l, // returned # knots, max maybe 2*ntau int *k, // always returned as 4 int *iflag) // 0 indicates call was ok { // Kelley: save the original pointers because these will be FREEd in the // calling subroutine -- this is NOT included in the NR code! SAVE; int s_dim1, s_offset; double r_1, r_2, r_3; // Local variables static double zeta, temp, c, d; static unsigned int i; static double alpha, z, denom, ratio, sixth, entry_, factr2, onemg3; static unsigned int ntaum1; static double entry3, divdif, factor; static int method; static double onemzt, zt2, del, gam; // Parameter adjustments --tau; // NEED TO PROTECT (see above) --gtau; // NEED TO PROTECT (see above) s_dim1 = ntau; s_offset = s_dim1 + 1; s -= s_offset; // NEED TO PROTECT (see above) --break_; // NEED TO PROTECT (see above) coef -= 5; // NEED TO PROTECT (see above) // From A PRACTICAL GUIDE TO SPLINES by C. de Boor // Constructs cubic spline interpolant to given data // tau(i), gtau(i), i=1,...,ntau. // if gamma .gt. 0., additional knots are introduced where needed to // make the interpolant more flexible locally. this avoids extraneous // inflection points typical of cubic spline interpolation at knots to // rapidly changing data. // // INPUT PARAMETERS // tau sequence of data points. must be strictly increasing. // gtau corresponding sequence of function values. // ntau number of data points. must be at least 4 . // gamma indicates whether additional flexibility is desired. // = 0., no additional knots // in (0.,3.), under certain conditions on the given data at // points i-1, i, i+1, and i+2, a knot is added in the // i-th interval, i=2,...,ntau-2. see description of meth- // od below. the interpolant gets rounded with increasing // gamma. a value of 2.5 for gamma is typical. // in (3.,6.), same , except that knots might also be added in // intervals in which an inflection point would be permit- // ted. a value of 5.5 for gamma is typical. // OUTPUT PARAMETERS // break, coef, l, k give the pp-representation of the interpolant. // specifically, for break(i) .le. x .le. break(i+1), the // interpolant has the form // f(x) = coef(1,i) +dx(coef(2,i) +(dx/2)(coef(3,i) +(dx/3)coef(4,i))) // with dx = x - break(i) and i=1,...,l . // iflag = 1, ok // = 2, input was incorrect. a printout specifying the mistake // was made. // workspace // s is required, of size (ntau,6). the individual columns of this // array contain the following quantities mentioned in the write- // up and below. // s(.,1) = dtau = tau(.+1) - tau // s(.,2) = diag = diagonal in linear system // s(.,3) = u = upper diagonal in linear system // s(.,4) = r = right side for linear system (initially) // = fsecnd = solution of linear system , namely the second // derivatives of interpolant at tau // s(.,5) = z = indicator of additional knots // s(.,6) = 1/hsecnd(1,x) with x = z or = 1-z. see below. // ------ m e t h o d ------ // on the i-th interval, (tau(i), tau(i+1)), the interpolant is of the // form // (*) f(u(x)) = a + b*u + c*h(u,z) + d*h(1-u,1-z) , // with u = u(x) = (x - tau(i))/dtau(i). here, // z = z(i) = addg(i+1)/(addg(i) + addg(i+1)) // (= .5, in case the denominator vanishes). with // addg(j) = abs(ddg(j)), ddg(j) = dg(j+1) - dg(j), // dg(j) = divdif(j) = (gtau(j+1) - gtau(j))/dtau(j) // and // h(u,z) = alpha*u**3 + (1 - alpha)*(max(((u-zeta)/(1-zeta)),0)**3 // with // alpha(z) = (1-gamma/3)/zeta // zeta(z) = 1 - gamma*min((1 - z), 1/3) // thus, for 1/3 .le. z .le. 2/3, f is just a cubic polynomial on // the interval i. otherwise, it has one additional knot, at // tau(i) + zeta*dtau(i) . // as z approaches 1, h(.,z) has an increasingly sharp bend near 1, // thus allowing f to turn rapidly near the additional knot. // in terms of f(j) = gtau(j) and // fsecnd(j) = 2.derivative of f at tau(j), // the coefficients for (*) are given as // a = f(i) - d // b = (f(i+1) - f(i)) - (c - d) // c = fsecnd(i+1)*dtau(i)**2/hsecnd(1,z) // d = fsecnd(i)*dtau(i)**2/hsecnd(1,1-z) // hence can be computed once fsecnd(i),i=1,...,ntau, is fixed. // f is automatically continuous and has a continuous second derivat- // ive (except when z = 0 or 1 for some i). we determine fscnd(.) from // the requirement that also the first derivative of f be contin- // uous. in addition, we require that the third derivative be continuous // across tau(2) and across tau(ntau-1) . this leads to a strictly // diagonally dominant tridiagonal linear system for the fsecnd(i) // which we solve by gauss elimination without pivoting. // there must be at least 4 interpolation points. if (ntau < 4) { err("Need more than 3 data points"); *iflag = 2; RESTORE; return 0; } // construct delta tau and first and second (divided) differences of data ntaum1 = ntau - 1; for (i = 1; i <= ntaum1; ++i) { #if 0 printf("i=%d\n",i); printf("gtau[i ]= %lf\n", gtau[i]); printf("gtau[i+1]= %lf\n", gtau[i+1]); printf("s[1+s_dim1]= %lf\n", s[1+s_dim1]); printf(" i+1+(s_dim1<<2)= %d\n", i+1+(s_dim1<<2)); printf("s[i+1+(s_dim1<<2)]= %lf\n", s[i+1+(s_dim1<<2)]); #endif s[i + s_dim1] = tau[i + 1] - tau[i]; if (s[i + s_dim1] <= 0.) { sprintf(_grTempString, "\ X data must be ordered and distinct.\n\ Problem at x[%d]=%f and x[%d]=%f\n", i, tau[i], i+1, tau[i+1]); err(_grTempString); *iflag = 2; RESTORE; return 0; } s[i + 1 + (s_dim1 << 2)] = (gtau[i + 1] - gtau[i]) / s[i + s_dim1]; } for (i = 2; i <= ntaum1; ++i) { s[i + (s_dim1 << 2)] = s[i + 1 + (s_dim1 << 2)] - s[i + (s_dim1 << 2)]; } // Construct system of equations for second derivatives at tau. at each // interior data point, there is one continuity equation, at the first // and the last interior data point there is an additional one for a // total of ntau equations in ntau unknowns. i = 2; s[(s_dim1 << 1) + 2] = s[s_dim1 + 1] / 3.0; sixth = 1.0 / 6.0; method = 2; gam = *gamma; printf("DEBUG: gam = %f\n",gam); if (gam <= 0.0) { method = 1; } if (gam > 3.0) { method = 3; gam += -3.0; } printf("DEBUG: gam=%f method=%d\n",gam,method); onemg3 = 1.0 - gam / 3.0; // ------ loop over i ------ L10: // construct z(i) and zeta(i) z = 0.5; switch (method) { case 1: goto L19; case 2: goto L11; case 3: goto L12; } L11: if (s[i + (s_dim1 << 2)] * s[i + 1 + (s_dim1 << 2)] < 0.) { goto L19; } L12: temp = (r_1 = s[i + 1 + (s_dim1 << 2)], GRI_ABS(r_1)); denom = (r_1 = s[i + (s_dim1 << 2)], GRI_ABS(r_1)) + temp; if (denom == 0.0) { goto L19; } z = temp / denom; if ((r_1 = z - 0.5, GRI_ABS(r_1)) <= sixth) { z = 0.5; } L19: s[i + s_dim1 * 5] = z; // ******set up part of the i-th equation which depends on // the i-th interval if ((r_1 = z - 0.5) < 0.0) { goto L21; } else if (r_1 == 0) { goto L22; } else { goto L23; } L21: zeta = gam * z; onemzt = 1.0 - zeta; zt2 = zeta * zeta; // Computing MAX r_1 = 1.0, r_2 = onemg3 / onemzt; alpha = dmin(r_2,r_1); factor = zeta / (alpha * (zt2 - 1.0) + 1.0); s[i + s_dim1 * 6] = zeta * factor / 6.0; s[i + (s_dim1 << 1)] += s[i + s_dim1] * ((1.0 - alpha * onemzt) * factor / 2.0 - s[i + s_dim1 * 6]); // if z = 0 and the previous z = 1, then d(i) = 0. since then // also u(i-1) = l(i+1) = 0, its value does not matter. reset // d(i) = 1 to insure nonzero pivot in elimination. if (s[i + (s_dim1 << 1)] <= 0.0) { s[i + (s_dim1 << 1)] = 1.0; } s[i + s_dim1 * 3] = s[i + s_dim1] / 6.0; goto L25; L22: s[i + (s_dim1 << 1)] += s[i + s_dim1] / 3.0; s[i + s_dim1 * 3] = s[i + s_dim1] / 6.0; goto L25; L23: onemzt = gam * (1.0 - z); zeta = 1.0 - onemzt; // Computing MAX r_1 = 1.0, r_2 = onemg3 / zeta; alpha = dmin(r_2,r_1); factor = onemzt / (1.0 - alpha * zeta * (onemzt + 1.0)); s[i + s_dim1 * 6] = onemzt * factor / 6.0; s[i + (s_dim1 << 1)] += s[i + s_dim1] / 3.0; s[i + s_dim1 * 3] = s[i + s_dim1 * 6] * s[i + s_dim1]; L25: if (i > 2) { goto L30; } s[s_dim1 * 5 + 1] = 0.5; // ******the first two equations enforce continuity of the first and of // the third derivative across tau(2). s[(s_dim1 << 1) + 1] = s[s_dim1 + 1] / 6.0; s[s_dim1 * 3 + 1] = s[(s_dim1 << 1) + 2]; entry3 = s[s_dim1 * 3 + 2]; if ((r_1 = z - 0.5) < 0.0) { goto L26; } else if (r_1 == 0) { goto L27; } else { goto L28; } L26: factr2 = zeta * (alpha * (zt2 - 1.0) + 1.0) / (alpha * (zeta * zt2 - 1.0) + 1.0); ratio = factr2 * s[s_dim1 + 2] / s[(s_dim1 << 1) + 1]; s[(s_dim1 << 1) + 2] = factr2 * s[s_dim1 + 2] + s[s_dim1 + 1]; s[s_dim1 * 3 + 2] = -(double)factr2 * s[s_dim1 + 1]; goto L29; L27: ratio = s[s_dim1 + 2] / s[(s_dim1 << 1) + 1]; s[(s_dim1 << 1) + 2] = s[s_dim1 + 2] + s[s_dim1 + 1]; s[s_dim1 * 3 + 2] = -(double)s[s_dim1 + 1]; goto L29; L28: ratio = s[s_dim1 + 2] / s[(s_dim1 << 1) + 1]; s[(s_dim1 << 1) + 2] = s[s_dim1 + 2] + s[s_dim1 + 1]; s[s_dim1 * 3 + 2] = -(double)s[s_dim1 + 1] * 6.0 * alpha * s[s_dim1 * 6 + 2]; // at this point, the first two equations read // diag(1)*x1 + u(1)*x2 + entry3*x3 = r(2) // -ratio*diag(1)*x1 + diag(2)*x2 + u(2)*x3 = 0. // eliminate first unknown from second equation L29: s[(s_dim1 << 1) + 2] = ratio * s[s_dim1 * 3 + 1] + s[(s_dim1 << 1) + 2]; s[s_dim1 * 3 + 2] = ratio * entry3 + s[s_dim1 * 3 + 2]; s[(s_dim1 << 2) + 1] = s[(s_dim1 << 2) + 2]; s[(s_dim1 << 2) + 2] = ratio * s[(s_dim1 << 2) + 1]; goto L35; L30: // ******the i-th equation enforces continuity of the first derivative // across tau(i). it has been set up in statements 35 up to 40 // and 21 up to 25 and reads now // -ratio*diag(i-1)*xi-1 + diag(i)*xi + u(i)*xi+1 = r(i) . // eliminate (i-1)st unknown from this equation s[i + (s_dim1 << 1)] = ratio * s[i - 1 + s_dim1 * 3] + s[i + (s_dim1 << 1) ]; s[i + (s_dim1 << 2)] = ratio * s[i - 1 + (s_dim1 << 2)] + s[i + (s_dim1 << 2)]; // ******set up the part of the next equation which depends on the // i-th interval. L35: if ((r_1 = z - 0.5) < 0.0) { goto L36; } else if (r_1 == 0) { goto L37; } else { goto L38; } L36: ratio = -(double)s[i + s_dim1 * 6] * s[i + s_dim1] / s[i + (s_dim1 << 1)]; s[i + 1 + (s_dim1 << 1)] = s[i + s_dim1] / 3.0; goto L40; L37: ratio = -(double)(s[i + s_dim1] / 6.0) / s[i + (s_dim1 << 1)]; s[i + 1 + (s_dim1 << 1)] = s[i + s_dim1] / 3.0; goto L40; L38: ratio = -(double)(s[i + s_dim1] / 6.0) / s[i + (s_dim1 << 1)]; s[i + 1 + (s_dim1 << 1)] = s[i + s_dim1] * ((1.0 - zeta * alpha) * factor / 2.0 - s[i + s_dim1 * 6]); // ------ end of i loop ------ L40: ++i; if (i < ntaum1) { goto L10; } s[i + s_dim1 * 5] = 0.5; // ------ last two equations ------ // the last two equations enforce continuity of third derivative and // of first derivative across tau(ntau-1). entry_ = ratio * s[i - 1 + s_dim1 * 3] + s[i + (s_dim1 << 1)] + s[i + s_dim1] / 3.0; s[i + 1 + (s_dim1 << 1)] = s[i + s_dim1] / 6.0; s[i + 1 + (s_dim1 << 2)] = ratio * s[i - 1 + (s_dim1 << 2)] + s[i + (s_dim1 << 2)]; if ((r_1 = z - 0.5) < 0.0) { goto L41; } else if (r_1 == 0) { goto L42; } else { goto L43; } L41: ratio = s[i + s_dim1] * 6.0 * s[i - 1 + s_dim1 * 6] * alpha / s[i - 1 + (s_dim1 << 1)]; s[i + (s_dim1 << 1)] = ratio * s[i - 1 + s_dim1 * 3] + s[i + s_dim1] + s[ i - 1 + s_dim1]; s[i + s_dim1 * 3] = -(double)s[i - 1 + s_dim1]; goto L45; L42: ratio = s[i + s_dim1] / s[i - 1 + (s_dim1 << 1)]; s[i + (s_dim1 << 1)] = ratio * s[i - 1 + s_dim1 * 3] + s[i + s_dim1] + s[ i - 1 + s_dim1]; s[i + s_dim1 * 3] = -(double)s[i - 1 + s_dim1]; goto L45; L43: // Computing 2nd power r_1 = onemzt; // Computing 3rd power r_2 = onemzt, r_3 = r_2; factr2 = onemzt * (alpha * (r_1 * r_1 - 1.0) + 1.0) / (alpha * (r_3 * (r_2 * r_2) - 1.0) + 1.0); ratio = factr2 * s[i + s_dim1] / s[i - 1 + (s_dim1 << 1)]; s[i + (s_dim1 << 1)] = ratio * s[i - 1 + s_dim1 * 3] + factr2 * s[i - 1 + s_dim1] + s[i + s_dim1]; s[i + s_dim1 * 3] = -(double)factr2 * s[i - 1 + s_dim1]; // at this point, the last two equations read // diag(i)*xi + u(i)*xi+1 = r(i) // -ratio*diag(i)*xi + diag(i+1)*xi+1 = r(i+1) // eliminate xi from last equation L45: s[i + (s_dim1 << 2)] = ratio * s[i - 1 + (s_dim1 << 2)]; ratio = -(double)entry_ / s[i + (s_dim1 << 1)]; s[i + 1 + (s_dim1 << 1)] = ratio * s[i + s_dim1 * 3] + s[i + 1 + (s_dim1 << 1)]; s[i + 1 + (s_dim1 << 2)] = ratio * s[i + (s_dim1 << 2)] + s[i + 1 + ( s_dim1 << 2)]; // ------ back substitution ------ s[ntau + (s_dim1 << 2)] /= s[ntau + (s_dim1 << 1)]; do { s[i + (s_dim1 << 2)] = (s[i + (s_dim1 << 2)] - s[i + s_dim1 * 3] * s[i + 1 + (s_dim1 << 2)]) / s[i + (s_dim1 << 1)]; } while (--i > 1); s[(s_dim1 << 2) + 1] = (s[(s_dim1 << 2) + 1] - s[s_dim1 * 3 + 1] * s[( s_dim1 << 2) + 2] - entry3 * s[(s_dim1 << 2) + 3]) / s[(s_dim1 << 1) + 1]; // ------ construct polynomial pieces ------ break_[1] = tau[1]; *l = 1; for (i = 1; i <= ntaum1; ++i) { coef[(*l << 2) + 1] = gtau[i]; coef[(*l << 2) + 3] = s[i + (s_dim1 << 2)]; divdif = (gtau[i + 1] - gtau[i]) / s[i + s_dim1]; z = s[i + s_dim1 * 5]; if ((r_1 = z - 0.5) < 0.0) { goto L61; } else if (r_1 == 0) { goto L62; } else { goto L63; } L61: if (z == 0.0) { goto L65; } zeta = gam * z; onemzt = 1.0 - zeta; c = s[i + 1 + (s_dim1 << 2)] / 6.0; d = s[i + (s_dim1 << 2)] * s[i + s_dim1 * 6]; ++(*l); del = zeta * s[i + s_dim1]; break_[*l] = tau[i] + del; // Computing 2nd power zt2 = zeta * zeta; // Computing MAX r_1 = 1.0, r_2 = onemg3 / onemzt; alpha = dmin(r_2,r_1); // Computing 2nd power r_1 = onemzt; factor = r_1 * r_1 * alpha; // Computing 2nd power r_1 = s[i + s_dim1]; coef[(*l << 2) + 1] = gtau[i] + divdif * del + r_1 * r_1 * (d * onemzt * (factor - 1.0) + c * zeta * (zt2 - 1.0)); coef[(*l << 2) + 2] = divdif + s[i + s_dim1] * (d * (1.0 - factor * 3.) + c * (zt2 * 3. - 1.)); coef[(*l << 2) + 3] = (d * alpha * onemzt + c * zeta) * 6.; coef[(*l << 2) + 4] = (c - d * alpha) * 6. / s[i + s_dim1]; coef[((*l - 1) << 2) + 4] = coef[(*l << 2) + 4] - d * 6. * (( double)1. - alpha) / (del * zt2); coef[((*l - 1) << 2) + 2] = coef[(*l << 2) + 2] - del * (coef[(*l << 2) + 3] - del / 2. * coef[((*l - 1) << 2) + 4]); goto L68; L62: coef[(*l << 2) + 2] = divdif - s[i + s_dim1] * (s[i + (s_dim1 << 2)] * 2. + s[i + 1 + (s_dim1 << 2)]) / 6.; coef[(*l << 2) + 4] = (s[i + 1 + (s_dim1 << 2)] - s[i + (s_dim1 << 2)] ) / s[i + s_dim1]; goto L68; L63: onemzt = gam * (1. - z); if (onemzt == 0.) { goto L65; } zeta = 1. - onemzt; // Computing MAX r_1 = 1., r_2 = onemg3 / zeta; alpha = dmin(r_2,r_1); c = s[i + 1 + (s_dim1 << 2)] * s[i + s_dim1 * 6]; d = s[i + (s_dim1 << 2)] / 6.; del = zeta * s[i + s_dim1]; break_[*l + 1] = tau[i] + del; coef[(*l << 2) + 2] = divdif - s[i + s_dim1] * (d * 2. + c); coef[(*l << 2) + 4] = (c * alpha - d) * 6. / s[i + s_dim1]; ++(*l); // Computing 3rd power r_1 = onemzt, r_2 = r_1; coef[(*l << 2) + 4] = coef[((*l - 1) << 2) + 4] + (1. - alpha) * 6. * c / (s[i + s_dim1] * (r_2 * (r_1 * r_1))); coef[(*l << 2) + 3] = coef[((*l - 1) << 2) + 3] + del * coef[((*l - 1) << 2) + 4]; coef[(*l << 2) + 2] = coef[((*l - 1) << 2) + 2] + del * (coef[((*l - 1) << 2) + 3] + del / 2. * coef[((*l - 1) << 2) + 4]); coef[(*l << 2) + 1] = coef[((*l - 1) << 2) + 1] + del * (coef[((*l - 1) << 2) + 2] + del / 2. * (coef[((*l - 1) << 2) + 3] + del / 3. * coef[((*l - 1) << 2) + 4])); goto L68; L65: coef[(*l << 2) + 2] = divdif; coef[(*l << 2) + 3] = 0.; coef[(*l << 2) + 4] = 0.; L68: ++(*l); // L70: break_[*l] = tau[i + 1]; if (*l > 1 + 2 * int(ntau)) { gr_error("Too many knots. Kelley thought max was 2*n\n"); RESTORE; return 0; // not reached } } --(*l); *k = 4; *iflag = 1; RESTORE; return 0; } // tautsp #undef SAVE #undef RESTORE // `convert columns to spline \[.gamma.\] \[.xmin. .xmax. .xinc.\]\' bool convert_col_to_splineCmd() { Require(_columns_exist, err("No (x,y) data exist yet. First `read columns'")); double gamma, xmin, xmax, xinc; switch (_nword) { case 4: // `convert columns to spline' gamma = 0; xmin = _colX.min(); xmax = _colX.max(); xinc = (xmax - xmin) / 200; break; case 5: // `convert columns to spline .gamma.' Require(getdnum(_word[4], &gamma), READ_WORD_ERROR(".gamma.")); xmin = _colX.min(); xmax = _colX.max(); xinc = (xmax - xmin) / 200; break; case 8: // `... .gamma. .xmin. .xmax. .xinc.' Require(getdnum(_word[4], &gamma), READ_WORD_ERROR(".gamma.")); Require(getdnum(_word[5], &xmin), READ_WORD_ERROR(".xmin.")); Require(getdnum(_word[6], &xmax), READ_WORD_ERROR(".xmax.")); Require(getdnum(_word[7], &xinc), READ_WORD_ERROR(".xinc.")); break; default: NUMBER_WORDS_ERROR; return false; } printf("DEBUG: gamma= %f\n", gamma); Require(xmax != xmin, err("Cannot have .xmin. equaling .xmax.")); Require(xinc != 0, err("Cannot have .xinc. equal to zero")); Require(xmax > xmin, err("Cannot have .xmin. exceeding .xmax.")); Require(xinc > 0.0, err("Cannot have .xinc. < 0")); int steps = int(1 + (xmax - xmin) / xinc); Require(steps > 0, err("Cannot have 0 or fewer elements in spline")); // Calculate spline if (_colX.size() < 4) { err("Must have more than 4 data points to convert to spline"); return false; } // Get storage unsigned int n = _colX.size(); // for tautsp double *xs, *ys, *coef, *break_point, *scrtch; xs = ys = coef = break_point = scrtch = (double*)NULL; #if 0 GET_STORAGE(xs, double, (size_t)steps); printf("DEBUG %s:%d: got xs storage at %x\n",__FILE__,__LINE__,int(xs)); GET_STORAGE(ys, double, (size_t)steps); printf("DEBUG %s:%d: got ys storage at %x\n",__FILE__,__LINE__,int(ys)); GET_STORAGE(coef, double, (size_t)(4 * 2 * steps)); printf("DEBUG %s:%d: got coef storage at %x\n",__FILE__,__LINE__,int(coef)); GET_STORAGE(break_point, double, (size_t)(2 * steps)); printf("DEBUG %s:%d: got break_point storage at %x\n",__FILE__,__LINE__,int(break_point)); GET_STORAGE(scrtch, double, (size_t)(6 * steps)); // BUG: is this enough storage?? printf("DEBUG %s:%d: got scrtch storage (%d elements) at %x\n",__FILE__,__LINE__,(6*steps),int(scrtch)); #else GET_STORAGE(coef, double, (size_t)(4 * 2 * n)); //printf("DEBUG %s:%d: got coef storage at %x\n",__FILE__,__LINE__,int(coef)); GET_STORAGE(break_point, double, (size_t)(2 * n)); //printf("DEBUG %s:%d: got break_point storage at %x\n",__FILE__,__LINE__,int(break_point)); GET_STORAGE(scrtch, double, (size_t)(6 * n)); // BUG: is this enough storage?? //printf("DEBUG %s:%d: got scrtch storage (%d elements) at %x\n",__FILE__,__LINE__,(6*n),int(scrtch)); #endif int l, k, iflag; tautsp(_colX.begin(), _colY.begin(), n, &gamma, scrtch, break_point, coef, &l, &k, &iflag); int zero = 0; GET_STORAGE(xs, double, (size_t)steps); //printf("DEBUG %s:%d: got xs storage at %x\n",__FILE__,__LINE__,int(xs)); GET_STORAGE(ys, double, (size_t)steps); //printf("DEBUG %s:%d: got ys storage at %x\n",__FILE__,__LINE__,int(ys)); for (unsigned int i = 0; i < (unsigned int)steps; i++) { xs[i] = xmin + i * xinc; ys[i] = ppvalu(break_point, coef, &l, &k, &xs[i], &zero); } // Dump spline output into (x,y) _colX.setDepth(steps); _colY.setDepth(steps); for (unsigned int i = 0; i < (unsigned int)steps; i++) { _colX[i] = xs[i]; _colY[i] = ys[i]; } //printf("DEBUG %s:%d: about to free xs at %x\n",__FILE__,__LINE__,int(xs)); free(xs); //printf("DEBUG %s:%d: about to free ys at %x\n",__FILE__,__LINE__,int(ys)); free(ys); //printf("DEBUG %s:%d: about to free coef at %x\n",__FILE__,__LINE__,int(coef)); free(coef); //printf("DEBUG %s:%d: about to free break_point at %x\n",__FILE__,__LINE__,int(break_point)); free(break_point); //printf("DEBUG %s:%d: about to free scrtch at %x\n",__FILE__,__LINE__,int(scrtch)); free(scrtch); //printf("DEBUG %s:%d ... after the free of scrtch\n",__FILE__,__LINE__); return true; } // Do interpolation search, using bisection rule on possibly irregular // array g[]. // // If 'x' is in the range of the grid, defined by g[0] to g[ng-1], // then set 'b' and 'f' such that // x = g[b] + f * (g[b+1] - g[b]) // and return true. // // If 'x' is not in the range, set b to the nearest endpoint, // set f to the distance to the nearest endpoint and return false. static bool nearest(double x, double g[], unsigned int ng, int *b, double *f) { int l = 0; // left index int r = ng - 1; // right index int m; // middle index if (g[0] < g[1]) { // ascending sequence if (x <= g[l]) { *b = 0; *f = g[l] - x; return false; } if (g[r] <= x) { *b = r; *f = x - g[r]; return false; } m = (l + r) / 2; while (r - l > 1) { if (x < g[m]) r = m; else if (g[m] < x) l = m; else { *b = m; *f = (x - g[*b]) / (g[*b+1] - g[*b]); return true; } m = (r + l) / 2; } *b = l; *f = (x - g[*b]) / (g[*b+1] - g[*b]); return true; } else { // descending sequence if (x >= g[l]) { *b = 0; *f = g[l] - x; return false; } if (g[r] >= x) { *b = r; *f = x - g[r]; return false; } m = (l + r) / 2; while (r - l > 1) { if (x > g[m]) r = m; else if (g[m] > x) l = m; else { *b = m; *f = (x - g[*b]) / (g[*b+1] - g[*b]); return true; } m = (r + l) / 2; } *b = l; *f = (x - g[*b]) / (g[*b+1] - g[*b]); return true; } } // Returns number gridpoints filled static int create_grid_neighborCmd(const std::vector &xgood, const std::vector &ygood, const std::vector &zgood) { if (!allocate_grid_storage(_num_xmatrix_data, _num_ymatrix_data)) { gr_Error("Insufficient space for matrix"); return 0; } // Set up geometrical (scale) factors for calculating distance double x_scale = fabs(_xmatrix[1] - _xmatrix[0]); double y_scale = fabs(_ymatrix[1] - _ymatrix[0]); GriMatrix dist; dist.set_size(_num_xmatrix_data, _num_ymatrix_data); // Unlegit to start _legit_xy.set_value(false); unsigned int numgood = xgood.size(); for (unsigned int ii = 0; ii < numgood; ii++) { int bx, by; // index to left double fx, fy; // fraction (if inside) or distance bool x_in = nearest(xgood[ii], _xmatrix, _num_xmatrix_data, &bx, &fx); bool y_in = nearest(ygood[ii], _ymatrix, _num_ymatrix_data, &by, &fy); // If bracketed, twiddle to aim at nearest. if (x_in && fx > 0.5) bx++; if (y_in && fy > 0.5) by++; // Only assign if blank or if this one is closer double dx = (xgood[ii] - _xmatrix[bx]) / x_scale; double dy = (ygood[ii] - _ymatrix[by]) / y_scale; double the_dist = sqrt(dx * dx + dy * dy); // // Change, vsn 2.1.8: only save the very nearest datum if (!_legit_xy(bx, by) || the_dist < dist(bx, by)) { dist(bx, by) = the_dist; _f_xy(bx, by) = zgood[ii]; _legit_xy(bx, by) = true; } } // count elements filled unsigned int found = 0; for (unsigned int i = 0; i < _num_xmatrix_data; i++) for (unsigned int j = 0; j < _num_ymatrix_data; j++) if (_legit_xy(i, j)) found++; return found; } bool convert_grid_to_columnsCmd(void) { if (!_grid_exists) { err("Cannot `convert grid to columns' since no grid data exist yet"); return false; } _colX.setDepth(0); _colY.setDepth(0); _colZ.setDepth(0); for (unsigned int i = 0; i < _num_xmatrix_data; i++) { for (unsigned int j = 0; j < _num_ymatrix_data; j++) { if (_legit_xy(i, j) == true) { _colX.push_back(_xmatrix[i]); _colY.push_back(_ymatrix[j]); _colZ.push_back(_f_xy(i, j)); } } } _columns_exist = true; return true; } bool convert_grid_to_imageCmd() { //printf("\n%s:%d ENTER convert_grid_to_imageCmd()\n", __FILE__,__LINE__); int i, ii, j, jj, val; int width, height; int clipped = 0, masked = 0; double value, xx, dxx, yy, dyy; double scale; bool directly = false; if (!_grid_exists) { err("Cannot `convert grid to image' since no grid data exist yet"); return false; } if (!_xgrid_exists) { err("Cannot `convert grid to image' since x-grid doesn't exist yet"); return false; } if (!_ygrid_exists) { err("Cannot `convert grid to image' since y-grid doesn't exist yet"); return false; } if (_nword < 4) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } // If no image range exists, use min/max in image. #if 0 // 20150425 if (_image_range_automatic) { bool start = true; double gmin, gmax; for (unsigned int i = 0; i < _num_xmatrix_data; i++) { for (unsigned int j = 0; j < _num_ymatrix_data; j++) { double d = _f_xy(i, j); if (!gr_missing(d)) { if (start) { gmin = d; gmax = d; start = false; } else { if (d < gmin) gmin = d; if (d > gmax) gmax = d; } } } } _image0 = gmin; _image255 = gmax; if (_chatty > 0) printf("Using 'automatic' image range, from grid data: %f to %f\n", _image0, _image255); } else { if (_chatty > 2) printf("DEBUG: using image range as set by 'set image range .value0. .value255.'\n"); if (!image_range_exists()) { _image0 = _f_min; _image255 = _f_max; } } #endif // See if the image size was given. width = IMAGE_SIZE_WHEN_CONVERTING; height = IMAGE_SIZE_WHEN_CONVERTING; // convert grid to image directly if (word_is(4, "directly")) { width = (int)_num_xmatrix_data; height = (int) _num_ymatrix_data; directly = true; //printf("DEBUG: using 'directly' method. %d by %d\n", width, height); } else if (2 == get_cmd_values(_word, _nword, "size", 2, _dstack)) { width = (int) (0.5 + _dstack[0]); height = (int) (0.5 + _dstack[1]); } //printf("DEBUG image width=%d height=%d\n", width, height); // BEGIN: Code prior to 2.005 // if (width % 2) { // warning("Making .width. in `convert grid to image' an even number"); // width++; // } // END: Code prior to 2.005 // Check for old-style usage (versions < 1.035) if (1 == get_cmd_values(_word, _nword, "white", 1, _dstack)) { err("The keyword `white' is no longer allowed; use `set image range'"); return false; } if (1 == get_cmd_values(_word, _nword, "black", 1, _dstack)) { err("The keyword `black' is no longer allowed; use `set image range'"); return false; } // Determine image scales, either from 'box' keyword or from the limits // of the data //printf("DEBUG [convert_grid_to_imageCmd() %s:%d] \n",__FILE__,__LINE__); switch (get_cmd_values(_word, _nword, "box", 4, _dstack)) { case 4: define_image_scales(_dstack[0], _dstack[1], _dstack[2], _dstack[3]); break; case 0: //printf("DEBUG [convert_grid_to_imageCmd() %s:%d] _num_xmatrix_data=%d\n",__FILE__,__LINE__,_num_xmatrix_data); //printf("DEBUG [convert_grid_to_imageCmd() %s:%d] _xmatrix[0]=%lf\n",__FILE__,__LINE__,_xmatrix[0]); define_image_scales(_xmatrix[0], _ymatrix[0], _xmatrix[_num_xmatrix_data - 1], _ymatrix[_num_ymatrix_data - 1]); break; default: err("`box .xleft. .ybottom. .xright. .ytop.' needs exactly 4 parameters"); return false; } //printf("_xmatrix[0]= %f _ymatrix[0] = %f _xmatrix[right] = %f _ymatrix[top] = %f\n", //_xmatrix[0], _ymatrix[0], _xmatrix[_num_xmatrix_data - 1], _ymatrix[_num_ymatrix_data - 1]); if (width < 2) { err("Can't have grid < 2 wide"); return false; } if (height < 2) { err("Can't have grid < 2 tall"); return false; } //printf("%s:%d convert_grid_to_imageCmd() ABOUT TO GET STORAGE FOR %d by %d \n", __FILE__,__LINE__,width,height); if (!allocate_image_storage(width, height)) { err("Can't allocate storage for image"); return false; } if (!allocate_imageMask_storage(width, height)) { err("Can't allocate storage for image mask"); return false; } scale = 255.0 / (_image255 - _image0); dxx = (_image_urx - _image_llx) / (width - 1); dyy = (_image_ury - _image_lly) / (height - 1); if (_chatty > 0) { sprintf(_grTempString, "\ `convert grid to image':\n Image is %d wide and %d tall, with x in range (%g,%g) and y in range (%g, %g)\n", width, height, _image_llx, _image_urx, _image_lly, _image_ury); ShowStr(_grTempString); } bool warned = false; GriTimer t; if (_chatty > 1) printf("width=%d height=%d _image.ras_height=%d, _image.ras_width=%d\n", width,height,_image.ras_height,_image.ras_width); if (directly) { for (i = 0; i < width; i++) { xx = _image_llx + i * dxx + 0.5 * dxx; for (j = 0; j < height; j++) { yy = _image_lly + j * dyy + 0.5 * dyy; if (locate_i_j(xx, yy, &ii, &jj) && _legit_xy(ii, jj)) { val = (int) floor(0.5 + scale * (_f_xy(ii, jj) - _image0)); if (val < 0) { val = 0; clipped++; } else if (val > 255) { val = 255; clipped++; } *(_image.image + _image.ras_height * i + j) = (unsigned char) val; *(_imageMask.image + _imageMask.ras_height * i + j) = (unsigned char) 0; } else { *(_image.image + _image.ras_height * i + j) = (unsigned char) _imageBLANK; *(_imageMask.image + _imageMask.ras_height * i + j) = 2; masked++; } if (!warned) { double frac = (height * (1.0 + i)) /(width * height); warned = warn_if_slow(&t, frac, "convert grid to image"); } } } } else { for (i = 0; i < width; i++) { xx = _image_llx + i * dxx; for (j = 0; j < height; j++) { yy = _image_lly + j * dyy; if (!locate_i_j(xx, yy, &ii, &jj) || !value_i_j(ii, jj, xx, yy, &value)) { *(_image.image + _image.ras_height * i + j) = (unsigned char) _imageBLANK; *(_imageMask.image + _imageMask.ras_height * i + j) = 2; masked++; } else { // Method for converting to integer follows that in // value_to_image(), but done here to speed up. Make sure to // update this if value_to_image() is updated. // XREF value_to_image() val = (int) floor(0.5 + scale * (value - _image0)); if (val < 0) { val = 0; clipped++; } else if (val > 255) { val = 255; clipped++; } *(_image.image + _image.ras_height * i + j) = (unsigned char) val; *(_imageMask.image + _imageMask.ras_height * i + j) = (unsigned char) 0; } if (!warned) { double frac = (height * (1.0 + i)) /(width * height); warned = warn_if_slow(&t, frac, "convert grid to image"); } } } } if (_chatty > 2) { printf("IMAGE:\n"); // NB. the image is flipped in y. for (j = 0; j < height; j++) { for (i = 0; i < width; i++) { if (*(_imageMask.image + _imageMask.ras_height * i + j) == 2) printf("."); else printf("*"); } printf("\n"); } } if (_chatty > 1) { if (clipped || masked) { sprintf(_grTempString, "\ `convert grid to image':\n Clipped %d (%.3f%%) pixels and masked %d (%.3f%%) pixels)\n", clipped, 100.0 * (double) clipped / (double) (width * height), masked, 100.0 * (double) masked / (double) (width * height)); } else { sprintf(_grTempString, "\ `convert grid to image':\n Did not clip or mask any of this image.\n"); } ShowStr(_grTempString); } return true; } // BUG -- just get a near pixel, with no proper interpolation bool convert_image_to_gridCmd() { bool bad = false; // See that an image exists if (!_image.storage_exists) { err("First `read image' or `convert grid to image'"); bad = true; } if (!_imageTransform_exists) { err("First `set image grayscale'"); bad = true; } // Check that x/y grid exists; then get (or reconfigure) storage if (!_xgrid_exists) { err("First `set x grid' or `read grid x'"); bad = true; } if (!_ygrid_exists) { err("First `set y grid' or `read grid y'"); bad = true; } if (bad) { demonstrate_command_usage(); return false; } if (!allocate_grid_storage(_num_xmatrix_data, _num_ymatrix_data)) { err("Insufficient space for `grid' data"); return false; } unsigned int i, j; unsigned int good = 0; double scale = 255.0 / (_image255 - _image0); bool warned = false; GriTimer t; for (i = 0; i < _num_xmatrix_data; i++) { for (j = 0; j < _num_ymatrix_data; j++) { int ii = (int)floor(0.5 + _image.ras_width * (_xmatrix[i] - _image_llx) / (_image_urx - _image_llx)); int jj = (int)floor(0.5 + _image.ras_height * (_ymatrix[j] - _image_lly) / (_image_ury - _image_lly)); if (ii < 0 || jj < 0 || ii >= int(_image.ras_width) || jj >= int(_image.ras_height)) { _legit_xy(i, j) = false; // outside image region } else { // Inside _f_xy(i, j) = _image0 + *(_image.image + _image.ras_height * ii + jj) / scale; _legit_xy(i, j) = true; good++; } } if (!warned) { double frac; frac = _image.ras_height * (1.0 + i); frac /= _image.ras_width * _image.ras_height; warned = warn_if_slow(&t, frac, "convert image to grid"); } } if (_chatty > 0) { sprintf(_grTempString, "`convert image to grid':\n Filled %.3f%% of the grid\n", 100.0 * (double) good / (double) (_num_xmatrix_data * _num_ymatrix_data)); ShowStr(_grTempString); } return true; } // Interpolate in box f2 f3 f0 f1 using f = f0 + f1'x + f2'y +f3'xy, where // ()' means () - f0, and x = xx - x_at_f0, etc. // NOTE: ii,jj is point to lower-left of desired point. If // at the top or right edge, just return the edge value. // RETURN whether point is legit. bool value_i_j(unsigned int ii, unsigned int jj, double xx, double yy, double *value) { double Dx, Dy; // width/height of domain with point double f0, f1, f2, f3; double dx; // x - x_to_left double dy; // y - y_below // Fiddle with dx,dy,Dx,Dy, to avoid looking past array dx = (ii == _num_xmatrix_data - 1 ? 0.0 : xx - _xmatrix[ii]); dy = (jj == _num_ymatrix_data - 1 ? 0.0 : yy - _ymatrix[jj]); if (_legit_xy(ii, jj) == false || (dx != 0.0 && _legit_xy(ii + 1, jj) == false) || (dy != 0.0 && _legit_xy(ii, jj + 1) == false) || (dx != 0.0 && dy != 0.0 && _legit_xy(ii + 1, jj + 1) == false)) { *value = gr_currentmissingvalue(); return false; } f0 = _f_xy(ii, jj); f1 = dx != 0 ? _f_xy(ii + 1, jj) - f0 : 0.0; f2 = dy != 0 ? _f_xy(ii, jj + 1) - f0 : 0.0; f3 = (dx != 0 && dy != 0) ? _f_xy(ii + 1, jj + 1) - f0 - f1 - f2 : 0; Dx = dx != 0 ? _xmatrix[ii + 1] - _xmatrix[ii] : 1; Dy = dy != 0 ? _ymatrix[jj + 1] - _ymatrix[jj] : 1; *value = f0 + f1 * dx / Dx + f2 * dy / Dy + f3 * dx / Dx * dy / Dy; return true; } // Find (ii,jj) such that _xmatrix[ii] _xmatrix[0]) { for (i = 0; i < _num_xmatrix_data - 1; i++) { if (_xmatrix[i] <= xx && xx <= _xmatrix[i + 1]) break; } } } else { if (xx > _xmatrix[0]) { return false; // outside range } if (xx < _xmatrix[0]) { for (i = 0; i < _num_xmatrix_data - 1; i++) { if (_xmatrix[i] >= xx && xx >= _xmatrix[i + 1]) break; } } } if (i == _num_xmatrix_data - 1) { return false; } if (_ygrid_increasing) { if (yy < _ymatrix[0]) { return false; // outside range } if (yy > _ymatrix[0]) { for (j = 0; j < _num_ymatrix_data - 1; j++) { if (_ymatrix[j] <= yy && yy <= _ymatrix[j + 1]) break; } } } else { if (yy > _ymatrix[0]) { return false; // outside range } if (yy < _ymatrix[0]) { for (j = 0; j < _num_ymatrix_data - 1; j++) { if (_ymatrix[j] >= yy && yy >= _ymatrix[j + 1]) break; } } } if (j == _num_ymatrix_data - 1) { return false; } *ii = i; *jj = j; return true; } // Returns number gridpoints filled static unsigned int create_grid_objectiveCmd(double xr, double yr, const std::vector &xgood, const std::vector &ygood, const std::vector &zgood) { int number_to_find = 5, enlargements = 1; double xx, yy; if (_nword == 9) { if (!getinum(_word[7], &number_to_find)) { READ_WORD_ERROR(".n."); demonstrate_command_usage(); return 0; } if (!getinum(_word[8], &enlargements)) { READ_WORD_ERROR(".e."); demonstrate_command_usage(); return 0; } } // Allocate storage. if (!allocate_grid_storage(_num_xmatrix_data, _num_ymatrix_data)) { err("Insufficient space for matrix"); return 0; } unsigned int i, j; unsigned int found = 0; // Zero out legit for (i = 0; i < _num_xmatrix_data; i++) for (j = 0; j < _num_ymatrix_data; j++) _legit_xy(i, j) = false; // Do interpolation. bool warned = false; GriTimer t; for (i = 0; i < _num_xmatrix_data; i++) { double fpred; xx = _xmatrix[i]; for (j = 0; j < _num_ymatrix_data; j++) { int number_found; yy = _ymatrix[j]; number_found = gr_grid1(xgood, ygood, zgood, xx, yy, xr, yr, 2, // method number_to_find, enlargements, &fpred); _f_xy(i, j) = fpred; if (number_found >= (int) (GRI_ABS((double) number_to_find))) { _legit_xy(i, j) = true; found++; } else { _legit_xy(i, j) = false; } } if (!warned) { double frac = (i + 1.0) * _num_ymatrix_data; frac /= _num_xmatrix_data * _num_ymatrix_data; warned = warn_if_slow(&t, frac, "convert columns to grid"); } } return found; } // Returns number gridpoints filled static int create_grid_boxcarCmd(double xr, double yr, const std::vector &xgood, const std::vector &ygood, const std::vector &zgood) { int number_to_find = 5, enlargements = 1; if (_nword == 9) { if (!getinum(_word[7], &number_to_find)) { READ_WORD_ERROR(".n."); demonstrate_command_usage(); return 0; } if (!getinum(_word[8], &enlargements)) { READ_WORD_ERROR(".e."); demonstrate_command_usage(); return 0; } } // Allocate storage. if (!allocate_grid_storage(_num_xmatrix_data, _num_ymatrix_data)) { err("Insufficient space for matrix"); return 0; } unsigned int i, j; // zero out legit for (i = 0; i < _num_xmatrix_data; i++) for (j = 0; j < _num_ymatrix_data; j++) _legit_xy(i, j) = false; unsigned int found = 0; // Do interpolation. for (i = 0; i < _num_xmatrix_data; i++) { if (_chatty > 0) printf("\n"); double xx = _xmatrix[i]; for (j = 0; j < _num_ymatrix_data; j++) { if (_chatty > 0) printf("."); unsigned int number_found; double yy = _ymatrix[j]; double fpred; number_found = gr_grid1(xgood, ygood, zgood, xx, yy, xr, yr, 0, // means boxcar number_to_find, enlargements, &fpred); _f_xy(i, j) = fpred; if (number_found >= (unsigned int)number_to_find) { _legit_xy(i, j) = true; found++; } else { _legit_xy(i, j) = false; } } } return found; } // Barnes-interpolate to given (xx,yy), with previously value being zz. // 'skip' used in cross-validation studies. static double interpolate_barnes(double xx, double yy, double zz, int skip, unsigned int n_k, const std::vector& x, const std::vector& y, const std::vector& z, const std::vector& weight, // relative weights const std::vector& z_last, double xr, double yr) { if (gr_missing(zz)) return zz; double sum = 0.0, sum_w = 0.0; for (int k = 0; k < (int)n_k; k++) { double w; if (k != skip) { #ifdef USE_APPROX_EXP double dx = (xx - x[k]) / xr; dx *= dx; double dy = (yy - y[k]) / yr; dy *= dy; double arg = dx + dy; // Fearing that the 'inline' didn't work on g++ without // optimization, I've reproduced the formula here. w = weight[k] / (0.999448 + arg * (1.023820 + arg * (0.3613967 + arg * (0.4169646 + arg * (-0.1292509 + arg * 0.0499565))))); #else double dx = (xx - x[k]) / xr; dx *= dx; double dy = (yy - y[k]) / yr; dy *= dy; double arg = dx + dy; w = weight[k] * exp(-arg); #endif sum += w * (z[k] - z_last[k]); sum_w += w; } } if (sum_w > 0.0) return (zz + sum / sum_w); else return gr_currentmissingvalue(); } //`convert columns to grid barnes [.xr. .yr. .gamma. .iter.]' static bool create_grid_barnes(double xr, double yr, double gamma, unsigned int iter, const std::vector &xgood, const std::vector &ygood, const std::vector &zgood, const std::vector &wgood) { // Get grid storage if it does not exist already if (!_grid_exists) { Require(allocate_grid_storage(_num_xmatrix_data, _num_ymatrix_data), err("Insufficient space for matrix")); } unsigned int numgood = xgood.size(); Require(numgood > 0, err("Cannot `convert columns to grid' since no non-missing column data")); _f_xy.set_value(0.0); _legit_xy.set_value(true); std::vector z_last((size_t)numgood, 0.0); std::vector z_last2((size_t)numgood, 0.0); bool warned = false; GriTimer t; double xr2 = xr, yr2 = yr; for (unsigned int iteration = 0; iteration < iter; iteration++) { // Interpolate on grid for (unsigned int i = 0; i < _num_xmatrix_data; i++) { unsigned int j; for (j = 0; j < _num_ymatrix_data; j++) { _f_xy(i, j) = interpolate_barnes(_xmatrix[i], _ymatrix[j], _f_xy(i, j), -1, // no skip numgood, xgood, ygood, zgood, wgood, z_last, xr2, yr2); } if (!warned) { double frac = (iteration + 1.) * (i + 1.) * (j + 1.); frac /= iter * _num_xmatrix_data * _num_ymatrix_data; warned = warn_if_slow(&t, frac, "convert columns to grid"); } } // Interpolate at data unsigned int k; for (k = 0; k < numgood; k++) { int ix, iy; double fx, fy; bool in_x = nearest(xgood[k], _xmatrix, _num_xmatrix_data, &ix, &fx); bool in_y = nearest(ygood[k], _ymatrix, _num_ymatrix_data, &iy, &fy); if (in_x && in_y) { value_i_j(ix, iy, xgood[k], ygood[k], &z_last2[k]); } else { z_last2[k] = interpolate_barnes(xgood[k], ygood[k], z_last[k], -1, // no skip numgood, xgood, ygood, zgood, wgood, z_last, xr2, yr2); } } // Calculate change in grid double rms_change = 0.0; int numgood_ok = 0; for (k = 0; k < numgood; k++) { if (!gr_missing(z_last[k]) && !gr_missing(z_last2[k])) { rms_change += (z_last[k] - z_last2[k]) * (z_last[k] - z_last2[k]); numgood_ok++; } } if (numgood_ok) rms_change = sqrt(rms_change / numgood_ok); else rms_change = gr_currentmissingvalue(); if (_chatty > 0) { sprintf(_grTempString, " Iteration %d: lengthscales = (%g,%g); RMS(z change) = %f\n", iteration + 1, xr2, yr2, rms_change); ShowStr(_grTempString); } // Update z_last for (k = 0; k < numgood; k++) z_last[k] = z_last2[k]; // Catch case of gamma=0, which means not to iterate if (!gamma) break; // Alter search range xr2 *= sqrt(gamma); yr2 *= sqrt(gamma); } // iteration return true; } // Barnes-interpolate to given (xx,yy), with previously value being zz. // 'skip' used in cross-validation studies. static double interpolate_barnes2(unsigned int k, unsigned int cv, unsigned int n, const std::vector& z, const std::vector& weight, const std::vector& z_last, const GriMatrix& W) { double sum = 0.0, sum_w = 0.0; for (unsigned int kk = 0; kk < n; kk++) { if (kk != cv) { double w = weight[kk] * W(k, kk); sum += w * (z[kk] - z_last[kk]); sum_w += w; } } if (sum_w) return (z_last[k] + sum / sum_w); else return gr_currentmissingvalue(); } //`convert columns to grid barnes_cross_validate [.xr. .yr. .gamma. .iter.]' static bool create_grid_barnes_cv(double xr, double yr, double gamma, unsigned int iter, const std::vector &xgood, const std::vector &ygood, const std::vector &zgood, const std::vector &wgood) { Require(allocate_grid_storage(_num_xmatrix_data, _num_ymatrix_data), err("Insufficient space for matrix")); unsigned int numgood = xgood.size(); std::vector z_last((size_t)numgood, 0.0); // from last iteration std::vector z_last2((size_t)numgood, 0.0); // prevent slurring iterations std::vector z_cv((size_t)numgood, 0.0); // predicted by cross-validation // Pre-calculate weighting factors to save time, about factor of 2 GriMatrix *W = new GriMatrix[iter]; double xr2 = xr, yr2 = yr; unsigned int k; for (unsigned int i = 0; i < iter; i++) { W[i].set_size(numgood, numgood); for (k = 0; k < numgood; k++) { for (unsigned int l = 0; l < numgood; l++) { #ifdef USE_APPROX_EXP double dx = (xgood[k] - xgood[l]) / xr2; dx *= dx; double dy = (ygood[k] - ygood[l]) / yr2; dy *= dy; W[i](k, l) = exp_approx(dx + dy); #else double arg; arg = - (xgood[k] - xgood[l]) * (xgood[k] - xgood[l]) / xr2 / xr2 - (ygood[k] - ygood[l]) * (ygood[k] - ygood[l]) / yr2 / yr2; W[i](k, l) = exp(arg); #endif } } xr2 *= sqrt(gamma); yr2 *= sqrt(gamma); } for (unsigned int cv = 0; cv < numgood; cv++) { for (k = 0; k < numgood; k++) z_last[k] = 0.0; xr2 = xr; yr2 = yr; for (unsigned int i = 0; i < iter; i++) { // Interpolate at data for (k = 0; k < numgood; k++) { z_last2[k] = interpolate_barnes2(k, cv, numgood, zgood, wgood, z_last, W[i]); } // Update z_last for (k = 0; k < numgood; k++) z_last[k] = z_last2[k]; // Catch case of gamma=0, which means not to iterate if (!gamma) break; // is this right? BUG ? // Alter search range xr2 *= sqrt(gamma); yr2 *= sqrt(gamma); } // i, iteration z_cv[cv] = z_last[cv]; } // cv // Calculate difference field and stats double diff_rms = 0.0; double diff_max = 0.0; int numgood_ok = 0; for (k = 0; k < numgood; k++) { double diff = GRI_ABS(zgood[k] - z_cv[k]); diff_rms += diff * diff; if (diff > diff_max) diff_max = diff; numgood_ok++; } diff_rms = sqrt(diff_rms / numgood_ok); double data_rms = 0.0; for (k = 0; k < numgood; k++) data_rms += zgood[k] * zgood[k]; data_rms = sqrt(data_rms / numgood); ShowStr("`convert grid to columns barnes_cross_validation' results:\n"); sprintf(_grTempString, " %10s %10s %10s %5s %5s %10s %10s %10s\n", "xr", "yr", "gamma", "iter", "numgood", "diff_rms", "diff_max", "data_rms"); ShowStr(_grTempString); sprintf(_grTempString, " %10f %10f %10f %5d %5d %10f %10f %10f\n", xr, yr, gamma, iter, numgood, diff_rms, diff_max, data_rms); ShowStr(_grTempString); sprintf(_grTempString, "%15s %15s %15s %15s %15s\n", "x", "y", "z", "z_pred", "|difference|"); ShowStr(_grTempString); for (k = 0; k < numgood; k++) { double diff = GRI_ABS(zgood[k] - z_cv[k]); sprintf(_grTempString, " %15f %15f %15f %15f %15f\n", xgood[k], ygood[k], zgood[k], z_cv[k], diff); ShowStr(_grTempString); } delete [] W; return true; } // Find value in grid bool grid_interp(double xx, double yy, double *value) { double Dx, Dy; // width/height of domain with point double f0, f1, f2, f3; double missing = gr_currentmissingvalue(); // Find (ii,jj) such that _xmatrix[ii] _xmatrix[_num_xmatrix_data - 1] || xx < _xmatrix[0]) return false; if (xx > _xmatrix[0]) { for (i = 0; i < _num_xmatrix_data - 1; i++) { if (_xmatrix[i] <= xx && xx <= _xmatrix[i + 1]) break; } } else { i = 0; } } else { if (xx < _xmatrix[_num_xmatrix_data - 1] || xx > _xmatrix[0]) return false; if (xx < _xmatrix[0]) { for (i = 0; i < _num_xmatrix_data - 1; i++) { if (_xmatrix[i] >= xx && xx >= _xmatrix[i + 1]) break; } } else { i = 0; } } if (_ygrid_increasing) { if (yy > _ymatrix[_num_ymatrix_data - 1] || yy < _ymatrix[0]) return false; if (yy > _ymatrix[0]) { for (j = 0; j < _num_ymatrix_data - 1; j++) { if (_ymatrix[j] <= yy && yy <= _ymatrix[j + 1]) break; } } else { j = 0; } } else { if (yy < _ymatrix[_num_ymatrix_data - 1] || yy > _ymatrix[0]) return false; if (yy < _ymatrix[0]) { for (j = 0; j < _num_ymatrix_data - 1; j++) { if (_ymatrix[j] >= yy && yy >= _ymatrix[j + 1]) break; } } else { j = 0; } } assert (i < _num_xmatrix_data); assert (j < _num_ymatrix_data); double dx; // x - x_to_left double dy; // y - y_below // Fiddle with dx,dy,Dx,Dy, to avoid looking past array dx = i == _num_xmatrix_data - 1 ? 0.0 : xx - _xmatrix[i]; dy = j == _num_ymatrix_data - 1 ? 0.0 : yy - _ymatrix[j]; if (_legit_xy(i, j) == false || (dx != 0.0 && _legit_xy(i + 1, j) == false) || (dy != 0.0 && _legit_xy(i, j + 1) == false) || (dx != 0.0 && dy != 0.0 && _legit_xy(i + 1, j + 1) == false)) { *value = missing; return false; } f0 = _f_xy(i, j); f1 = dx != 0 ? _f_xy(i + 1, j) - f0 : 0.0; f2 = dy != 0 ? _f_xy(i, j + 1) - f0 : 0.0; f3 = dx != 0 && dy != 0 ? _f_xy(i + 1, j + 1) - f0 - f1 - f2 : 0; Dx = dx != 0 ? _xmatrix[i + 1] - _xmatrix[i] : 1; Dy = dy != 0 ? _ymatrix[j + 1] - _ymatrix[j] : 1; *value = f0 + f1 * dx / Dx + f2 * dy / Dy + f3 * dx / Dx * dy / Dy; return true; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/command.cc����������������������������������������������������������������������������������0000644�0001750�0001750�00000075171�13147557614�012547� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ //#define DEBUG_COMMAND #include #include #include #include #if defined(HAVE_LSTAT) #include #endif #if defined(CPLUSPLUSNEW) #include #else #include #endif #include "gr.hh" #include "extern.hh" #include "private.hh" #include "files.hh" #include "tags.hh" #include "command.hh" #include "superus.hh" std::vector bsStack; static inline bool testible(const char *s); static inline int white_space(const char *sp); static inline int word_length(const char *s); static bool extract_help(FILE * fp, char *line); static bool extract_procedure(FILE * fp, char *line); static bool extract_syntax(char *line); static bool perform_new_command(const char *s); // Store info about execution blocks. bool get_line_in_block(const char *block, unsigned int *offset); const char *_command_word_separator = "-----"; int _num_command_word = 0; char *_command_word[MAX_cmd_word]; static bool have_command_word_buffer = false; void display_command_word_buffer(char *); void display_cmd_being_done_stack(void); void register_source(void); bool listCmd() { if (_nword == 1) { err("`list' what?"); return false; } // Try to use tempnam(), or tmpnam(), before using hardwired name FILE *fp; std::string tmpname_file(tmp_file_name()); if (!(fp = fopen(tmpname_file.c_str(), "w"))) { err("Error opening buffer-file for `list' command"); return false; } // Figure out what command, and give help for it. int i = 0; while (!isspace(*(_cmdLine + i))) i++; while (isspace(*(_cmdLine + i))) i++; strcat(_cmdLine, " *"); bool found = false; for (int cmd = 0; cmd < _num_command; cmd++) { if (same_syntax(_cmdLine + i, _command[cmd].syntax, 1)) { found = true; fprintf(fp, "%s\n{\n", _command[cmd].help); fprintf(fp, "%s}\n", _command[cmd].procedure); } } if (found) { fclose(fp); more_file_to_terminal(tmpname_file.c_str()); delete_file(tmpname_file.c_str()); } else { fclose(fp); delete_file(tmpname_file.c_str()); err("Help ?WHAT?"); } return true; } // BUG -- not used 1.065?? void dup_cmd_being_done_stack() { if (_cmd_being_done < cmd_being_done_LEN) { _cmd_being_done_code[_cmd_being_done] = _cmd_being_done_code[_cmd_being_done - 1]; } _cmd_being_done++; } void push_cmd_being_done_stack(int cmd) { if (_cmd_being_done < cmd_being_done_LEN) { _cmd_being_done_code[_cmd_being_done] = cmd; } _cmd_being_done++; } void pop_cmd_being_done_stack() { if (_cmd_being_done > 0) { _cmd_being_done--; } } int cmd_being_done() { if (_cmd_being_done > 0) return _cmd_being_done_code[_cmd_being_done - 1]; else return -1; } void display_cmd_being_done_stack() { int i; for (i = _cmd_being_done - 1; i > -1; i--) { if (i == _cmd_being_done - 1) gr_textput(" called by: `"); else gr_textput(" which was called by: `"); gr_textput(_command[_cmd_being_done_code[i]].syntax); ShowStr("'\n"); } } bool nullCmd() { return true; } // Return 1 if first character is '`', which indicates defn of new gri cmd bool is_create_new_command(const char *s) { register char i = 0; while (isspace(*(s + i))) i++; return ((*(s + i) == '`') ? true : false); } // Parse the command line. If it's a call to a C function, search a list // (defined in tags.h) for a C function of that name. Some restrictions // apply here; the syntax must be exactly // // extern "C" bool NAME(void) // // where NAME is the name of the C function as listed in the list stored in the // tags.h file. #define C_call "extern \"C\"" #define C_declaration " bool " int parse_C_commandCmd(const char *s) { int i = 0, start = 0; while (isspace(*(s + start))) // skip white-space start++; if (0 == strncmp(s + start, C_call, strlen(C_call))) { unsigned int length = 0; // It's a C command. Use tags.h to find a function to call start += strlen(C_call); start += strlen(C_declaration); while (*(s + start + length) && *(s + start + length) != '\n' && *(s + start + length) != '(') { length++; } // Scan to find command name. i = 0; #if 0 // test name lengths while (c_fcn[i].fcn) { if (strlen(c_fcn[i].name)!= c_fcn[i].name_len) { printf("code wants %d for \"%s\" but actually is %d\n", c_fcn[i].name_len,c_fcn[i].name,strlen(c_fcn[i].name)); } i++; } i = 0; #endif // // Using name_len, rather than strlen(.name), below, // speeds up by 7% the following test program, // with .n. valued 5e3, 10e3, 15e3, 20e3, and // with regression on the timed result. // .n. = 5000 // .i. = 0 // while {rpn .i. .n. >} // set x size 3.3 // set y size 10 // .i. += 1 // end while while (c_fcn[i].fcn) { if (length == strlen(c_fcn[i].name) //if (length == c_fcn[i].name_len && !strncmp(s + start, c_fcn[i].name, length)) { c_fcn[i].fcn(); return 1; } i++; } extern char _grTempString[]; sprintf(_grTempString, "\ Gri cannot execute the command\n\ \t %s\ since it is not defined in the tags.hh file.\n\ Please report this internal error to the author.", s); gr_Error(_grTempString); return 0; // will not be done } else { // It's not a C command. // It must be a gri command line // or a series of lines. #if 1 perform_new_command(s + start); #else GET_STORAGE(_cmd_being_done_IP[_cmd_being_done], char, 1 + strlen(s + start)); strcpy(_cmd_being_done_IP[_cmd_being_done], s + start); push_command_word_buffer(); perform_block(_cmd_being_done_IP[_cmd_being_done], _command[_cmd_being_done_code[_cmd_being_done - 1]].filename, _command[_cmd_being_done_code[_cmd_being_done - 1]].fileline ); pop_command_word_buffer(); #endif } return 1; // BUG: no check on newcommands! } // parse_C_commandCmd() #undef C_call #undef C_declaration bool perform_new_command(const char *s) { GET_STORAGE(_cmd_being_done_IP[_cmd_being_done], char, 1 + strlen(s)); strcpy(_cmd_being_done_IP[_cmd_being_done], s); push_command_word_buffer(); //printf("DEBUG %s:%d about to perform a NC <%s ...>\n",__FILE__,__LINE__,_cmdLine); marker_draw(); perform_block(_cmd_being_done_IP[_cmd_being_done], _command[_cmd_being_done_code[_cmd_being_done - 1]].filename, _command[_cmd_being_done_code[_cmd_being_done - 1]].fileline ); marker_erase(); //printf("DEBUG %s:%d done performing NC\n",__FILE__,__LINE__); pop_command_word_buffer(); free(_cmd_being_done_IP[_cmd_being_done]); // BUG: untested return true; } void no_gri_cmd(const char *msg_postscript) { std::string msg; msg.append("ERROR: Gri cannot locate the `gri.cmd' file.\n"); msg.append(" This file was expected to be at path\n "); msg.append(msg_postscript); msg.append("\n"); msg.append(" This problem may be solved in 3 ways.\n"); msg.append(" (1) Name the directory when you invoke Gri, e.g.\n"); msg.append(" gri -directory /usr/share/gri/lib\n"); msg.append(" (2) Set an environment variable named GRI_DIRECTORY_LIBRARY\n"); msg.append(" to the name of the directory.\n"); msg.append(" (3) Recompile Gri so it will know where to look; see the\n"); msg.append(" INSTALL file in the source directory for instructions).\n"); //char wd[1024], *ptr = wd; //ptr = getcwd(ptr,1023); //msg.append("DEBUG INFO FOR DEVELOPER: in no_gri_cmd() the working directory is '"); //msg.append(ptr); //msg.append("'\n"); gr_textput(msg.c_str()); gri_exit(1); } bool create_commands(const char *filename, bool user_gave_directory) { std::string fullfilename(_lib_directory.c_str()); // Must check for '/' as file separator, on some machines. #if !defined(VMS) #if defined(MSDOS) // Insert a '\' if required if (fullfilename[fullfilename.length() - 1] != '\\') { fullfilename += "\\"; } #else // Insert a '/' if required if (fullfilename[fullfilename.length() - 1] != '/') { fullfilename += "/"; } #endif #endif fullfilename += filename; #ifdef OSX_BUNDLE //fullfilename = "/Applications/Gri/gri.cmd"; extern std::string _lib_directory; fullfilename = _lib_directory; fullfilename.append("/gri.cmd"); // printf("DEBUG:%s:%d OSX_BUNDLE looking for %s'\n",__FILE__,__LINE__,fullfilename.c_str()); #endif if (!push_cmd_file(fullfilename.c_str(), false, false, "r")) { if (user_gave_directory) { no_gri_cmd(fullfilename.c_str()); // exits } char *gri_directory_library = egetenv("GRI_DIRECTORY_LIBRARY"); if (*gri_directory_library == '\0') no_gri_cmd(fullfilename.c_str()); // exits std::string envvar_location(gri_directory_library); envvar_location.append("/gri.cmd"); printf("TRY <%s>\n",envvar_location.c_str()); if (!push_cmd_file(envvar_location.c_str(), false, false, "r")) no_gri_cmd(envvar_location.c_str()); // exits } /* First, see if the version number in gri.cmd matches hard-wired one. The gri.cmd is of the form: // gri - scientific graphic program (version 2.1.6) and is contained on first line of file. */ get_command_line(); char *s = _cmdLine; while (*s != '(') s++; int major_version, minor_version, minor_minor_version; if (3 != sscanf(s, "(version %d.%d.%d)", &major_version, &minor_version, &minor_minor_version)) { warning("Cannot find version info in gri.cmd"); } else { int major2 = int(floor(1e-10+_version)); int minor2 = int(floor(1e-10 + 100.0*(_version - major2))); int minor_minor2 = int(floor(1e-10+10000.0*(_version - major2 - 0.01*minor2))); if (major2 != major_version || minor2 != minor_version || minor_minor2 != minor_minor_version) { char msg[200]; sprintf(msg, "Gri version number (%d.%d.%d) doesn't match version (%d.%d.%d) in library file gri.cmd", major2, minor2, minor_minor2, major_version, minor_version, minor_minor_version); warning(msg); } } // Finally, ok to process the startup file while (do_command_line()) { ; // EMPTY } return true; } bool create_new_command(FILE * fp, char *line) { if (_num_command >= COMMAND_STACK_SIZE) fatal_err("Too many commands defined"); if (!extract_syntax(line)) fatal_err("Can't extract syntax for new command `\\", line, "'", "\\"); if (!extract_help(fp, line)) fatal_err("Can't extract help for new command `\\", _command[_num_command].syntax, "'", "\\"); register_source(); // Note file/line where defined if (!extract_procedure(fp, line)) fatal_err("Can't extract procedure for new command `\\", _command[_num_command].syntax, "'", "\\"); // Warn if matches existing syntax, but has different procedure. If the // procedure is the same, no warning. This is to allow for the re-use of // code with different help messages and different "looking" syntax; e.g. // the following have the same procedure, and are syntactically // identical, but are separated for ease of documenting in the help // files: `draw symbol .code.|\name at .x. .y. [cm]' `draw symbol // [.code.|\name]' int existing = match_gri_syntax(_command[_num_command].syntax, 0); if (existing && strcmp(_command[_num_command].procedure, _command[existing - 1].procedure) && *(_command[_num_command].syntax) != '?') { warning("Your new command\n `\\", _command[_num_command].syntax, "'\n\ matches a pre-existing command, but has a different procedure.\n\ The *older* definition will be used.", "\\"); extern char source_indicator[]; printf(" NB: the proposed new cmd is `%s' at %s\n", _command[_num_command].syntax, source_indicator); printf(" NB: the existing new cmd is `%s' at %s\n", _command[existing-1].syntax, source_indicator); } _num_command++; return true; } void register_source() { GET_STORAGE(_command[_num_command].filename, char, 1 + strlen(_cmdFILE.back().get_name())); strcpy(_command[_num_command].filename, _cmdFILE.back().get_name()); _command[_num_command].fileline = _cmdFILE.back().get_line() + 1; } // require closing ' to be on same line as opening ` static bool extract_syntax(char *line) { char *cp; // Register file/line where defined (used later to determine line numbers // if error GET_STORAGE(_command[_num_command].filename, char, 1 + strlen(_cmdFILE.back().get_name())); strcpy(_command[_num_command].filename, _cmdFILE.back().get_name()); _command[_num_command].fileline = _cmdFILE.back().get_line(); GET_STORAGE(_command[_num_command].syntax, char, 1 + strlen(line)); cp = _command[_num_command].syntax; while (*line == ' ' || *line == '\t') // skip initial white space line++; while (*++line != '\'') { if (*line == '\n' || *line == '\0') { err("Missing final ' on new command definition line"); return false; } *cp++ = *line; } *cp = '\0'; _cmdFILE.back().increment_line(); return true; } // extract_help() - extract help lines for new command, getting // new lines from file 'fp', and starting with string 'line', // which contains the syntax, as the first line of the help. bool extract_help(FILE * fp, char *line) { unsigned size = 2 + strlen(line); // total length of help unsigned offset = 0; // where to put next char size = strlen(line) + 1 + 2; // for string catted below char *cp = NULL; GET_STORAGE(cp, char, size); strcpy(cp, line); strcat(cp, "\n\n"); offset = size - 1; while (!feof(fp)) { unsigned len; // length of a given line unsigned i; char lastc = '\0'; if (NULL == fgets(line, LineLength, fp)) break; fix_line_ending(line); _command[_num_command].fileline++; _cmdFILE.back().increment_line(); insert_cmd_in_ps(line/*, "command.cc:387"*/); len = strlen(line); size += len + 2; // chars for NEWLINE and NULL (needed?) if (NULL == (cp = (char *) realloc(cp, size))) { gr_Error("Can't reallocate space for help for new command"); free(cp); // BUG: need this? return false; } // An unprotected '{' designates end of help text for (i = 0; i < len; i++) { if (*(line + i) == '{') { if (lastc == '\\') { // Brace was protected, so overwrite the backslash *(cp + offset - 1) = '{'; lastc = '{'; } else { // Unprotected -- check rest is whitespace for (unsigned int ii = i + 1; ii < len; ii++) { if (*(line + ii) == '\n' || *(line + ii) == '\r' // DOS || *(line + ii) == '\0') { break; } else if (!isspace(*(line + ii))) { err("Require `{' to be on line by itself."); free(cp); return false; } } *(cp + offset++) = '\0'; _command[_num_command].help = cp; return true; } } else { // Normal character *(cp + offset++) = lastc = *(line + i); } } } cp[0] = '\0'; return false; } // extract_procedure() - extract procedure portion of new command BUG: stops // when sees "}" as the first character of a line; should really tally the {} // pairs instead. BUG: dies if "`" is seen at the start of a line; this is // taken as an indication that the procedure was not terminated properly. // This might be a useless test. bool extract_procedure(FILE * fp, char *line) { int size = 0; if (!re_compare(line, "\\s*{\\s*")) { err("Couldn't find { in the following line `\\", line, "'", "\\"); return false; } GET_STORAGE(_command[_num_command].procedure, char, 2); strcpy(_command[_num_command].procedure, ""); while (!feof(fp)) { if (NULL == fgets(line, LineLength, fp)) break; fix_line_ending(line); #if 0 // messing up if (((unsigned) superuser()) & FLAG_AUT1) { extern void insert_source_indicator(char *cl); insert_source_indicator(line); } #endif if (feof(fp)) break; insert_cmd_in_ps(line /*, "command.cc:454"*/); //printf("\n[%s] ", line); remove_comment(line); //printf("-> [%s]\n",line); // Test whether starting to define a newcommand within this one if (*(line + skip_space(line)) == '`') { err("Missing `}' in procedure body."); return false; } if (*line == '}') { if (((unsigned) superuser()) & FLAG_AUT2) printf("%s:%d got procedure: <%s>\n",__FILE__,__LINE__,_command[_num_command].procedure); return true; } _cmdFILE.back().increment_line(); unsigned len = 0; while (line[len] != '\0' ) { len++; } if (len == 0) continue; if (len > 1 && *(line + len - 2) == '\\') *(line + len - 2) = '\0'; else if (*(line + len - 1) != '\n') *(line + len - 1) = '\n'; size += len; _command[_num_command].procedure = (char *) realloc(_command[_num_command].procedure, 1 + size); if (!_command[_num_command].procedure) { err("Insufficient storage space for new command."); return false; } strcat(_command[_num_command].procedure, line); } err("Missing `}' in procedure body ... EOF encountered."); return false; } // Does syntax match a gri command? RETURN (1 + cmd) or 0 if not matching // any known command int match_gri_syntax(const char *cmdline, int flag) { int cmd; for (cmd = 0; cmd < _num_command; cmd++) if (same_syntax(cmdline, _command[cmd].syntax, flag)) return (1 + cmd); return 0; } // return 1 if syntax is the same. If flag = 1 then being called by help, // and "*" in cmdline matches any word or words following in syntax bool same_syntax(const char *cmdline, const char *syntax, int flag) { if (cmdline == NULL) return false; int ci = 0, si = 0; while (flag || testible(syntax + si)) { if (cmdline[ci] == '\0' || cmdline[ci] == '\n') return isspace(syntax[si]) ? true : false; if (syntax[si] == '\0' || syntax[si] == '\n') return true; // at end-of-line if (flag && cmdline[ci] == '*') return true; // being used for help, not cmd parsing if (!same_word(cmdline + ci, syntax + si)) return false; // words differ, cannot be same syntax ci += word_length(cmdline + ci); ci += white_space(cmdline + ci); si += word_length(syntax + si); si += white_space(syntax + si); } return true; } inline bool testible(const char *s) { if (*s == '.') return false; if (*s == '\\') return false; if (*s == '[') return false; if (*s == '"') return false; if (*s == '{') return false; if (*s == '&') return false; if (*s == '*') return false; if (*s == '\n') return false; if (*s == '\0') return false; // May still be non-testible, if the next character after the next blank // is | while (!isspace(*s)) { if (*s == '|') return false; if (*s == '\0' || *s == '\n') return true; s++; } while (isspace(*s)) s++; if (*s == '|') return false; return true; } static inline int word_length(const char *s) { register int i = 0; while (*(s + i) != ' ' && *(s + i) != '\t' && *(s + i) != '\n' && *(s + i) != '\0') i++; return i; } // Return number of white characters after point static inline int white_space(const char *sp) { if (*sp == '\0') return 0; else { int i = 0; while (*(sp + i) == ' ' || *(sp + i) == '\t') i++; return i; } } // same_word () - are the words cp (command) and sp (syntax) the same? bool same_word(const char *cp, const char *sp) { int cplen = skip_nonspace(cp); int splen = skip_nonspace(sp); if (cplen != splen) return false; else { return (!strncmp(cp, sp, cplen) ? true : false); } } // Register, then perform, indicated command. int perform_gri_cmd(int cmd) { return parse_C_commandCmd(_command[cmd].procedure); } // Maintain linear pushdown buffer of command-words for \.word0. etc void push_command_word_buffer() { // Figure out where last chunk started, so can nest & syntax, int last_separator_at = -1; for (int ii = _num_command_word - 1; ii >= 0; ii--) { if (strEQ(_command_word[ii],_command_word_separator)) { last_separator_at = ii; break; } } char *cp = NULL; // assignment prevents warning GET_STORAGE(cp, char, 1 + strlen(_command_word_separator)); strcpy(cp, _command_word_separator); _command_word[_num_command_word] = cp; _num_command_word++; if (_num_command_word >= MAX_cmd_word) { gr_Error("ran out of storage (must increase MAX_cmd_word in private.hh"); } for (unsigned int i = 0; i < _nword; i++) { //printf("DEBUG %s:%d push_command_word_buffer loop i= %d word[i]= <%s>\n",__FILE__,__LINE__,i,_word[i]); if (*_word[i] == '&') { // 2001-feb-10 trying new syntax //printf("DEBUG %s:%d & found on word[%d] <%s>\n",__FILE__,__LINE__,i,_word[i]); const char *name = 1 + _word[i]; char buf[300]; // BUG: should make bigger int cmd_word_index = -1; if (1 == sscanf(name, "\\.word%d.", &cmd_word_index)) { // Nesting //printf("DEBUG %s:%d & on \\.word%d. last_sep at %d\n",__FILE__,__LINE__,cmd_word_index,last_separator_at); std::string the_cmd_word; //for (int ii = _num_command_word - 1; ii >= 0; ii--) printf("DEBUG %s:%d stack %3d [%s] %d\n",__FILE__,__LINE__,ii,_command_word[ii],ii-last_separator_at); if (last_separator_at + cmd_word_index + 1 < _num_command_word) { char *cw = _command_word[last_separator_at + cmd_word_index + 1]; //printf("DEBUG %s:%d think it's [%s]\n",__FILE__,__LINE__,cw); GET_STORAGE(cp, char, strlen(cw + 1)); strcpy(cp, cw); } else { err("Internal error command.cc:672; contact author"); } } else if (is_var(name)) { // Variable int index = index_of_variable(name); if (index < 0) { err("cannot do \\", _word[i], " since `", name, "' does not exist", "\\"); return; } sprintf(buf, AMPERSAND_CODING, 1 + _word[i], marker_count()); GET_STORAGE(cp, char, 1 + strlen(buf)); strcpy(cp, buf); //printf("DEBUG %s:%d WAS VAR. made <%s>\n",__FILE__,__LINE__,cp); } else if (is_syn(name)) { // Synonym int index = index_of_synonym(name); if (index < 0) { err("cannot do \\", _word[i], " since `", name, "' does not exist", "\\"); return; } sprintf(buf, AMPERSAND_CODING, 1 + _word[i], marker_count()); GET_STORAGE(cp, char, 1 + strlen(buf)); strcpy(cp, buf); //printf("DEBUG %s:%d WAS SYN. made <%s>\n",__FILE__,__LINE__,cp); } else { err("INTERNAL ERROR command.cc:677 -- notify author\n"); return; } } else if (is_var(_word[i])) { // 2000-dec-18 SF bug 122893 double v; bool ok = get_var(_word[i], &v); if (ok) { char value[100]; sprintf(value, "%g", v); GET_STORAGE(cp, char, 1 + strlen(value)); strcpy(cp, value); } else { GET_STORAGE(cp, char, 2); strcpy(cp, "0"); } } else { GET_STORAGE(cp, char, 1 + strlen(_word[i])); strcpy(cp, _word[i]); } _command_word[_num_command_word] = cp; //printf("DEBUG %s:%d pushed command word %d as '%s'\n", __FILE__, __LINE__, _num_command_word, _command_word[_num_command_word]); _num_command_word++; if (_num_command_word >= MAX_cmd_word) { gr_Error("ran out of storage (must increase MAX_cmd_word in private.hh"); } } } void pop_command_word_buffer() { // Trash last end-point, then find new start-point by looking backwards // for most recently pushed separator if (_num_command_word > 1) { for (int i = _num_command_word - 1; i > -1; i--) { if (!strcmp(_command_word[i], _command_word_separator)) { _num_command_word = i; free((char *) _command_word[i]); break; } else { free((char *) _command_word[i]); } } } } void display_command_word_buffer(const char *s) { int i; if (_num_command_word > 0) { for (i = 0; i < _num_command_word; i++) { printf("%s\t%d/%d `%s'\n", s, i, _num_command_word, _command_word[i]); } } else { printf("%s ...empty...\n", s); } } void set_up_command_word_buffer() { if (!have_command_word_buffer) { _num_command_word = 0; have_command_word_buffer = true; } } // Return true if got to end without executing a `break' or `quit' // NOTE: catch 'while' and 'system' commands and run them here, // since they are special cases. bool perform_block(const char *block, const char *source_file, int source_line) { unsigned int lines = 0, offset = 0; BlockSource bs(block, source_file, source_line); bsStack.push_back(bs); // Scan through block line by line. If a 'while' is found, then scan the // loop and give it to perform_while_block. extern int chars_read; // defined in read.cc while (get_line_in_block(block, &offset)) { lines++; massage_command_line(_cmdLine); if (_nword == 1 && (word_is(0, "break") || word_is(0, "return") || word_is(0, "quit")) && !skipping_through_if()) { if (word_is(0, "quit")) quitCmd(); bsStack.pop_back(); return false; } if (word_is(0, "read") && !skipping_through_if()) { extern unsigned int offset_for_read; offset_for_read = offset; } else if (*_word[0] == '\\' && word_is(1, "=") && word_is(2, "system") && !skipping_through_if()) { extern unsigned int offset_for_read; offset_for_read = offset; } if (word_is(0, "while") && !skipping_through_if()) { // Capture the loop (look for matching 'end while') std::string test; unsigned buffer_offset = offset; int loop_level = 1; test.assign((char*)(6 + (char*)strstr(_cmdLine, "while"))); if (re_compare(test.c_str(), " *")) { err("`while .test.|{rpn ...}' missing the test part"); bsStack.pop_back(); return false; } std::string buffer; while (get_line_in_block(block, &buffer_offset)) { // Search for matching `end while' if (re_compare(_cmdLine, "\\s*while.*")) { loop_level++; } else if (re_compare(_cmdLine, "\\s*end\\s+while\\s*.*")) { loop_level--; if (loop_level < 1) { break; } } buffer.append(_cmdLine); buffer.append("\n"); } if (loop_level != 0) { err("Missing `end while'."); bsStack.pop_back(); return false; } perform_while_block(buffer.c_str(), test.c_str(), lines); // Adjust 'offset' to skip this interior loop, then skip the `end // while' line. Therefore will next capture line after the loop. offset += buffer.size() + 1; // point to after this loop get_line_in_block(block, &offset); // skip `end while' //printf("AFTER THE WHILE, \n~~~%s~~~\n",block+offset); } else if (word_is(0, "system")) { // Intercept system commands, since if they are of the // < <%s> <%s>\n",_cmdLine, _cmdLine+skip_space(_cmdLine),read_until.c_str()); if (!strncmp(_cmdLine + skip_space(_cmdLine), read_until.c_str(), read_until.size())) { cmd.append("\n"); cmd.append(_cmdLine + skip_space(_cmdLine)); //printf("PUT IN <%s>\nFULL IS:\n<%s>",_cmdLine + skip_space(_cmdLine),cmd.c_str()); break; } cmd.append("\n"); cmd.append(_cmdLine); } if (!skipping_through_if()) { std::string cmd_new; substitute_synonyms_cmdline(cmd.c_str(), cmd_new, false); status = call_the_OS(cmd_new.c_str(), __FILE__, __LINE__); PUT_VAR("..exit_status..", (double) status); } } else { // It's just a simple system command. if (!skipping_through_if()) { status = call_the_OS(s, __FILE__, __LINE__); PUT_VAR("..exit_status..", (double) status); } } } else { // It's not a system command chars_read = 0; perform_command_line(NULL, true); offset += chars_read; //printf("DEBUG %s:%d AFTER PERFORMING CMD LINE chars read= %d. next is what's left:\n{%s}\n",__FILE__,__LINE__,chars_read,block+offset); } #if 0 // Increment offset bsStack[bsStack.size() - 1].increment_offset(); #endif // See if an error, or if `quit' executed stop_replay_if_error(); if (_done) { bsStack.pop_back(); return false; } } // while (get_line_in_block(block, &offset)) bsStack.pop_back(); return true; } // perform_block int block_level() { return bsStack.size(); } // Do not call this if block_level()<=0 const char* block_source_file() { if (bsStack.size() < 1) { gr_Error("Underflow of block-stack (internal error)"); } return bsStack[bsStack.size() - 1].get_filename(); } // Do not call this if block_level()<=0 unsigned int block_source_line() { if (bsStack.size() < 1) { gr_Error("Underflow of block-stack (internal error)"); } return bsStack[bsStack.size() - 1].get_line(); } // Do not call this if block_level()<=0 unsigned int block_offset_line() { if (bsStack.size() < 1) { gr_Error("Underflow of block-stack (internal error)"); } return bsStack[bsStack.size() - 1].get_offset(); } // Return true if got a line bool get_line_in_block(const char *block, unsigned int *offset) { //printf("DEBUG %s:%d in get_line_in_block ... <%s>\n",__FILE__,__LINE__,block+*offset); if (*(block + *offset) == '\0') return false; unsigned int i = 0; while (1) { if (*(block + *offset) == '\n') { *(_cmdLine + i) = '\0'; (*offset)++; bsStack.back().increment_line(strlen(_cmdLine)); return true; } else if (*(block + *offset) == '\0') { *(_cmdLine + i) = '\0'; bsStack.back().increment_line(strlen(_cmdLine)); // Note -- next time will still point to '\0', and will catch return true; } *(_cmdLine + i++) = *(block + (*offset)++); } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/show.cc�������������������������������������������������������������������������������������0000644�0001750�0001750�00000061510�13147557614�012101� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include #include "gr.hh" #include "extern.hh" #include "image_ex.hh" #include "private.hh" #include "files.hh" #include "DataFile.hh" extern char _grTempString[]; bool show_expression_or_stringCmd(void); bool show_axesCmd(void); bool show_licenseCmd(void); bool show_miscCmd(void); bool show_colorCmd(void); bool show_colornamesCmd(void); bool show_columnsCmd(void); bool show_columns_statisticsCmd(void); bool show_flagsCmd(void); static bool show_grid(void); bool show_gridCmd(void); bool show_hintCmd(void); bool show_imageCmd(void); bool show_next_lineCmd(void); #if 0 bool show_stopwatchCmd(void); // moved to timer.cc #endif bool show_allCmd(void); bool show_variablesCmd(void); bool show_timeCmd(void); bool show_synonymsCmd(void); static const unsigned int GRID_MAX_WIDTH_TO_SHOW = 32; #define IMAGE_MAX_WIDTH_TO_SHOW 32 #define MISSING " ---missing--- " // If end in "...", no newline added bool show_expression_or_stringCmd() { bool no_newline = false; double value; Require(_nword > 1, err("`show' what?")); for (unsigned int i = 1; i < _nword; i++) { if (i == (_nword - 1) && !strcmp(_word[i], "...")) { no_newline = true; break; } if (*_word[i] == '"') { // Copy to 's' the unquoted string. int len = strlen(_word[i]); if (len > 2) { char *s = new char[1 + len]; if (!s) OUT_OF_MEMORY; strncpy(s, 1 + _word[i], len - 2); *(s + len - 2) = '\0'; remove_esc_quotes(s); // may shorten, but can't lengthen ShowStr(s); delete [] s; } } else if (getdnum(_word[i], &value)) { if (gr_missing(value)) { ShowStr("missing_value_code"); } else { // Use integer format if that's valid if (value == double(int(value))) { sprintf(_grTempString, "%d", int(value)); } else { sprintf(_grTempString, "%g", value); } ShowStr(_grTempString); } } else { err("`show' doesn't understand item `\\", _word[i], "'", "\\"); return false; } } if (!no_newline) ShowStr("\n"); return true; } bool show_axesCmd() { double tmp; if (get_var("..xsize..", &tmp)) { sprintf(_grTempString, "Plot is %.1f cm wide, ", tmp); ShowStr(_grTempString); } if (get_var("..ysize..", &tmp)) { sprintf(_grTempString, "%.1f cm tall; margins ", tmp); ShowStr(_grTempString); } if (get_var("..xmargin..", &tmp)) { sprintf(_grTempString, "%.1f cm at left, ", tmp); ShowStr(_grTempString); } if (get_var("..ymargin..", &tmp)) { sprintf(_grTempString, "%.1f cm at bottom.\n", tmp); ShowStr(_grTempString); } if (_xscale_exists) { if (_xtype == gr_axis_LINEAR) { sprintf(_grTempString, "Linear x axis, named `%s'\n ranges from %f to %f stepping by %f\n", _colX.getName(), _xleft, _xright, _xinc); } else if (_xtype == gr_axis_LOG) { sprintf(_grTempString, "Logarithmic x axis, named `%s'\n ranges from %f to %f stepping by %f\n", _colX.getName(), _xleft, _xright, _xinc); } else { sprintf(_grTempString, "Unknown-type x axis, named `%s'\n ranges from %f to %f stepping by %f\n", _colX.getName(), _xleft, _xright, _xinc); } ShowStr(_grTempString); if (_clipData) { ShowStr(" Data are clipped to these limits\n"); } else { ShowStr(" Data are not clipped to these limits\n"); } } else { ShowStr("x scale not defined yet\n"); } if (_yscale_exists) { if (_ytype == gr_axis_LINEAR) { sprintf(_grTempString, "Linear y axis, named `%s'\n ranges from %f to %f stepping by %f\n", _colY.getName(), _ybottom, _ytop, _yinc); } else if (_ytype == gr_axis_LOG) { sprintf(_grTempString, "Logarithmic y axis, named `%s'\n ranges from %f to %f stepping by %f\n", _colY.getName(), _ybottom, _ytop, _yinc); } else { sprintf(_grTempString, "Unknown-type y axis, named `%s'\n ranges from %f to %f stepping by %f\n", _colY.getName(), _ybottom, _ytop, _yinc); } ShowStr(_grTempString); if (_clipData) { ShowStr(" Data are clipped to these limits\n"); } else { ShowStr(" Data are not clipped to these limits\n"); } } else { ShowStr("y scale not defined yet\n"); return false; } return true; } bool show_licenseCmd() { extern std::string _lib_directory; std::string license(_lib_directory.c_str()); license.append("doc/license.txt"); more_file_to_terminal(license.c_str()); return true; } bool show_miscCmd() { double tmp; ShowStr("Miscellaneous information:\n"); sprintf(_grTempString, "Missing value= %g\n", gr_currentmissingvalue()); ShowStr(_grTempString); if (get_var("..fontsize..", &tmp)) { sprintf(_grTempString, "Fontsize = %5.0f points\n", tmp); ShowStr(_grTempString); } double r, g, b, h, s, v; if (_griState.color_line().isRGB()) { r = _griState.color_line().getR(); g = _griState.color_line().getG(); b = _griState.color_line().getB(); sprintf(_grTempString, "Line color: red=%.2f green=%.2f blue=%.2f\n", r, g, b); } else { h = _griState.color_line().getH(); s = _griState.color_line().getS(); v = _griState.color_line().getV(); gr_hsv2rgb(h, s, v, &r, &g, &b); sprintf(_grTempString, "Line color: hue=%.2f saturation=%.2f brightness=%.2f\n", h, s, v); } if (r == g && g == b) sprintf(_grTempString, "Line graylevel = %5.1f (note: 0=black, 1=white)\n", r); ShowStr(_grTempString); if (_griState.color_text().isRGB()) { r = _griState.color_text().getR(); g = _griState.color_text().getG(); b = _griState.color_text().getB(); sprintf(_grTempString, "Text color: red=%.2f green=%.2f blue=%.2f\n", r, g, b); } else { h = _griState.color_text().getH(); s = _griState.color_text().getS(); v = _griState.color_text().getV(); gr_hsv2rgb(h, s, v, &r, &g, &b); sprintf(_grTempString, "Text color: hue=%.2f saturation=%.2f brightness=%.2f\n", h, s, v); } if (r == g && g == b) sprintf(_grTempString, "Text graylevel = %5.1f (note: 0=black, 1=white)\n", r); ShowStr(_grTempString); if (get_var("..linewidth..", &tmp)) { sprintf(_grTempString, "Line width = %5.1f points\n", tmp); ShowStr(_grTempString); } // Dash if (_dash.size() == 0) { ShowStr("Line is solid, not dashed\n"); } else { ShowStr("Line is dashed. Length of dash/blank/dash/blank... = "); for (unsigned int i = 0; i < _dash.size(); i++) { sprintf(_grTempString, "%.2fcm ", _dash[i]); ShowStr(_grTempString); } ShowStr("\n"); } return true; } bool show_colorCmd() { char buffer[256]; if (_griState.color_line().isRGB() == true) { sprintf(buffer, "Lines drawn in RGB color (red=%f, green=%f, blue=%f)\n", _griState.color_line().getR(), _griState.color_line().getG(), _griState.color_line().getB()); ShowStr(buffer); } else { sprintf(buffer, "Lines drawn in HSV color (hue=%f, saturation=%f, brightness=%f)\n", _griState.color_line().getH(), _griState.color_line().getS(), _griState.color_line().getV()); ShowStr(buffer); } if (_griState.color_text().isRGB() == true) { sprintf(buffer, "Text drawn in RGB color (red=%f, green=%f, blue=%f)\n", _griState.color_text().getR(), _griState.color_text().getG(), _griState.color_text().getB()); ShowStr(buffer); } else { sprintf(buffer, "Text drawn in HSV color (hue=%f, saturation=%f, brightness=%f)\n", _griState.color_text().getH(), _griState.color_text().getS(), _griState.color_text().getV()); ShowStr(buffer); } return true; } bool show_colornamesCmd() { extern bool display_colors(); display_colors(); return true; } bool show_columnsCmd() { unsigned int i; unsigned int xlength = _colX.size(); if (xlength < 1) { warning("`show columns' -- no columns exist"); return true; } unsigned int length = xlength; if (_nword == 2) { // `show columns' // print label line std::string tmp; unbackslash(_colX.getName(), tmp); sprintf(_grTempString, "\"x\" column has name `%s'\n", tmp.c_str()); unbackslash(_colY.getName(), tmp); ShowStr(_grTempString); sprintf(_grTempString, "\"y\" column has name `%s'\n", tmp.c_str()); ShowStr(_grTempString); sprintf(_grTempString, "%s:\n", "column data"); ShowStr(_grTempString); if (xlength > 0) { sprintf(_grTempString, "%15s\t", "x"); ShowStr(_grTempString); } if (_colY.size() > 0) { sprintf(_grTempString, "%15s\t", "y"); ShowStr(_grTempString); } if (_colU.size() > 0) { sprintf(_grTempString, "%15s\t", "u"); ShowStr(_grTempString); } if (_colV.size() > 0) { sprintf(_grTempString, "%15s\t", "v"); ShowStr(_grTempString); } if (_colZ.size() > 0) { sprintf(_grTempString, "%15s\t", "z"); ShowStr(_grTempString); } if (_colWEIGHT.size() > 0) { sprintf(_grTempString, "%15s\t", "weight"); ShowStr(_grTempString); } ShowStr("\n"); for (i = 0; i < length; i++) { double tmp; if (xlength > 0) { tmp = _colX[i]; if (gr_missingx(tmp)) { ShowStr(MISSING); } else { sprintf(_grTempString, "%15g\t", tmp); ShowStr(_grTempString); } } if (_colY.size() > 0) { if (_colY.size() <= i) { ShowStr(MISSING); } else { tmp = _colY[i]; if (gr_missingy(tmp)) { ShowStr(MISSING); } else { sprintf(_grTempString, "%15g\t", tmp); ShowStr(_grTempString); } } } if (_colU.size() > 0) { if (_colU.size() <= i) { ShowStr(MISSING); } else { tmp = _colU[i]; if (gr_missing(tmp)) { ShowStr(MISSING); } else { sprintf(_grTempString, "%15g\t", tmp); ShowStr(_grTempString); } } } if (_colV.size() > 0) { if (_colV.size() <= i) { ShowStr(MISSING); } else { tmp = _colV[i]; if (gr_missing(tmp)) { ShowStr(MISSING); } else { sprintf(_grTempString, "%15g\t", tmp); ShowStr(_grTempString); } } } if (_colZ.size() > 0) { if (_colZ.size() <= i) { ShowStr(MISSING); } else { tmp = _colZ[i]; if (gr_missing(tmp)) { ShowStr(MISSING); } else { sprintf(_grTempString, "%15g\t", tmp); ShowStr(_grTempString); } } } if (_colWEIGHT.size() > 0) { if (_colWEIGHT.size() <= i) { ShowStr(MISSING); } else { tmp = _colWEIGHT[i]; if (gr_missing(tmp)) { ShowStr(MISSING); } else { sprintf(_grTempString, "%15g\t", tmp); ShowStr(_grTempString); } } } ShowStr("\n"); } } else if (_nword == 3 && !strncmp(_word[2], "sta", 3)) { // `show columns statistics' show_columns_statisticsCmd(); } return true; } bool show_columns_statisticsCmd() { double ave, adev, sdev, svar, skew, kurt, q1, q2, q3; if (_colX.size() > 0) { moment(_colX.begin(), _colX.size(), &ave, &adev, &sdev, &svar, &skew, &kurt); histogram_stats(_colX.begin(), _colX.size(), &q1, &q2, &q3); sprintf(_grTempString, "\ x[1-%4d]: mean stddev skewness kurtosis\n\ %12g %12g %12g %12g\n", (unsigned int)(_colX.size()), ave, sdev, skew, kurt); gr_textput(_grTempString); sprintf(_grTempString, "\ minimum q1 median q3 maximum\n\ %12g %12g %12g %12g %12g\n", _colX.min(), q1, q2, q3, _colX.max()); gr_textput(_grTempString); } if (_colY.size() > 0) { moment(_colY.begin(), _colY.size(), &ave, &adev, &sdev, &svar, &skew, &kurt); histogram_stats(_colY.begin(), _colY.size(), &q1, &q2, &q3); sprintf(_grTempString, "\ y[1-%4d]: mean stddev skewness kurtosis\n\ %12g %12g %12g %12g\n", int(_colY.size()), ave, sdev, skew, kurt); gr_textput(_grTempString); sprintf(_grTempString, "\ minimum q1 median q3 maximum\n\ %12g %12g %12g %12g %12g\n", _colY.min(), q1, q2, q3, _colY.max()); gr_textput(_grTempString); } if (_colZ.size() > 0) { moment(_colZ.begin(), _colZ.size(), &ave, &adev, &sdev, &svar, &skew, &kurt); histogram_stats(_colZ.begin(), _colZ.size(), &q1, &q2, &q3); sprintf(_grTempString, "\ z[1-%4d]: mean stddev skewness kurtosis\n\ %12g %12g %12g %12g\n", int(_colZ.size()), ave, sdev, skew, kurt); gr_textput(_grTempString); sprintf(_grTempString, "\ minimum q1 median q3 maximum\n\ %12g %12g %12g %12g %12g\n", _colZ.min(), q1, q2, q3, _colZ.max()); gr_textput(_grTempString); } if (_colU.size() > 0) { moment(_colU.begin(), _colU.size(), &ave, &adev, &sdev, &svar, &skew, &kurt); histogram_stats(_colU.begin(), _colU.size(), &q1, &q2, &q3); sprintf(_grTempString, "\ u[1-%4d]: mean stddev skewness kurtosis\n\ %12g %12g %12g %12g\n", int(_colU.size()), ave, sdev, skew, kurt); gr_textput(_grTempString); sprintf(_grTempString, "\ minimum q1 median q3 maximum\n\ %12g %12g %12g %12g %12g\n", _colU.min(), q1, q2, q3, _colU.max()); gr_textput(_grTempString); } if (_colV.size() > 0) { moment(_colV.begin(), _colV.size(), &ave, &adev, &sdev, &svar, &skew, &kurt); histogram_stats(_colV.begin(), _colV.size(), &q1, &q2, &q3); sprintf(_grTempString, "\ v[1-%4d]: mean stddev skewness kurtosis\n\ %12g %12g %12g %12g\n", int(_colV.size()), ave, sdev, skew, kurt); gr_textput(_grTempString); sprintf(_grTempString, "\ minimum q1 median q3 maximum\n\ %12g %12g %12g %12g %12g\n", _colV.min(), q1, q2, q3, _colV.max()); gr_textput(_grTempString); } if (_colWEIGHT.size() > 0) { moment(_colWEIGHT.begin(), _colWEIGHT.size(), &ave, &adev, &sdev, &svar, &skew, &kurt); histogram_stats(_colWEIGHT.begin(), _colWEIGHT.size(), &q1, &q2, &q3); sprintf(_grTempString, "\ weight[1-%4d]: mean stddev skewness kurtosis\n\ %12g %12g %12g %12g\n", int(_colWEIGHT.size()), ave, sdev, skew, kurt); gr_textput(_grTempString); sprintf(_grTempString, "\ minimum q1 median q3 maximum\n\ %12g %12g %12g %12g %12g\n", _colWEIGHT.min(), q1, q2, q3, _colWEIGHT.max()); gr_textput(_grTempString); } return true; } bool show_flagsCmd(void) { extern void show_flags(); // set.cc show_flags(); return true; } bool show_gridCmd() { if (_nword == 2) return show_grid(); else if (_nword == 3 && word_is(2, "mask")) return show_grid_maskCmd(); else { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } } bool show_grid_maskCmd() { if (_num_ymatrix_data < 1) return true; unsigned int j = _num_ymatrix_data - 1; do { for (unsigned int i = 0; i < _num_xmatrix_data; i++) { if (_legit_xy(i, j) == true) { ShowStr("1 "); } else { ShowStr("0 "); } } ShowStr("\n"); } while (j-- != 0); return true; } static bool show_grid(void) { if (!_grid_exists && !_xgrid_exists && !_ygrid_exists) { ShowStr("No grid data exist yet.\n"); return true; } if (_xgrid_exists) { if (_num_xmatrix_data < GRID_MAX_WIDTH_TO_SHOW) { ShowStr("x-locations of matrix are:\n"); for (unsigned int i = 0; i < _num_xmatrix_data; i++) { sprintf(_grTempString, "%f\n", _xmatrix[i]); ShowStr(_grTempString); } } else { sprintf(_grTempString, "Grid `x' has %d elements (too many to display)\n", _num_xmatrix_data); ShowStr(_grTempString); } } else { ShowStr("Grid `x' not defined yet\n"); } if (_ygrid_exists) { if (_num_ymatrix_data < GRID_MAX_WIDTH_TO_SHOW) { ShowStr("y-locations of matrix are:\n"); for (unsigned int j = 0; j < _num_ymatrix_data; j++) { sprintf(_grTempString, "%f\n", _ymatrix[j]); ShowStr(_grTempString); } } else { sprintf(_grTempString, "Grid `y' has %d elements (too many to display)\n", _num_ymatrix_data); ShowStr(_grTempString); } } else { ShowStr("Grid `y' not defined yet\n"); } if (!_grid_exists) { ShowStr("Grid data don't exist yet\n"); return true; } if (_num_xmatrix_data < GRID_MAX_WIDTH_TO_SHOW && _num_ymatrix_data < GRID_MAX_WIDTH_TO_SHOW) { if (_f_min == _f_max) { if (gr_missing((double) _f_min)) { ShowStr("Grid data don't exist yet\n"); return true; } else { sprintf(_grTempString, "Grid data all equal to %f", _f_min); ShowStr(_grTempString); return true; } } else { ShowStr("Grid data:\n"); unsigned int j = _num_ymatrix_data - 1; do { for (unsigned int i = 0; i < _num_xmatrix_data; i++) { if (_legit_xy(i, j) == true) { sprintf(_grTempString, "%g\t", _f_xy(i, j)); ShowStr(_grTempString); } else { ShowStr(" * \t"); } } ShowStr("\n"); } while (j-- != 0); } } else { ShowStr("Grid `data' matrix is too big to display\n"); } sprintf(_grTempString, "Grid is %d wide and %d tall, with values ranging from %f to %f\n", _num_xmatrix_data, _num_ymatrix_data, _f_min, _f_max); ShowStr(_grTempString); #if 1 double *tmp = (double*)NULL; GET_STORAGE(tmp, double, _num_xmatrix_data * _num_ymatrix_data); unsigned int tmp_len = 0; for (unsigned int i = 0; i < _num_xmatrix_data; i++) { for (unsigned int j = 0; j < _num_ymatrix_data; j++) { if (_legit_xy(i, j) == true) { tmp[tmp_len++] = _f_xy(i, j); } } } double ave, adev, sdev, svar, skew, kurt; moment(tmp, tmp_len, &ave, &adev, &sdev, &svar, &skew, &kurt); free(tmp); sprintf(_grTempString, "Grid statistics, for %d legitimate data: mean=%f stddev=%f skewness=%f kurtosis=%f\n", tmp_len, ave, sdev, skew, kurt); ShowStr(_grTempString); #endif return true; } // DELETE THIS COMMAND FOR VERSION 2.6.0 SINCE I NO LONGER HAVE // ABILITY TO PROVIDE A CGI-BIN BASED SOURCE OF HINTS. // I TRIED USING SOURCE-FORGE (SEE BELOW) BUT PROCESSING THE // OUTPUT FROM THE 'LYNX' COMMAND IS TOO DAUNTING TO JUSTIFY, // GIVEN THAT I THINK *NOBODY* HAS EVER USED THIS COMMAND! #if 0 bool show_hintCmd() { // The next declaration contains a URL; old versions are listed in // the rest of this comment. // http://www.phys.ocean.dal.ca/cgi-bin/ocean/gri_hints const char *lynx_cmd = "lynx -dump \"http://gri.sourceforge.net/gridoc/html/Hints.html\" | tail +7 >> %s"; std::string filename(getenv("HOME")); filename.append("/.gri-hint-cache"); SECOND_TYPE sec; time(&sec); char now[30]; // 27 should be enough by Sun manpage strcpy(now, asctime(localtime(&sec))); // String now is e.g. "Thu Jul 20 19:57:26 1995\n\0"; trim to get // just the dayname/month/day unsigned int i, count = 0; for (i = 0; i < strlen(now); i++) { if (now[i] == ' ') count++; if (count == 3) break; } if (count != 3) { err("Problem figuring out time, in `show hint of the day'"); return false; } now[i] = '\0'; bool get_new_hints = false; FILE *fp = fopen(filename.c_str(), "r"); if (fp) { char file_time[100]; fgets(file_time, 99, fp); file_time[strlen(file_time) - 1 ] = '\0'; if (strcmp(file_time, now)) get_new_hints = true; fclose(fp); } else { get_new_hints = true; } char cmd[200]; if (get_new_hints) { sprintf(cmd, "echo '%s' > %s\n", now, filename.c_str()); call_the_OS(cmd, __FILE__, __LINE__); sprintf(cmd, lynx_cmd, filename.c_str()); ShowStr("Getting new hints file from Gri WWW site ..."); call_the_OS(cmd, __FILE__, __LINE__); ShowStr(" done\n"); } // Now see if we have an up-to-date hints file fp = fopen(filename.c_str(), "r"); if (!fp) { warning("Sorry, but the ~/gri-hint-cache file does not exist\n"); return true; // do not fail only because of this } sprintf(cmd, "cat %s\n", filename.c_str()); call_the_OS(cmd, __FILE__, __LINE__); return true; } #endif bool show_imageCmd() { double sum; if (_nword != 2) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (!_image.storage_exists) { ShowStr("No image exists yet\n"); return false; } sprintf(_grTempString, "Image: %d cols, %d rows, %f<=x<=%f and %f<=y<=%f\n", _image.ras_width, _image.ras_height, _image_llx, _image_urx, _image_lly, _image_ury); ShowStr(_grTempString); sprintf(_grTempString, "Image=000 <-> %f; ", _image0); ShowStr(_grTempString); sprintf(_grTempString, "Image=255 <-> %f\n", _image255); ShowStr(_grTempString); sprintf(_grTempString, "\ Image histogram:\n\ Image # Physical value Percentage Each * represents 2%% of pixels\n\ -------- ----------------------- ---------- ------------------------------\n"); ShowStr(_grTempString); calculate_image_histogram(); sum = 0.0; unsigned int modulo = 16; if (_chatty == 2) modulo = 8; else if (_chatty == 3) modulo = 4; for (unsigned int i = 0; i < 256; i++) { sum += _imageHist[i]; if (i && (!(i % modulo) || i == 255)) { sprintf(_grTempString, "%3d->%3d ", i - modulo, i); ShowStr(_grTempString); sprintf(_grTempString, "%11g->%11g %10.3f ", _image0 + (i - modulo) * (_image255 - _image0) / 255.0, _image0 + i * (_image255 - _image0) / 255.0, 100.0 * sum); ShowStr(_grTempString); if (sum > 0.0) { unsigned int num = (unsigned int) floor(50.0 * sum + 0.5); for (unsigned int j = 0; j < num; j++) { ShowStr("*"); } } sum = 0.0; ShowStr("\n"); } } if (_image.ras_width < IMAGE_MAX_WIDTH_TO_SHOW && _image.ras_height < IMAGE_MAX_WIDTH_TO_SHOW) { int j; ShowStr("Image is, in terms of internal values from 0 to 255:\n"); for (j = int(_image.ras_height - 1); j > -1; j--) { for (unsigned int i = 0; i < _image.ras_width; i++) { if (!*(_image.image + i * _image.ras_height + j)) { sprintf(_grTempString, "%03d ", *(_image.image + i * _image.ras_height + j)); ShowStr(_grTempString); } else { ShowStr("*** "); } } ShowStr("\n"); } ShowStr("\nImage is, in terms of user values:\n"); float scale = 255.0 / (_image255 - _image0); for (j = int(_image.ras_height - 1); j > -1; j--) { for (unsigned int i = 0; i < _image.ras_width; i++) { if (!*(_image.image + i * _image.ras_height + j)) { int val = *(_image.image + i * _image.ras_height + j); float val_float; if (_imageTransform == NULL) val_float = _image0 + float(val) / scale; else val_float = _image0 + _imageTransform[val] / scale; sprintf(_grTempString, "%10f ", val_float); ShowStr(_grTempString); } else { ShowStr("********* "); } } ShowStr("\n"); } } else { ShowStr("Image is too big to display here\n"); } return true; } bool show_next_lineCmd() { int result_code; #if defined(VMS) warning("`show next line' does not work on VMS"); return true; #endif if (_dataFILE.back().get_type() == DataFile::from_cmdfile) return true; // Cannot show for binary files -- don't bother with warning though if (_dataFILE.back().get_type() != DataFile::ascii) return true; if (feof(_dataFILE.back().get_fp())) { sprintf(_grTempString, "%s is at END-OF-FILE.\n", _dataFILE.back().get_name()); ShowStr(_grTempString); return true; } fgets(_errorMsg, LineLength_1, _dataFILE.back().get_fp()); if (feof(_dataFILE.back().get_fp())) { sprintf(_grTempString, "%s is at END-OF-FILE\n", _dataFILE.back().get_name()); ShowStr(_grTempString); return true; } sprintf(_grTempString, "%sNext line (%d): %s", _margin.c_str(), _dataFILE.back().get_line(), _errorMsg); ShowStr(_grTempString); result_code = fseek(_dataFILE.back().get_fp(), long(-strlen(_errorMsg)), 1); if (result_code) { sprintf(_errorMsg, "`show next line' had internal problems [%d]", result_code); warning(_errorMsg); } return true; } // show_stopwatchCmd() -- moved to timer.cc bool show_allCmd() { // vsn0.97: need to test _word because `show' gets parsed to here if (_nword == 2) { show_miscCmd(); show_axesCmd(); show_columnsCmd(); show_gridCmd(); show_imageCmd(); show_variablesCmd(); show_synonymsCmd(); if (!_cmdFILE.back().get_interactive()) { show_next_lineCmd(); } } else { err("`show' what?"); return false; } return true; } bool show_tracebackCmd() { display_cmd_being_done_stack(); return true; } bool show_timeCmd() { SECOND_TYPE sec; time(&sec); sprintf(_grTempString, "%s", asctime(localtime(&sec))); ShowStr(_grTempString); return true; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/errors.hh�����������������������������������������������������������������������������������0000644�0001750�0001750�00000004054�13147557614�012447� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #if !defined(_errors_hh_) #define _errors_hh_ #if defined(VMS) void err(va_dcl va_alist); void fatal_err(va_dcl va_alist); #else void err(const char *string, ...); void fatal_err(const char *string, ...); #endif void gr_error(const char *lab); // as in gr.hh // Error with filename and line number #if !defined(gr_Error) #define gr_Error(err) \ { \ std::string msg; \ msg.append((char*)__FILE__); \ msg.append(":"); \ char num[20]; \ sprintf(num, "%d", __LINE__); \ msg.append(num); \ msg.append(": "); \ msg.append((err)); \ gr_error(msg.c_str()); \ } #endif #define READ_WORD_ERROR(word) {err("Can't read `\\", (word), "'", "\\");} #define NUMBER_WORDS_ERROR {err("Wrong number of words in command");} #define MISSING_WORD_ERROR(word) {err("Missing keyword `\\", (word), "'", "\\");} #define NO_NEGATIVE_ERROR(word) {err("Cannot have negative value of `\\", (word), "'", "\\");} #define NO_COLUMN_ERROR(word) {err("Column `\\", (word), "' has no data", "\\");} #define OUT_OF_MEMORY {gr_Error("Out of storage");} #endif // _errors_hh_ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/GCounter.hh���������������������������������������������������������������������������������0000644�0001750�0001750�00000002322�13147557614�012655� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // Keep track of references to object #if !defined(_GriCounter_h_) #define _GriCounter_h_ class GriCounter { public: GriCounter() { count = 0; } GriCounter(const GriCounter& c) { count = c.getCount(); } ~GriCounter() { ; } void incrementCount() { count++; } void decrementCount() { if (count) count--; } unsigned getCount() const { return count; } private: int count; }; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/synonyms.cc���������������������������������������������������������������������������������0000644�0001750�0001750�00000071354�13147557614�013027� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* #define DEBUG_SYNONYMS */ #include #include #include #include #include "gr.hh" #include "extern.hh" #include "Synonym.hh" std::vector synonymStack; static inline int end_of_synonym(char c, bool inmath, bool need_brace); //static bool get_starred_synonym(const char* name, bool want_value/*or name*/, string& result); static int get_num_cmdwords(); static int find_synonym_name(const std::string& s, std::string& name, bool in_math); bool get_cmdword(unsigned int index, std::string& cmdword); static int get_num_cmdwords() { extern int _num_command_word; if (_num_command_word <= 0) return 0; extern char *_command_word[MAX_cmd_word]; extern char *_command_word_separator; int cmd, level = 0, count = 0; for (cmd = _num_command_word - 1; cmd > -1; cmd--) { if (!strcmp(_command_word[cmd], _command_word_separator)) level++; if (level == 1 || cmd <= 0) { for (cmd++; cmd < _num_command_word; cmd++) { if (!strcmp(_command_word[cmd], _command_word_separator)) break; else count++; } return count; } } return 0; } bool get_cmdword(unsigned int index, std::string& cmdword) { extern int _num_command_word; extern char *_command_word[MAX_cmd_word]; extern char *_command_word_separator; // The synonym \.wordn. is the n-th word in the command. if (_num_command_word == 0) return false; int cmd, level = 0; // Trace back through the stack until at next level deep, then // move forward to indicated word. for (cmd = _num_command_word - 1; cmd > -1; cmd--) { //printf("DEBUG %d <%s> <%s>\n",cmd,_command_word[cmd],_command_word_separator); if (!strcmp(_command_word[cmd], _command_word_separator)) level++; if (level == 1 || cmd <= 0) { cmd += index + 1; break; } } // If the command is requesting a word beyond the list (e.g. // \.word10. in a line with only 3 words) just paste the name of // the desired synonym (e.g "\.word10.") onto the line, and let // further processing catch the error, if it is in a bit of code // that is not being skipped. if (cmd >= _num_command_word) { return false; } else { // The word does exist. If it's a quoted string, remove the // quotes ... if (*_command_word[cmd] == '"') { cmdword.assign(1 + _command_word[cmd]); if (cmdword[cmdword.size() - 1] == '"') { cmdword.STRINGERASE(cmdword.size() - 1, 1); } } else { // ... otherwise copy it directly cmdword.assign(_command_word[cmd]); } } //printf("DEBUG %s:%d level= %d cmd= %d res <%s>\n",__FILE__,__LINE__,level,cmd,_command_word[cmd]); return true; // .word#. } #if 0 static bool get_starred_synonym(const char* name, bool want_value/*or name*/, std::string& result) { if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d in get_starred_synonym(%s,%c)\n",__FILE__,__LINE__,name,want_value?'T':'F'); std::string coded_reference; get_syn(name, coded_reference); if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d coded_reference <%s>\n",__FILE__,__LINE__,coded_reference.c_str()); if (!strncmp(coded_reference.c_str(), "\\#v", 3)) { if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d A VAR in <%s>\n",__FILE__,__LINE__,coded_reference.c_str()); int var_index; sscanf(coded_reference.c_str(), "\\#v%d#", &var_index); if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d var_index %d\n",__FILE__,__LINE__,var_index); if (var_index < 0 || var_index > int(variablePointer.size())) { err("Internal error with variable stack"); return false; } int which = variablePointer[var_index]; if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d var ptr is %d\n",__FILE__,__LINE__,which); if (which > -1) { if (want_value) { char buffer[100]; sprintf(buffer, "%g", variableStack[which].get_value()); result.assign(buffer); } else { result.assign(variableStack[which].get_name()); } } else { result.assign(coded_reference); } } else if (!strncmp(coded_reference.c_str(), "\\#s", 3)) { if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d A SYN in <%s>\n",__FILE__,__LINE__,coded_reference.c_str()); int syn_index; sscanf(coded_reference.c_str(), "\\#s%d#", &syn_index); if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d syn_index %d\n",__FILE__,__LINE__,syn_index); if (syn_index < 0) { err("Internal error with synonym stack"); return false; } if (which > -1) { if (want_value) { result.assign(synonymStack[which].get_value()); } else { result.assign(synonymStack[which].get_name()); } } else { result.assign(coded_reference); } } else { if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d HUH?? no idea what <%s> is\n",__FILE__,__LINE__,coded_reference.c_str()); result.assign(coded_reference); } if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d get_starred_synonym returning <%s>\n",__FILE__,__LINE__,result.c_str()); return true; } #endif // Get index of synonym // RETURN non-negative integer if 'name' is an existing synonym, or -1 if not. int index_of_synonym(const char *name, int mark) { if (!is_syn(name)) return -1; unsigned int stackLen = synonymStack.size(); if (mark == -1) { for (int i = stackLen - 1; i >= 0; i--) if (!strcmp(name, synonymStack[i].get_name())) return i; return -1; } else { int mark_above = mark + 1; unsigned int index; int this_mark = 0; for (index = 0; index < stackLen; index++) { const char *n = synonymStack[index].get_name(); if (*n == '\0') if (++this_mark == mark_above) break; } if (this_mark != mark_above) { //printf("DEBUG %s:%d no match for <%s>\n",__FILE__,__LINE__,name); return -1; } //printf("DEBUG %s:%d index %d\n",__FILE__,__LINE__,index); for (int i = index - 1; i >= 0; i--) { //printf("check <%s> to see if <%s>\n",synonymStack[i].get_name(),name); if (!strcmp(synonymStack[i].get_name(), name)) { return i; } } return -1; } return -1; } bool create_synonym(const char *name, const char *value) { GriSynonym newSynonym(name, value); synonymStack.push_back(newSynonym); return true; } bool show_synonymsCmd() { ShowStr("Synonyms...\n"); bool have_some = false; unsigned int stackLen = synonymStack.size(); for (unsigned int i = 0; i < stackLen; i++) { const char *n = synonymStack[i].get_name(); if (*n == '\0') { printf(" ------------------------------------------------\n"); } else { extern char _grTempString[]; sprintf(_grTempString, " %-25s = \"%s\"\n", n, synonymStack[i].get_value()); ShowStr(_grTempString); have_some = true; } } if (!have_some) { ShowStr(" ... none exist\n"); } return true; } // display unused user synonyms void display_unused_syn() { int i; unsigned stackLen = synonymStack.size(); extern char _grTempString[]; if (stackLen > 0) { char *name; for (i = stackLen - 1; i >= 0; i--) { if (0 == synonymStack[i].getCount()) { name = strdup(synonymStack[i].get_name()); if (strlen(name) > 0 && *(name + 1) != '.') { std::string tmp; unbackslash(name, tmp); sprintf(_grTempString, "Warning: synonym `%s' defined but not used\n", tmp.c_str()); ShowStr(_grTempString); } free(name); } } } } bool update_readfrom_file_name() { // .readfrom_file. if (!put_syn("\\.readfrom_file.", _dataFILE.back().get_name(), true)) { err("Sorry, can't update `\\.readfrom_file.'"); return false; } return true; } // is_syn - return 0 if not a synonym, or 1 if is bool is_syn(const char *name) { return ((name[0] == '\\') ? true : false); } bool is_syn(const std::string& name) { return ((name[0] == '\\') ? true : false); } void show_syn_stack() { unsigned int stackLen = synonymStack.size(); if (stackLen > 0) { printf("Synonym stack [\n"); for (unsigned int i = 0; i < stackLen; i++) { const char *n = synonymStack[i].get_name(); if (*n == '\0') printf(" ------------------------------------------------\n"); else printf("%3d %s = \"%s\"\n", i, n, synonymStack[i].get_value()); } printf("]\n"); } } // delete_syn() - delete synonym bool delete_syn(const std::string& name) { unsigned stackLen = synonymStack.size(); for (int i = stackLen - 1; i >= 0; i--) { if (name == synonymStack[i].get_name()) { if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d DELETING syn %d named <%s>\n",__FILE__,__LINE__,i,name.c_str()); for (unsigned j = i; j < stackLen - 1; j++) synonymStack[j] = synonymStack[j + 1]; synonymStack.pop_back(); if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d after handling 'delete syn', the list is...\n",__FILE__,__LINE__); return true; } } return false; } // get_syn() - get value of synonym Sufficient storage for (char *value) must // have been set aside by the calling routine. // RETURN true if synonym is defined and has a value bool get_syn(const char *name, std::string& value, bool do_decoding) { unsigned int name_len = strlen(name); //printf("DEBUG %s:%d get_syn(%s,)\n",__FILE__,__LINE__,name); if (!is_syn(name)) return false; int word_index; if (!strncmp(name, "\\.proper_usage.", 15)) { // Take care of synonym \.proper_usage., used to demonstrate the // proper usage of a command. unbackslash(_command[cmd_being_done()].syntax, value); return true; } else if (!strcmp(name, "\\.words.")) { int nc = get_num_cmdwords(); if (nc <= 0) { value.assign("\\.words."); return false; } else { char value_buffer[100]; sprintf(value_buffer, "%d", nc); value.assign(value_buffer); return true; } } else if (1 == sscanf(name, "\\.word%d.", &word_index)) { if (!get_cmdword(word_index, value)) { value.assign(name); return false; } if (do_decoding) { std::string coded_name; int coded_level = -1; if (is_coded_string(value, coded_name, &coded_level)) { //printf("DEBUG %s:%d cmdword[%d]='%s' was encoded `%s' at level %d\n",__FILE__,__LINE__,word_index, value.c_str(), coded_name.c_str(), coded_level); get_coded_value(coded_name, coded_level, value); } } return true; // .word#. } else if (name_len > 1 && name[1] == '[') { // word within synonym (e.g. \[0]syn) //printf("DEBUG %s:%d word within synonym [%s]\n",__FILE__,__LINE__,name); int index_len = -1; for (unsigned int i = 2; i < name_len; i++) { if (name[i] == ']') { index_len = i - 2; break; } } if (index_len == -1) { // malformed; no closing ']' value.assign(name); return false; } std::string name_unindexed = name; name_unindexed.STRINGERASE(1, 2 + index_len); //printf("name_unindexed [%s]\n", name_unindexed.c_str()); int the_index = 0; if (index_len) { std::string the_index_s = name; double tmp; if (!getdnum(the_index_s.substr(2, index_len).c_str(), &tmp)) { value.assign(name); return false; } the_index = int(floor(0.5 + tmp)); if (the_index < 0) { value.assign(name); return false; } } // Check for e.g. \[0].word1. int which_word; if (1 == sscanf(name_unindexed.c_str(), "\\.word%d.", &which_word)) { //printf("DEBUG %s:%d which_word %d\n",__FILE__,__LINE__,which_word); std::string word_buf; if (!get_cmdword(which_word, word_buf)) { value.assign(name); return false; } //printf("DEBUG %s:%d word_buf [%s]\n",__FILE__,__LINE__,word_buf.c_str()); if (word_buf[0] == '"') { word_buf.STRINGERASE(0, 1); if (word_buf[word_buf.size() - 1] == '"') { word_buf.STRINGERASE(word_buf.size() - 1, 1); } } //printf("DEBUG %s:%d word_buf [%s] the_index= %d\n",__FILE__,__LINE__,word_buf.c_str(), the_index); if (index_len) { if (get_nth_word(word_buf, the_index, value)) return true; } else { char num[30]; sprintf(num, "%d", get_number_of_words(word_buf)); value.assign(num); return true; } } // Now know it's not of the form "\[0].word#." or "\[].word#.", etc. // It must be of the form "\[]syn" or "\[0]syn", etc. unsigned int stackLen = synonymStack.size(); for (int ii = stackLen - 1; ii >= 0; ii--) { if (!strcmp(name_unindexed.c_str(), synonymStack[ii].get_name())) { if (index_len) { if (get_nth_word(synonymStack[ii].get_value(), the_index, value)) { ; } else { value.assign(name); return true; } } else { char num[30]; sprintf(num, "%d", get_number_of_words(synonymStack[ii].get_value())); value.assign(num); } synonymStack[ii].incrementCount(); return true; } } } else { // It's an ordinary synonym. Look it up in the stack unsigned int stackLen = synonymStack.size(); if (stackLen > 0) { for (int i = stackLen - 1; i >= 0; i--) { if (!strcmp(name, synonymStack[i].get_name())) { value.assign(synonymStack[i].get_value()); synonymStack[i].incrementCount(); return true; } } } } return false; } // Convert single backslashes into double. void unbackslash(const char *s, std::string& res) { res = ""; char lastc = '\0'; while (*s != '\0') { if (*s == '\\' && lastc != '\\') res += '\\'; res += *s; lastc = *s++; } } // put_syn() -- assign value to name, creating new synonm if necessary. // RETURN true if successfull bool put_syn(const char *name, const char *value, bool replace_existing) { // In the case where instructed by the value of // replace_existing, simply replace the value of // the variable (if it already exists). if (replace_existing) { unsigned stackLen = synonymStack.size(); if (stackLen) { for (int i = stackLen - 1; i >= 0; i--) { if (!strcmp(name, synonymStack[i].get_name())) { synonymStack[i].set_value(value); return true; } } } } // Store on end of stack. GriSynonym newSynonym(name, value); synonymStack.push_back(newSynonym); return true; } // Scan through input string s[], substituting synonyms. The result is put // into string sout[]. // // If inmath=1, special math strings such as \alpha are inserted as different // fonts. // // RETURN true if line not empty bool substitute_synonyms_cmdline(const char *s, std::string& sout, bool allow_math) { sout = ""; if (strlen(s) < 1) { return false; } // To speed action, maintain a buffer in which 's' will be copied, // prior to chopping into words. BUG: this buffer is only cleaned // up at exit() time, since I never free() it. unsigned int space_needed = 1 + strlen(s); static char* copy = NULL; static unsigned int copy_len = 0; if (copy_len == 0) { copy_len = space_needed; copy = (char*)malloc(copy_len * sizeof(char)); if (!copy) { gr_Error("Out of memory in `substitute_synonyms_cmdline'"); } } else { if (copy_len < space_needed) { copy_len = space_needed; copy = (char*)realloc(copy, copy_len * sizeof(char)); if (!copy) { gr_Error("Out of memory in `substitute_synonyms_cmdline'"); } } } strcpy(copy, s); unsigned int nword; chop_into_words(copy, _Words2, &nword, MAX_nword); int offset = 0; // Pass `sprintf \synonym ...' through directly if (nword > 1 && !strcmp(_Words2[0], "sprintf")) { sout.append(_Words2[0]); sout.append(" "); sout.append(_Words2[1]); // the synonym name sout.append(" "); offset = skip_space(s); // initial blanks offset += skip_nonspace(s + offset); // SPRINTF offset += skip_space(s + offset); // blanks offset += skip_nonspace(s + offset); // the synonym name offset += skip_space(s + offset); // blanks } // Pass `show defined ... (\synonym)' through directly if (nword > 2 && !strcmp(_Words2[0], "show") && !strcmp(_Words2[1], "defined")) { sout = s; return true; } // Pass `delete \synonym' through directly. if (nword == 2 && !strcmp(_Words2[0], "delete") && *_Words2[1] == '\\') { return true; } if (nword < 1) { return true; } // Pass `read \syn ...', `read .var. ...' and `read line \syn' through if (strEQ(_Words2[0], "read")) { if (nword >= 2 && (strEQ(_Words2[1], "*") || is_syn(_Words2[1]) || is_var(_Words2[1]))) { sout = s; return true; } else if (nword == 3 && strEQ(_Words2[1], "line") && is_syn(_Words2[2])) { sout = s; return true; } } // Pass `while ...' through if (!strcmp(_Words2[0], "while")) { sout = s; return true; } // Some special cases are passed through without the syn name being // substituted. This is done by supplying an offset to the string. if (!strcmp(_Words2[0], "query")) { sout.append(_Words2[0]); sout.append(" "); sout.append(_Words2[1]); sout.append(" "); offset = skip_space(s); // initial blanks offset += skip_nonspace(s + offset); // query offset += skip_space(s + offset); // blanks offset += skip_nonspace(s + offset); // item offset += skip_space(s + offset); // blanks } // Catch e.g. \@.word1 = ... if (!strncmp(_Words2[0], "\\@", 2) && nword > 1 && is_assignment_op(_Words2[1])) { if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d caught \\@ with first cmdword being [%s]\n",__FILE__,__LINE__,_Words2[0]); std::string tmp("\\"); tmp.append(2 + _Words2[0]); std::string unaliased; get_syn(tmp.c_str(), unaliased); if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d unaliased <%s>\n",__FILE__,__LINE__,unaliased.c_str()); if (unaliased[0] == '\\') { // Not sure on the below. Cropped up 2001-feb-15. if (unaliased[1] == '\\') { sout.append(1 + unaliased.c_str()); } else { sout.append(unaliased.c_str()); } sout.append(" "); if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d SYN named [%s]\n",__FILE__,__LINE__,sout.c_str()); offset = 1 + strlen(_Words2[0]); } else if (unaliased[0] == '.') { sout.append(unaliased.c_str()); sout.append(" "); offset = 1 + strlen(_Words2[0]); if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d VAR name [%s]\n",__FILE__,__LINE__,unaliased.c_str()); } else { // Leave in place to worry about later sout.append(_Words2[0]); sout.append(" "); offset = 1 + strlen(_Words2[0]); } } else if (*_Words2[0] == '\\') { // Protect first word of `\name = "value"', but not of `\syn ...'. In // other words, protect first word if matches \synonym[ ]*=.* if (nword > 1 && is_assignment_op(_Words2[1])) { sout = _Words2[0]; sout.append(" "); offset = 1 + strlen(_Words2[0]); } } #if 0 // Catch *\name = something if (*_Words2[0] == '*' || *(1 + _Words2[0]) == '\\') { if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d NEED CODE HERE!\n",__FILE__,__LINE__); if (nword > 1 && !strcmp(_Words2[1], "=")) { if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d item is <%s>\n",__FILE__,__LINE__,_Words2[0]); std::string syn_value(1 + _Words2[0]); if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d looking up ref from <%s>\n",__FILE__,__LINE__,syn_value.c_str()); std::string pointed_to_name; bool res = get_starred_synonym(syn_value.c_str(), false, pointed_to_name); if (res) { if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d pointed_to_name <%s>\n",__FILE__,__LINE__,pointed_to_name.c_str()); sout.append(pointed_to_name); sout.append(" "); } else { sout.append(_Words2[0]); sout.append(" "); } offset = 1 + strlen(_Words2[0]); } } #endif return substitute_synonyms(s + offset, sout, allow_math); } // Walk through string, substituting synonyms if not in math mode. // RETURN 0 if empty line, 1 otherwise. bool substitute_synonyms(const char *s, std::string& sout, bool allow_math) { if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d substitute_synonyms('%s',...)\n",__FILE__,__LINE__,s); bool inmath = false; // are we within a math string? int slen = strlen(s); std::string sname; // Keep this buffer forever. BUG: may not be long enough static char* svalue = NULL; if (svalue == NULL) { svalue = (char*)malloc(_grTempStringLEN * sizeof(char)); if (!svalue) OUT_OF_MEMORY; } for (int i = 0; i < slen; i++) { //printf("%s:%d i=%d s+i = [%s]\n",__FILE__,__LINE__,i,s+i); // If entering or leaving math mode, just paste $ onto the end and // skip to the next character. // if (s[i] == '$' && allow_math) { if (i == 0) { inmath = true; } else if (s[i - 1] != '\\') { // \$ is escape to pass $ inmath = inmath ? false : true; } sout.append("$"); //printf(" DONE appending 1\n"); continue; } // If it is the &\ syntax, pass it through directly if (s[i] == '&' && i < slen - 2 && s[i + 1] == '\\' && s[i + 2] != '\\') { sout.append("&\\"); i++; continue; } #if 0 // See if it is the *\syn syntax, and handle if so. if (s[i] == '*' && i < slen - 2 && s[i + 1] == '\\' && s[i + 2] != '\\') { if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d got * i=%d <%s> <%s>\n",__FILE__,__LINE__,i,s,s+i-1); i += 2; // skip ahead, looking for synonym name. std::string tmp("\\"); while (i < slen && !end_of_synonym(s[i], false /*inmath*/, false/*need_brace*/)) { tmp += s[i++]; } std::string coded_reference; get_syn(tmp.c_str(), coded_reference); std::string value; get_starred_synonym(tmp.c_str(), true, value); sout.append(value); } #endif // If not start of synonym, just paste character onto end of string // and continue. (This also applies to apparent synonyms, if they are // during math mode.) if (s[i] != '\\' || inmath) { sout += s[i]; continue; } // We now know that s[i] is a '\\' and now must // investigate further. There are several possibilities // depending on what the previous character was // and what the next character is. // Translate two backslashes into one backslash if (s[i + 1] == '\\') { sout += '\\'; i++; continue; } #if 1 // Catch \& syntax if (s[i + 1] == '&') { bool want_name = true; // or level, for \&& int iS = i + 2; if (s[i + 2] == '&') { want_name = false; iS++; } //printf("DEBUG %s:%d got & syntax on <%s>\n",__FILE__,__LINE__, s); std::string S("\\"); while (iS < slen && !end_of_synonym(s[iS], false /*inmath*/, false/*need_brace*/)) { S += s[iS++]; } int word_index; if (1 == sscanf(S.c_str(), "\\.word%d.", &word_index)) { //printf("A WORd %d\n", word_index); std::string value; if (get_cmdword(word_index, value)) { //printf("WORD IS [%s]\n", value.c_str()); std::string coded_name; int coded_level; if (is_coded_string(value, coded_name, &coded_level)) { //printf("CODED. [%s]\n",coded_name.c_str()); if (want_name) { //printf("SHOULD STORE [%s]\n", coded_name.c_str()); sout.append(coded_name.c_str()); } else { char buf[20]; // BUG: should be big enough sprintf(buf, "%d", coded_level); sout.append(buf); } } } } i = iS - 1; continue; } #endif #if 1 // Catch \@ [alias synonyms] if (s[i + 1] == '@') { i += 2; // skip the '\\' and the '@' std::string tmp("\\"); while (i < slen && !end_of_synonym(s[i], false /*inmath*/, false/*need_brace*/)) { tmp += s[i++]; } if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d ALIAS tmp [%s]\n",__FILE__,__LINE__,tmp.c_str()); std::string alias_name; get_syn(tmp.c_str(), alias_name); if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d this syn value is [%s]\n",__FILE__,__LINE__,alias_name.c_str()); std::string alias_value; if (alias_name[0] == '\\') { if (get_syn(alias_name.c_str(), alias_value)) { sout.append(alias_value); if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d looked up '%s' (after skipping) to get '%s'\n",__FILE__,__LINE__,alias_name.c_str(),alias_value.c_str()); } else { if (!skipping_through_if()) { err("Cannot un-alias synonym in `\\", alias_name.c_str(), "'.", "\\"); return false; } } } else if (alias_name[0] == '.') { double value = 0.0; if (get_var(alias_name.c_str(), &value)) { if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d isvar=%d\n",__FILE__,__LINE__,is_var(alias_name)); if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d looked up '%s' to get %f NUM\n",__FILE__,__LINE__,alias_name.c_str(),value); char alias_value_buffer[100]; sprintf(alias_value_buffer, "%f", value); sout.append(alias_value_buffer); } else { if (!skipping_through_if()) { err("Cannot un-alias variable in `\\", alias_name.c_str(), "'.", "\\"); return false; } } } else { err("The purported alias `\\", alias_name.c_str(), "' doesn't name a synonym or a variable.", "\\"); return false; } i--; // BUG: not sure on this! continue; } #endif // Now know that s[i] is backslash, and not inmath. // Pass a few escape strings through directly. if (s[i + 1] == '$' || s[i + 1] == '"' || s[i + 1] == '\\') { sout += s[i]; sout += s[++i]; continue; } // Now know that it's the start of a synonym. Isolate it, // then find value. sname = "\\"; sname.append(s + i + 1); std::string the_syn_name; int syn_name_len = find_synonym_name(sname, the_syn_name, inmath); if (syn_name_len != 0) { sname = the_syn_name; i += syn_name_len - 1; } if (((unsigned) superuser()) & FLAG_SYN) printf(" %s:%d the sname is '%s'\n",__FILE__, __LINE__, sname.c_str()); #if 0 // Catch '\ ', which is not a synonym, and which can come in by // malformed continuation lines if (sname[1] == ' ') { warning("Found `\\ ', which is not legal; is this a malformed continuation?"); } #endif // Substitute known synonym, then skip over the space the synonym // name occupied. std::string synonym_value; if (get_syn(sname.c_str(), synonym_value)) { if (synonym_value.size() > _grTempStringLEN - 1) { OUT_OF_MEMORY; } strcpy(svalue, synonym_value.c_str()); if (((unsigned) superuser()) & FLAG_SYN) printf("Syn value is <%s>\n", svalue); sout.append(synonym_value.c_str()); } else { sout.append(sname.c_str()); } } // Paste on final blank [can't remember why, but what the heck]. sout.append(" "); if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d finally [%s]\n",__FILE__,__LINE__,sout.c_str()); return true; } static int // return length find_synonym_name(const std::string &s, std::string& name, bool inmath) { unsigned int slen = s.size(); if (s[0] != '\\') return 0; unsigned int dots_in_name = 0; name += '\\'; unsigned int len = 1; if (s[len] == '[') { name += '['; len++; while (len < slen) { name += s[len]; if (s[len++] == ']') break; } // BUG: should check for missing ']' } if (s[len] == '.') { dots_in_name++; name += '.'; len++; while (len < slen && s[len] == '.') { dots_in_name++; name += '.'; len++; } } while (len < slen) { char c = s[len]; if (c == ' ') break; if (c == '\t') break; if (c == '\n') break; if (c == '`') break; if (c == '\'') break; if (c == '\\') break; if (c == '"') break; if (c == '|') break; if (c == ':') break; if (c == ';') break; if (c == '#') break; if (c == '(') break; if (c == ')') break; if (c == '{') break; if (c == '}') break; if (c == ']') break; // CAUTION: might break "\[3]syn" if (c == '/') break; if (c == '*') break; if (c == '-') break; if (c == '+') break; if (c == '<') break; if (c == '>') break; if (c == '=') break; if (c == '>') break; if (c == '$') break; if (c == ',' && !inmath) break; if (c == '.') { unsigned int trailing_dots = 0; while (len < slen && s[len] == '.' && trailing_dots < dots_in_name) { name += s[len]; len++; } break; } name += c; len++; } if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d find_synonym_name() got syn-name [%s]\n",__FILE__,__LINE__,name.c_str()); return len; } static inline int end_of_synonym(char c, bool inmath, bool need_brace) { if (need_brace) { return c == '}'; } switch (c) { case ' ': case '\t': case '\n': case '`': case '\'': case '\\': case '\0': case '"': case '|': case ':': case ';': case '#': case '(': case ')': // case '[': // case ']': case '{': case '}': case '/': case '*': case '@': case '-': case '+': case '<': case '>': case '=': case '$': return true; case ',': return (!inmath); } return false; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/new.cc��������������������������������������������������������������������������������������0000644�0001750�0001750�00000010663�13147557614�011715� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include "gr.hh" #include "extern.hh" #include "defaults.hh" extern char _grTempString[]; bool new_pageCmd(); bool newCmd(void); // for synonyms and vars bool new_pageCmd() { extern void reset_top_of_plot(void); // in set.cc gr_showpage(); gr_setfont(gr_currentfont(), true); _need_x_axis = true; _need_y_axis = true; reset_top_of_plot(); return true; } // new postscript file "name" bool new_postscript_fileCmd() { if (_nword < 4) { err("`new postscript file' needs a filename."); demonstrate_command_usage(); return false; } else if (_nword > 4) { err("`new postscript file' takes just 1 argument, a filename"); demonstrate_command_usage(); return false; } //printf("DEBUG. Should now start a new ps file named '%s'\n",_word[3]); gr_end("!"); std::string unquoted(_word[3]); un_double_quote(unquoted); gr_setup_ps_filename(unquoted.c_str()); #if 0 // BUG: don't know argc/argv from here! insert_creator_name_in_PS(argc, argv, psname); #endif gr_begin(2); // Trick it into resetting to present font gr_fontID present_font = gr_currentfont(); gr_setfont(gr_font_Courier); gr_setfont(present_font); return true; } // new [.var.|\syn [.var.|\syn [...]] bool newCmd() { if (_nword == 1) { err("Need name of thing (synonym or variable) to make new version of"); demonstrate_command_usage(); return false; } for (unsigned int i = 1; i < _nword; i++) { std::string w(_word[i]); un_double_quote(w); //printf("DEBUG %s:%d <%s>\n",__FILE__,__LINE__,w.c_str()); std::string value; if (get_syn(w.c_str(), value, false)) { std::string coded_name; int coded_level = -1; //printf("DEBUG <%s>\n", value.c_str()); if (is_coded_string(value.c_str(), coded_name, &coded_level)) { //printf("DEBUG %s:%d is <%s> <%s> level %d\n",__FILE__,__LINE__,value.c_str(),coded_name.c_str(),coded_level); if (coded_name[0] == '.') { int index = index_of_variable(coded_name.c_str(), coded_level); GriVariable newVariable(coded_name.c_str(), 0.0); variableStack.insert(variableStack.begin() + index + 1, newVariable); //printf("VAR index is %d\n", index); } else if (coded_name[0] == '\\'){ int index = index_of_synonym(coded_name.c_str(), coded_level); //printf("SYN index is %d, now holds <%s>\n", index, synonymStack[index].get_value()); GriSynonym newSynonym(coded_name.c_str(), ""); synonymStack.insert(synonymStack.begin() + index + 1, newSynonym); } else { err("new cannot decode item `\\", _word[i], "'.", "\\"); return false; } return true; } } // de_reference(w); if (is_syn(w)) { //printf("DEBUG 4-a SYN <%s>\n", w.c_str()); if (w[1] == '@') { std::string clean("\\"); clean.append(w.substr(2, w.size())); std::string named; get_syn(clean.c_str(), named, false); //printf("NEW IS AN ALIAS SYN %s:%d <%s> [%s]\n",__FILE__,__LINE__,clean.c_str(),named.c_str()); if (is_var(named.c_str())) { //printf("NEW VAR [%s]\n",named.c_str()); create_variable(named.c_str(), 0.0); } else if (is_syn(named.c_str())) { //printf("NEW SYN [%s]\n",named.c_str()); create_synonym(named.c_str(), ""); } else { err("`new' cannot decode `\\", w.c_str(), "'", "\\"); return false; } } else { create_synonym(w.c_str(), ""); } } else if (is_var(w)) { //printf("DEBUG 4-b VAR <%s>\n", w.c_str()); create_variable(w.c_str(), 0.0); } else { demonstrate_command_usage(); err("`new' only works on synonyms and variables, not on an item named `\\", _word[i], "'", "\\"); return false; } } return true; } �����������������������������������������������������������������������������gri/src/gri.cmd�������������������������������������������������������������������������������������0000644�0001750�0001750�00000556620�13147557614�012073� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# gri - scientific graphic program (version 2.12.26) # Copyright 2017 by Dan E. Kelley; GPLv2+ licensing. # # NOTE: The linkages to `extern "C"' routines makes use a list of C # functions defined in the file tags.hh. `assert .condition. ["message"]' The condition may be a variable, a synonym, or an RPN expression. If this condition is true (i.e. evaluates to a non-zero number), do nothing. If the condition is false, the program will terminate with an error condition (in unix, it will terminate with a non-zero exit code). Before termination, a message will be printed, the form of which depends on the optional `"msg"' string. If no `"msg"' string is given, the the printed message will indicate the name of the command-file and the line at which the assert command was encountered. If a `"msg"' string is given, and if it ends in a newline (`"\\n"'), then this string is printed. If a `"msg"' string is given, and if it does not end in `"\\n"', then the string is printed along with an indication of the location in the command-file. (Perl users will recognize this as being patterned on the `"die"' command.) { extern "C" bool assertCmd(void); } `cd [\pathname]' If a pathname specified, change to that directory. Normal unix filenames are used, according to the C-shell convention; thus `cd ~/src' and `cd $HOME/src' are equivalent. You may specify relative pathnames as in `cd ../sister_directory'. If no \pathname directory path specified, go to the home directory, exactly as `cd ~' and `cd $HOME' do. { extern "C" bool cdCmd(void); } `close [\filename]' If no filename is specified, close the most recently opened data-file; otherwise close indicated file. { extern "C" bool closeCmd(void); } `convert columns to grid [neighbor | {objective|boxcar .xr. .yr. [.n. .e.]} | {barnes [.xr. .yr. .gamma. .iter.]}]' Various forms exist: `convert columns to grid' `convert columns to grid neighbor' `convert columns to grid boxcar [.xr. .yr. [.n. .e.]]' `convert columns to grid objective [.xr. .yr. [.n. .e.]]' `convert columns to grid barnes [.xr. .yr. .gamma. .iter.]' All these commands ``grid'' columnar (x,y,z) data. That is, they fill up a grid based on some form of interpolation of the possibly randomly spaced columnar data. There are many methods in existence for doing this, and Gri implements several of them as alternatives. The grid will have been defined by commands such as `set x grid', `set y grid', `read grid x' and `read grid y'. As of version 2.1.9, Gri does not require a grid to have been pre-defined; it will create a regular 20 by 20 grid, spanning the range of x and y data, as a default. This is a good starting point in many cases. *`neighbor' method* Very fast but very limited. *`boxcar' method* Slower but a lot better. Still, this can produce noisy contours if the data are not densely and uniformly ditributed through domain. *`objective' method* Somewhat slower than `boxcar', but produces better fields since the averaging function is smooth. *`barnes' method* Somewhat slower than `objective', but only by a constant factor (that is, independent of number of data). This produces by far the best results, since the smoothing function has variable spatial scale. This is the default method if no method is supplied. All except the `neighbor' method may take optional arguments to define the x and y scales of the smoothing function (called `.xr.' and `.yr.'). (The barnes method has two other optional arguments - see below.) If you do not supply these arguments, Gri will make a reasonable choice and inform you of its decision. Many users find that it's best to `convert columns to grid' with no additional parameters as a first step, to get advice on values to use for the optional parameters. The default `.xr.' and `.yr.' are calculated by determining the span in x and in y directions, and dividing each by the square root of the number of data points. These numbers are then multiplied by the square root of 2. The method is as proposed by S. E. Koch and M. DesJardins and P. J. Kocin, 1983. "An interactive Barnes objective map anlaysis scheme for use with satellite and conventional data,", J. Climate Appl. Met., vol 22, p. 1487-1503. If `.xr.' and `.yr.' were supplied but negative, then Gri interprets this as an instruction to modify the default values, described in last paragraph, by multiplying by the absolute values of the negative numbers given, instead of muliplying by square root of 2. If the `chatty' option is turned on, then Gri will print out the values of (dx,dy) that it has calculated; this gives you some guidance for supplying your own values of `(.xr.,.yr.)' if you choose to supply them yourself. It is also a good idea to let these parameters be a guide for your grid spacing; for example, Koch et al., 1983, suggest using grid spacing of 0.3 to 0.5 times (dx,dy). And now, the details ... * *"Neighbor" method* The `convert columns to grid neighbor' method is useful for (x,y,z) data which are already gridded (i.e., for which x and y take only values which lie on the grid), or nearly gridded. The (x,y,z) data are scanned from start to finish. For each data point, the nearest grid point is found. Nearness is measured as Cartesian distance, with scale factor given by the distance between the first and second grid points. In other words, distance is given by D=sqrt(dx*dx+dy*dy) where dx is ratio of distance from data point to nearest grid point, in x-units, divided by the difference between the first two elements of the x-grid, and dy is similarly defined. Once the grid point nearest the data point is determined, Gri adds the z-value to a list of possible values to store in the grid. Once the entire data set has been scanned, Gri then goes back to each grid point, and chooses the z-value of the data point that was nearest to the grid point - that is, it stores the z value of the (x,y,z) data triplet which has minimal D value. Note that this scheme is independent of the order of the data within the columns. The `neighbor' method is useful when the data are already pre-gridded, meaning that the (x,y,z) triplets have x and y values which are already aligned with the grid. *Computational cost:* For `P' data points, `X' x-grid points, and `Y' y-grid points, the method calculation cost is proportional to `P*[log2(X)+log2(Y)]' where `log2' is logarithm base 2. As discussed below, this is often several orders of magnitude lower than the other methods of gridding. * *"Objective" method* In the `objective' method, a smoothing technique known as objective mapping is applied. It is essentially a variable-size smoothing filter of approximately Gaussian shape (it is method "two" of Levy and Brown [1986 J. Geophysical Res. vol 91, p 5153-5158]) The parameters `.xr.' and `.yr.' give the width of the filter. With the optional additional parameters `.n.' and `.e.' are specified, then grid values will be assigned the missing value if there are fewer than `.n.' (x,y,f) data in the neighborhood of the gridpoint, even after enlarging the neighborhood by widening and heightening by root(2) up to `.e.' times. (The enlargement is only done if fewer than `.n.' points are found.) If these parameters are not specified in the command, then values `.n.'=5 and `.e.'=1 are assumed. The special case where `.e.' is negative tells Gri to *always* fill in each grid point, by extending the neighborhood to enclose the entire dataset if necessary. *Computational cost:* For `P' data points, `X' x-grid points, and `Y' y-grid points, the method calculation cost is proportional to `P*X*Y'. Given that `X' and `Y' are determined by the requirement for smoothness of contours and the size of the graph, they are more or less fixed for all applications. They are often in the range of 20 or so - on 10 cm wide graph, this yields a contour footprint of 1/2 cm, which is often small enough to yield smooth contours. Therefore, the computational cost scales linearly with the number of data points. Compared to the "neighborhood" method, this is more costly by a factor of `X*Y/log_2(X)/log_2(Y)' which is normally in the range from 20 to 50. * *"Boxcar" method* In the `boxcar' method, the grid points are derived from simple averages calculated in rectangles `.xr.' wide and `.yr.' tall, centred on the gridpoints. The `.n.' and `.e.' parameters have similar meanings as in the "objective" method. *Computational cost:* Roughly same as `objective' method described above. * *"Barnes" method* This is the default scheme. The Barnes algorithm is applied. If no parameters are specified, `.xr.' and `.yr.' are determined as above, with `.gamma.' set to 0.5, and `.iter.' set to 2 so that two iterations are done. On successive iterations, the smoothing lengthscales `.xr' and `.yr' are each reduced by multiplying by the square root of `.gamma.'. Smaller `.gamma.' values yield better resolution of small-scale features on successive iterations. Koch et al., 1983, recommend using a `.gamma.' value in the range 0.2 to 1, with two iterations. Provided that all the grid points are close enough to at least some column data, the entire grid is filled. But if `.xr.' and `.yr.' are too small, the weighting function can fall to zero, since it is exponential in the sum of the squares of the x-distance/`.xr.' and the y-distance/`.yr.'; in that case missing values result at those grid points. On a 32 bit computer, the weighting function will fall to zero when x-distance/`.xr.' and y-distance/`.yr.' are less than about 15 to 20. If weights have been read in, then these values are applied in addition to the distance-based weighting. (The normalization means that weights for two data points of e.g. 1 and 2 will yield the same result as if the weights had been given as 10 and 20.) The computational cost is proportional to `P*P+P*X*Y)'. For large datasets, the first term (which results from the necessity to interpolate not only to the grid points but also to the data points) overwhelms the second term. For example, `X' and `Y' are normally less than approximately 20. This value is common because on a graph with a 10 cm axis, this yields a contour footprint of 1/2 cm, which is normally fine enough to get smooth contours. Therefore, if there are more than 400 data points, the `P*P' term exceeds the `P*X*Y' term. A data set may well have thousands of data points, and in this case the computational cost is approximately `P*P'. This is, therefore, a "order n-squared" algorithm, and it is therefore, by it's very nature, slow. The other methods, "neighbor", "objective" and "boxcar" are "order n" algorithms, so that "barnes" is much more costly for large data sets. As an example, for a dataset with a `P' of 1000, and with `X' and `Y' of 20, "barnes' is slower than "neighbor" by a factor of about 100. (The ratio increases to 300 for 5000 points.) Compared to "objective" and "boxcar," however, "barnes" is slower by a factor of 13 for 5000 data points and 26 for 10000 data points. For most practical purposes, therefore, the many advantages of "barnes" over "objective" and "boxcar" far outweigh the additional computational cost. On the other hand, the very swift "neighbor" method,is only suitable for very particular types of data sets. References: (1) Section 3.6 in Roger Daley, 1991, "Atmospheric data analysis," Cambridge Press, New York. (2) S. E. Koch and M. DesJardins and P. J. Kocin, 1983. "An interactive Barnes objective map anlaysis scheme for use with satellite and conventional data,", J. Climate Appl. Met., vol 22, p. 1487-1503. The Barnes algorithm is as follows: The gridded field is estimated iteratively. Successive iterations retain largescale features from previous iterations, while adding details at smaller scales. The first estimate of the gridded field, here denoted `G_(ij)^0' (the superscript indicating the order of the iteration) is given by a weighted sum of the input data, with `z_k' denoting the k-th `z' value. sum_1^n W_(ijk)^0 z_k G_(ij)^(0) = ---------------------- sum_1^n W_(ijk)0 where the notation `sum_1^n' means to sum the elements for the `k' index ranging from 1 to `n'. The weights `W_(ijk)^0' are defined in terms of a Guassian function decaying with distance from observation point to grid point: ( (x_k - X_i)^2 (y_k - Y_j)^2 ) W_(ijk)^0 = exp ( - --------------- - --------------- ) ( L_x^2 L_y^2 ) Here `L_x' and `L_y' are lengths which define the smallest `(x,y)' scales over which the gridded field will have significant variations (for details of the spectral response see Koch et al. 1983). Note: if the user has supplied weights, then these are applied in addition to the distance-based weights. That is, `w_i W_(ijk)' is used instead of `W_(ijk)'. The second iteration derives a grid `G_(ij)^1' in terms of the first grid `G_(ij)^0' and "analysis values" `f_k^0' calculated at the `(x_k,y_k)' using a formula analogous to that above. (Interpolation based on the first estimate of the grid `G_(ij)^0' can also be used to calculate `f_k^0', with equivalent results for a grid of sufficiently fine mesh.) In this iteration, however, the weighted average is based on the difference between the data and the gridded field, so that no further adjustment of the gridded field is done in regions where it is already close to through the observed values. The second estimate of the gridded field is given by sum_1^n W_(ijk)^1 (f_k - f_k^0) G_(ij)^1 = G_(ij)^0 + ------------------------------- sum_1^n W_(ijk)^1 where the weights `w_(ik,1)' are defined by analogy with `W_(ik)^0' except that `L_x' and `L_y' are replaced by `gamma^(1/2)L_x' and `gamma^(1/2)L_y'. The nondimensional parameter `gamma' (`0 tmp else if {"\.system." == "vax"} system awk/COMMANDS =\ "BEGIN { for (x = \xmin; x <= \xmax; x += \xinc) {print (x, \function)} \ } " \ /OUTPUT=TMP NL: end if open tmp read columns x y close tmp if {"\.system." == "unix"} system rm tmp else if {"\.system." == "vax"} system DELETE TMP.*;* end if if .must_clean_up_xmin. delete \xmin end if if .must_clean_up_xmax. delete \xmax end if if .must_clean_up_xinc. delete \xinc end if delete .must_clean_up_xmin. delete .must_clean_up_xmax. delete .must_clean_up_xinc. } `create image grayscale banded .band.' Make a banded grayscale with in units of .band. pixel values each. Thus, pixel values 0 to (.band. - 1) on the image will map to 0, while values from .band. to (2 * .band. - 1) will map to .band., etc. For example, .band. = 2 gives grayscale = (0 0 2 2 4 4 6 6 ... 252 252 254 254). { if {rpn \.words. 5 ==} \band = "\.word4" else show "ERROR: Require 4 words, but got \.words. words." show traceback quit end if system awk 'BEGIN \ { \ for (i = 0; i < 256; i++) \ { \ printf ("%d ", \band * int (i / \band)) \ } \ printf ("\n") \ }' \ > GRAYSCALE.TMP open GRAYSCALE.TMP read image grayscale close system rm GRAYSCALE.TMP delete \band } `create image greyscale banded .band.' Alternate spelling of grayscale. { if {rpn \.words. 5 ==} \band = "\.word4" else show "ERROR: Require 4 words, but got \.words. words." show traceback quit end if system awk 'BEGIN \ { \ for (i = 0; i < 256; i++) \ { \ printf ("%d ", \band * int (i / \band)) \ } \ printf ("\n") \ }' \ > GRAYSCALE.TMP open GRAYSCALE.TMP read image grayscale close system rm GRAYSCALE.TMP delete \band } `debug [.n.] | [clipped values in draw commands] | off' With no optional parameters, sets the value of `..debug..' to 1. (Normally, `..debug..' is 0.) You may use `..debug..' in if statements, etc. Note that `..debug..' is also set to 1 when gri is invoked with the commandline switch `-d'. With `.n.' specified, `..debug..' is set to `.n.'; a value of zero for `.n.' turns debugging off, while 1 turns it on. Higher values may be used for deeper debugging, if you choose: if \{rpn ..debug.. 2 <} # Code to do if ..debug.. is greater than 2. end if Note that you can assign to `..debug..' as you can to any other variable; `debug .n.' is equivalent to `..debug.. = .n.'. With the `clipped' option, Gri prints any clipped data encountered during any `draw ...' commands, EXCEPT in the case of `postscript' clipping, where no check is possible. (Note that `..debug..' is not affected.) All these forms of debugging are cancelled by `debug off'. { extern "C" bool debugCmd(void); } `delete {.variable. | \synonym [...]} | columns [{randomly .fraction.}|{where missing}] | grid | {[x|y] scale}' Delete some item or characteristic. `delete .variable.' Delete definition of variable `.variable.', making it undefined. `delete \synonym' Delete definition of synonym `\synonym', making it undefined. `delete columns' Delete column data. `delete columns randomly .fraction.' Randomly select fraction `.fraction.' of the non-missing column data, and designate them as being missing. `delete grid' Delete grid data. `delete scale' Delete scales for both x and y, so next `read columns' will set it. `delete x scale' Delete scales for x, so next `read columns' will set it. `delete y scale' Delete scales for y, so next `read columns' will set it. { extern "C" bool deleteCmd(void); } `differentiate {x|y wrt index|y|x} | {grid wrt x|y}' Differentiate column data or grid data. Only the `x' and `y' columns may be differentiated. They may be differentiated either with respect to ("wrt") the index (forming a first difference) or with respect to the other column. The derivative is done with the backwards-difference algorithm. Grid data may differentiated with respect to `x' direction or `y' direction. Grid differentiation is done with a centred difference, with endpoints being assigned the derivative of the neighboring interior point (so that the second derivative is zero at the edges of the grid). { extern "C" bool differentiateCmd(void); } `draw arc [filled] .xc_cm. .yc_cm. .r_cm. .angle_1. .angle_2.' Draw an "arc", that is, a portion of a circle. The center of the circle is at the coordinate (`.xc_cm.', `.yc_cm.'), and the circle radius is `.r_cm.', all three quantities being in cm on the page, _not_ in user-units. The arc starts at angle `.angle_1.', measured in degrees counterclockwise from a horizontal line, and extends to angle `.angle_2.', in the same units. If the keyword `filled' is present, the arc is filled with the current color. Otherwise it is drawn with the current "curve" linewidth. { extern "C" bool draw_arcCmd(void); } `draw arrow from .x0. .y0. to .x1. .y1. [cm]' With no optional parameters, draw an arrow from (`.x0.', `.y0.') to (`.x1.', `.y1.'), where coordinates are in user units. The arrow head will be at (`.x1.', `.y1.'), and its size is as set by most recent call to `set arrow size'. With the `cm' keyword present, the coordinates are in centimetres on the page. NOTE: This will not cause auto-drawing of axes. { extern "C" bool draw_arrow_from_toCmd(void); } `draw arrows' Draw a vector field consisting of arrows emanating from the coordinates stored in the (x, y) columns. The lengths and orientations of the arrows are stored in the (u, v) columns, and the scale for the (u,v) columns is set by `set u scale' and `set v scale'. SEE ALSO: (1) To set arrow size, use `set arrow size'. (2) To get a single arrow, for labelling plots, etc, use the `draw arrow from .x0. .y0. to .x1. .y1. [cm]' command. { extern "C" bool draw_arrowsCmd(void); } `draw axes if needed' Draw axes frame if required. Used within gri commands that auto-draw axes. NOTE: this should only be done by developers. { extern "C" bool draw_axes_if_needed(void); } `draw axes [.style.|frame|none]' With no style (`.style.') specified, draw x-y axes frame labelled at left and bottom. The value of `.style.' determines the style of axes: `.style. = 0' Draw x-y axes frame labelled at left and bottom `.style. = 1' Draw axes without tics at top and right `.style. = 2' Draw axes frame with no tics or labels With the keyword `frame' specified, draw axes frame with no tics or labels (just like `.style.' = 2). With the keyword `none' specified, prevent Gri from automatically drawing axes when drawing curves. { extern "C" bool draw_axesCmd(void); } `draw border box [.xleft. .ybottom. .xright. .ytop. .width_cm. .brightness.]' Draw gray box, as decoration or alignment key for pastup. The box, with outer lower left corner at (`.xleft.', `.ybottom.') and outer upper right corner at (`.xright'., `.ytop.') - both coordinates being in centimetres on the page - is drawn with thickness `.width_cm.' and with graylevel `.brightness.' (0 for black; 1 for white). The gray line is drawn inside the box. After drawing the gray line, a thin black line is drawn along the outside edge. If the geometry is not specified with `.xleft.' and the other parameters, then a reasonable margin is used around the present axes area, and the defaults (`.border.' = 0.2, `.brightness.' = 0.75) are used. NOTE: This command does not cause auto-drawing of axes. { if {rpn \.words. 3 ==} .xleft. = {rpn ..xmargin.. "M" width 5 * -} .ybottom. = {rpn ..ymargin.. "M" ascent 6 * -} .xright. = {rpn ..xmargin.. ..xsize.. + "M" width 2.0 * +} .ytop. = {rpn ..ymargin.. ..ysize.. + "M" width 2.0 * +} .width_cm. = 0.2 .brightness. = 0.75 else if {rpn \.words. 9 ==} .xleft. = \.word3. .ybottom. = \.word4. .xright. = \.word5. .ytop. = \.word6. .width_cm. = \.word7. .brightness. = \.word8. else show "ERROR: Require 3 or 9 words, but got \.words. words." show traceback quit end if # # Save old values of things that will be changed. .old_graylevel. = ..graylevel.. .old_linewidth. = ..linewidth.. set graylevel .brightness. set line width {rpn .width_cm. cmtopt} .tmp. = {rpn .ybottom. ..linewidth.. 2 / pttocm +} draw line from .xleft. .tmp. to .xright. .tmp. cm # lower edge .tmp. = {rpn .xleft. ..linewidth.. 2 / pttocm +} draw line from .tmp. .ybottom. to .tmp. .ytop. cm # left edge .tmp. = {rpn .ytop. ..linewidth.. 2 / pttocm -} draw line from .xleft. .tmp. to .xright. .tmp. cm # upper edge .tmp. = {rpn .xright. ..linewidth.. 2 / pttocm -} draw line from .tmp. .ybottom. to .tmp. .ytop. cm # right edge # # Draw thin black border. set line width 0.25 set graylevel black draw box .xleft. .ybottom. .xright. .ytop. cm # # Return to old values. set line width .old_linewidth. set graylevel .old_graylevel. # # Clean up local storage. delete .tmp. delete .old_graylevel. delete .old_linewidth. delete .brightness. delete .width_cm. delete .xleft. delete .ybottom. delete .xright. delete .ytop. } `draw box filled .xleft. .ybottom. .xright. .ytop. [cm|pt]' Draw filled box spanning indicated range, with lower-left corner at (`.xleft.', `.ybottom.') and upper-right corner at (`.xright.', `.ytop.'). The corners are specified in user coordinates, unless the optional `cm' or 'pt' keyword is present, in which case they are in centimetres or points on the page. An error will result if you specify user coordinates but they aren't defined yet. No checking is done on the rectangle; for example, there is no requirement that `.xleft.' be to the left of `.xright.' in your coordinate system. NOTE: if the box is specified in user units, this command will cause auto-drawing of axes, but not if the box is specified in cm or pt units. { extern "C" bool draw_box_filledCmd(void); } `draw box .xleft. .ybottom. .xright. .ytop. [cm|pt]' Draw box spanning indicated range, with lower-left corner at (`.xleft.', `.ybottom.') and upper-right corner at (`.xright.', `.ytop.'). The corners are specified in user coordinates, unless the optional `cm' or `pt' keyword is present, in which case they are in centimetres or points on the page. An error will result if you specify user coordinates but they aren't defined yet. No checking is done on the rectangle; for example, there is no requirement that `.xleft.' be to the left of `.xright.' in your coordinate system. { extern "C" bool draw_boxCmd(void); } `draw circle with radius .r_cm. at .x_cm. .y_cm.' Draw circle of specified radius (in cm) at the specified location (in cm on the page). { extern "C" bool draw_circleCmd(void); } `draw contour [{.value. [unlabelled|{labelled "\label"}]} | {.min. .max. .inc. [.inc_unlabelled.] [unlabelled]}]' This command draws contours based on the "grid" data previously read in by a `read grid data' command or created by gridding column data with a `create grid from columns' command. If the grid data don't exist, or if the x and y locations of the grid points do not exist (see `set x grid', `set y grid', `read grid x' and `read grid y'), Gri will complain. With no optional parameters, draw labelled contours at an interval that is picked automatically based on the range of the data. With a single numerical value (`.value.'), draw the indicated contour. With the addition of `labelled "\label"', put the indicated label instead of a numeric label. This can be useful, say, for using scientific notation instead of computer notation for exponents. For example, you might do something like `draw contour 1e-5 labelled "10$^\{-5}$"' or maybe `draw contour 1e-5 labelled "critical value"'. With (`.min.', `.max.' and `.inc.') given, draw contours for z(x,y) = `.min.', z(x,y) = `.min. + .inc.', z(x,y) = `.min. + 2*.inc.', ..., z(x,y) = `.max.' With the additional value `.inc_unlabelled.' specified, extra unlabelled contours are drawn at this finer interval. With the optional parameter `unlabelled' at the end of any form of this command (except the `labelled "\label"' variation, of course), Gri will not label the contour(s). *Hint:* It can be effective to draw contours at a certain interval with labels, and a thicker pen, e.g. set line width rapidograph 3x0 draw contour -2 5 1 0.25 set line width rapidograph 1 draw contour -2 5 1 { extern "C" bool draw_contourCmd(void); } `draw curve overlying' Like `draw curve', except that before drawing, the area underneath the curve (+/- one linewidth) is whited out. This clarifies graphs where curves overly other curves or the axes. SEE ALSO: `draw curve'. { state save set dash off set color white set line width {rpn ..linewidth.. 3 *} draw curve # clean space underneath state restore draw curve # draw actual curve } `draw curve filled [to {.y. y} | {.x. x}]' The form `draw curve filled ...' draws filled curves. If `to .value.' is not specified, fill the region defined by the x-y points using the current paint colour (see `set graylevel'). To complete the shape, an extra line is drawn from the first and last point. The form `draw curve filled to .y. y' fills the region between y(x) and y = `.y.'; do not connect the first and last points as in the case where `to .yvalue.' is not specified. The form `draw curve filled to .x. x' fills the region between x(y) and x = `.x.' { extern "C" bool draw_curveCmd(void); } `draw curve' Draws a curve connecting the points (x,y), which have been read in by a command like `read columns x y'. Line segments are drawn between all (x,y) points, except: (1) no line segments are drawn to any missing data (see `set missing value'), and (2) if clipping is turned on (see `set clip on'), no line segments are drawn outside the clipping region. SEE ALSO: `draw curve overlying' { extern "C" bool draw_curveCmd(void); } `draw essay "text"|reset' Draw indicated text on the page. Succeeding calls draw text further and further down the page, starting at the top. The current font size is used; to alter this, do `set font size' before calling `draw essay'. When `reset' is present instead of text, the drawing position is reset to the top of the page. Use this after a `new page' command to ensure that the next text lines will appear at the top of the page as expected. EXAMPLE: set font size 2 cm draw essay "Line 1, at top of page" draw essay "Line 2, below top line" { # Check for proper format, and give error message if not. if {rpn \.words. 3 ==} # Check to see if this is the first call; if so, initialize location. if {"\.word2." == "reset"} # Reset .top_of_page. and return. if ..landscape.. .top_of_page. = {rpn 8.5 2.54 * 1 -} else .top_of_page. = {rpn 11. 2.54 * 1 -} end if return end if # Last word is not `reset', so draw it. if {rpn ".top_of_page." defined !} # if ..landscape.. .top_of_page. = {rpn 8.5 2.54 * 1 -} else .top_of_page. = {rpn 11. 2.54 * 1 -} end if end if .top_of_page. -= {rpn ..fontsize.. pttocm 1.5 *} draw label "\.word2." at 1 .top_of_page. cm else show "ERROR: Require 3 words, but got \.words. words." show traceback quit end if } `draw gri logo .x_cm. .y_cm. .height_cm. .style. \fgcolor \bgcolor' .style. style ======= =================== 0 stroke curve 1 fill with color \fgcolor, no background 2 fill with color \fgcolor it in tight box of color \bgcolor 3 as 2 but in square box 4 draw in \fgcolor on top of shifted copy in \bgcolor { extern "C" bool draw_gri_logoCmd(void); } `draw grid' Draw plus-signs at locations where grid data are non-missing. { extern "C" bool draw_gridCmd(void); } `draw image palette [axisleft|axisright|axistop|axisbottom] [left .left. right .right. [increment .inc.]] [box .xleft_cm. .ybottom_cm. .xright_cm. .ytop_cm.]' With no optional parameters, draw palette for image, placed above the current top showing values ranging from `.min_value.' to `.max_value.' as given in `set image range'. Optional keywords (`axisleft', etc) control the orientation of the palette, the default being `axisbottom'. The optional parameters `.left.' and `.right.' may be used to specify the range to be drawn in the palette. If the additional optional parameter `.inc.' is present, it specifies the interval between tics on the scale; if not present, the tics are at increments of 2 * (`.right.' - `.left'.). (If `.inc.' has the wrong sign, it will be corrected without warning.) When the optional `box' parameters are present, they prescribe the bounding box to contain the palette. The units are centimetres on the page. If these parameters are not present, the box will be drawn above the image plot. HINT: It is a good idea to make the palette range `.left.' to `.right.' extend a little beyond the range of full white and full black, since otherwise neither pure white nor pure black will appear in the colorbar. For example: set image grayscale black 0 white 1 increment 0.1 draw image palette left -0.1 right 1.1 increment 0.1 { extern "C" bool draw_image_paletteCmd(void); } `draw image grayscale [left .left. right .right. [increment .inc.]] [box .xleft_cm. .ybottom_cm. .xright_cm. .ytop_cm.]' Old name for `draw image palette' { extern "C" bool draw_image_paletteCmd(void); } `draw image histogram [box .xleft_cm. .ybottom_cm. .xright_cm. .ytop_cm.]' With no optional parameters, draw histogram of all unmasked parts of the image, placing it above the current top of the plot. When the `box' options are present, they specify the box (in centimetre coordinates on the page) in which the histogram plot is to be done. { extern "C" bool draw_image_histogramCmd(void); } `draw image' Draw black/white image made by `convert grid to image' or by `read image'. { extern "C" bool draw_imageCmd(void); } #* @param .P_sigma. = reference pressure for density @default 0dbar #* @param .P_theta. = reference pressure for temperature @default 0dbar `draw isopycnal [unlabelled] .density. [.P_sigma. [.P_theta.]]' Draw isopycnal curve for a temperature-salinity diagram. This curve is the locus of temperature and salinity values which yield seawater of the indicated density, at the indicated pressure. The UNESCO equation of state is used. For the results to make sense, the x-axis should be salinity and the y-axis should be either in-situ temperature or potential temperature. The `.density.' unit is kg/m^3. If the supplied value exceeds 100 it will be taken to indicate the actual density; otherwise it will be taken to indicate density minus 1000 kg/m^3. (Thus, 1020 and 20 each correspond to an actual density of 1020 kg/m^3.) The reference pressure for density, `.P_sigma.', is in decibars (roughly corresponding to meters of water depth). If no value is supplied, a pressure of 0 dbar (i.e. atmospheric pressure) is used. The reference pressure for theta, `.P_theta.', is in decibars, and defaults to zero (i.e. atmospheric pressure) if not supplied. This option is used if the y-axis is potential temperature referenced to a pressure other than the surface. Normally the potential temperature is, however, referenced to the surface, so that specifying a value for `.P_theta.' is uncommon. By default, labels will be drawn on the isopycnal curve; this may be prevented by supplying the keyword `unlabelled'. If labels are drawn, they will be of order 1000, or of order 10 to 30, according to the value of `.density.' supplied (see above). The label format defaults to "%g" in the C-language format notation, and may be controlled by `set contour format'. The label position may be controlled by `set contour label position' command (bug: only non-centered style works). Setting label position is useful if labels collide with data points. Labels are drawn in the whiteunder mode, so they can white-out data below. For this reason it is common to draw data points after drawing isopycnals. If the y-axis is in-situ temperature, the command should be called without specifying `.P_sigma.', or, equivalently, with `.P_sigma.' = 0. That is, the resultant curve will correspond to the (S,T) solution to the equation .density. = RHO(S, T, 0) where `RHO=RHO(S,T,p' is the UNESCO equation of state for seawater. This is a curve of constant sigma_T. If the y-axis is potential temperature referenced to the surface, `.P_theta.' should not be specified, or should be specified to be zero. The resultant curve corresponds to a constant value of potential density referenced to pressure `.P_sigma.', i.e. the (S,theta) solution to the equation .density. = RHO(S, theta, .P_sigma.) For example, with `.P_sigma.=0' (the default), the result is a curve of constant sigma_theta. If the y-axis is potential temperature referenced to some pressure other than that at the surface, `.P_theta.' should be supplied. The resultant curve will be the (S,theta) solution to the equation .density. = RHO(S, T', .P_sigma.) where T'=THETA(S, theta, .P_theta., .P_sigma.) where `THETA=THETA(S,T,P,Pref)' is the UNESCO formula for potential temperature of a water-parcel moved to a reference pressure of `Pref'. Note that `theta', potential temperature referenced to pressure `.P_theta.', is the variable assumed to exist on the y-axis. { extern "C" bool draw_isopycnalCmd(void); } `draw isospice .spice. [unlabelled]' Draw an iso-spice line for a "TS" diagram, using (S, T) data stored in files in a subdirectory named `iso-spice0' in a directory named by the environment variable `GRI_EOS_DIR'. You must set this environment variable yourself, in the normal unix way. If `GRI_EOS_DIR' is not defined, Gri looks in the directory `/data/po/ocean/EOS/iso0'; of course, this will work only for people on the same machine as the author. Only certain iso-spice lines are stored in these files, so only certain values of `.spice.' are allowed. They are 21.75, 22.00, 22.25, ..., 30.75. You must supply `.density.' in exactly this format (with 2 decimal places), or else Gri will not find the appropriate TS file, and will give a "can't open file" error. NB: isopycnals ranging from about 23.00 to 26.00 cross a TS diagram spanning 34 \.words. 4 < |} show "ERROR: Require 3 or 4 words, but got \.words. words." show traceback quit end if # don't have 3 or 4 words get env \gri_eos_dir GRI_EOS_DIR if {rpn "\gri_eos_dir" "" ==} \eos_file = "/data/po/ocean/EOS/iso-spice0/spice0_\.word2." else \eos_file = "\gri_eos_dir/iso-spice0/spice0_\.word2." end if if ..trace.. show "Plotting iso-spice lines in \eos_file" end if # ..trace.. open \eos_file read columns x y close if ..num_col_data.. draw curve if {rpn \.words. 4 ==} if {"\.word3." == "unlabelled"} # no label else # improper final word show "ERROR: Bad 4th word \"\.word3.\"; expecting \"labelled\"" show traceback quit end if # improper final word else # not 4 words if {rpn ..xlast.. ..xright.. - ..ylast.. ..ytop.. - >} # Put label above. draw label "\.word2." at \ {rpn ..xlast.. xusertocm "\.word2." width 0.35 * -} \ {rpn ..ytop.. yusertocm ..fontsize.. pttocm 0.7 * +} cm else # label at right # Put label to right. draw label "\.word2." at \ {rpn ..xright.. xusertocm ..fontsize.. pttocm 0.7 * +} \ {rpn ..ylast.. yusertocm ..fontsize.. pttocm 0.4 * -} cm end if # label at right end if else # iso-spice not in region show "WARNING from `draw isospice ...': iso-spice \.word2. not in clip region." end if # iso-spice not in region delete \gri_eos_dir \eos_file } `draw label boxed "\string" at .xleft. .ybottom. [cm]' Draw boxed label for plot, located with lower-left corner at indicated (x,y) position (specified in user units, or in cm on the page). The current font size and pen color are used. The geometry derives from the current font size, with the label being centered within the box. { if {rpn "\.word4." "at" !=} show "ERROR: Fifth word must be \"at\", not \"\.word4.\"" show traceback quit end if new .x. .y. new .draw_boxed_labelR. new .draw_boxed_labelG. new .draw_boxed_labelB. .draw_boxed_labelR. = ..red.. .draw_boxed_labelG. = ..green.. .draw_boxed_labelB. = ..blue.. if {rpn \.words. 7 ==} .x. = {rpn \.word5. xusertocm} .y. = {rpn \.word6. yusertocm} else if {rpn \.words. 8 ==} if {rpn "\.word7." "cm" !=} show "ERROR: Require 7th word to be `cm'" show traceback quit end if .x. = \.word5. .y. = \.word6. else show "ERROR: Require 7 or 8 words, but got \.words. words." show traceback quit end if # Coordinates now in cm .draw_boxed_label_offset. = {rpn ..linewidth.. pttocm 4 *} draw box filled \ {rpn .x. .draw_boxed_label_offset. +} \ {rpn .y. .draw_boxed_label_offset. -} \ {rpn .x. "MM\.word3." width + .draw_boxed_label_offset. +} \ {rpn .y. "M" ascent 2 * + .draw_boxed_label_offset. -} cm set color white draw box filled \ .x. \ .y. \ {rpn .x. "MM\.word3." width +} \ {rpn .y. "M" ascent 2 * +} cm set color rgb .draw_boxed_labelR. .draw_boxed_labelG. .draw_boxed_labelB. draw box \ .x. \ .y. \ {rpn .x. "MM\.word3." width +} \ {rpn .y. "M" ascent 2 * +} cm draw label "\.word3." at \ {rpn .x. "M" width +} \ {rpn .y. "M" ascent 0.5 * +} cm delete .x. .y. delete .draw_boxed_labelR. delete .draw_boxed_labelG. delete .draw_boxed_labelB. } `draw label whiteunder "\string" at .xleft. .ybottom. [cm]' Draw label for plot, located with lower-left corner at indicated (x,y) position (specified in user units or in cm on the page). Whiteout is used to clean up the area under the label. BUGS: Cannot handle angled text; doesn't check for super/subscripts. { if {rpn "\.word4." "at" !=} show "ERROR: Fifth word must be \"at\", not \"\.word4.\"" show traceback quit end if new .x. .y. .space. .oldR. .oldG. .oldB. .oldR. = ..red.. .oldG. = ..green.. .oldB. = ..blue.. if {rpn \.words. 7 ==} .x. = {rpn \.word5. xusertocm} .y. = {rpn \.word6. yusertocm} else if {rpn \.words. 8 ==} if {rpn "\.word7." "cm" !=} show "ERROR: Require 7th word to be `cm'" show traceback quit end if .x. = \.word5. .y. = \.word6. else show "ERROR: Require 7 or 8 words, but got \.words. words." show traceback quit end if # Coordinates now in cm. Next, white out a box under the # text (and .space. centimetres beyond text), then draw label. .space. = 0.1 # cm set color white draw box filled \ {rpn .x. .space. -} \ {rpn .y. .space. -} \ {rpn .x. "\.word3." width + .space. +} \ {rpn .y. "M" ascent + .space. + } cm set color rgb .oldR. .oldG. .oldB. draw label "\.word3." at .x. .y. cm delete .x. .y. .space. .oldR. .oldG. .oldB. } `draw label for last curve "label"' Draw a label for the last curve drawn, using the `..xlast..' and `..ylast..' built-in variables. { if {rpn \.words. 6 ==} draw label "\.word5." at\ {rpn ..xlast.. xusertocm "M" width 0.5 * +} \ {rpn ..ylast.. yusertocm "M" ascent 0.5 * -} cm else show "ERROR: Require 6 words, but got \.words. words." show traceback quit end if } `draw label "\string" [centered|rightjustified] at .x. .y. [cm|pt] [rotated .deg.]' With no optional parameters, draw string at given location in USER units. With the `cm' or `pt' keyword is present, the location is in centimetres or points on the page. With the `rotated' keyword present, the angle in degrees from the horizontal, measured positive in the counterclockwise direction, is given. With the keyword `centered' present, the text is centered at the given location; similarly the keyword `rightjustified' makes the text end at the given location. { extern "C" bool draw_labelCmd(void); } `draw line from .x0. .y0. to .x1. .y1. [cm|pt]' With no optional parameters, draw a line from (`.x0.', `.y0.') to (`.x1.', `.y1'.), where coordinates are in user units. With the `cm' or 'pt' keyword present, the coordinates are in centimetres or points on the page. NOTE: This will not cause auto-drawing of axes. { extern "C" bool draw_line_from_toCmd(void); } `draw line legend "label" at .x. .y. [cm] [length .cm.]' Draw a legend identifying the current line type with the given label. A short horizontal line is drawn starting at the location (`.x.', `.y.'), which may be specified in centimetres or, the default, in user coordinates. The line length is normally 1 cm, but this length can be set by the last option. The indicated label string is drawn 0.25 cm to the right of the line. SEE ALSO `draw symbol legend ...'. EXAMPLE (of keeping track of the desired location for the legend) .offset. = 1 # cm to offset legends # ... get salinity data set line width 0.25 draw curve draw line legend "Salinity" at .x. .y. # ... get temperature data set line width 1.0 set dash 0.45 0.05 draw curve .y. += .offset. draw line legend "Temperature" at .x. .y. { # Check for too few or too many words. if {rpn \.words. 7 >} show "ERROR: Require 7 or more words, but got \.words. words." show traceback quit end if if {rpn \.words. 10 <} show "ERROR: Require 10 or fewer words, but got \.words. words." show traceback quit end if .tmp_len. = 1 # cm if {rpn \.words. 9 ==} .tmp_len. = \.word8. else if {rpn \.words. 10 ==} .tmp_len. = \.word9. end if if {"\.word7." == "cm"} # Position given in centimetres. draw line from \ \.word5. \ \.word6. \ to \ {rpn \.word5. .tmp_len. +} \ \.word6. \ cm draw label "\.word3." at\ {rpn \.word5. .tmp_len. + 0.25 +} \ {rpn \.word6. ..fontsize.. pttocm 0.4 * -} \ cm else # Position given in user units. draw line from \ \.word5. \ \.word6. \ to \ {rpn \.word5. xusertocm .tmp_len. + xcmtouser} \ \.word6. draw label "\.word3." at\ {rpn \.word5. xusertocm .tmp_len. + 0.25 + xcmtouser} \ {rpn \.word6. yusertocm ..fontsize.. pttocm 0.4 * - ycmtouser} end if } `draw lines {vertically .left. .right. .inc.} | {horizontally .bottom. .top. .inc.}' Draw several lines, either vertically or horizontally. This can be useful in drawing gridlines for axes, etc. The following example shows how to draw thin gray lines extending from the labelled tics on the x axis (ie, at 0, 0.1, 0.2, ... 1): set x axis 0 1 0.1 0.05 set y axis 10 20 10 draw axes set graylevel 0.75 set line width 0.5 draw lines vertically 0 1 0.1 set graylevel black { extern "C" bool draw_linesCmd(void); } `draw patches .width. .height. [cm]' With the optional `cm' keyword not present, draw column data z(x,y) as gray patches according to the grayscale as set by most recent `set image grayscale'. The patches are aligned along the horizontal, and have the indicated size in user units. With the optional keyword `cm' is present, the patch size is specified in centimetres. { extern "C" bool draw_patchesCmd(void); } `draw polygon [filled] .x0. .y0. .x1. .y1. .x2. .y2. [...]' Draw a polygon connecting the indicated points, specified in user units. The last point is joined to the first by a line segment. At least two points must be specified. If the `filled' keyword is present, the polygon is filled with the current pen color. { extern "C" bool draw_polygonCmd(void); } `draw regression line [clipped]' Fit a regression line to column data, of the form `y = ..coeff0.. + ..coeff1.. * x' (exporting `..coeff0..' and `..coeff1..' as global variables) and draw this line on the plot, for the range `..xleft.. <= x <= ..xright..' on the x-axis. Fit and draw a regression line to column data, of the form `y = ..coeff0.. + ..coeff1.. * x' (exporting `..coeff0..', `..coeff0_sig..', `..coeff1..' and `..coeff1_sig..' as global variables; see `regress'). Normally, the line is not clipped to the axes frame, but it will be if the keyword 'clipped' is given. HINT: to label the plot you might do the following: sprintf \label "y = %f + %f * x. R$^2$=%f" ..coeff0.. ..coeff1.. ..R2.. draw title "The linear fit is \label" SEE ALSO: `regress' { regress y vs x new .clipped. .xl. .xr. .yl. .yr. if {rpn \.words. 4 ==} if {rpn "\.word3." "clipped" ==} .clipped. = 1 else show "ERROR: 4-th word must be 'clipped', not '\.word3.'" show traceback quit end if else .clipped. = 0 end if .xl. = ..xleft.. .xr. = ..xright.. .yl. = {rpn .xl. ..coeff1.. * ..coeff0.. +} .yr. = {rpn .xr. ..coeff1.. * ..coeff0.. +} if .clipped. if {rpn .yl. ..ybottom.. > } .yl. = ..ybottom.. .xl. = {rpn .yl. ..coeff0.. - ..coeff1.. /} end if if {rpn .yl. ..ytop.. < } .yl. = ..ytop.. .xl. = {rpn .yl. ..coeff0.. - ..coeff1.. /} end if if {rpn .yr. ..ytop.. < } .yr. = ..ytop.. .xr. = {rpn .yr. ..coeff0.. - ..coeff1.. /} end if if {rpn .yr. ..ybottom.. > } .yr. = ..ybottom.. .xr. = {rpn .yr. ..coeff0.. - ..coeff1.. /} end if end if draw line from .xl. .yl. to .xr. .yr. draw axes if needed delete .clipped. .xl. .xr. .yl. .yr. } `draw symbol legend \symbol_name "label" at .x. .y. [cm]' Draw indicated symbol at indicated location, with the indicated label beside it. The label is drawn one M-space to the right of the symbol, vertically centered on the indicated `.y.' location. { # Note kludge in y position, because ascent is inaccurate as # of version 1.17 anyway if {rpn \.words. 8 ==} draw symbol \.word3. at \.word6. \.word7. draw label "\.word4." at\ {rpn \.word6. xusertocm "M" width +} \ {rpn \.word7. yusertocm "M" ascent 0.7 * 2 / -} cm else if {rpn \.words. 9 ==} if {rpn "\.word8." "cm" ==} draw symbol \.word3. at \.word6. \.word7. cm draw label "\.word4." at \ {rpn \.word6. "M" width +} \ {rpn \.word7. "M" ascent 0.7 * 2 / -} cm else show "ERROR: Can't understand [\.word8.]; expecting [cm]" show traceback quit end if else show "ERROR: Require 8 or 9 words, not \.words. as given." show traceback quit end if } `draw symbol [.code.|\name [at .x. .y. [cm|pt]] [graylevel z]|[colorrange .h.]|[color [hue z|.h.] [brightness z|.b.] [saturation z|.s.]]]' The "at" form `draw symbol .code.|\name at .x. .y. [cm|pt]' draws a single symbol at the named location. The non-"at" form draws symbols at the (x,y) data. If a z-column has been read with `read columns', then it's value codes the symbol to draw, according to the table below. (The value of z is first rounded to the nearest integer.) If no z-column has been read, the symbol X is drawn at each datum. With the optional numerical/name code specified, then the symbol of that number or name is drawn at each (x,y) datum, whether or not a z-column exists. The numerical/name codes are: # name description -- ---- ----------- 0 plus + 1 times x 2 box box 3 circ circle 4 diamond diamond 5 triangleup triangle with base at bottom 6 triangleright triangle with base at left 7 triangledown triangle with base at top 8 triangleleft triangle with base at right 9 asterisk * 10 star star of David 11 filledbox filled box 12 bullet filled circle 13 filleddiamond filled diamond 14 filledtriangleup filled triangleup 15 filledtriangleright filled triangleright 16 filledtriangledown filled triangledown 17 filledtriangleleft filled triangleleft With the optional `graylevel z' fields specified, the graylevel is given by the `z` column (0=black, 1=white). With the optional `colorrange .hue.` fields specified, the color model is in the form of (hue, saturation, brightness), with hue being fixed at the indicated value, and with saturation given by 1-z, and brightness by (1+2*z)/3. (This mode was contributed by Philip Eisenlohr.) With the optional `color' field specified, the color is specified, either directly in the command (the `hue .h.' form) or in the z column. For more information on color, refer to the `set color hsb ...' command. Examples: both `draw symbol bullet color' and `draw symbol bullet color hue z' draw bullets whose hue is given by the value in the z column. The hue (or the color, in other words) blends smoothly across the spectrum as the numerical value ranges from 0 to 1. The value 0yields red, 1/3 yields green, 2/3 yields blue, etc. If the `brightness' and the `saturation' are not specified, they both default to the value 1, which yields pure, bright colors. Example: `draw symbol bullet color hue 0.333 brightness 1 saturation 1' draws green dots. { extern "C" bool draw_symbolCmd(void); } `draw time stamp [fontsize .points. [at .x_cm. .y_cm. cm [with angle .deg.]]]' Draw the command-file name, PostScript file name, and time, at the top of graph. Normally, the timestamp is drawn at the top of the page, in a fontsize of 10 points. But the user can specify the fontsize, and additionally the location (in cm) and additionally the angle measured in degrees anticlockwise from the horizontal. NOTE: If you want to have the plot in landscape mode on the page, make sure that you do `set page landscape' before `draw time stamp.' { new .old_fontsize. .old_fontsize. = ..fontsize.. if {rpn \.words. 3 ==} # Just `draw time stamp' set font size 10 if ..landscape.. draw label "Gri-\.version. \.wd./\.command_file. (\.time.)" at \ 1.5 20.6 cm else draw label "Gri-\.version. \.wd./\.command_file. (\.time.)" at \ 1.5 27.0 cm end if else if {rpn \.words. 5 ==} # `draw time stamp fontsize .points.' # 0 1 2 3 4 set font size \.word4. if ..landscape.. draw label "Gri-\.version. \.wd./\.command_file. (\.time.)" at \ 1.5 20.6 cm else draw label "Gri-\.version. \.wd./\.command_file. (\.time.)" at \ 1.5 27.0 cm end if else if {rpn \.words. 9 ==} # `draw time stamp fontsize .points. at .x_cm. .y_cm. cm' # 0 1 2 3 4 5 6 7 8 set font size \.word4. draw label "Gri-\.version. \.wd./\.command_file. (\.time.)" at \ \.word6. \.word7. cm else if {rpn \.words. 12 ==} # `draw time stamp fontsize .points. at .x_cm. .y_cm. cm with angle .deg.' # 0 1 2 3 4 5 6 7 8 9 10 11 set font size \.word4. draw label "Gri-\.version. \.wd./\.command_file. (\.time.)" at \ \.word6. \.word7. cm rotated \.word11. else show "ERROR: Require 3, 5, 9 or 12 words, but got \.words. words." show traceback quit end if set font size .old_fontsize. delete .old_fontsize. } `draw title "\string"' Draw the indicated string above the plot. { extern "C" bool draw_titleCmd(void); } `draw values [.dx. .dy.] [\format] [separation .xcm. .ycm.]' Draw values of `z' column, at corresponding (`x', `y') locations. If the `separation' keyword is present, the distance between successive points is checked, and points are skipped unless the x and y separations exceed than the indicated distances. `draw values' Draw the values of `z(x,y)', positioned 1/2 M-space to the right of `(x,y)' and vertically centred on `y'. The values are written in a good general format known as `%g', in C terminology. `draw values %.2f' Draw values of `z(x,y)' positioned as described above, but using the indicated format string. This format string specifies that 2 numbers be used after the decimal place, and that floating point should be used. See any C manual for format codes. `draw values .dx. .dy.' Print values of `z(x,y)' at indicated offset vector (`.dx.',`.dy.'), measured in centimeters, from the values of `(x,y)' at which the data are defined. `draw values .dx. .dy. %.3f' Print values of `z(x,y)' at indicated distance from `(x,y)', indicated format. { extern "C" bool draw_valuesCmd(void); } `draw x axis [at bottom|top|{.y. [cm]} [lower|upper]]' Draw an x axis, optionally at a specified location and of a specified style. `draw x axis' Draw a lower x axis (ie, one with the numbers below the line) at the bottom of the box defined by `set y axis'. `draw x axis at bottom' Draw a lower x axis (ie, one with the numbers below the line) at the bottom of the box defined by `set y axis'. `draw x axis at top' Draw an upper x axis (ie, one with the numbers above the line) at the top of the box defined by `set y axis' (or above any existing stacked x axes there) `draw x axis at .y.' Draw a lower x axis at indicated value of `.y.'. `draw x axis at .y. upper' Draw an upper x axis at indicated value of .y. { extern "C" bool draw_x_axisCmd(void); } `draw x box plot at .y. [size .cm.]' Draw Tukey box plots (which give a summary of histogram properties). Box plots were invented by Tukey for eda (exploratory data analysis). The centre of the box is the median. The box edges show the first quartile (q1) and the third quartile (q3). The distance from q3 to q1 is called the inter-quartile range. The whiskers (i.e., the lines with crosses at the end) extend from q1 and q3 to the furthest data points which are still within a distance of 1.5 inter-quartile ranges from q1 and q3. Beyond the whiskers, all outliers are shown: open circles are used for data within a distance of 3 inter-quartile ranges beyond q1 and q3, and in closed circles beyond that. `draw x box plot at .y.' Draw Tukey's box plot, spreading in the x direction, centered at y=`.y.' and of default width 0.5 cm. `draw x box plot at .y. size .cm.' Draw Tukey's box plot, spreading in the x direction, centered at y=`.y.' and of width `.cm.' centimetres. { extern "C" bool draw_x_box_plotCmd(void); } `draw y axis [at left|right|{.x. cm} [left|right]]' Draw a y axis, optionally at a specified location and of a specified style. `draw y axis' Draw a left-hand-side y axis (ie, one with the numbers to the left of the line) at left of box defined by `set x axis' `draw y axis at left' Draw a left-hand-side y axis (ie, one with the numbers to the left of the line) at left of box defined by `set x axis'. `draw y axis at right' Draw a right-hand-side y axis (ie, one with the numbers to the right of the line) at right of box defined by `set x axis'. `draw y axis at .x.' Draw a left-hand-side y axis (ie, one with the numbers to the left of the line) at indicated value of `.x.' `draw y axis at .x. right' Draw a right-hand-side y axis (ie, one with the numbers to the right of the line) at indicated value of `.x.' { extern "C" bool draw_y_axisCmd(void); } `draw y box plot at .x. [size .cm]' Draw Tukey box plots (which give summary of histogram properties). `draw y box plot at .x.' Draw Tukey's box plot, spreading in the y direction, centered at x=`.x.' and of default width 0.5 cm. `draw y box plot at .x. size .cm.' Draw Tukey's box plot, spreading in the y direction, centered at x=`.x.' and of width `.cm.' centimetres. { extern "C" bool draw_y_box_plotCmd(void); } `draw zero line [horizontally|vertically]' Draw lines corresponding to x=0 or y=0. `draw zero line' Draw line y=0 if it's within axes. `draw zero line horizontally' Draw line y=0 if it's within axes. `draw zero line vertically' Draw line x=0 if it's within axes. { extern "C" bool draw_zero_lineCmd(void); } `end group ["\name"]' Ene a group, i.e. a collection of graphical objects. (NOT IMPLEMENTED YET. SYNTAX MAY CHANGE.) { extern "C" bool end_groupCmd(void); } `expecting version .n.' Show a list of incompatibilites since the named version. This protects you from being clobbered by changes made to Gri, since you will be assured of being warned of these changes. For example, if you are doing a lot of work with version 2.1.0, but want to move up to a higher version, you would include the line `expecting version 2.0100' in all your commandfiles. Once you are sure that your commandfile will not be affected by the newer version, you should change the version that is expected. Note: As of October 1996, Gri version numbers have been in the form `a.b.c'. Numerical version numbers are created by the formula `a + b/100 + c/10000'. For example, version `2.1.0' has a numerical value of `2.0100'. { extern "C" bool expectingCmd(void); } `filter column x|y|z|u|v recursively .a0. .a1. ... .b0. .b1. ...' Filter indicated column, using a two-pass recursive filter. The first pass runs from the start to the end, while the second pass runs from the end to the start; in this way, the phase shift inherent in this type of filter is removed entirely. The coefficients are used in the following formula (demonstrated on the `x' column): x_new[i] = b[0] * x[i] + b[1] * x[i-1] + b[2] * x[i-2] + ... - a[1] * x_new[i-1] - a[2] * x_new[i-2] - ... Thus, for example, setting `a[i]' = 0 results in a simple backwards-looking moving-average filter applied in two passes. The real power of this type of filter, however, comes when non-zero `a[i]' coefficients are given, thus adding recursion (i.e., `x_new[i]' depends on `x_new[i-...]'). See any standard reference on digital filters for an explanation. You might find that the Matlab command `butter' an easy way to design filter coefficients. Here are some examples: # Filter x column with simple 2-point moving average. filter column x recursively 0 0 0.5 0.5 # Use filter designed with the Matlab command butter(2,0.1), # which creates a 2nd order lowpass butterworth filter, with a cutoff # frequency of 0.1 (in units which have a frequency of 1 corresponding # to one-half the sampling rate). filter column x recursively 1 -1.561 0.6414 0.0201 0.0402 0.0201 { extern "C" bool filter_columnCmd(void); } `filter grid rows|columns recursively .a0. .a1. ... .b0. .b1. ...' Apply recursive filter (see `filter column ... recursively' for meaning of this filter) to the individual rows or columns of the grid data. For example, `filter grid columns recursively 0 0 .5 .5' applies a 2-point moving average filter across the columns, smoothing the grid in the x-direction. { extern "C" bool filter_gridCmd(void); } `filter image highpass|lowpass' `filter image highpass' Remove low-wavenumber components from image (ie, sharpen edges). Do this by subtracting a Laplacian smoothed version of the image. `filter image lowpass' Remove high-wavenumber components from image (ie, smooth shapes). Do this by Laplacian smoothing. { extern "C" bool filter_imageCmd(void); } `flip grid|image x|y' Flip image by relecting it about a horizontal or vertical centerline. `flip grid x' Flip grid so right-hand side becomes left-hand side. `flip grid y' Flip grid so bottom side becomes top side. `flip image x' Flip image so right-hand side becomes left-hand side. `flip image y' Flip image so bottom side becomes top side. { extern "C" bool flipCmd(void); } `get env \result \environment_variable' Get the value of an "environment variable" from the operating system, and store the result in the indicated synonym. This makes most sense on unix systems (hence the name, patterned after the unix command `getenv'). This command can be useful in making gri programs resistant to changes in data-file locations. Suppose, for example, there is a file called `data', normally in a local directory called `Bravo'. The line `open Bravo/data' will fail if the Bravo directory is moved. But if the name of the datafile is stored in an environment variable, `DIR_BRAVO' say, then the gri program will work no matter where the Bravo data are moved, so long as an appropriate environment variable is modified when the data are moved. Example: get env \dir DIR_BRAVO if \{rpn "\dir" "" ==} show "Cannot determine location of the Bravo data, which should" show "be stored in the environment-variable DIR_BRAVO. You should" show "do something like" show " export DIR_BRAVO='/users/dek/kelley/data/Bravo/'" show "in your ~/.environment file" quit end if open \dir/data ... { extern "C" bool get_envCmd(void); } `get options "LIST" [keep]' { extern "C" bool get_optionsCmd(void); } `group ["\name"]' Start a group, i.e. a collection of graphical objects. (NOT IMPLEMENTED YET. SYNTAX MAY CHANGE.) { extern "C" bool groupCmd(void); } `heal columns|{grid along x|y}' The `heal' command heals over gaps in either columnar or gridded data. This is done by linear interpolation across the missing-value gaps. * `heal columns' Fill in missing values in x, y, z, ... columns, by linear interpolation to neighboring valid data. All gaps in the data will get replaced by a linear function of index which matches the data at the indices just before and just after the gap. For example, if the y data were like 111 3 -9 -9 -9 7 333 where `-9' is the missing-value code, then they would get replace by 111 3 4 5 6 7 333 Notes: (1) This is done *independently* for all existing columns. (2) Gaps at the start and end of the columns are not filled in. * `heal grid along x' Scan in the x direction, filling in missing values by linearly interpolation. Since this uses the the x-grid, you must first have done `read grid x' or `set x grid'. * `heal grid along y' Scan in the y direction, filling in missing values by linearly interpolation. Since this uses the the y-grid, you must first have done `read grid y' or `set y grid'. { extern "C" bool healCmd(void); } `help [*|command_name|{- topic}]' Give help on a command or topic. `help' Print a general help message. `help *' Prints complete help info. `help command_name' Prints help on the command whose name begins with the string `command_name'. The string may be several words long; e.g. `help set' or `help set x axis'. `help - topic_name' The minus sign tells Gri that the string to follow it is a topic, not a command. Topics Gri knows about are listed by the one-word `help' request. { extern "C" bool helpCmd(void); } `if {[!] .flag.}|\flag|{{"string1" == "string2"}}' Control program flow. The `if' block is ended with a line containing `end if'. Optional `else' and `else if' blocks are allowed. Note that RPN expressions are allowed, and a special form of string comparison is allowed, as in the examples below. if .flag. # List of Gri commands to be done if .flag. is 1. # This list may extend across any number of lines. end if If the variable `.flag.' is not equal to 0, do the code between the `if' line and the `end if' line. if .flag. # Commands done if .flag. is 1 else # Commands done if .flag. is 0 end if If the variable `.flag.' is not equal to 0, do the code between the `if' line and the `else' line. If `.flag.' is equal to 0, do the code between the `else' line and the `end if' line. if ! .flag. # Commands done if .flag. is 0 end if If the variable `.flag.' is equal to 0, do the code between the `if' line and the `end if' line. if \{rpn .flag. 10 <} # Commands done if 10 is less than .flag. end if If the variable `.flag.' is less than 10, do the code between the `if' line and the `end if' line. if \smooth # Commands done if \smooth is 1 else # Commands done if \smooth is 0 end if If the number stored in the synonym `\smooth' is not equal to 0, do the code between the `if' line and the `else' line. If the synonym stores a representation of a number not equal to zero, do the `else' part. If the synonym contains text that does not decode to a number, generate error message. if \{"\item" == "Temperature"} # Commands done if the synonym \item is equal to the # indicated text string. end if If the synonym `\item' has the value `Temperature' stored in it, do the indicated code. if \{rpn "\item" "Temperature" ==} # Commands done if the synonym \item is equal to the # indicated text string. end if As above, but using the `rpn' calculator. { extern "C" bool null; } `ignore last .n.' Ignores last `.n.' lines read by `read columns'. { extern "C" bool ignoreCmd(void); } `input \ps_filename [.xcm. .ycm. [.xmag. .ymag. [.rot_deg.]]]' Input the named PostScript file directly into the Gri output PostScript file. (If the filename has punctuation, insert it in double quotes, e.g. `input "../thefile"'.) If no options are specified, the file is input at normal scale, with normal margins. (Aside to PostScript programmers: the named file is sandwiched between `gsave' and `grestore' commands.) If `.xcm.' and `.ycm.' are specified, then the origin is moved to the named location first. If, in addition, `.xmag.' and `.ymag.' are specified, then these are used as scale factors after translation. Finally, if `.rot_deg.' is specified in addition, then the indicated counterclockwise rotation is applied after translation and scaling. Hint: if the results look wrong, the first thing to do is to think carefully about the order of the (translation, scaling, rotation) operations. { extern "C" bool inputCmd(void); } `insert \filename' Insert instructions in named file into current file. This is useful as a way of sharing global information between several Gri programs. On unix systems, if a full filename is specified (i.e., a filename beginning with slash or period), then that particular file will be used. For filenames beginning with a letter or number, though, Gri will search for the file in the list of directories stored in your `GRIINPUTS' environment variable, or in the list (`.', `/usr/local/lib/gri') if that environment variable is not set. { extern "C" bool insertCmd(void); } `interpolate x|y grid to ...' The forms are interpolate x grid to .left. .right. .inc.|\{/.cols.} interpolate y grid to .bottom. .top. .inc.|\{/.rows.} Transform grid by interpolating between existing grid data, according to a new x or y grid specified in the manner of `set x grid' and `set y grid'. Note that the new grid is neccessarily regular, while the first grid needn't have been. The data of the new grid are constructed by interpolation, using the same interpolation algorithm as the `convert grid to image' command. { extern "C" bool interpolateCmd(void); } `list \command-syntax' List the source of a gri command. Often this is just the name of a C function internal to gri (try `list list' for an example), but when the command is written in the gri programming language the source will be more understandable (try `list set panel'). { extern "C" bool listCmd(void); } `ls [\file_specification]' List files in current directory. (The current directory can be printed by the gri command `pwd' and can be set by the gri command `cd'.) `ls \file_specification' lists files in current directory which match the file specification. Normal unix file specification options are understood. { extern "C" bool lsCmd(void); } `mask image [to {uservalue .u.}|{imagevalue .i.}]' Examine both the image and the mask pixel by pixel. For any pixels which have a mask value of 1 (which indicates an invalid region of the image), change the image value. If no `to' phrase is present, change the image value to 0 in pixel units. If the `to uservalue .u.' phrase is present, change the pixel to hold the imagevalue that corresponds to this uservalue (see `set image range' command for a discussion of this correspondance). If the `to imagevalue .i.', change the pixel to hold that imagevalue (in range 0 to 255 inclusive for 8-bit images). { extern "C" bool maskCmd(void); } `new page' Finish the present page, and start a new page. All settings (of linewidth, axes, landscape/portrait, etc.) and data are retained on the new page. { extern "C" bool new_pageCmd(void); } `new postscript file \name' Finish the present Postscript file, and start a new page with the given name. All settings (of linewidth, axes, landscape/portrait, etc.) and data are retained on the new file. { extern "C" bool new_postscript_fileCmd(void); } `new .variable_name.|\synonym_name [.variable_name.|\synonym_name [...]]' Set aside storage for new version of the named variable(s) and/or synonym(s). Any number of variables and synonyms may be specified. If a given variable/synonym already exists, this will create a new version of it, and future assignments will be stored in this new version *without* affecting the pre-existing version. If the variable/synonym is `delete'ed, the new version is deleted, making the old, unaltered, version accessible again. This command is used mostly for temporary use, to prevent clashing with existing values. Suppose you want to change the font size inside a new command or an if block. Then you might do the following, where the variable `.tmp.' is used to store the old font size. Note that the use of the `new/delete' statements prevents the assignment to the local version of the variable `.tmp.' from affecting the value known outside the `if' block, if in fact `.tmp.' happened to exist outside the block. set font size 10 draw label "This is in fontsize 10, before modification" at 10 2 cm if .want_title. new .tmp. # Get storage .tmp. = ..fontsize.. # Save old size set font size 22 # Set new size draw label "This is in fontsize 22" at 10 5 cm set font size .tmp. # Restore old size delete .tmp. # Clean up end if draw label "This is in fontsize 10, after modification" at 10 8 cm { extern "C" bool newCmd(void); } `open {\filename}|{"system command|"} {[binary [uchar|int|float|double|16bit]]}|{netCDF}' Possibilities are: `open \filename' `open \filename binary [uchar|int|float|double]' `open \filename netCDF' `open "SYSTEM-COMMAND |" [binary [uchar|int|float|double]]' The first three forms work on data files. Use double-quotes around filenames with punctuation in them (e.g. `open "../data"'). Files may be ascii (the default), binary or - on systems with the `netCDF' libraries installed - in the `netCDF' format. The `SYSTEM-COMMAND' form is used to work on a temporary file created by a system command. Several binary file types are allowed. The keywords `uchar', etc, can be used to specify the type of data in the file. If no keyword is given, Gri assumes that images use `unsigned char' (8 bits), columns use `float' (32 bits), and that grids use `float' (32 bits). In the `SYSTEM-COMMAND' form, the indicated system command is performed, with the output being inserted into a temporary file. Future `read', `close', etc, commands apply to to this temporary file. (The temporary file is automaticaly deleted by Gri, but if Gri fails for some reason you should scan `/usr/tmp/' for files that you own.) For example open "cat a.dat | awk '\{$1, $2 * 22}' |" read columns x y gets awk to multiply the y column by 22. The ability to use system commands in `open' statements lets you use familiar system tools like `head', `sed', `awk', `perl', etc, to work on your data. For example, if you store your data in compressed form, and do not wish to have temporary files sitting around, you might wish to do something like open "zcat myfile.dat.Z | " Files may be opened across the WWW (world-wide web). Here is a replacement for example1.gri: open "lynx -dump http://www.phys.ocean.dal.ca/~kelley/gri/examples/example1.dat | tail +2 |" read columns x y draw curve draw title "Example 1" Note: the `tail +2' removes the initial blank line that lynx generates. For complicated data manipulation, a system tool like `awk' or `perl' is ideal. For example, suppose x and y data are stored in Hour.minutesecond format, e.g. 12.2133 means hour 12, minute 21, second 33. Gri doesn't read HMS format, but gawk can be told to: open "cat datafile.HMS | \ awk '\{ \ split($1, hms, \".\"); \ h = hms[1]; \ m = int(hms[2] / 100); \ s = hms[2] - 100 * m; \ x = h + m / 60 + s / 3600; \ split($2, hms, \".\"); \ h = hms[1]; \ m = int(hms[2] / 100); \ s = hms[2] - 100 * m; \ y = h + m / 60 + s / 3600; \ print(x,y) \ }' | " read columns x y { extern "C" bool openCmd(void); } `postscript \string' Write the indicated string to the PostScript output file, after substitution of synonyms if there are any. Example: \angle = "45" \page_width = "8.5" postscript gsave \page_width 72 mul 0 translate \angle rotate # ... other code to do stuff postscript grestore Here is how to draw an image palette vertically instead of horizontally: \originX = "3" # cm \originY = "10" # cm \angle = "90" # degrees counterclockwise postscript gsave \originX 28.35 mul \originY 28.35 mul translate \angle rotate draw image palette box 0 0 10 1 # this is at user's origin postscript grestore NOTE: the `postscript' command is *very* dangerous, and should normally only be used by developers. Most of the code concerning this is in the file `doline.cc'; look for the string `postscriptCmd' to find the relevant code. { extern "C" bool postscriptCmd(void); } `pwd' Print current directory (which can be set by `cd'). { extern "C" bool pwdCmd(void); } `query \synonym|.variable ["\prompt" [("\default"|.default)]]' Ask the user for the value of a variable (number) or synonym (text string). Gri recognizes the type of the item being asked for, either a variable or synonym, by the presence of a dot or backslash in the second word of the command line. If a prompt string is given (in quotes), then this string is shown to the user. If a default is given (in parentheses), then it will be displayed also, and if the user types carriage-return, then that item will be assigned to the variable or synonym. If the default has more than one item, then Gri considers this a restrictive list of possibilities, and will demand that the answer be in that list, going into an infinite query loop until an item from the list (or carriage-return, meaning take first item) is found. The items in the list are to be separated by spaces, not commas or any other non-whitespace characters. NOTE: The `-y' command-line option bypasses all query commands, fooling Gri into thinking that the user typed a carriage-return to all questions. Thus the defaults, if they exist, are selected. { extern "C" bool queryCmd(void); } `quit [.exit_status.]' Exits the gri program. If an exit status (`.exit_status.') is specified, then Gri returns this value, rounded to the nearest integer, as the "exit status" (a concept meaningful mostly in the unix environment). { extern "C" bool quitCmd(void); } `read colornames from RGB {"/usr/lib/X11/rgb.txt" | \filename}' Read colornames from named file, which is in the X11 format. This format has 4 or more columns, the first three giving the red, green and blue values in the range 0 to 255, and the last columns giving the colorname (which may have more than one word). You can create colors yourself or read an X11 color file. In many cases you will want to `read colornames from RGB "/usr/lib/X11/rgb.txt"'. Full filenames must be used; the '~' syntax is not permitted. Once you have read in a colorname table, the named colors may be used as builtin colors (see also `set color'). To view the colors available on your particular system, use the Unix command `xcolors' or `excolors'; to see the RGB values for all colors on your system, use the `showrgb' Unix command. To view the names and RGB values of the colors Gri knows, including builtin ones and ones from `read colornames', use `show colornames'. { extern "C" bool read_colornamesCmd(void); } `read columns ...' Read numbers into columns. These columns have predefined meanings and names. For example, `read columns x y' instructs Gri to read data into columns called `x' and `y'; it is these data that Gri will use if you tell it to `draw curve'. Other columns are: `z', used for contouring a function `z=z(x,y)'; `weight', used for weighting data points; `u' and `v', used for arrow (vector) plots. If the keyword `appending' is given as the last word on the `read columns' line, then the new data will be appended to any existing columnar data; otherwise they will overwrite any existing data. * `read columns x y' Read `x' in column 1, `y' in column 2 until blank-line found. Only the first tow numbers on each line will be read; any extra numbers (or words) on the line will be ignored. * `read columns * y * * x' Read `x' in column 5, `y' in column 2. The `*' character is a spacer. It instructs Gri to skip the first, third, and fourth words on the data line. These words need not be numbers. This example illustrates a general mechanism of using the `*' character to skip over unwanted items in the data file. Note that there is no need to supply `*' characters for trailing extraneous words; Gri will skip them anywary. Finally, note that any order of `x' and `y' (and the other columns; see below) is allowed. * `read columns y=2 x=5' or `read columns x=5 y=2' As above; read `x' in column 5 and `y' in column 2. The column number may be specified in this manner for all the named column variables. No spaces are allowed before or after the `=' sign. The first column is called column 1. Whether this format is used or the `*' format is a matter of choice, except that numbered format also permits using a given number to fill several variables (e.g. `read columns x=1 y=2 u=1 v=2'). * `read columns x="netCDF name" ...' If the file is a `netCDF' file, opened by e.g. `open myfile.nc netCDF', then the `netCDF' variables for the columns, e.g. open latlon.nc netCDF read columns x="longitude" y="latitude" Note: the data *must* be stored as the `netCDF' "float" type. * `read columns y' Read `y' in column 1. Since `x' is not read from the file, it will be assigned the default values `x' = (0,1,2, `..num_col_data..'); that is, it will have the same number of elements as `y'. * `read columns * y z * x' Read `x' in column 5, `y' in column 2, and `z' in column 3. The `z' column is used for contouring. * `read columns x y u v' Read `x' and `y' in first two columns, and the "arrow" data `u' and `v' as third and fourth columns. * `read columns .rows. x y' Read `.rows.' rows of column data. NOTE FOR BINARY FILES: For ascii files, Gri will proceed to a new line after it has read the items requested; it skips any words appearing on the data line after the last object of interest. Thus `read columns x y' will read the first two columns and ignore any other columns that might be present. But for binary files, Gri has no way of knowing how to "skip" to the next line (see `skip' command), so you will have to flesh out the `read columns' command with as many spacers as are present in your data. For example, if you have four numbers in each data record and want to interpret the first two as `x' and `y', you would use `read columns x y * *' to read the data. RETURN VALUE: Sets `\.return_value' to `N rows N non-missing N inside-clip-region' { extern "C" bool read_columnsCmd(void); } `read grid {x [.rows.|{="name"}]}|{y [.cols.]{="name"}}|{data {[spacers] [.rows. .cols.] [spacers] [bycolumns]}|{="name"}}' "Read grid" commands read grid characteristics. (The "grid" is the object that is contoured.) For normal ascii or binary files, the commands to read the grid's x-locations, y-locations and data are: `read grid x [.rows.]' `read grid y [.rows.]' `read grid data [spacers] [.rows. .cols.] [spacers] [bycolumns]' For `netCDF' files, the commands are as follows (note that it is not possible to specify the number of data to read, nor to read the grid by columns). `read grid x = "variable name"' `read grid y = "variable name"' `read grid data = "variable name"' The data *must* be stored as the `netCDF' "float" type. The ordering of the y-grid data is the same as if they were read from a normal file: the first number is considered to be at the top of the plot. Details of the non-netCDF commands: * `read grid x [.cols.]' Read the `x' locations of the grid points, one number per line. If `.cols.' is supplied, then that many values will be read; otherwise, reading will stop at end-of-file or blank-line. * `read grid y [.rows.]' As above, but for y grid; `.rows.' is the number of rows. The first number to be read corresponds to the location of the *top* edge of the grid. Thus, if you were to view the column of numbers with a text editor, they would be oriented the same way as the corresponding elements will appear on the page. * `read grid data [.rows. .cols.]' Read data for a grid having `.rows.' and `.cols.' columns. (If `.rows.' and `.cols.' are not supplied, but the grid already exists, then those pre-existing values are used. If they are specified here, then they are checked for consistency with the pre-existing values if they exist.) Gri will read `.rows.' lines, each containing `.cols.' numbers. (Extra information in the file can be skipped; see discussion of the `*' keyword below.) Gri will interpret the first line it reads as the grid data corresponding to a value of y equal to `y[.rows.]'. Thus, file should be arranged like this: f(x[1], y[.rows.]) f(x[2], y[.rows.]) ... f(x[.cols.], y[.rows.]) . . . f(x[1], y[3]) f(x[2], y[3]) ... f(x[.cols], y[3]) f(x[1], y[2]) f(x[2], y[2]) ... f(x[.cols], y[2]) f(x[1], y[1]) f(x[2], y[1]) ... f(x[.cols], y[1]) * `read grid data [.rows. .cols.] bycolumns' As above, but the `bycolumns' keyword tells Gri to read the data one column at a time, instead of one row at a time. Each line is expected to contain `.rows.' numbers (as opposed to `.cols.' numbers, as in the format where the `bycolumns' keyword is not present). (Extra information in the file can be skipped; see discussion of the `*' keyword below). The first line of the data file contains the first column of the gridded data, corresponding to x equal to `x[1]'). The file should look like this: f(x[1], y[1]) f(x[1], y[2]) ... f(x[1], y[.cols.]) f(x[2], y[1]) f(x[2], y[2]) ... f(x[2], y[.cols.]) f(x[3], y[1]) f(x[3], y[2]) ... f(x[3], y[.cols.]) . . . f(x[.rows.],y[1]) f(x[.rows], y[2]) ... f(x[.rows.], y[.cols.]) * `read grid data * * [.rows. .cols.]' As `read grid data .rows. .cols.' except that the first two words on each line are skipped. As usual, trailing extraneous numbers are also skipped. The following example illustrates how to use these together. read grid x 3 --- results in the grid locations 1 4 1 2 3 4 5 5 0 *-------------------------*--------* 10 | | | read grid y 3 20 *-------------------------*--------* 0 30 | | | 20 40 *-------------------------*--------* 40 read grid data 3 3 --- fills in the grid as follows 9 1 2 3 4 5 1 2 3 4 5 6 7 8 0 9-------------------------1--------2 10 | | | 20 3-------------------------4--------5 30 | | | 40 6-------------------------7--------8 SEE ALSO: `set x grid', `set y grid' RETURN CODES: `read grid x' sets `\.return_value to `N cols' `read grid y' sets `\.return_value' to `N rows' `read grid data' sets `\.return_value to `N rows N cols' { extern "C" bool read_gridCmd(void); } `read image colorscale [rgb|hsb]' Read colorscale for image, from 256 lines each containing values for Red, Green, and Blue (or Hue, Saturation and Brightness), separated by whitespace. The values are expected to be in the range 0 to 1, and are clipped to these limits if not. For hints on how to create such an input file, see `read image grayscale'. If the example given there has the following code instead, open "awk 'BEGIN \{ \ for(i=0;i<256;i++) \{ \ print((i - 50)/50, 1, 1) \ } \ }' |" read image colorscale hsb then a full-color spectrum running from red at 10C to magenta at 15C is achieved. { extern "C" bool read_image_colorscaleCmd(void); } `read image grayscale' Read grayscale for image for image, from 256 lines each containing a single value. The values are expected to be in the range 0 to 1, and are clipped to these limits if not. For 8-bit images, Gri multiplies these values by 255, and uses this list for the grayscale mapping. Such a list is created by `write image grayscale'. As an example, the code fragment set image range 5 30.5 set image grayscale black 10 white 15 is equivalent to set image range 5 30.5 open "awk 'BEGIN\{for(i=0;i<256;i++) print(1-(i-50)/50)}' |" read image grayscale close because the image formula is Temperature = 5C + 0.1C * pixelvalue where the pixelvalue ranges from 0 to 255. Therefore, a temperature of 10C is a pixelvalue of 50, and 15C is 100. To get a grayscale ranging between these values, therefore, we create a linear function which maps the 50th pixelvalue into grayvalue 1, and the 100th pixelvalue into grayvalue 0. That is what the awk line does; to see the actual numbers, you could insert the line `write image grayscale to TMP' and look at the file `TMP' (bear in mind that Gri will clip the values to the range 0 to 1). Sometimes you will have a file, say named `map.dat', with RGB numbers in the range 0-255, rather than 0-1 as Gri requires. To read them, use the operating system to convert the numbers for you: open "cat map.dat | awk '\{print(($1+$2+$3)/3/255)}' |" read image grayscale close { extern "C" bool read_image_grayscaleCmd(void); } `read image greyscale' Alternate spelling of grayscale { extern "C" bool read_image_grayscaleCmd(void); } `read image mask rasterfile' Read image mask. The mask is associated with the image read in by the `read image' command in the following way. When computing image histograms, Gri ignores any pixels in the image for which the corresponding pixel in the mask is set to `1'. The image size is specified in the rasterfile file itself, so it is not specified. { extern "C" bool read_image_mask_rasterfileCmd(void); } `read image mask .rows. .cols.' Read image mask. The mask is associated with the image read in by the ` read image' command in the following way. When computing image histograms, Gri ignores any pixels in the image for which the corresponding pixel in the mask is set to `1'. The file must contain `.rows.*.cols.' binary data. Pixel order is the same as for images. { extern "C" bool read_image_maskCmd(void); } `read image pgm [box .xleft. .ybottom. .xright. .ytop.]' Read image in pgm (portable graymap) format. The image range must have previously have been set by `set image range'. The image width and height are specified in the image file itself. Both ascii and binary PGM formats are supported (that is, files with magic characters of P2 and P5). When the `box' option is specified, the geometry of the image, in user coordinates, is specified in terms of the cartesian coordinates of the lower-left corner (`.xleft.', `.ybottom.') and upper-right corner (`.xright.', `.ytop.'). If the `box' option is not specified, this geometry can be specified with either `read grid x' or `set x grid', plus either `read grid y' or `set y grid'. { extern "C" bool read_image_pgmCmd(void); } `read image rasterfile [box .xleft. .ybottom. .xright. .ytop.]' Read image in Sun rasterfile format. The image range must have previously have been set by `set image range'. The image width and height are specified in the rasterfile file itself. When the `box' option is specified, the geometry of the image, in user coordinates, is specified in terms of the cartesian coordinates of the lower-left corner (`.xleft.', `.ybottom.') and upper-right corner (`.xright.', `.ytop.'). If the `box' option is not specified, this geometry can be specified with either `read grid x' or `set x grid', plus either `read grid y' or `set y grid'. { extern "C" bool read_image_rasterfileCmd(void); } `read image .rows. .cols. [box .xleft. .ybottom. .xright. .ytop.] [bycolumns]' With no options specified (`read image .rows. .cols.'), read binary data defining an `image'. The image range must have previously have been set by `set image range'. The data are as written as "unsigned char" format in C. When the `box' option is specified, the geometry of the image, in user coordinates, is specified in terms of the cartesian coordinates of the lower-left corner (`.xleft.', `.ybottom.') and upper-right corner (`.xright.', `.ytop.'). If the `box' option is not specified, this geometry can be specified with either `read x grid' or `set x grid', plus either `read y grid' or `set y grid'. With the `bycolumns' keyword present, the image is read sweeping from top-to-bottom, then left-to-right, instead of the user order. { extern "C" bool read_imageCmd(void); } `read from \filename' Cause future `read' commands to read from the indicated file. If that file is not open, an error message will result. Use `read from \filename' to shuffle reading between several open files. { extern "C" bool read_from_filenameCmd(void); } `read line [raw] \synonym' Read the next line of the datafile (or commandfile) and then store the next line of datafile into the named synonym. Normally, comments are removed from the line first, but if the keyword "raw" is present, then comments are retained. { extern "C" bool read_lineCmd(void); } `read [raw] [* [*...]] \synonym|{.variable. [.variable. ...]}' As the same command without the "raw" keyword, except that in this instance comments are not removed from the line before reading. If the optional `raw' keyword is not present, comments are first trimmed from the data line. If `raw' is present, however, any comments are retained on the line. { extern "C" bool read_synonym_or_variableCmd(void); } `read [* [*...]] \synonym|{.variable. [.variable. ...]}' Read whitespace-separated words from datafile, assigning to any number of synonyms or variables as indicated. The token `*' indicates that the word in the datafile should be skipped. As usual, the datafile may be embedded in the commandfile. If the input file is in the netCDF format, the indicated item will be read. For example, `read \time:_MissingValue' reads the missing value for the variable called `time' (you might follow this by a line like `.missing. = \time:_MissingValue'). Similarly, `read \location' stores the value of the global attribute called `location' into the variable named `\location'. { extern "C" bool read_synonym_or_variableCmd(void); } `regress {y vs x [linear]}|{x vs y [linear]}' Perform linear regression of `y' as a function of `x' or `x' as a function of `y'. * `regress y vs x' Linear regression of y vs x. Several quantities are reported and also saved into builtin variables. The intercept is defined as `..coeff0..', it's 95 percent confidence limit is defined as `..coeff0_sig..'. Thus the confidence range is `..coeff0..-..coeff0_sig..' to `..coeff0..+..coeff0_sig..'. Similarly the slope and confidence limit are stored in `..coeff1..' and `..coeff1_sig..' The squared correlation coefficient is stored in `..R2..'. Historical note' prior to version 2.1.15, a different meaning was attached to `..coeff0_sig..' and `..coeff1_sig..'; they used be defined as standard error, without having been multiplied by the appropriate student-t coefficient. * `regress x vs y' Linear regression of x vs y; for notation see above. * `regress y vs x linear' Linear regression of y vs x; for notation see above. * `regress x vs y linear' Linear regression of x vs y; for notation see above. SEE ALSO `draw regression line' { extern "C" bool regressCmd(void); } `reorder columns randomly|{ascending in x|y|z}|{descending in x|y|z}' Reorder the columns in various ways. In the `randomly' style, the column data are shuffled randomly by index, retaining the correspondance between a given x and y. This is useful with `draw symbol' using colored dots -- it prevents the overpainting of one dot on another from biasing the color field to values that happened to occur near the end of the column data. If you prefer the overpainting to be done in random order, use this command to reorder the columns randomly. The random number is selected using the system `rand' call, with the seed being provided by the PID (process ID) of the job. The `ascending' and `descending' styles do what you'd expect. { extern "C" bool reorder_columnsCmd(void); } `rpnfunction \name "action"' Create a new keyword for use in RPN expressions. Inside any RPN expression which follows this line, the word `name' will be substituted with the indicated replacement words. For example, the following shows the definition and use of a function which computes the sine of twice an angle, by multiplying whatever is on the stack by `2', and then taking the sine of the result. rpnfunction sin2 2 * sin show "expect the number 1 to follow: " \{rpn 45 sin2} NOTE: The replacement words will have any synonyms in them translated first, unless they start with an underscore followed by a double backslash. Similarly, variables are substituted unless they start with an underscore. These exceptions are to allow the use of the `defined' operator. { extern "C" bool rpnfunctionCmd(void); } `rescale' Re-determine the scales for the x and y axes. Typically used after a column math operation, when you want the new data to be auto-scaled. (Note: this is not the default action after column mathematics, since Gri lets users add offsets, etc, without altering the axes scales.) { extern "C" bool rescaleCmd(void); } `resize x for maps' Resize the axes frame region in such a way that geographical objects appear in correct proportions. This assumes that y is degrees latitude and x is degrees latitude. `resize x for maps' Resize the plot width for maps, assuming that x represents longitude and y represents latitude. Before using this, you must have defined scales for both x and y, and a size for y (ie, you must have done `set x axis ...', `set y axis ...' and `set y size'); this command sets the x size, thus eliminating `set x size.' The result is that, at the central latitude (y), a centimetre on the page will correspond to an equal distance on the earth, in both the north-south and east-west directions. { set x size {rpn ..ysize.. ..xright.. ..xleft.. - * \ ..ybottom.. ..ytop.. - /\ ..ybottom.. ..ytop.. + 2 / cos * abs} } `resize y for maps' Resize the axes frame region in such a way that geographical objects appear in correct proportions. This assumes that y is degrees latitude and x is degrees latitude. `resize y for maps' Resize the plot height for maps, assuming that x represents longitude and y represents latitude. Before using this, you must have defined scales for both x and y, and a size for x (ie, you must have done `set x axis ...', `set y axis ...' and `set x size'); this command sets the y size, thus eliminating `set y size.' The result is that, at the central latitude (y), a centimetre on the page will correspond to an equal distance on the earth, in both the north-south and east-west directions. SEE ALSO `resize x for maps' command. { set y size {rpn ..xsize.. ..ybottom.. ..ytop.. - * \ ..xright.. ..xleft.. - /\ ..ybottom.. ..ytop.. + 2 / cos / abs} } `return' Return early from a user-defined function or an `insert' file. Or, in the main gri program, do the same thing as `quit'. { show "ERROR in `return' -- should not get here in gri.cmd" show traceback quit } `rewind [filename]' Rewind a data-file to the beginning. If no filename is given, this is done for the currently active file; otherwise the named file is rewound. { extern "C" bool rewindCmd(void); } #* @param .style. = style of axes @default 0 `set axes style .style. | {offset [.dist_cm.]} | rectangular | none | default' Tell Gri how you want axes to look. `set axes style 0' Set axes to be rectangular, with an x-y axes frame labelled at the left and bottom. `set axes style 1' As style `0' but only put tics on the lower and left axes. `set axes style 2' As style `0' but without labels or tics on any axis, i.e. just an axis frame. Set axes to be rectangular, with an x-y frame without tics or numbers on any side. `set axes style offset [.dist_cm.]' Set axes so that the actual x and y axes will be drawn with a space separating them from the data area. The space, if not set by the `.distance_cm.' option, will be equal to the current tic size (see `set tic size'). This command can be used together with any other `set axes style' command. It applies to both the `draw axes' command and with any `draw x|y axis' command in which the axis location is not explicitly given. `set axes style rectangular' Set axes to be rectangular, with an x-y axes frame labelled at the left and bottom. `set axes style none' Tell gri not to bother drawing axes before drawing curves, etc. `set axes style default' Same as `set axes style 0', and with `offset' turned off. { extern "C" bool set_axes_styleCmd(void); } #* @param .size. arrowhead half-width @unit cm @default 0.2 `set arrow size .size.|{as .num. percent of length}|default' Set the arrowsize (which is stored in the builtin variable `..arrowsize..'). `set arrow size .size.' Set the arrow size (ie, half-width of the arrowhead) to `.size.' centimetres. `set arrow size as .num. percent of length' Set the arrow size to be the indicated percentage of arrow length, as in "HWP" in the singles ads. (As a flag to this, `..arrowsize..' is set to the negative of the fractional size measured in percent.) `set arrow size default' Set the arrow size to the default of 0.2 cm. { extern "C" bool set_arrow_sizeCmd(void); } #* @param .type. 0 for 3-strokes, 1 for outline, 2 for filled swept-back @default 0 `set arrow type .which.' Set type of arrow. `.which.'=0 yields the default arrows, drawn with three line strokes, `.which.'=1 yields outline arrows, and `.which.'=2 yields swept-back filled arrows. { extern "C" bool set_arrow_typeCmd(void); } `set beep on|off' The command `set beep on' makes gri beep on errors and `query'. `set beep off' turns this beeping off. { extern "C" bool set_beepCmd(void); } `set bounding box .xleft. .ybottom. .xright. .ytop. [cm|pt]' Set the PostScript bounding box for graph to indicated value. The bounding box is used by some programs to determine the region of the page on which marks have been made. For example, LaTeX uses the bounding box to decide how to position figures in documents. Normally, the bounding box is computed automatically (unless the `-no_bounding_box' commandline option has been specified. But if `set bounding box' is done, the automatically computed value is ignored and the given box is used instead. Use this if Gri makes mistakes in its automatic selection of bounding box. The coordinates of the bounding box may be specified in (1) user coordinates, as defined *at the moment* the command is executed, or (2) in points on the page, measured from an origin at the lower-left (72 point per inch), or (3) in centimeters on the page. Which coordinate system is used depends on the last keyword - use `pt' for points, `cm' for centimeters, and nothing at all for user-units. The most common use is in points, since that is how many other application packages, e.g. LaTeX and dvips, specify the bounding box. If the box is specified in the user units, the user units in effect *at the moment* of executing the `set bounding box' command are used. This must be born in mind if the coordinate system is changing during the execution of the program, e.g. if margins are changing or the x and y axes are changing. For this reason it often makes sense to put this command at the end of the commandfile. { extern "C" bool set_bounding_boxCmd(void); } `set clip [postscript] {on [.xleft. .xright. .ybottom. .ytop.]}|{to curve}|off' Control clipping of following drawing commands. `set clip on' Don't plot data outside axes. `set clip on .xleft. .xright. .ybottom. .ytop.' Don't plot data outside indicated box. `set clip off' Plot all data, whether in axes or not. `set clip to curve' Set clip to the curve, as would be drawn by a `draw curve filled' command, i.e. to the polygon constructed by running along the xy points, in order, followed by a final segment from the last point back to the first point. This is a "postscript" clip, as explained in the next item. `set clip postscript on .xleft. .xright. .ybottom. .ytop.' Turn PostScript clipping on. This will prevent *any* drawing outside the named box. Note that it will also prevent axis drawing, so the recommended procedure is something like draw axes set clip postscript on 10 20 0 1 draw curve set clip postscript off `set clip postscript off' Turn PostScript clipping off. SEE ALSO: `set input data window' command. { extern "C" bool set_clipCmd(void); } `set color \name|{rgb .red. .green. .blue.}|{hsb .hue. .saturation. .brightness.}' Set the color of the "pen" used for drawing lines and text. Normally lines and text are drawn in the same color, but the text color can be specified independently if desired (see `set font color') this might be useful to get contour lines of one color and labels of another. In the `set colour \name' style, set the drawing color to the indicated name, either from the builtin list (`white', `LightGray', `darkslategray', `black', `red', `brown', `tan', `orange', `yellow', `green', `ForestGreen', `cyan', `blue', `skyblue', `magenta'), or from a list created by `read colornames'. In the latter case, if the colorname has more than one word in it, use quotes, e.g. `set color "ghost white"'. In the `set colour rgb ...' style, set the individual color components as indicated. The numbers `.red.', `.green.' and `.blue.' range from 0 (for no contribution of that color component to the final color) to 1 (for maximal contribution). Values less than 0 are clipped to 0; values greater than 1 are clipped to 1. EXAMPLES: set color rgb 0 0 0 # black set color rgb 1 1 1 # white set color rgb 1 0 0 # bright red set color rgb 0.5 0 0 # dark red (only 50 percent) set color rgb 0 1 0 # pure green set color rgb 1 1 0 # yellow: red + green In the `set colour hsb ...' style, set the individual color components as indicated. The numbers `.hue.', `.saturation.' and `.brightness.' range from 0 to 1. The color, represented by .hue., ranges from 0 for pure red, through 1/3 for pure green, and 2/3 for pure blue, and back to 1 again for pure red. The purity of the color, represented by .saturation., ranges from 0 (none of the hue is visible) to 1 (the maximal amount is present). The brightness of the color, represented by `.brightness.', ranges from 0 (black) to 1 (maximal brigntness). Values less than 0 are clipped to 0; values greater than 1 are clipped to 1. EXAMPLES: set color hsb 0 1 1 # pure, bright red set color hsb 0 1 0.5 # half black, half red set color hsb .333 1 1 # pure, bright green { extern "C" bool set_colorCmd(void); } `set colour \name|{rgb .red. .green. .blue.}|{hsb .hue. .saturation. .brightness.}' Alternate spelling of 'color'. { extern "C" bool set_colorCmd(void); } `set colorname \\name {rgb .red. .green. .blue.}|{hsb .hue. .saturation. .brightness.}' Create a colorname with the indicated color. The color components range from 0 to 1, and will be clipped to these values if they are outside this range. EXAMPLE (borrowing a color from /usr/lib/X11/rgb.txt): set colorname peachpuff rgb 1 \{rpn 218 255 /} \{rpn 185 255 /} draw box filled 2 2 3 3 cm { extern "C" bool set_colornameCmd(void); } #* @param \style for contour format @default %g `set contour format \style|default' Normally, Gri draws the numeric labels of contour using a format code called `%g' in the "C" language. You may specify any other "long" format using this command. For example, `set contour format %.1f' tells Gri to use one decimal place in the numbers, and also to prefer the "float" notation to the exponential notation. `set contour format default' resets to the default `%f' format. You may use quotes around the format if you need to, to make the item be a single word (e.g. `set contour format "%.1f m/s"'). { extern "C" bool set_contour_formatCmd(void); } `set contour label for lines exceeding .x. cm' Make it so contour lines shorter than `.x.' centimeters will not be labelled. { extern "C" bool set_contour_labelCmd(void); } `set contour label position {.start_cm. .between_cm.}|centered|default' By default, contour labels are drawn at the location where contours start (e.g., the boundary), and then at a uniform distance along the contour. By default, this uniform distance is the average dimension of the plotting area inside the axes. If `.start_cm.' and `.between_cm.' are specified, the first label is drawn at a distance `.start_cm.' from the start of the contour, and thereafter at a separation of `.between_cm.'. If the `centered' option is used, then the contour labels are centered along the length of the line. { extern "C" bool set_contour_labelCmd(void); } `set contour labels rotated|horizontal|whiteunder|nowhiteunder' The first two options control whether contour labels are rotated to line up with the contour lines, or whether they are horizontal (the default). The second two options control whether the region under contour labels is whited out before drawing the label. The default is `whiteunder', which has the visual effect of the label having been drawn on a piece of paper and then pasted on. This can look jarring when the material under the contour is an image. When `nowhiteunder' is specified, the contour line is broken to make space for the text, but no whiting out is done. { extern "C" bool set_contour_labelsCmd(void); } #* @param .type. style of dash to use (range 0 to 15) @default 2 -> 0.4 cm dashes and 0.1 cm blanks `set dash [.type.|{.dash_cm. .blank_cm. ...}|off]' Control dash-style for following `draw curve' and `draw line' commands. * `set dash' Set to dashed line (0.4cm dashes, 0.1cm blanks). * `set dash .type.' Set to indicated pre-defined dashed line, according to table: .n. dash/cm blank/cm 0 - - ... (Solid line) 1 0.2 0.1 2 0.4 0.1 3 0.6 0.1 4 0.8 0.1 5 1.0 0.1 10 w w 11 w 2w 12 w 3w 13 w 4w 14 w 5w 15 w 6w Where `w' is written, it indicates the current linewidth. Thus, types 10 through 15 give square-dotted lines. * `set dash .dash_cm. .blank_cm. .dash_cm. .blank_cm. ...' Set to indicated dashed line. The series of lengths `.dash_cm.' and `.blank_cm.' give the lengths of dash and blank portions (measured in centimeters). Any number of dash/blank lengths may be given. For example, `set dash 0.5 0.1 0.1 0.1' looks good. * `set dash off' Turn dashing off, setting to a solid line. { extern "C" bool set_dashCmd(void); } `set environment' Set environment (graylevel, axis length, etc) so that following plotting commands will make use of anything set by either a `set' command or by direct manipulation of builtin variables like `..xsize..', etc. NOTE: this should *only* be done by developers. { extern "C" bool set_environmentCmd(void); } `set error action to core dump' Make Gri dump core when any error is found, to facilitate debugging. { extern "C" bool set_error_actionCmd(void); } `set flag \name [off]' Set the indicated flag to YES. The name of the flag is contained in a single word, e.g. `set flag dan_28sep_test'. The action of the flags may change with time and is undocumented. This command is provided to enable selected users (e.g., the developer himself) to use test features of Gri before they are frozen into a fixed syntax and action. The keyword `off' turns the indicated flag off. NOTE: this should *only* be done by developers. FLAG DATE ACTION jinyu1 29sep94 'convert columns to grid' outputs (x,y,z,z_predicted) emulate_gre 9jun97 'E' format on axes yields scientific notation kelley1 17jun97 for kelley only - quit contour trace if hit nonlegit kelley2 17jun97 for kelley only - print out tons of info as trace contour { extern "C" bool set_flagCmd(void); } `set font color \name|{rgb .red. .green. .blue.}|{hsb .hue. .saturation. .brightness.}' The syntax is the same as `set color', except that this applies to text only. By default, text is drawn in the same color as lines, so text color is changed as line color is changed (e.g. by using the `set color' or `set graylevel' commands)). However, once `set font color' is used in a Gri program, the font thereafter maintains a separate color from the lines. { extern "C" bool set_font_colorCmd(void); } `set font colour \name|{rgb .red. .green. .blue.}|{hsb .hue. .saturation. .brightness.}' Alternate spelling of 'color'. { extern "C" bool set_font_colorCmd(void); } `set font encoding PostscriptStandard | isolatin1' Permits one to control the so-called ``font encoding'' used in text. The default font encoding is ISO-Latin-1, which is best for English and other European languages. If the so-called `Postscript Standard'' font encoding is required, this command permits changing the encoding. Note: few users will ever need this command. If you don't even know what ``font encoding'' is about, ignore this command! { extern "C" bool set_font_encodingCmd(void); } #* @param .size. of font @unit point @default 12 @variable ..fontsize.. `set font size {.size. [cm]}|default' Set the size of the font for drawing of text. `set font size .size.' Set font size to `.size.' points. (A point is 1/72 of an inch, or 1/28 of a centimetre.) `set font size .size. cm' Set font size to `.size.' centimetres. `set font size default' Set font size to default = 12 pts. { extern "C" bool set_font_sizeCmd(void); } #* @param \fontname of font @default Helvetica `set font to \fontname' Set font to named style. Note that the backslash is *not* to be written, but here merely means that this word has several alternatives. For example, one might say `set font to Courier'. The allowed fontnames are: `Courier', a typewriter font; `Helvetica', a sans-serif font commonly used in drafting scientific graphs; `HelveticaBold', a bold version of Helvetica; `Times' (also called `TimesRoman'), a font used in most newspapers; `Palatino' (also called `PalatinoRoman'), similar to Times, but somewhat more elegant; `ZapfChancery', a font akin to the TeX caligraphic font; `Symbol', included for completeness, is a mathematical font in which "a" becomes $\alpha$ of the math mode, etc. For reference on these fonts see any book on PostScript. The default font is `Helvetica'. { extern "C" bool set_font_toCmd(void); } #* @param .brightness. of ink with 0 for black and 1 for white @default 0=black `set graylevel .brightness.|white|black' Set graylevel for lines to indicated numerical value between 0=black and 1=white, or to the named color. Note: if your diagram is to be reproduced by a journal, it is unlikely that the reproduction will be able to distinguish between any two graylevels which differ by less than 0.2. Also, graylevels less than 0.2 may appear as pure black, while those of 0.8 or more may appear as pure white. These guidelines are as specified by American Geophysical Union (publishers of J. Geophysical Res.), as of 1997. { extern "C" bool set_graylevelCmd(void); } `set greylevel .brightness.|white|black' Alternate spelling of graylevel. { extern "C" bool set_graylevelCmd(void); } `set grid missing {above|below .intercept. .slope.}|{inside curve}' The style `set grid missing above|below .intercept. .slope' sets grid to missing value for all points above/below the line defined by y = .intercept. + .slope. * x The style `set grid missing inside curve' sets the grid to the missing value throughout an area described by the curve last read in with `read columns'. This is useful for e.g. excluding land areas while contouring ocean properties. The curve may contain several "islands," each tracing (clockwise) a region inside of which the grid is to considered missing. If the first point in an island doesn't match the last, then an imaginary line is assumed which connects them. Multiple islands may be separated by missing-value codes. { extern "C" bool set_grid_missingCmd(void); } `set ignore initial newline [off]' Make Gri ignore a newline if it occurs as the first character of the next data file. This is used for files made by FORTRAN programs on VAX/VMS computers. { extern "C" bool set_ignore_initial_newlineCmd(void); } `set ignore error eof' Stop Gri from considering that to encounter an end of file in future `read' commands consitutes an error; Gri will simply warn about future EOFs. { extern "C" bool set_ignoreCmd(void); } `set image colorscale ...' set image colorscale hsb .h. .s. .b. .im_value. hsb .h. .s. .b. .im_value. [increment .im_value.] set image colorscale rgb .r. .g. .b. .im_value. rgb .r. .g. .b. .im_value. [increment .im_value.] set image colorscale \name .im_value. \name .im_value. [increment .im_value.] Set colorscale mapping for image, using HSB (hue, saturation, brightness) specification, RGB (red, green, blue) color specification, or named colors. The image range must have previously have been set by `set image range', so that the `.im_value.' values will have meaning. Two pairs of (color, image-value) are given, and possibly an increment. Normally the colors are smoothly blended between the endpoints, but if an increment is supplied, the colors are quantized. The HSB method allows creation of spectral palettes, while the other two methods create simple blending between the two endpoints. EG: To get a spectrum ranging between pure red (H=0) for image value of -10.0, and pure blue (H=2/3) for image value of 10.0, do this: set image colorscale hsb 0 1 1 -10.0 hsb .66666 1 1 10.0 EG: To get a scale running from pure red (at image-value 10.0) into pure blue (at image-value 25.1), but with the colors blending intuitively in between (i.e., blending as paint might), use `rgb' color specification, as follows: set image colorscale rgb 1 0 0 10.0 rgb 0 0 1 25.1 EG: To get a quantized blend between the X11 colors `skyblue' at image value of 0 and `tan' at image value of 20, and with steps at image values incrementing by 5, do this: set image colorscale skyblue 0 tan 20 increment 5 Note that the traversal is through RGB space, so it is intuitive, not spectral. See `set color' for a list of X11 colors known to Gri. { extern "C" bool set_image_colorscaleCmd(void); } `set image colourscale ...' Alternate spelling of colorscale. { extern "C" bool set_image_colorscaleCmd(void); } `set image grayscale using histogram [black .bl. white .wh.]' Create a grayscale mapping using linearized cumulative histogram enhancement. The image range must have previously have been set by `set image range'. This creates maximal contrast in each range of graylevels, and is useful for tracing subtle features between different images (for example, it makes it easier to trace fronts between successive satellite images). The entire histogram is expanded, from the smallest value in the image to the largest. With no options specified, the histogram is done from 0 in the image to 255 in the image. If the black/white options are specified, the histogram is done between these values. { extern "C" bool set_image_grayscale_using_histogram(void); } `set image greyscale using histogram [black .bl. white .wh.]' Alternate spelling of grayscale { extern "C" bool set_image_grayscale_using_histogramCmd(void); } `set image grayscale [black .bl. white .wh. [increment .inc.]]' With no optional parameters, create a grayscale mapping for the current image, scaling it from black for the mininum value in the image to white for the maximum value. The image range must have previously have been set by `set image range'. The optional parameters `.wh.' and `.bl.' specify the values to be drawn in white and black in the image, with smooth linear blending in between. Normally the blending from white to black is smooth (linear), but if the additional optional parameter `.inc.' is specified, the blending is quantized, jumping to darker values at (`.wh.' + `.inc.'), (`.wh.' + 2* `.inc.'), etc. (The sign of `.inc.' will be altered, if necessary, to ensure that (`.wh.' + `.inc.') is between `.wh.' and `.inc.'.) The colour switches to pure white at the value `.wh.', and remains pure white everywhere on the "white" side of this value. Similarly, the transition to pure black occurs at the value `.bl.'. In other words, neither pure white nor pure black is present inside the interval from `.wh.' to `.bl.'. Therefore, when drawing grayscales with the `draw image palette' command, you might want to extend the range by one increment so as to get an example of both pure white and pure black. .w. = 0 .b. = 1 .i. = 0.2 set image grayscale white .w. black .b. increment .i. draw image palette left \{rpn .w. .i. -} right \{rpn .b. .i. +} increment .i. { extern "C" bool set_image_grayscaleCmd(void); } `set image greyscale [black .bl. white .wh. [increment .inc.]]' Alternate spelling of grayscale. { extern "C" bool set_image_grayscaleCmd(void); } `set image missing value color to white|black|{graylevel .brightness.}{rgb .red. .green. .blue.}' Set the color of "missing" pixels (white by default). The image range must have previously have been set by `set image range'. Pixels with missing values can result from creating images from grids which have missing values; see the `convert grid to image' command. The `.brightness.' parameter in the `graylevel' style ranges from 0 for black to 1 for white. The `rgb' parameter allows specification in colour. { extern "C" bool set_image_missingCmd(void); } `set image missing value colour to white|black|{graylevel .brightness.}' Alternate spelling of color. { extern "C" bool set_image_missingCmd(void); } `set image range .min_value. .max_value.' Specify maximum possible range of values that images can hold, in user units. Gri needs to know this because it stores images in a limited format capable of holding only 256 distinct values. Unlike some other programs, Gri encourages (forces) the user to specify things in terms of user-units, not image-units. This has the advantage of working regardless of the number of bits per pixel. Thus, for example, `set image grayscale', `set image colorscale', `draw image grayscale', etc, all use *user* units. When an image is created by `convert grid to image', values outside the range spanned by `.0value.' and `.255value.' are clipped. (There is no need, however, for `.0value.' to be less than `.255value.'.) This clipping discards information, so make sure the range you give is larger than the range of data in the grid. EXAMPLE: consider a satellite image in which an internal value of 0 is meant to correspond to 0 degrees Celsius, and an internal value of 255 corresponds to 25.5 degrees. (This is a common scale.) Then Gri command `set image range 0 25.5' would establish the required range. If this range were combined with a linear grayscale mapping (see `set image grayscale'), the resultant granularity in the internal representation of the user values would be (25.5-0)/255 or 0.1 degrees Celsius; temperature variations from pixel to pixel which were less than 0.1 degrees would be lost. All other image commands *require* that the range has been set. Thus, all these commands fail unless `set image range' has been done: `draw image', `draw image palette', `read image', `convert grid to image', `set image grayscale', and `set image colorscale'. NOTE: If a range already exists when `set image range' is used, then the settings are altered. Thoughtless usage can therefore lead to confusing results. (The situation is like setting an axis scale, plotting a curve with no axes, then altering the scale and plotting the new axes. It's legal but not necessarily smart.) { extern "C" bool set_image_rangeCmd(void); } `set input data window x|y {.min. .max.}|off' Create a data window for following `read' statements. `set input data window x .min. .max.' For future reading commands, ignore all data with x < `.min.' or x > `.max.' The data not in the interval will not be read in at all. This will hold until `set data window x off' is done, in which case all data will be read in. `set input data window x off' Return to normal conditions, in which all data are read in. `set input data window y .min. .max.' Analogous to command for x. `set input data window y off' Analagous to command for x. EXAMPLE: To set the input data window as the current x axis plus a border of 5 centimetres to left and right, do the following: set input data window x \{rpn ..xleft.. xusertocm 5 - xcmtouser} \ \{rpn ..xright.. xusertocm 5 + xcmtouser} SEE ALSO `set clip' command. { extern "C" bool set_input_data_windowCmd(void); } `set input data separator TAB|default' Set the separator between data items. The `default' method is to assume that data items are separated by one or more spaces or tabs, and also to ignore any spaces or tabs at the start of a data line. In the TAB method the data are assumed to be separated by a SINGLE tab character. (Multiple tabs will result in null values being assigned to items -- almost certainly not what you want!) Also, initial spaces and tabs on lines are NOT skipped. Use the TAB method only after thinking carefully about the above, since the assignment of null values is problematic. { extern "C" bool set_input_data_separatorCmd(void); } `set line cap .type.' Set the type of ends (caps) of lines. Use `.type.' of value 0 for square ends, cut off precisely at the end of line, or 1 for round ends which overhang half the line width, or 2 for square ends which overhang half the line width. The selected style is used for the ends of line segments, as well as at corners. In PostScript parlance, therefore, this command sets both the linecap and the linejoin parameters. This command only applies to lines drawn with `draw curve', `draw line' and `draw polygon'. Axes are always drawn with a line cap of 0. { extern "C" bool set_line_capCmd(void); } `set line join .type.' Set the type of intersection of lines. Use `.type.' of value 0 for mitered joins (pointy ends that may extend beyond the data points), a value of 1 for rounded ends (the default), or a value of 2 for bevelled (squared-off) ends. See the `setlinejoin' command in any text on the PostScript language for more information. This command only applies to lines drawn with `draw curve', `draw line' and `draw polygon'. Axes are always drawn with a line join of 0. { extern "C" bool set_line_joinCmd(void); } #* @param .width_pt. @unit point @default 0.709 @variable ..linewidth.. `set line width [axis|symbol|all] .width_pt.|{rapidograph \name}|default' Set the width of lines used to draw curves (default), axes, symbols, or all of the above. The width may be set to a value specified in points (conversion: 72 pt = 1 inch), to a named rapidograph width, or to the default value. The initial default values are: 0.709pt (or rapidograph 3x0) for curves; 0.369pt (or rapidograph 6x0) for axes; 0.369pt (or rapidograph 6x0) for symbols. The rapidograph settings match the standard set of widths used in technical fountain pens. The table below gives width names along with the width in points and centimetres, as given in the specifications supplied with Rapidograph technical fountain pens. Names marked by the symbol `*' are in sequence increasing by the factor root(2). Texts on technical drawing often suggest using linewidths in the ratio of 2 or root(2). On many printers, the variation in width from root(2) increase is too subtle to see, so the factor-of-2 rule may be preferable. To get sizes in a sequence doubling in width, pick from the list (`6x0', `3x0', `1', `3.5' `7'). To get a sequence increasing in width by root(2), pick from the list (`6x0', `4x0', `3x0', `0', `1', `2.5', `3.5', `6', `7'). The eye can distinguish curves with linewidths differing by a factor of root(2) if the image is of high quality, but a factor of 2 is usually better. Similarly, for overhead projections and projected slides, one would do well to use linewidths differing by a factor of 4. This is the list of `rapidograph' linewidths: Name pt cm ==== ===== ===== * 6x0 0.369 0.013 * 4x0 0.510 0.018 * 3x0 0.709 0.025 00 0.850 0.03 * 0 0.992 0.035 * 1 1.417 0.05 2 1.701 0.06 * 2.5 1.984 0.07 3 2.268 0.08 * 3.5 2.835 0.1 4 3.402 0.12 * 6 3.969 0.14 * 7 5.669 0.2 { extern "C" bool set_line_widthCmd(void); } #* @param .value. to be considered missing @default 1.0e22 @variable ..missingvalue.. `set missing value .value.' Set missing-value code (stored in the builtin variable `..missingvalue..' and builtin synonym `\.missingvalue..') to `.value.', which mean that data within 0.1 percent of this value are ignored. The initial default is 1.0e22. { extern "C" bool set_missing_valueCmd(void); } `set postscript filename "\string"' Set name of PostScript file, over-riding the present name. { extern "C" bool set_postscript_filenameCmd(void); } `set page size letter|legal|folio|tabloid|A0|A1|A2|A3|A4|A5' Prevent bounding box from extending outside the indicated page domain. { extern "C" bool set_page_sizeCmd(void); } `set page portrait|landscape|{factor .mag.}|{translate .xcm. .ycm.}' Control orientation or scaling of what is drawn on the paper. * `set page portrait' Print graph normally (default). * `set page landscape' Print graph sideways. * `set page factor .mag.' Scale everything to be drawn on the paper by the indicated magnification factor. This *must* be called before any drawing commands. * `set page translate .xcm. .ycm.' Translate everything to be drawn on the paper by the indicated x/y distances. This *must* be called before any drawing commands. *Note*: The order of the factor/translate commands matters, so you may need to experiment. For example, set page translate 2 1 set page factor 0.5 moves anything that would have been drawn at the lower-left corner of the paper onto the point 2cm from the left side and 1cm from the bottom side of the paper, and then applies the multiplication factor. Reversing the order gives quite different results. PostScript gurus should note that the following two commands are inserted into the PostScript file: 56.900000 28.450000 translate 0.500000 0.500000 scale { extern "C" bool set_pageCmd(void); } `set panel .row. .col.' Establish geometry for the panel in the indicated row and column. The bottom row has .row. = 1, and the leftmost column has .col. = 1. This must be used only after using `set panels .row. .col. .dx_cm. .dy_cm.' { if {rpn \.words. 4 !=} show "ERROR: `\.proper_usage.' needs 3 words" quit 1 end if new .row. .col. .row. = \.word2. .col. = \.word3. set x margin {rpn .col. 1 - .panel_xsize. .panel_dx. + * .panel_xmargin. +} set y margin {rpn .row. 1 - .panel_ysize. .panel_dy. + * .panel_ymargin. +} set x size .panel_xsize. set y size .panel_ysize. delete .row. .col. } `set panels .rows. .cols. [.dx_cm. .dy_cm.]' Set up for multipanel plots, with spacing .dx_cm. between the columns and .dy_cm. between the rows. If the spacings are not supplied, 2cm is used. The panels fill the rectangle which would otherwise contain the single axis frame, as set by `set x size' and `set x margin', etc. The global variables .panel_dx., .panel_dy., .panel_xmargin., .panel_ymargin., .panel_xsize., and .panel_ysize are created, to be used by later calls to `set panel'. EXAMPLE # Draw 2 panels across, 3 up the page. # The Panel interiors will be in region cornered # by (2,2), (12,22) cm set x margin 2 set y margin 2 set x size 10 set y size 20 set panels 2 3 # Create dummy scale set x axis 0 1 set y axis 0 1 # Draw blank axes set panel 1 1 draw axes set panel 1 2 draw axes set panel 1 3 draw axes set panel 2 1 draw axes set panel 2 2 draw axes set panel 2 3 draw axes SEE ALSO `set panel .row. .col.' { # creates globals # .panel_dx. .panel_dy. # .panel_xmargin. .panel_ymargin. # .panel_xsize. .panel_ysize. if {rpn \.words. 4 ==} .panel_dx. = 2 .panel_dy. = 2 else if {rpn \.words. 6 ==} .panel_dx. = \.word4. .panel_dy. = \.word5. else show "ERROR: `\.proper_usage.' needs 5 words" quit 1 end if new .rows. .cols. # local storage .rows. = \.word2. .cols. = \.word3. if {rpn .panel_dx. 0 >} show "ERROR: `\.proper_usage.' needs .dx. to be non-negative" quit 1 end if if {rpn .panel_dy. 0 >} show "ERROR: `\.proper_usage.' needs .dy. to be non-negative" quit 1 end if .panel_xmargin. = ..xmargin.. .panel_ymargin. = ..ymargin.. .panel_xsize. = {rpn ..xsize.. .panel_dx. .cols. 1 - * - .cols. /} .panel_ysize. = {rpn ..ysize.. .panel_dy. .rows. 1 - * - .rows. /} delete .rows. .cols. } #* @param \path for data or command files @default "." `set path to "\path"|default for data|commands' Set directory path for finding data files or command files. The default is ".", the current directory. { extern "C" bool set_pathCmd(void); } #* @param .diameter_cm. diameter size of symbols @unit cm @default 0.1 `set symbol size .diameter_cm.|default' Control the size (diameter) of symbols drawn by `draw symbol' command. `set symbol size .diameter_cm.' Make symbol size (diameter) be `.diameter_cm.' centimeters. `set symbol size default' Set to default diameter of 0.1 cm. { extern "C" bool set_symbol_sizeCmd(void); } #* @param $.size. of axes tics @unit cm @default 0.2 `set tic size .size.|default' Control size of tics on axes. `set tic size .size.' Set tic size to `.size.' centimetres. `set tic size default' Set tic size to default of 0.2 cm { extern "C" bool set_tic_sizeCmd(void); } `set tics in|out' Make axis tics point inward or outward. The default is outward. { extern "C" bool set_ticsCmd(void); } `set trace [on|off]' Control printing of command lines as they are processed. `set trace' Make Gri print command lines as they are processed. `set trace on' Same as `set trace'. `set trace off' Prevent printing command lines (default). { extern "C" bool set_traceCmd(void); } `set transparency .transparency.' Set the transparency of drawn items, 0 for opaque and 1 for invisibly faint. { extern "C" bool set_transparencyCmd(void); } `set u scale .cm_per_unit.|{as x}' Set scale for x-component of arrows. `set u scale .cm_per_unit.' Set scale for `u' component of arrows. `set u scale as x' Set scale for u component of arrows to be the same as the x-scale. Equivalent to `set u scale as \{rpn ..xsize.. ..xright.. ..xleft.. - /}'. NOTE: this only works if the x-scale is LINEAR (see `set x type'). { extern "C" bool set_u_scaleCmd(void); } `set v scale .cm_per_unit.|{as y}' Set scale for y-component of arrows. `set v scale .cm_per_unit.' Set scale for `v' component of arrows. `set v scale as y' Set scale for v component of arrows to be the same as the y-scale. Equivalent to `set v scale as \{rpn ..ysize.. ..ytop.. ..ybottom.. - /}'. NOTE: this only works if the y-scale is LINEAR (see `set y type'). { extern "C" bool set_v_scaleCmd(void); } `set x axis top|bottom|increasing|decreasing|{.left. .right. [.incBig. [.incSml.]]}|{labels [add] .pos. "label" [...]}|{labels automatic}||unknown' Control various things about the x axis. `set x axis top' Make next x-axis to be drawn have labels above the axis. `set x axis bottom' Make next x-axis to be drawn have labels below the axis. `set x axis increasing' Make next x-axis to be drawn have numeric labels increasing to the right. This applies only if autoscaling is done; otherwise, the supplied values (`.left. .right. [.incBig. [.incSml.]]') are used. `set x axis decreasing' ke next x-axis to be drawn have numeric labels decreasing to the right. This applies only if autoscaling is done; otherwise, the supplied values (`.left. .right. [.incBig. [.incSml.]]') are used. `set x axis unknown' Make Gri forget any existing scale for the x axis, whether set by another `set x axis' command or automatically, during reading of data. This is essentially a synonym for `delete x scale'. `set x axis .left. .right.' Make x-axis range from `.left.' to `.right.' `set x axis .left. .right. .incBig.' Make x-axis range from `.left.' to `.right.', with labelled increments at `.incBig.' Note: In the case of log axes, and provided that `set x type log' has been called previously, the `.incBig.' parameter has a different meaning: it is the interval, in decades, between numbered labels; the default is 1. `set x axis .left .right. .incBig. .incSml.' Make x-axis range from `.left.' to `.right.', with labelled increments at `.incBig.', and small tics at `.incSml.' NOTE: if the axis is logarithmic, the value of `.incSml.' takes on a special meaning: if it is positive then small tics are put at values 2, 3, 4, etc. between the decades, but if `.incSml.' is negative then no such small tics are used. `set x axis labels [add] .position. "label" [.position. "label" [...]]' Override the automatic labelling at axis tics, and instead put the indicated labels at the indicated x values. For example, a day-of-week axis can be created by the code: set x axis 0 7 1 set x axis labels 0.5 "Mon" 1.5 "Tue" 2.5 "Wed" \ 3.5 "Thu" 4.5 "Fri" 5.5 "Sat" \ 6.5 "Sun" The command replaces any existing labels, unless the `add' keyword is present, in which case the new label information is appended to any existing information. `set x axis labels automatic' Return to automatically-generated axis labels, undoing the command of the previous item. { extern "C" bool set_x_axisCmd(void); } #* @param \format for axis numbers in C notation @default %g `set x format \format|default|off' Set format for numbers on x axis. The format is specified in the manner of the "C" programming language. The "C" formats (i.e., `%f', `%e' and `%g') are permitted. For example, `set x format %.1f' tells Gri to use 1 decimal place, and to prefer the "float" notation to the exponential notation. The form `set x format off' tells Gri not to write numbers on the axis. To get spaces in your format, enclose the format string in double-quotes, e.g., you might use `set x format "%.0f$\circ$ W"' for a map, or `set x format "%f "' to make the numbers appear to the left of their normal location. The default format is `%lg'. { extern "C" bool set_x_formatCmd(void); } `set x grid .left. .right. .inc.|{/.cols.}' Create x-grid for contour or image. `set x grid .left. .right. .inc.' Create x-grid ranging from the value `.left.' at the left to `.right.' at the right, stepping by an increment of `.inc.'. `set x grid .left. .right. /.cols.' Create x-grid with `.cols.' points, ranging from the value `.left.' at the left to `.right.' at the right. { extern "C" bool set_x_gridCmd(void); } #* @param .size. of x margin @unit cm @default 6 @variable ..xmargin.. `set x margin {[bigger|smaller] .size.} | default' Control x margin, that is, the space between the left-hand side of the page and the left-hand side of the plotting area. (Note that axis labels are drawn inside the margin; the margin extends to the axis line, not to the labels.) `set x margin .size.' Set left margin to `.size.' cm. It is permissible to have negative margins, with the expected effect. `set x margin bigger .size.' Increases left margin by `.size.' cm. `set x margin smaller .size.' Decreases left margin by `.size.' cm. `set x margin default' Set left margin to default = 6 cm. { extern "C" bool set_x_marginCmd(void); } #* @param \name of x axis @default "" `set x name "\name"|default' Set name of x-axis to the indicated string. An empty string (`set x name ""') causes the x axis to be unlabelled. The `default' is `"x"'. { extern "C" bool set_x_nameCmd(void); } #* @param .width_cm. of axis @unit cm @default 10 @variable ..xsize.. `set x size .width_cm.|default' Set the width of the plotting area. This does not include axis labels, only the interior part of the plot. `set x size .width_cm.' Set width of x-axis in centimeters. `set x size default' Set width of x-axis to default = 10 cm. { extern "C" bool set_x_sizeCmd(void); } `set x type linear|log|{map E|W|N|S}' Control transformation function mapping user units to centimetres on the page. * `set x type linear' Set to linear axis. * `set x type log' Set to log axis. To avoid clashes in the linear to log transform, this command should precede the creation of an axis scale, either explicitly through the `set x axis .left. .right. ...' command or implicitly through the `read columns' command. * `set x type map E|W|N|S' Set to be a map. This means that whole numbers on the axis will have a degree sign written after them (and then the letter `E', etc) and that numbers which are multiples of 1/60 will be written in degree-minute format, and that similarly numbers which are divisible by 1/3600 will be in degree-minute-second format. If none of these things apply, the axis labels will be written in decimal degrees. Note that this command overrides any format set by `set x format'. BUG: this only has an effect if the axis is not already of type `log'. SEE ALSO: `set map projection', to set to non-rectangular axes for various map projections. { extern "C" bool set_x_typeCmd(void); } `set y axis left|right|increasing|decreasing|{.bottom. .top. [.incBig. [.incSml.]]}|{labels [add] .pos. "label" [...]}|{labels automatic}|{name vertical|horizontal}|unknown' Control various things about the y axis. `set y axis left' Make next y-axis to be drawn have labels to the left of the axis. `set y axis right' Make next y-axis to be drawn have labels to the right of the axis. `set y axis increasing' Make next y-axis to be drawn have numeric labels increasing up the page. This applies only if autoscaling is done; otherwise, the supplied values (`.left. .right. [.incBig. [.incSml.]]') are used. `set y axis decreasing' Make next y-axis to be drawn have numeric labels decreasing up the page. This applies only if autoscaling is done; otherwise, the supplied values (`.left. .right. [.incBig. [.incSml.]]') are used. `set y axis unknown' Make Gri forget any existing scale for the y axis, whether set by another `set y axis' command or automatically, during reading of data. This is essentially a synonym for `delete y scale'. `set y axis .bottom. .top.' Make y-axis range from `.bottom.' to `.top.' `set y axis .bottom. .top. .incBig.' Make y-axis range from `.bottom.' to `.top.', with labelled increments at `.incBig.' `set y axis .bottom. .top. .incBig. .incSml.' Make y-axis range from `.bottom.' to `.top.', with labelled increments at `.incBig.', and small tics at `.incSml.' NOTE: if the axis is logarithmic, the value of `.incSml.' takes on a special meaning: if it is positive then small tics are put at values 2, 3, 4, etc. between the decades, but if `.incSml.' is negative then no such small tics are used. `set y axis labels [add] .position. "label" [.position. "label" [...]]' Override the automatic labelling at axis tics, and instead put the indicated labels at the indicated y values. For example, a day-of-week axis can be created by the code: set y axis 0 1 0.5 set y axis labels 0.25 "Weak" 0.75 "Strong" The command replaces any existing labels, unless the `add' keyword is present, in which case the new label information is appended to any existing information. `set y axis labels automatic' Return to automatically-generated axis labels, undoing the command of the previous item. `set y axis name vertical' Cause future y axes to be drawn with the name aligned vertically (the default). `set y axis name horizontal' Cause future y axes to be drawn with the name aligned horizontally. { extern "C" bool set_y_axisCmd(void); } #* @param \format for axis numbers in C notation @default %g `set y format \format|default|off' Set format for numbers on y axis. The format is specified in the manner of the "C" programming language. The "C" formats (i.e., `%f', `%e' and `%g') are permitted. For example, `set y format %.1f' tells Gri to use 1 decimal place, and to prefer the "float" notation to the exponential notation. The form `set y format off' tells Gri not to write numbers on the axis. To get spaces in your format, enclose the format string in double-quotes, e.g., you might use `set y format "%.0f$\circ$ N"' for a map, or `set y format " %f"' to make the numbers appear to the right of their normal location. The default format is `%lg'. { extern "C" bool set_y_formatCmd(void); } `set y grid .bottom. .top. .inc.|{/.rows.}' Create y-grid for contour or image. `set y grid .bottom. .top. .inc.' Create y-grid ranging from the value `.bottom.' at the bottom to `.top.' at the top, stepping by an increment of `.inc.'. `set y grid .bottom. .top. /.rows.' Create y-grid with `.rows.' points, ranging from the value `.bottom.' at the bottom to `.top.' at the top. { extern "C" bool set_y_gridCmd(void); } #* @param .size. of y margin @unit cm @default 6 @variable ..ymargin.. `set y margin {[bigger|smaller] .size.} | default' Control y margin, that is, the space between the bottom side of the page and the bottom of the plotting area. (Note that axis labels are drawn inside the margin; the margin extends to the axis line, not to the labels.) `set y margin .size.' Set bottom margin to `.size.' centimeters. It is permissible to have negative margins, with the expected effect. `set y margin bigger .size.' Increases bottom margin by `.size.' centimeters. `set y margin smaller .size.' Decreases bottom margin by `.size.' centimeters. `set y margin default' Set bottom margin to default = 6 cm. { extern "C" bool set_y_marginCmd(void); } #* @param \name of y axis @default "y" `set y name "\name"|default' Set name of y-axis to the indicated string. An empty string (`set y name ""') causes the y axis to be unlabelled. The `default' is `"y"'. { extern "C" bool set_y_nameCmd(void); } #* @param .height_cm. of y axis @unit cm @default 10 @variable ..ysize.. `set y size .height_cm.|default' Set the width of the plotting area. This does not include axis labels, only the interior part of the plot. `set y size .height_cm.' Set height of y-axis in centimeters. `set y size default' Set width of y-axis to default = 10 cm. { extern "C" bool set_y_sizeCmd(void); } `set y type linear|log|{map N|S|E|W}' Control transformation function mapping user units to centimetres on the page. * `set y type linear' Set to linear axis. * `set y type log' Set to log axis. To avoid clashes in the linear to log transform, this command should precede the creation of an axis scale, either explicitly through the `set y axis .left. .right. ...' command or implicitly through the `read columns' command. * `set y type map N|S|E|W' Set to be a map. This means that whole numbers on the axis will have a degree sign written after them (and then the letter `N', etc), and that numbers which are multiples of 1/60 will be written in degree-minute format, and that similarly numbers which are divisible by 1/3600 will be in degree-minute-second format. If none of these things apply, the axis labels will be written in decimal degrees. Note that this command overrides any format set by `set y format'. BUG: this only has an effect if the axis is not already of type `log'. SEE ALSO: `set map projection', to set to non-rectangular axes for various map projections. { extern "C" bool set_y_typeCmd(void); } `set z missing above|below .intercept. .slope.' Set `z' column to be missing whenever the associated `y' and `x' columns are above/below the line defined by y = .intercept. + .slope. * x { extern "C" bool set_z_missingCmd(void); } `set "..."' { extern "C" bool setCmd(void); } `show all' Show lots of information about plot. { extern "C" bool show_allCmd(void); } `show axes' Show information about axes. { extern "C" bool show_axesCmd(void); } `show color' Show the current pen color used for lines and text. This is not to be confused with image color, which is independent. { extern "C" bool show_colorCmd(void); } `show colornames' Show all colors known by name, as defined by `read colornames' command and also the builtin colors defined automatically (e.g. `white', `black', `red', etc). { extern "C" bool show_colornamesCmd(void); } `show columns [statistics]' `show columns' Show x, y, z, u, v column data. `show columns statistics' Show means, std devs, etc for columns. { extern "C" bool show_columnsCmd(void); } `show flags' Show values of all flags. (Developers only.) { extern "C" bool show_flagsCmd(void); } `show grid [mask]' Show grid data (used for contouring), or show the grid mask (1 if data are acceptable for contouring, or 0 if contours will not extend into this region). { extern "C" bool show_gridCmd(void); } `show hint of the day' Show a Gri hint for today, randomly selected from a list of hints maintained on the Gri WWW site. Hints are cached, so that today's your hint will only be dowloaded once, and stored in your ~/.gri-hint-cache file. { extern "C" bool show_hintCmd(void); } `show image' Show information about image, such as a histogram of values, and, if the image is small enough, the actual data. { extern "C" bool show_imageCmd(void); } `show license' Show license, allowing copying of Gri { extern "C" bool show_licenseCmd(void); } `show misc' Show miscellaneous information about the plot, the data, etc. { extern "C" bool show_miscCmd(void); } `show next line' Show next line of data-file. { extern "C" bool show_next_lineCmd(void); } `show traceback' Show traceback (i.e., the tree of commands being done at this instant). { extern "C" bool show_tracebackCmd(void); } `show stopwatch' Show elapsed time since first call to this command in the given Gri program. { extern "C" bool show_stopwatchCmd(void); } `show synonyms' Show values of all synonyms, whether built-in or user-defined. { extern "C" bool show_synonymsCmd(void); } `show time' Show the current time. { extern "C" bool show_timeCmd(void); } `show variables' Show values of all variables, whether built-in or user-defined. { extern "C" bool show_variablesCmd(void); } `show .value. | {rpn ...} | "\text" [.value.|{rpn ...}|text [...]]' `show .value.' Show value of indicated variable. `show \{rpn ...}' Show result of computing indicated expression. `show "some text"' Print the indicated string. `show "time=" .time. "; depth=" .depth.' Print strings and values as indicated. If the last item is ellipses (three dots with no spaces between them), then no newline is printed; this makes the next `show' statement print on the same line. { extern "C" bool show_expression_or_stringCmd(void); } `skip [forward|backward] [.n.]' `skip' For ascii files, skip forward 1 line in the data file. For binary files, skip forward 1 byte. `skip backward' For ascii files, skip backward 1 line in the data file. For binary files, skip backward 1 byte. `skip .n.' `skip forward .n.' For ascii files, skip forward `.n.' lines in the data file. For binary files, skip forward `.n.' bytes. `skip backward .n.' For ascii files, skip backward `.n.' lines in the data file. For binary files, skip backward `.n.' bytes. { extern "C" bool skipCmd(void); } `sleep .sec.' Cause Gri to sleep for the indicated number of seconds, which should be a positive integer. This command is ignored if `.sec.' is zero or negative, and the value of `.sec.' is first rounded to the nearest integer. Normally, this command is used only be the developer, as a way to slow down Gri execution, to allow easier monitoring for debugging purposes. Beware: it is tricky to kill a sleeping job! { extern "C" bool sleepCmd(void); } `smooth {x [.n.]} | {y [.n.]} | {grid data [.f.|{along x|y}]}' All these smoothing commands ignore the *location* of the data. For equispaced data these algorithms have the standard interpretation in terms of digital filters. For non-equispaced data, the interpretation is up to the user. The `smooth x' command does smoothing by the following formula x[i-1] x[i] x[i+1] ------ + ---- + ------ 4 2 4 The `smooth x .n.' command does boxcar smoothing using centred boxcars `.n.' points wide. The `smooth y' command does the same as `smooth x', but on the `y' column. There are several methods of smoothing grid data. Note that isolated missing values are filled in by each method. (Let the author know if you'd like that `feature' to be an option.) The `smooth grid data' command smooths gridded data, by weighted average in a plus-shaped window about each gridpoint. The smoothing algorithm replaces each interior gridpoint value `z[i][j]' by z[i][j] z[i-1][j] + z[i+1][j] + z[i][j-1] + z[i][j+1] ------- + --------------------------------------------- 2 8 Points along the edges are smoothed by the same formula, after inventing image points outside the domain by planar extrapolation. The `smooth grid data .f.' command performs partial smoothing. A temporary fully-smoothed grid `zSMOOTH[i][h]' is constructed as above, and a linear combination of this grid and the original grid is used as the replacement grid: z[i][j] = (1-f) * z[i][j] + f * zSMOOTH[i][j] where `f' is the value indicated on the command line. Thus, `smooth grid data 0' performs no smoothing at all, while `smooth grid data 1' is equivalent to `smooth grid data'. The `smooth grid data along x' command smooths the grid data along `x' (i.e., horizontally), by replacing each value `z[i][j]' with the value z[i][j] z[i-1][j] + z[i+1][j] ------- + --------------------- 2 4 Points along the edges are smoothed by the same formula, after inventing image points outside the domain by linear extrapolation. The `smooth grid data along y' command does the same thing as `smooth grid data along x', but the smoothing is along `y'. SEE ALSO: `filter', a generalization of `smooth x|y' which allows for more sophisticated filters. { extern "C" bool smoothCmd(void); } `source \filename' Insert instructions in named file into current file. This is useful as a way of sharing global information between several Gri programs. On unix systems, if a full filename is specified (i.e., a filename beginning with slash or period), then that particular file will be used. { extern "C" bool sourceCmd(void); } `sprintf \synonym "format" .variable. [.variable. [...]]' Write numbers into a synonym (text string). This is useful for labelling plots. `sprintf \out "a = %f b = %.2f" .a. .b.' - Create a synonym called `\out', and print the values of the variables `.a.' and `.b.' into it. If `.a.' = 1 and `.b.' = 0.112, then `\out' will be `"a = 1 b = 0.11"' Formatting codes are as in the C programming language, eg: %.2f -- Use floating point notation with 2 decimal places. %9.2f -- As above, but specify the number to occupy 9 characters. %e -- Use exponential notation. WARNING: Variables are stored in the "double" storage type of the "C" programming language, so "long" formats must be used in `sprintf'. { extern "C" bool sprintfCmd(void); } `state save|restore|display' The `save' operation pushes a record of the graphics state (pen and font characteristics, margins, axis lengths, min/max/inc values on axes, etc) onto a stack. The `restore' operation replaces the present state with whatever is on top of the stack, and then pops the stack. Use the `display' operation to see some of the state properties. The `state' command is useful for temporary changes of axis properties, etc. BUG: only line characteristics (width, color) and font characteristics (font, size, color) are saved so far. In fact, the full list of what should be saved has not yet been finalized by the author. { extern "C" bool stateCmd(void); } `superuser' Allow extra debugging information and commands. Normally, this command and the corresponding commandline flag -superuser are only used by programmers altering the Gri source. These are the flags and their meanings: 1 Print cmdline before/after substituting synonyms 2 Print cmdline before/after substituting rpn expressions 4 Print all new commands as they are being defined 8 Print system commands and `open "...|"' commands before they are passed to the system Note that all flags are equal to 2 raised to an integer power. Since the flag values are detected by a bitwise OR, you can combine glags by adding; thus specifying a flag of 5 yields flags 1 and 4 together. { extern "C" bool superuserCmd(void); } `system \system-command' Tell the operating system to perform the indicated action. Whatever string follows the word `system' is passed directly to the operating system, *after* substitution of synonyms if any exist. Note that `rpn' expressions are not evaluated, and variable values are not substituted before passing the string to the operating system. The exit status is stored in the builtin variable `..exit_status..'. There are two ways to use the system: * *Assign output to synonym*: The form `\synonym = system ...' does the system command and then inserts the output from that command into the indicated synonym.) * *Just run a command*: The command `system ls' will list the files in the current directory. For long commands, there are two approaches, the second preferred: * *Use continuation lines*: String a lot of information onto one effective system line, using the `\' line-continuation character at the ends of lines. The problem is that it's very easy to lose one of these backslashes. The next method is better. * *Here-is syntax* The here-is syntax of many unix shells is also provided. If the system command contains the characters `<<' followed by a word (with no space between!) then Gri will issue a system command which includes not only this line but also all succeeding lines, until a line is found which matches the indicated word precisely (with no leading space allowed). The `<< "WORD"' syntax is also supported, meaning that the operating system is being told not to mess with the dollar-signs - needed in perl. *Note:* Be carefull using this inside a new-command. Gri Recognizes the end of the body of a new-command by a line with `}' in the *first column*, and no non-white characters thereafter. If you system command happens to use a line with a curly brace (as in a loop in perl, for example), you must put whitespace before the brace. This won't affect the system command, but it will let Gri correctly realize that this is *not* the end of the new-command. For more information on new-commands. *Caution:* Before sending the string to the system, Gri first translates any synonyms present. Be careful with this, since system commands calling awk, etc, very often use backslashes for the newline character `\n' within strings. If you have a synonym whose name starts with `\n', you can get a conflict. For example, the awk command `print "foo\nbar";' should print a line with `foo' on it, followed by a line with `bar' on it, but it will instead print a single line with `fooMISTAKE', if you had previously defined a synonym as `\nbar = "MISTAKE"'. One way to avoid this mistake is to make sure any `\n' characters appear at the end of strings, and then simply avoid having a synonym named `\n'. Here is a Perl example. \message = "Foo bar" system perl <<"EOF" $a = 100; print "foo bar is \message, and a is $a\nQ: was a 100?\n"; print "BETTER: foo bar is \message, and a is $a\n"; print "Q: was a 100?\n"; EOF which, written more safely (partially avoiding the string `\n'), is \message = "Foo bar" system perl <<"EOF" $a = 100; print "foo bar is \message, and a is $a\n"; print "Q: was a 100?\n"; EOF Here is an Awk example. Note that the commandline flags `-f -' are required to force awk to take commands from standard input. Note also the absence of a final newline in the string; Awk does not require one, while Perl does. (Finally, as usual, note that the synonym `awk' is being used instead of `awk', to ensure portability.) \message = "Foo bar" system awk -f - <<"EOF" BEGIN \{ a = 100; print "foobar is \message, and a is ", a, "\nQ: was a 100?"; } EOF which, written more safely (avoiding the string `\n'), is \message = "Foo bar" system awk -f - <<"EOF" BEGIN\{ a = 100; print "foobar is \message, and a is ", a; print "Q: was a 100?"; } EOF *Some more examples*: * To get the first 10 lines of a file called `foo.dat' inserted into another file called `bar.dat', you might do the following. Only the first method works; the second will fail because `.n.' will not be translated before passing to the operating system. \num = "-10" system head \num foo.dat > bar.dat # Following fails since .num. will not be translated .num. = -10 system head .num. foo.dat > bar.dat * Issue a unix command to get a listing of files in the current working directory, and pipe them into the `more' system command. system ls -l *c | more * Store the date and time into a synonym, and use it in a title: \time = system date ... draw title "Plotted at time \time" * Use `awk' to prepare a two-column table of x, ranging from 0 to 1 in steps of 0.1, and sin(x). The table is stored in a file whose suffix is the process ID of the Gri job. This file is then opened, and the data plotted. Finally, a system command is issued to remove the temporary file. system awk 'BEGIN \{ \ for (x=0; x<1; x+=0.1) \{ \ printf("%f %f\n", x, sin(x)) \ } \ }' > tmp.\.pid. open tmp.\.pid. read columns x y close system rm tmp.\.pid. draw curve quit NOTE Under unix, this command calls the Bourne shell, not the C-shell that is often used interactively. For many simple uses, the only difference from normal interactive use will be that `~' is not expanded to the home directory. For example, you'd do system awk -f $HOME/foo/bar/cmd.gawk instead of the system awk -f ~/foo/bar/cmd.gawk that you might expect from interactive C-shell usage. RETURN VALUE: Sets `\.return_value' to system status, `N status' { extern "C" bool systemCmd(void); } `while .test.|{rpn ...}' Perform statements in loop while the value of `.test.' or the RPN expression is nonzero. The end of the loop designated by a line containing the words `end while'. The value `.test.' may be an RPN expression. To leave the loop prematurely, use a `break' statement. Upon encountering a `break' statement, Gri jumps to the line immediately following the loop. If the `-chatty' option is nonzero, a notification is printed every 1000 passes through the loop, as a debugging measure to catch unintended infinite loops. *Examples*: * Loop forever, printing a message over and over. while 1 show "DANGER: This loop goes on forever. You need a break statement!" end while * Repeatedly read two numbers, and plot a bullet at the indicated location. If (or, hopefully, "when") the end of the file is encountered, break out of the loop; otherwise continue plotting forever. while 1 read .x. .y. if ..eof.. break end if draw symbol bullet at .x. .y. end while * Loop 10 times, printing the values of `.i.' as they range 0, 1, ..., 9. After exiting from the loop, `.i.' will equal 10. Be *careful* to use the correct RPN greater-than test to avoid an infinite loop. .i. = 0 while \{rpn .i. 10 >} show .i. .i. += 1 end while { extern "C" bool whileCmd(void); } `write columns to \filename' Append data columns to the end of the indicated file. { extern "C" bool writeCmd(void); } `write contour .value. to \filename' As corresponding `draw contour' command, but don't actually draw the contours; instead, write to the indicated file, starting at the EOF of the file if it is nonempty (thus, appending to the end of the file.) The first line of output is a header line, containing two numbers: the contour value and the missing value. Then the xy pairs are written a line at a time, with missing values being used to indicate ends of segments. A blank line is written after the last data pair. For example, if the contour contained two closed regions, Gri would output a pair of missing values as one of the xy pairs, to denote the separation of the two curves. You could read and plot the output as in this example write contour 10 to contour.out write contour 20 to contour.out open contour.out read .contour_value. .missing. set missing value .missing. read columns x y draw curve { extern "C" bool writeCmd(void); } `write grid to \filename [bycolumns]' Append grid to the end of the named file. Storage is in `%f' format, and is in normal image order. If the keyword `bycolumns' is present, then the grid is transposed first, in such a way that `read grid data bycolumns' performed on that file will read back the original grid data. { extern "C" bool writeCmd(void); } `write image colorscale to \filename' Append image colorscale transform to the end of the named file. Storage is a series of 256 lines, each containing 3 numbers (for Red, Green and Blue) in the range 0 to 1. The file is suitable for reading with the `read image colorscale' command. */ { extern "C" bool writeCmd(void); } `write image grayscale to \filename' Append image grayscale transform to the end of the named file. Storage is a series of 256 lines, each containing a number in the range 0 to 1. The file is suitable for reading with the `read image grayscale' command. */ { extern "C" bool writeCmd(void); } `write image greyscale to \filename' Alternate spelling of grayscale { extern "C" bool writeCmd(void); } `write image mask [pgm|rasterfile] to \filename' `write image mask to mask.dat' Append image mask to the end of the named file. Storage is by unsigned-char, and is in normal image order. There is no header. `write image mask rasterfile to mask.dat' Append image mask to the end of the named file, in Sun Rasterfile format. `write image mask pgm to mask.dat' Append image mask to the end of the named file, in PGM 'rawbits' format. { extern "C" bool writeCmd(void); } `write image [pgm|rasterfile] to \filename' `write image to image.dat' Append image to the end of the named file. Storage is by unsigned-char, and is in normal image order. There is no header. `write image rasterfile to image.dat' Append image to the end of the named file, in Sun Rasterfile format. `write image pgm to image.dat' Append image to the end of the named file, in PGM 'rawbits' format. { extern "C" bool writeCmd(void); } `unlink \filename' Delete a filename and possibly the file to which it refers. On non-unix machines, this simply means to delete the file. On unix machines, the action is more subtle. The unix OS permits several processes to use a given file at once. Therefore, `unlink' doesn't immediately remove the file, but instead waits until other processes are done with it. Most users will never realize the difference, however, and it is safe to think of `unlink' as simply removing the file. To learn more, type `man unlink' in a unix shell. A common use of `unlink' is to remove files that were created with the `tmpname' facility, e.g. \tmp = tmpname # do some system commands to put data into this file open \tmp read columns x y draw curve unlink \tmp { extern "C" bool unlinkCmd(void); } `?draw axes exploded' Fragment to draw the xy axes at left and bottom, offset 0.2 cm from a simple axis frame. { draw axes frame # Draw frame draw x axis at {rpn ..ymargin.. 0.2 -} cm lower # X axis below frame draw y axis at {rpn ..xmargin.. 0.2 -} cm left # Y axis left of frame } `?contour xyz data' Fragment to read xyz data (from a file called "file.dat"), then interpolate these xyz data onto a uniform grid (of size 30x30, chosen to span the data), and then draw contours (at levels selected by autoscaling the data). For reference, dots are also drawn at the data locations. Adjustments: filename, grid characteristics, method/details of converting columns to grid. { open input.dat # You'll want to change the filename read columns x y z # Can read in any order, e.g '... y x z' close # Close this file set x grid ..xleft.. ..xright.. / 30 # Spans data, 30 wide set y grid ..ybottom.. ..ytop.. / 30 # Spans data, 30 high convert columns to grid # Uses default "objective" method draw contour # Levels selected automatically draw symbol bullet # Put dots at data locations } `?set axes' { set x margin 2 # 2cm at left of axis frame set x margin 2 # 2cm at left of axis frame set x size 12 # Axis frame 12cm wide set y size 12 # Axis frame 12cm high set x name "x" # Name of x axis set y name "y" # Name of y axis } `?draw image BW raster' Fragment to read/draw a Sun rasterfile image in BW, blown up to full size on (portrait orientation) 8.5x11 paper. No axes are drawn. A palette is drawn, assuming that the limits of the image value are 0 and 1. Main adjustable parameters marked with '*' in comment. { \file = "A.rs" # * filename .min. = 0 # * lowest possible value .max. = 1 # * largest possible value set image range .min. .max. open \file binary read image rasterfile # ALTERNATIVE: # read image pgm close .margin. = 1 # * margin space in cm set x margin .margin. set y margin .margin. set x axis 0 ..image_width.. ..image_width.. set y axis 0 ..image_height.. ..image_height.. set font size 10 # * font size set x size {rpn 8.5 2.54 * .margin. 2 * -} set y size {rpn ..xsize.. ..image_width.. / ..image_height.. *} # Want 2cm for palette .left_over. = {rpn 11 2.54 * ..ysize.. - .margin. 2 * -} if {rpn .left_over. 2 >} set y size {rpn 11 2.54 * .margin. 2 * - 2 -} set x size {rpn ..ysize.. ..image_height.. / ..image_width.. *} end if draw axes none draw image draw image palette left .min. right .max. box \ {rpn ..xmargin..} \ {rpn ..ymargin.. ..ysize.. + 1.0 +} \ {rpn ..xmargin.. ..xsize.. +} \ {rpn ..ymargin.. ..ysize.. + 2.0 +} } rpnfunction e 2.7182818284590452354 rpnfunction pi 3.14159265358979323846 # The following assume stack containing four numbers, 'x0 y0 x1 y', # and return the slope and intercept of the line joining the points. rpnfunction linear_slope exch roll_right - roll_right exch - / rpnfunction linear_intercept exch dup roll_left roll_left roll_left dup roll_right - roll_right exch - / roll_left * - # /----------------------------------------------------------------\ # |The following material is for the benefit of the Emacs gri mode | # \----------------------------------------------------------------/ # # @variable ..R2.. squared correlation coefficient (defined if regression has been done) # @variable ..coeff0.. intercept in linear regression (defined if regression has been done) # @variable ..coeff0_sig.. 95% C.I. on intercept in linear regression (defined if regression has been done) # @variable ..coeff1.. slope in linear regression (defined if regression has been done) # @variable ..coeff1_sig.. 95% C.I. on slope in linear regression (defined if regression has been done) # @variable ..num_col_data.. number of column data # @variable ..num_col_data_missing.. number of missing column data # @variable ..arrowsize.. size of arrow heads @unit cm @default 0.2 # @variable ..batch.. is Gri in batch mode? @default 0 # @variable ..debug.. debugging flag @default 0 # @variable ..fontsize.. size of font @unit point @default 12 # @variable ..graylevel.. graylevel of pen (0 means black) @default 0 # @variable ..linewidth.. width of curves @unit point @default 0.709 # @variable ..linewidthaxis.. width of axis lines @unit point @default 0.369 # @variable ..linewidthsymbol.. width of symbol lines @unit point @default 0.369 # @variable ..missingvalue.. missing value @default 1e+22 # @variable ..symbolsize.. size of symbols @unit point @default 0.1 # @variable ..superuser.. superuser flag @default 0 # @variable ..trace.. are executed commands printed? @default 0 # @variable ..tic_direction.. direction of tics (0 means out and 1 means in) @default 0 # @variable ..tic_size.. size of tic marks @unit cm @default 0.2 # @variable ..xmargin.. margin to left of axis area @unit cm @default 6 # @variable ..xsize.. width of axis area @unit cm @default 10 # @variable ..ymargin.. margin below axis area @unit cm @default 6 # @variable ..ysize.. height of axis area @unit cm @default 10 # @variable ..red.. red-ness of pen (0 to 1) @default 0 # @variable ..blue.. blue-ness of pen (0 to 1) @default 0 # @variable ..green.. green-ness of pen (0 to 1) @default 0 # @variable ..exit_status.. exit status used for OS @default 0 # @variable ..xleft.. x-value at left of axis area @default 0 # @variable ..xright.. x-value at right of axis area @default 10 # @variable ..ybottom.. y-value at bottom of axis area @default 0 # @variable ..ytop.. y-value at top of axis area @default 10 # @variable ..use_default_for_query.. use default for query statements? (0 or 1) @default 0 # @variable ..words_in_dataline.. number of words in data line @default 0 # @variable ..eof.. at end of data file yet? (0 or 1) @default 0 # @variable ..landscape.. is the graph in landscape mode? (0 or 1) @default 0 # @variable ..publication.. use publication quality? (0 or 1) @default 0 # @variable ..xlast.. last value of x column @default 0 # @variable ..ylast.. last value of y column @default 0 # @variable ..image_width.. pixel width of image @default 0 # @variable ..image_height.. pixel height of image @default 0 # @variable \.missingvalue. missing value code @default "1e22" # @variable \.return_value. return value from last command # @variable \.version. version of gri being used # @variable \.pid. process id of this job # @variable \.wd. present working directory # @variable \.time. day, date and time # @variable \.user. name of user who started this job # @variable \.host. name of computer on which job is running # @variable \.system. name of operating system # @variable \.home. name of this users home directory # @variable \.lib_dir. directory that holds gri library files # @variable \.command_file. name of command file for this job # @variable \.readfrom_file. name of file being read for data # @variable \.ps_file. name of PostScript file being created # @variable \.path_data. directory path for finding data @default "." # @variable \.path_commands. directory path for finding commands @default "." # BEGIN deprecated commands # @deprecated 2.10.0 `set y axis label horizontal|vertical' # END deprecated commands ����������������������������������������������������������������������������������������������������������������gri/src/Makefile.in���������������������������������������������������������������������������������0000644�0001750�0001750�00000113622�13147560320�012645� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = gri$(EXEEXT) subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_gri_OBJECTS = main.$(OBJEXT) G_string.$(OBJEXT) GriColor.$(OBJEXT) \ GriPath.$(OBJEXT) GriState.$(OBJEXT) assert.$(OBJEXT) \ chopword.$(OBJEXT) close.$(OBJEXT) command.$(OBJEXT) \ convert.$(OBJEXT) debug.$(OBJEXT) delete.$(OBJEXT) \ differ.$(OBJEXT) doline.$(OBJEXT) draw.$(OBJEXT) \ endup.$(OBJEXT) expect.$(OBJEXT) file.$(OBJEXT) \ filter.$(OBJEXT) flip.$(OBJEXT) gr.$(OBJEXT) gr_coll.$(OBJEXT) \ graxes.$(OBJEXT) grcntour.$(OBJEXT) gri.$(OBJEXT) \ grimage.$(OBJEXT) grinterp.$(OBJEXT) grsmooth.$(OBJEXT) \ grstring.$(OBJEXT) group.$(OBJEXT) heal.$(OBJEXT) \ help.$(OBJEXT) if.$(OBJEXT) ignore.$(OBJEXT) image.$(OBJEXT) \ input.$(OBJEXT) insert.$(OBJEXT) interp.$(OBJEXT) \ mask.$(OBJEXT) math.$(OBJEXT) new.$(OBJEXT) open.$(OBJEXT) \ popen.$(OBJEXT) query.$(OBJEXT) quit.$(OBJEXT) read.$(OBJEXT) \ regress.$(OBJEXT) reorder.$(OBJEXT) rescale.$(OBJEXT) \ rewind.$(OBJEXT) rpn.$(OBJEXT) rpncalc.$(OBJEXT) \ scales.$(OBJEXT) set.$(OBJEXT) show.$(OBJEXT) skip.$(OBJEXT) \ sleep.$(OBJEXT) smooth.$(OBJEXT) source.$(OBJEXT) \ startup.$(OBJEXT) state.$(OBJEXT) stats.$(OBJEXT) \ storage.$(OBJEXT) synonyms.$(OBJEXT) template.$(OBJEXT) \ timer.$(OBJEXT) unlink.$(OBJEXT) utility.$(OBJEXT) \ variable.$(OBJEXT) version.$(OBJEXT) while.$(OBJEXT) \ write.$(OBJEXT) nodist_gri_OBJECTS = gri_OBJECTS = $(am_gri_OBJECTS) $(nodist_gri_OBJECTS) gri_DEPENDENCIES = popt/libgripopt.a AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(gri_SOURCES) $(nodist_gri_SOURCES) DIST_SOURCES = $(gri_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ $(top_srcdir)/mkinstalldirs install-sh DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" VPATH = @srcdir@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = -DDEFAULT_GRI_DIR=\"$(DGD)\" $(OSX_BUNDLE) @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS_TEMPLATE = @EXTRA_CFLAGS_TEMPLATE@ $(LINUX_EXTRA_CFLAGS) GREP = @GREP@ HAVE_CONVERT = @HAVE_CONVERT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PROGS = @PROGS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ # gri: src/Makefile.am srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = popt DIST_SUBDIRS = popt gri_LDADD = @LIBS@ popt/libgripopt.a gridir = $(datadir)/gri #gri_DATA = gri.cmd nodist_gri_SOURCES = startup.debian startup.redhat gri_SOURCES = main.cc G_string.cc GriColor.cc GriPath.cc GriState.cc assert.cc\ chopword.cc close.cc command.cc convert.cc debug.cc delete.cc differ.cc\ doline.cc draw.cc endup.cc expect.cc file.cc filter.cc flip.cc\ gr.cc gr_coll.cc graxes.cc grcntour.cc gri.cc grimage.cc grinterp.cc\ grsmooth.cc grstring.cc group.cc heal.cc help.cc if.cc ignore.cc\ image.cc input.cc insert.cc interp.cc mask.cc math.cc new.cc open.cc\ popen.cc query.cc quit.cc read.cc regress.cc reorder.cc rescale.cc\ rewind.cc rpn.cc rpncalc.cc scales.cc set.cc show.cc skip.cc sleep.cc\ smooth.cc source.cc startup.cc state.cc stats.cc storage.cc\ synonyms.cc template.cc timer.cc unlink.cc utility.cc variable.cc\ version.cc while.cc write.cc\ CmdFile.hh command.hh DataFile.hh debug.hh defaults.hh errors.hh\ extern.hh files.hh GCounter.hh GMatrix.hh gr_coll.hh gr.hh\ GriColor.hh GriPath.hh GriState.hh GriTimer.hh G_string.hh image_ex.hh\ install-sh macro.hh postscpt.hh private.hh superus.hh Synonym.hh\ tags.hh types.hh Variable.hh EXTRA_DIST = Makefile.dj2 \ gri.cmd-skel logo.dat rgb.txt\ gri-mode.el gri_merge gri_unpage\ startup.msg startup.debian startup.redhat @OS_IS_APPLE_OSX_FALSE@@OS_IS_FINK_FALSE@@OS_IS_LINUX_DEBIAN_FALSE@@OS_IS_OSX_BUNDLE_FALSE@DGD = ${prefix}/share/gri/ @OS_IS_APPLE_OSX_FALSE@@OS_IS_FINK_TRUE@@OS_IS_LINUX_DEBIAN_FALSE@DGD = /sw/share/gri/ @OS_IS_APPLE_OSX_FALSE@@OS_IS_LINUX_DEBIAN_TRUE@DGD = $(prefix)/share/gri/$(PACKAGE_VERSION)/ #if OS_IS_LINUX_DEBIAN #DEFS = -DDEFAULT_GRI_DIR=\"$(prefix)/share/gri/$(PACKAGE_VERSION)/\" @DEFS@ #else #DEFS = -DDEFAULT_GRI_DIR=\"$(prefix)/share/gri/\" @DEFS@ #endif @OS_IS_APPLE_OSX_TRUE@DGD = /Applications/Gri @OS_IS_APPLE_OSX_FALSE@@OS_IS_FINK_FALSE@@OS_IS_LINUX_DEBIAN_FALSE@@OS_IS_OSX_BUNDLE_TRUE@OSX_BUNDLE = -DOSX_BUNDLE #.cc.o: # $(CXX) -c $(CXXFLAGS) $(EXTRA_CFLAGS) $(AM_CXXFLAGS) $(DEFS) -I$(srcdir) $< debian_lib = $(debian)/usr/share/gri/$(PACKAGE_VERSION) # @echo "" # @echo " /-----------------------------------------------------\\" # @echo " | NOTE: Developers should do 'make author_check' next |" # @echo " \\----------------------------------------------------/" # @echo "" # Sun microsystems, sunOS 5.x # NOTE: this target doesn't depend on 'gri' or 'doc', etc; this # is to be done manually, the first step perhaps on an # entirely different computer!! SUNOS5_NAME = gri-$(PACKAGE_VERSION)-SunOS5 @OS_IS_LINUX_REDHAT_FALSE@the_startup_file = $(srcdir)/startup.msg # The '-local' part means that these are appended after the automake-created # targets of names 'all', etc. @OS_IS_LINUX_REDHAT_TRUE@the_startup_file = $(srcdir)/startup.redhat all: all-recursive .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) gri$(EXEEXT): $(gri_OBJECTS) $(gri_DEPENDENCIES) $(EXTRA_gri_DEPENDENCIES) @rm -f gri$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(gri_OBJECTS) $(gri_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/G_string.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GriColor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GriPath.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GriState.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/assert.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chopword.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/close.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/command.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/convert.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/delete.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/differ.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/doline.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/draw.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/endup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/expect.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flip.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gr_coll.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graxes.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grcntour.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gri.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grimage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grinterp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/group.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grsmooth.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grstring.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heal.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/help.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/if.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ignore.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/image.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/input.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/insert.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mask.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/math.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/new.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/open.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/popen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/query.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quit.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regress.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reorder.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rescale.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rewind.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpn.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpncalc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scales.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/show.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/skip.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sleep.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smooth.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/source.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/startup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/state.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stats.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/storage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/synonyms.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/template.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unlink.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utility.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/variable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/while.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/write.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(PROGRAMS) all-local installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-data-local install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-binPROGRAMS install-exec-local install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-local .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ check check-am clean clean-binPROGRAMS clean-generic \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-data-local install-dvi \ install-dvi-am install-exec install-exec-am install-exec-local \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-binPROGRAMS uninstall-local .PRECIOUS: Makefile #### End of system configuration section. #### # Special rule for templates, so as not to use # -fno-implicit-templates (g++ weirdness). This special # case depends on whether -frepo exists ... and whether the installer # has temerity to try it! template.o: template.cc $(CXX) -c $(CXXFLAGS) $(EXTRA_CFLAGS_TEMPLATE) $(DEFS) -I$(srcdir) $< install_linux_debian: gri @echo "Installing into '$(debian)' directory" install -d $(debian_lib) if test -f startup.debian; then sed -e s,VERSION,${PACKAGE_VERSION}, startup.debian > $(debian_lib)/startup.msg; else echo "WARNING: no startup.debian file!"; fi; install -d $(debian)/usr/bin install -m 755 gri $(debian)/usr/bin/gri-$(PACKAGE_VERSION) (cd $(debian)/usr/bin; ln -fs gri-$(PACKAGE_VERSION) gri) install -m 644 gri.cmd $(debian_lib)/gri.cmd install -m 644 rgb.txt $(debian_lib)/rgb.txt install -m 644 logo.dat $(debian_lib)/logo.dat if test -f gri_merge; then install -m 755 gri_merge $(debian)/usr/bin; else echo "WARNING: no gri_merge file!"; fi; if test -f gri_unpage; then install -m 755 gri_unpage $(debian)/usr/bin; else echo "WARNING: no gri_unpage file!";fi; # install -d $(debian)/usr/share/emacs/site-lisp # install -m 644 gri-mode.el $(debian)/usr/share/emacs/site-lisp/ install_linux_debian_grionly: gri @echo "Installing into '$(debian)' directory" install -d $(debian_lib) install -m 644 gri.cmd $(debian_lib)/gri.cmd install -m 644 rgb.txt $(debian_lib)/rgb.txt install -m 644 logo.dat $(debian_lib)/logo.dat if test -f startup.debian; then sed -e s,VERSION,${PACKAGE_VERSION}, startup.debian > $(debian_lib)/startup.msg; else echo "WARNING: no startup.debian file!"; fi; install -d $(debian)/usr/bin install -m 755 gri $(debian)/usr/bin/gri-$(PACKAGE_VERSION) author_check: @perl $(srcdir)/check.pl check: @./gri -directory . -c 0 $(srcdir)/../doc/tst_suite/tst_var_syn.gri @./gri -directory . -c 0 $(srcdir)/../doc/tst_suite/tst_control.gri @./gri -directory . -c 0 $(srcdir)/../doc/tst_suite/tst_rpn.gri # The next few lines are a kludge since I got bored with trying # to figure out how to redirect things for automake. @cp $(srcdir)/../doc/tst_suite/tst_IO.gri . @cp $(srcdir)/../doc/tst_suite/tst_IO_1.dat . @cp $(srcdir)/../doc/tst_suite/tst_IO_2.dat . @./gri -directory . -c 0 tst_IO.gri @rm -f tst_IO.gri tst_IO_1.dat tst_IO_2.dat @cat $(srcdir)/../gri.spec | perl -ane 'if(/griversion (.*)/) {$$v=$$1; if ("$$v" ne "$(PACKAGE_VERSION)") {print "** Version in gri.spec ($$v) disagrees with $(PACKAGE_VERSION) in Makefile.\n"} else { print "Version number in gri.spec ... is OK\n";}}' @cat $(srcdir)/../debian/changelog | perl -ne 'if (($$. == 1)&&(/\(([^-]+)-/)) {if ("$$1" ne "$(PACKAGE_VERSION)") {print "** Version in debian/changelog ($$1) disagrees with $(PACKAGE_VERSION) in Makefile.\n"} else { print "Version number in debian/changelog ... is OK\n";}}' package-SunOS5: -rm -rf $(SUNOS5_NAME) -mkdir -m 755 -p $(SUNOS5_NAME) -mkdir -m 755 -p $(SUNOS5_NAME)/bin -mkdir -m 755 -p $(SUNOS5_NAME)/lib -mkdir -m 755 -p $(SUNOS5_NAME)/doc -mkdir -m 755 -p $(SUNOS5_NAME)/doc/html -mkdir -m 755 -p $(SUNOS5_NAME)/doc/html/resources -mkdir -m 755 -p $(SUNOS5_NAME)/doc/html/screenshots -mkdir -m 755 -p $(SUNOS5_NAME)/doc/html/tst_suite -mkdir -m 755 -p $(SUNOS5_NAME)/doc/html/examples -cp -p gri $(SUNOS5_NAME)/bin -cp gri.cmd rgb.txt logo.dat copyright.txt license.txt gri-mode.el $(SUNOS5_NAME)/lib -cat startup.msg | sed -e s,VERSION,${PACKAGE_VERSION}, | sed -e "s/DATE/`date`/" > tmp -cp tmp $(SUNOS5_NAME)/lib/startup.msg -cat install-SunOS5 | sed -e s,VERSION,${PACKAGE_VERSION}, > tmp -cp tmp $(SUNOS5_NAME)/install -chmod a+rx $(SUNOS5_NAME)/install -cp README-SunOS5 $(SUNOS5_NAME)/README -cat ../doc/gri-manpage-SunOS5.1 | sed -e s,VERSION,${PACKAGE_VERSION}, >tmp -cp tmp $(SUNOS5_NAME)/doc/gri.1 -rm -f tmp # Next should really be done by "cd doc; make something" etc. -cp ../doc/*html $(SUNOS5_NAME)/doc/html -cp ../doc/*png $(SUNOS5_NAME)/doc/html -cp ../doc/resources/*gif $(SUNOS5_NAME)/doc/html/resources -cp ../doc/screenshots/*png $(SUNOS5_NAME)/doc/html/screenshots -cp ../doc/tst_suite/*dat ../doc/tst_suite/*gri ../doc/tst_suite/*html $(SUNOS5_NAME)/doc/html/tst_suite -cp ../doc/examples/*dat ../doc/examples/*gri ../doc/examples/*html $(SUNOS5_NAME)/doc/html/examples -tar chof $(SUNOS5_NAME).tar $(SUNOS5_NAME) -rm -rf $(SUNOS5_NAME) -gzip $(SUNOS5_NAME).tar gri.cmd: gri.cmd-skel cat $(srcdir)/gri.cmd-skel | sed -e s,VERSION,${PACKAGE_VERSION}, > gri.cmd startup.msg-tmp: $(the_startup_file) cat $(the_startup_file) | sed -e s,VERSION,${PACKAGE_VERSION}, -e s,PREFIX,$(prefix), > startup.msg-tmp all-local: gri.cmd startup.msg-tmp install-exec-local: mkdir -m 755 -p $(DESTDIR)$(prefix)/bin $(INSTALL_SCRIPT) $(srcdir)/gri_unpage $(DESTDIR)$(prefix)/bin/gri_unpage $(INSTALL_SCRIPT) $(srcdir)/gri_merge $(DESTDIR)$(prefix)/bin/gri_merge install-data-local: @OS_IS_FINK_TRUE@ mkdir -m 755 -p $(DESTDIR)$(prefix)/share/emacs/site-lisp @OS_IS_FINK_TRUE@ $(INSTALL_DATA) $(srcdir)/gri-mode.el $(DESTDIR)$(prefix)/share/emacs/site-lisp/gri-mode.el @OS_IS_FINK_FALSE@@OS_IS_LINUX_DEBIAN_TRUE@ mkdir -m 755 -p $(DESTDIR)$(prefix)/share/emacs/site-lisp/gri @OS_IS_FINK_FALSE@@OS_IS_LINUX_DEBIAN_TRUE@ $(INSTALL_DATA) $(srcdir)/gri-mode.el $(DESTDIR)$(prefix)/share/emacs/site-lisp/gri/gri-mode.el @OS_IS_FINK_FALSE@@OS_IS_LINUX_DEBIAN_FALSE@ mkdir -m 755 -p $(DESTDIR)$(prefix)/share/emacs/site-lisp @OS_IS_FINK_FALSE@@OS_IS_LINUX_DEBIAN_FALSE@ $(INSTALL_DATA) $(srcdir)/gri-mode.el $(DESTDIR)$(prefix)/share/emacs/site-lisp/gri-mode.el mkdir -m 755 -p $(DESTDIR)$(prefix)/share/gri $(INSTALL_DATA) startup.msg-tmp $(DESTDIR)$(prefix)/share/gri/startup.msg $(INSTALL_DATA) gri.cmd $(DESTDIR)$(prefix)/share/gri/gri.cmd $(INSTALL_DATA) rgb.txt $(DESTDIR)$(prefix)/share/gri/rgb.txt $(INSTALL_DATA) logo.dat $(DESTDIR)$(prefix)/share/gri/logo.dat uninstall-local: rm -f $(DESTDIR)$(prefix)/bin/gri_unpage rm -f $(DESTDIR)$(prefix)/bin/gri_merge rm -f $(DESTDIR)$(prefix)/share/emacs/site-lisp/gri-mode.el rm -f $(DESTDIR)$(prefix)/share/gri/startup.msg rm -f $(DESTDIR)$(prefix)/share/gri/gri.cmd rm -f $(DESTDIR)$(prefix)/share/gri/rgb.txt rm -f $(DESTDIR)$(prefix)/share/gri/logo.dat rm -f startup.msg-tmp rm -f gri.cmd # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ��������������������������������������������������������������������������������������������������������������gri/src/GriPath.cc����������������������������������������������������������������������������������0000644�0001750�0001750�00000034416�13147557614�012464� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2010 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // Classes for Gri. See gr_coll.hh for docs //#define DEBUG_GR_COLL 1 // uncomment to debug #include #include #include #include "GriPath.hh" #include "superus.hh" #include "gr.hh" #include "extern.hh" #include "gr_coll.hh" #include "defaults.hh" extern FILE *_grPS; extern FILE *_grSVG; static const int CAPACITY_DEFAULT = 32; double missing_value = -999.0; // in case not gri static void ps_begin_path(double width, char s_or_f); static int straighten_curve(double *x, double *y, GriPath::type *a, unsigned int length, double allow); GriPath::GriPath() { capacity = CAPACITY_DEFAULT; x = new double[capacity]; if (!x) OUT_OF_MEMORY; y = new double[capacity]; if (!y) OUT_OF_MEMORY; action = new GriPath::type[capacity]; if (!action) OUT_OF_MEMORY; depth = 0; } GriPath::GriPath(unsigned c) { capacity = c; x = new double[capacity]; if (!x) OUT_OF_MEMORY; y = new double[capacity]; if (!y) OUT_OF_MEMORY; action = new GriPath::type[capacity]; if (!action) OUT_OF_MEMORY; depth = 0; } GriPath::~GriPath() { delete [] x; delete [] y; delete [] action; } void GriPath::clear() { depth = 0; } void GriPath::expand() { if (!capacity) capacity = CAPACITY_DEFAULT; capacity *= 2; double *tmp; // Enlarge x tmp = new double[capacity]; if (!tmp) OUT_OF_MEMORY; unsigned int i; for (i = 0; i < depth; i++) tmp[i] = x[i]; delete [] x; x = tmp; // Enlarge y tmp = new double[capacity]; if (!tmp) OUT_OF_MEMORY; for (i = 0; i < depth; i++) tmp[i] = y[i]; delete [] y; y = tmp; // Enlarge action GriPath::type* tmp_c = new GriPath::type[capacity]; if (!tmp_c) OUT_OF_MEMORY; for (i = 0; i < depth; i++) tmp_c[i] = action[i]; delete [] action; action = tmp_c; } void GriPath::push_back(double xx, double yy, char a) { while (depth >= capacity - 1) expand(); x[depth] = xx; y[depth] = yy; switch (a) { case 'm': action[depth] = moveto; break; case 'l': action[depth] = lineto; break; default: fprintf(stderr, "INTERNAL error at GriPath.cc line %d (a path action is neither 'moveto' nor 'lineto')\n", __LINE__); exit(99); } depth++; } unsigned GriPath::size() { return depth; } static void ps_begin_path(double width, char s_or_f='s') // Q: what's with this width=-1 condition?? { switch (_output_file_type) { case postscript: case gif: set_ps_color('p'); if (width != -1) { fprintf(_grPS, "1.0 i %d J %d j %.3f w 10.0 M [", _griState.line_cap(), _griState.line_join(), width); } else { fprintf(_grPS, "1.0 i %d J %d j %.3f w 10.0 M [", _griState.line_cap(), _griState.line_join(), _griState.linewidth_line()); } for (unsigned int i = 0; i < _dash.size(); i++) fprintf(_grPS, "%.3f ", _dash[i] * PT_PER_CM); fprintf(_grPS, "] %d d\n", int(_dash.size())); break; case svg: fprintf(_grSVG, "\n 0) fprintf(stderr, "%s:%d:gr_begin_path() is ignoring dash type for SVG output\n", __FILE__,__LINE__); break; } } void GriPath::stroke(units the_units, double width, bool closepath) { stroke_or_fill('s', the_units, width, closepath); bounding_box_update(bounding_box(the_units)); } void GriPath::fill(units the_units, bool closepath) { stroke_or_fill('f', the_units, -1.0, closepath); bounding_box_update(bounding_box(the_units)); } void GriPath::stroke_or_fill(char s_or_f, units the_units, double width, bool closepath) { double page_height_pt = gr_page_height_pt(); if (depth < 1) return; const unsigned int max_length = GR_POINTS_IN_PS_PATH - 1; // If no 'lineto' in the path, ignore it completely ... unsigned int i; for (i = 0; i < depth; i++) if (action[i] == GriPath::lineto) break; if (i == depth) return; // if (_output_file_type != postscript) { // fprintf(stderr, "%s:%d:stroke_or_file() is broken on non-postscript file output\n", __FILE__,__LINE__); // } // must be some data. Process island by island double *xc = new double[depth]; if (!xc) OUT_OF_MEMORY; double *yc = new double[depth]; if (!yc) OUT_OF_MEMORY; GriPath::type *ac = new GriPath::type[depth]; if (!ac) OUT_OF_MEMORY; unsigned int start = 0, stop; do { // Gobble to first 'm' not at beginning xc[0] = x[start]; yc[0] = y[start]; ac[0] = action[start]; stop = depth; for (i = start + 1; i < depth; i++) { if (char(action[i]) == 'm') { stop = i; break; } else { xc[i - start] = x[i]; yc[i - start] = y[i]; ac[i - start] = action[i]; } } unsigned int length = stop - start; // If too many points, chop some. double allow = 0.005; // initial allowed distance off curve, cm unsigned int iteration = 0, max_iteration = 20; char msg[1000]; while (0&&iteration < max_iteration && length > max_length) { if (iteration == 0) { if (s_or_f == 'f') sprintf(msg, "`draw curve filled' can't have > %d points in a", max_length); else sprintf(msg, "`draw curve' can't have > %d points in a", max_length); warning(msg); sprintf(msg, "\ curve, owing to a limitation of PostScript. FYI, the\n\ curve starts with the coordinate pairs\n\ (%f, %f), (%f, %f), ...\n\ and has %d points.", x[start], y[start], x[start + 1], y[start + 1], length); ShowStr(msg); ShowStr(" Gri will now remove nearly co-linear\n"); ShowStr(" points, in an iterative triplet-wise fashion.\n"); } length = straighten_curve(xc, yc, ac, length, allow); sprintf(msg, " Iteration %2d: removed points %.2f mm from curve, shortening to %d.\n", iteration, 10.0 * allow, length); ShowStr(msg); allow *= 1.414213562; iteration++; } if (iteration >= max_iteration) { sprintf(msg, "\ `draw curve filled' didn't get a small enough curve even after %d\n\ iterations. Your PostScript interpreter may fail\n", iteration - 1); warning(msg); } if (length > 1) { ps_begin_path(width, s_or_f); if (the_units == units_user) { // convert user -> cm for (i = 0; i < length; i++) { double xcm, ycm; gr_usertocm(xc[i], yc[i], &xcm, &ycm); xc[i] = xcm; yc[i] = ycm; } } else if (the_units == units_pt) { // convert pt -> cm for (i = 0; i < length; i++) { xc[i] /= PT_PER_CM; yc[i] /= PT_PER_CM; } } ac[0] = GriPath::moveto; for (i = 0; i < length; i++) { if (_warn_offpage && ( xc[i] < OFFPAGE_LEFT || xc[i] > OFFPAGE_RIGHT || yc[i] < OFFPAGE_BOTTOM || yc[i] > OFFPAGE_TOP)) { warning("Gri drew a point that is offpage."); } switch (ac[i]) { case GriPath::moveto: // moveto (skip multiple) #if 0 if (i < length - 1 && ac[i + 1] == GriPath::moveto) continue; #endif switch (_output_file_type) { case postscript: fprintf(_grPS, "%.2f %.2f m\n", xc[i] * PT_PER_CM, yc[i] * PT_PER_CM); break; case svg: fprintf(_grSVG, "M%.2f %.2f\n", xc[i] * PT_PER_CM, page_height_pt - yc[i] * PT_PER_CM); break; case gif: break; } break; case GriPath::lineto: // lineto (skip identical) #if 0 if (i < length - 1 && ac[i + 1] == GriPath::lineto && xc[i] == xc[i + 1] && yc[i] == yc[i + 1]) continue; #endif switch (_output_file_type) { case postscript: fprintf(_grPS, "%.2f %.2f l\n", xc[i] * PT_PER_CM, yc[i] * PT_PER_CM); break; case svg: fprintf(_grSVG, "L%.2f %.2f\n", xc[i] * PT_PER_CM, gr_page_height_pt() - yc[i] * PT_PER_CM); break; case gif: break; } break; } } switch(_output_file_type) { case postscript: if (s_or_f == 'f') { fprintf(_grPS, "h\n"); fprintf(_grPS, "F\n"); } else { if (closepath) fprintf(_grPS, "h\n"); fprintf(_grPS, "S\n"); } fprintf(_grPS, "%% END GriPath stroke/fill\n"); break; case svg: if (s_or_f == 'f') { ; //fprintf(stderr, "%s:%d ERROR - cannot fill paths in SVG mode\n", __FILE__,__LINE__); } else { if (closepath) fprintf(stderr, "%s:%d ERROR - cannot close paths in SVG mode\n", __FILE__,__LINE__); } fprintf(_grSVG, "\"/>\n\n"); break; case gif: break; } } start = stop /*+ 1*/; // point at last, which is 'm' } while (stop < depth); delete [] xc; delete [] yc; delete [] ac; _drawingstarted = true; } // Remove points in curve which lie within 'allow' centimeters // a line connecting the points before and after. // BUG: I'm not sure of missing-value behaviour. int straighten_curve(double *x, double *y, GriPath::type *a, unsigned int length, double allow) { if (length < 3) return length; double a1, a2, b1, b2, c1, c2; // in points allow *= PT_PER_CM; std::vector remove; unsigned int i; for (i = 0; i < length; i++) remove.push_back(false); double A, cos_theta; double ab, ac; // distances a<->b and a<->c remove[0] = false; // Keep endpoints remove[length - 1] = false; for (i = 1; i < length - 1; i++) { if (remove[i - 1]) { // avoid huge holes remove[i] = false; continue; } gr_usertopt(x[i - 1], y[i - 1], &a1, &a2); // last gr_usertopt(x[i], y[i], &b1, &b2); // this gr_usertopt(x[i + 1], y[i + 1], &c1, &c2); // next ab = sqrt((a1 - b1) * (a1 - b1) + (a2 - b2) * (a2 - b2)); if (ab == 0.0) { remove[i] = true; continue; } ac = sqrt((a1 - c1) * (a1 - c1) + (a2 - c2) * (a2 - c2)); if (ac == 0.0) { remove[i] = false; continue; } cos_theta = ((a1 - b1) * (a1 - c1) + (a2 - b2) * (a2 - c2)) / ab / ac; if (cos_theta < 1.0) // roundoff protection A = ab * sqrt(1.0 - cos_theta * cos_theta); else A = 0.0; if (A <= allow) { remove[i] = true; } else { remove[i] = false; } } // Very SLOW int new_length = length; for (i = length - 1; i + 1 > 0; i--) { if (remove[i]) { new_length--; int ir; for (ir = i; ir < new_length; ir++) { x[ir] = x[ir + 1]; y[ir] = y[ir + 1]; a[ir] = a[ir + 1]; } } } return new_length; } void GriPath::print() { printf("Path @ %x is:\n", unsigned(long(this))); for (unsigned int i = 0; i < depth; i++) printf(" %f %f %c\n", x[i], y[i], action[i]); } void GriPath::translate(double dx, double dy) { for (unsigned int i = 0; i < depth; i++) { x[i] += dx; y[i] += dy; } } void GriPath::scale(double enlargement) { for (unsigned int i = 0; i < depth; i++) { x[i] *= enlargement; y[i] *= enlargement; } } // Rotate anticlockwise by indicated angle void GriPath::rotate(double degrees) { double c = cos(degrees / DEG_PER_RAD); double s = sin(degrees / DEG_PER_RAD); double oldx; for (unsigned int i = 0; i < depth; i++) { oldx = x[i]; x[i] = c * oldx - s * y[i]; y[i] = s * oldx + c * y[i]; } } void GriPath::trim() // remove junk { double *xx = new double[depth]; if (!xx) OUT_OF_MEMORY; double *yy = new double[depth]; if (!yy) OUT_OF_MEMORY; GriPath::type *aa = new GriPath::type[depth]; if (!aa) OUT_OF_MEMORY; unsigned newlen = 0; unsigned int i = 0; // Trim any junk at start while (action[i] == GriPath::moveto) i++; if (i > 0) // keep one 'moveto' though! i--; // Now trim interior. Keep first and last of any series though for (; i < depth; i++) { if ((i > 0 && i < depth - 1) && action[i - 1] == GriPath::moveto && action[i ] == GriPath::moveto && action[i + 1] == GriPath::moveto) continue; xx[newlen] = x[i]; yy[newlen] = y[i]; aa[newlen] = action[i]; newlen++; } // Finally, trim from end while(newlen && aa[newlen - 1] == GriPath::moveto) newlen--; //printf("trim started with :\n"); for (i = 0; i < depth; i++) printf("%.2f %.2f %s\n",x[i],y[i],action[i]==moveto?"moveto":"lineto"); for (i = 0; i < newlen; i++) { x[i] = xx[i]; y[i] = yy[i]; action[i] = aa[i]; } depth = newlen; //printf("trim created:\n"); for (i = 0; i < depth; i++) printf("%.2f %.2f %s\n",x[i],y[i],action[i]==moveto?"moveto":"lineto"); delete [] xx; delete [] yy; delete [] aa; } // Return bounding box for this path (in cm on page). // Assume already did trim() rectangle GriPath::bounding_box(units u) { rectangle *r = new rectangle; bool first = true; for (unsigned int i = 0; i < depth; i++) { if (gr_missingx(x[i]) || gr_missingy(y[i])) continue; double xx, yy; xy_to_cm(x[i], y[i], u, &xx, &yy); if (first) { r->set(xx, yy, xx, yy); first = false; } else { if (xx < r->llx()) r->set_llx(xx); if (r->urx() < xx) r->set_urx(xx); if (yy < r->lly()) r->set_lly(yy); if (r->ury() < yy ) r->set_ury(yy); } } if (_clipping_postscript && _clip_ps_xleft != _clip_ps_xright && _clip_ps_ybottom != _clip_ps_ytop) { //printf("BEFORE BBOX ll=(%f %f) ur=(%f %f)\n",r->llx(), r->lly(), r->urx(), r->ury()); if (r->llx() < (_clip_ps_xleft / PT_PER_CM)) r->set_llx(_clip_ps_xleft / PT_PER_CM); if (r->urx() > (_clip_ps_xright / PT_PER_CM)) r->set_urx(_clip_ps_xright / PT_PER_CM); if (r->lly() < (_clip_ps_ybottom / PT_PER_CM)) r->set_lly(_clip_ps_ybottom / PT_PER_CM); if (r->ury() > (_clip_ps_ytop / PT_PER_CM)) r->set_ury(_clip_ps_ytop / PT_PER_CM); } //printf("test BBOX ll=(%f %f) ur=(%f %f)\n",r->llx(), r->lly(), r->urx(), r->ury()); return *r; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/GMatrix.hh����������������������������������������������������������������������������������0000644�0001750�0001750�00000006272�13147557614�012512� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ //#define DEBUG_GRIMATRIX // debug // Store items in a matrix. Items can be builtins or classes. #if !defined(_GMatrix_h_) #define _GMatrix_h_ template class GriMatrix { public: GriMatrix(); ~GriMatrix(); void set_size(unsigned int num_cols, unsigned int num_rows); void set_value(T value); T& operator()(unsigned int col, unsigned int row); T operator()(unsigned int col, unsigned int row) const; protected: int haveData; unsigned int rows; // row < rows unsigned int cols; // col < cols T *contents; }; template GriMatrix::GriMatrix() { haveData = rows = cols = 0; } template GriMatrix::~GriMatrix() { if (haveData) delete [] contents; } template void GriMatrix::set_size(unsigned int num_cols, unsigned int num_rows) { if (num_rows == 0 && num_cols == 0) { if (haveData) delete [] contents; haveData = rows = cols = 0; } else { if (haveData) delete [] contents; rows = num_rows; cols = num_cols; contents = new T[rows * cols]; if (!contents) gr_Error("Out of memory (GriMatrix)"); haveData = 1; #ifdef DEBUG_GRIMATRIX printf("GriMatrix.set_size(rows=%d,cols=%d) start=%lx end=%lx\n",rows,cols,contents,contents + cols * rows - 1); #endif } } template void GriMatrix::set_value(T value) { for (unsigned int col = 0; col < cols; col++) for (unsigned int row = 0; row < rows; row++) contents[row + col * rows] = value; } template T& GriMatrix::operator()(unsigned int col, unsigned int row) { if (!haveData) gr_Error("Trying to get data from empty GriMatrix"); char errorMsg[100]; if (row > rows - 1) { sprintf(errorMsg, "\ Can't use row %d of matrix; valid range: 0-%d", row, rows-1); gr_Error(errorMsg); } if (col > cols - 1) { sprintf(errorMsg, "\ Can't use col %d of matrix; valid range: 0-%d", col, cols-1); gr_Error(errorMsg); } return contents[row + col * rows]; } template T GriMatrix::operator()(unsigned int col, unsigned int row) const { if (!haveData) gr_Error("Trying to get data from empty GriMatrix"); char errorMsg[100]; if (row > rows - 1) { sprintf(errorMsg, "\ Can't use row %d of matrix; valid range: 0-%d", row, rows-1); gr_Error(errorMsg); } if (col > cols - 1) { sprintf(errorMsg, "\ Can't use col %d of matrix; valid range: 0-%d", col, cols-1); gr_Error(errorMsg); } return contents[row + col * rows]; } #endif // _GMatrix_h_ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/gri.cmd-skel��������������������������������������������������������������������������������0000644�0001750�0001750�00000556620�13147557614�013027� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# gri - scientific graphic program (version VERSION) # Copyright 2016 by Dan E. Kelley; GPLv2+ licensing. # # NOTE: The linkages to `extern "C"' routines makes use a list of C # functions defined in the file tags.hh. `assert .condition. ["message"]' The condition may be a variable, a synonym, or an RPN expression. If this condition is true (i.e. evaluates to a non-zero number), do nothing. If the condition is false, the program will terminate with an error condition (in unix, it will terminate with a non-zero exit code). Before termination, a message will be printed, the form of which depends on the optional `"msg"' string. If no `"msg"' string is given, the the printed message will indicate the name of the command-file and the line at which the assert command was encountered. If a `"msg"' string is given, and if it ends in a newline (`"\\n"'), then this string is printed. If a `"msg"' string is given, and if it does not end in `"\\n"', then the string is printed along with an indication of the location in the command-file. (Perl users will recognize this as being patterned on the `"die"' command.) { extern "C" bool assertCmd(void); } `cd [\pathname]' If a pathname specified, change to that directory. Normal unix filenames are used, according to the C-shell convention; thus `cd ~/src' and `cd $HOME/src' are equivalent. You may specify relative pathnames as in `cd ../sister_directory'. If no \pathname directory path specified, go to the home directory, exactly as `cd ~' and `cd $HOME' do. { extern "C" bool cdCmd(void); } `close [\filename]' If no filename is specified, close the most recently opened data-file; otherwise close indicated file. { extern "C" bool closeCmd(void); } `convert columns to grid [neighbor | {objective|boxcar .xr. .yr. [.n. .e.]} | {barnes [.xr. .yr. .gamma. .iter.]}]' Various forms exist: `convert columns to grid' `convert columns to grid neighbor' `convert columns to grid boxcar [.xr. .yr. [.n. .e.]]' `convert columns to grid objective [.xr. .yr. [.n. .e.]]' `convert columns to grid barnes [.xr. .yr. .gamma. .iter.]' All these commands ``grid'' columnar (x,y,z) data. That is, they fill up a grid based on some form of interpolation of the possibly randomly spaced columnar data. There are many methods in existence for doing this, and Gri implements several of them as alternatives. The grid will have been defined by commands such as `set x grid', `set y grid', `read grid x' and `read grid y'. As of version 2.1.9, Gri does not require a grid to have been pre-defined; it will create a regular 20 by 20 grid, spanning the range of x and y data, as a default. This is a good starting point in many cases. *`neighbor' method* Very fast but very limited. *`boxcar' method* Slower but a lot better. Still, this can produce noisy contours if the data are not densely and uniformly ditributed through domain. *`objective' method* Somewhat slower than `boxcar', but produces better fields since the averaging function is smooth. *`barnes' method* Somewhat slower than `objective', but only by a constant factor (that is, independent of number of data). This produces by far the best results, since the smoothing function has variable spatial scale. This is the default method if no method is supplied. All except the `neighbor' method may take optional arguments to define the x and y scales of the smoothing function (called `.xr.' and `.yr.'). (The barnes method has two other optional arguments - see below.) If you do not supply these arguments, Gri will make a reasonable choice and inform you of its decision. Many users find that it's best to `convert columns to grid' with no additional parameters as a first step, to get advice on values to use for the optional parameters. The default `.xr.' and `.yr.' are calculated by determining the span in x and in y directions, and dividing each by the square root of the number of data points. These numbers are then multiplied by the square root of 2. The method is as proposed by S. E. Koch and M. DesJardins and P. J. Kocin, 1983. "An interactive Barnes objective map anlaysis scheme for use with satellite and conventional data,", J. Climate Appl. Met., vol 22, p. 1487-1503. If `.xr.' and `.yr.' were supplied but negative, then Gri interprets this as an instruction to modify the default values, described in last paragraph, by multiplying by the absolute values of the negative numbers given, instead of muliplying by square root of 2. If the `chatty' option is turned on, then Gri will print out the values of (dx,dy) that it has calculated; this gives you some guidance for supplying your own values of `(.xr.,.yr.)' if you choose to supply them yourself. It is also a good idea to let these parameters be a guide for your grid spacing; for example, Koch et al., 1983, suggest using grid spacing of 0.3 to 0.5 times (dx,dy). And now, the details ... * *"Neighbor" method* The `convert columns to grid neighbor' method is useful for (x,y,z) data which are already gridded (i.e., for which x and y take only values which lie on the grid), or nearly gridded. The (x,y,z) data are scanned from start to finish. For each data point, the nearest grid point is found. Nearness is measured as Cartesian distance, with scale factor given by the distance between the first and second grid points. In other words, distance is given by D=sqrt(dx*dx+dy*dy) where dx is ratio of distance from data point to nearest grid point, in x-units, divided by the difference between the first two elements of the x-grid, and dy is similarly defined. Once the grid point nearest the data point is determined, Gri adds the z-value to a list of possible values to store in the grid. Once the entire data set has been scanned, Gri then goes back to each grid point, and chooses the z-value of the data point that was nearest to the grid point - that is, it stores the z value of the (x,y,z) data triplet which has minimal D value. Note that this scheme is independent of the order of the data within the columns. The `neighbor' method is useful when the data are already pre-gridded, meaning that the (x,y,z) triplets have x and y values which are already aligned with the grid. *Computational cost:* For `P' data points, `X' x-grid points, and `Y' y-grid points, the method calculation cost is proportional to `P*[log2(X)+log2(Y)]' where `log2' is logarithm base 2. As discussed below, this is often several orders of magnitude lower than the other methods of gridding. * *"Objective" method* In the `objective' method, a smoothing technique known as objective mapping is applied. It is essentially a variable-size smoothing filter of approximately Gaussian shape (it is method "two" of Levy and Brown [1986 J. Geophysical Res. vol 91, p 5153-5158]) The parameters `.xr.' and `.yr.' give the width of the filter. With the optional additional parameters `.n.' and `.e.' are specified, then grid values will be assigned the missing value if there are fewer than `.n.' (x,y,f) data in the neighborhood of the gridpoint, even after enlarging the neighborhood by widening and heightening by root(2) up to `.e.' times. (The enlargement is only done if fewer than `.n.' points are found.) If these parameters are not specified in the command, then values `.n.'=5 and `.e.'=1 are assumed. The special case where `.e.' is negative tells Gri to *always* fill in each grid point, by extending the neighborhood to enclose the entire dataset if necessary. *Computational cost:* For `P' data points, `X' x-grid points, and `Y' y-grid points, the method calculation cost is proportional to `P*X*Y'. Given that `X' and `Y' are determined by the requirement for smoothness of contours and the size of the graph, they are more or less fixed for all applications. They are often in the range of 20 or so - on 10 cm wide graph, this yields a contour footprint of 1/2 cm, which is often small enough to yield smooth contours. Therefore, the computational cost scales linearly with the number of data points. Compared to the "neighborhood" method, this is more costly by a factor of `X*Y/log_2(X)/log_2(Y)' which is normally in the range from 20 to 50. * *"Boxcar" method* In the `boxcar' method, the grid points are derived from simple averages calculated in rectangles `.xr.' wide and `.yr.' tall, centred on the gridpoints. The `.n.' and `.e.' parameters have similar meanings as in the "objective" method. *Computational cost:* Roughly same as `objective' method described above. * *"Barnes" method* This is the default scheme. The Barnes algorithm is applied. If no parameters are specified, `.xr.' and `.yr.' are determined as above, with `.gamma.' set to 0.5, and `.iter.' set to 2 so that two iterations are done. On successive iterations, the smoothing lengthscales `.xr' and `.yr' are each reduced by multiplying by the square root of `.gamma.'. Smaller `.gamma.' values yield better resolution of small-scale features on successive iterations. Koch et al., 1983, recommend using a `.gamma.' value in the range 0.2 to 1, with two iterations. Provided that all the grid points are close enough to at least some column data, the entire grid is filled. But if `.xr.' and `.yr.' are too small, the weighting function can fall to zero, since it is exponential in the sum of the squares of the x-distance/`.xr.' and the y-distance/`.yr.'; in that case missing values result at those grid points. On a 32 bit computer, the weighting function will fall to zero when x-distance/`.xr.' and y-distance/`.yr.' are less than about 15 to 20. If weights have been read in, then these values are applied in addition to the distance-based weighting. (The normalization means that weights for two data points of e.g. 1 and 2 will yield the same result as if the weights had been given as 10 and 20.) The computational cost is proportional to `P*P+P*X*Y)'. For large datasets, the first term (which results from the necessity to interpolate not only to the grid points but also to the data points) overwhelms the second term. For example, `X' and `Y' are normally less than approximately 20. This value is common because on a graph with a 10 cm axis, this yields a contour footprint of 1/2 cm, which is normally fine enough to get smooth contours. Therefore, if there are more than 400 data points, the `P*P' term exceeds the `P*X*Y' term. A data set may well have thousands of data points, and in this case the computational cost is approximately `P*P'. This is, therefore, a "order n-squared" algorithm, and it is therefore, by it's very nature, slow. The other methods, "neighbor", "objective" and "boxcar" are "order n" algorithms, so that "barnes" is much more costly for large data sets. As an example, for a dataset with a `P' of 1000, and with `X' and `Y' of 20, "barnes' is slower than "neighbor" by a factor of about 100. (The ratio increases to 300 for 5000 points.) Compared to "objective" and "boxcar," however, "barnes" is slower by a factor of 13 for 5000 data points and 26 for 10000 data points. For most practical purposes, therefore, the many advantages of "barnes" over "objective" and "boxcar" far outweigh the additional computational cost. On the other hand, the very swift "neighbor" method,is only suitable for very particular types of data sets. References: (1) Section 3.6 in Roger Daley, 1991, "Atmospheric data analysis," Cambridge Press, New York. (2) S. E. Koch and M. DesJardins and P. J. Kocin, 1983. "An interactive Barnes objective map anlaysis scheme for use with satellite and conventional data,", J. Climate Appl. Met., vol 22, p. 1487-1503. The Barnes algorithm is as follows: The gridded field is estimated iteratively. Successive iterations retain largescale features from previous iterations, while adding details at smaller scales. The first estimate of the gridded field, here denoted `G_(ij)^0' (the superscript indicating the order of the iteration) is given by a weighted sum of the input data, with `z_k' denoting the k-th `z' value. sum_1^n W_(ijk)^0 z_k G_(ij)^(0) = ---------------------- sum_1^n W_(ijk)0 where the notation `sum_1^n' means to sum the elements for the `k' index ranging from 1 to `n'. The weights `W_(ijk)^0' are defined in terms of a Guassian function decaying with distance from observation point to grid point: ( (x_k - X_i)^2 (y_k - Y_j)^2 ) W_(ijk)^0 = exp ( - --------------- - --------------- ) ( L_x^2 L_y^2 ) Here `L_x' and `L_y' are lengths which define the smallest `(x,y)' scales over which the gridded field will have significant variations (for details of the spectral response see Koch et al. 1983). Note: if the user has supplied weights, then these are applied in addition to the distance-based weights. That is, `w_i W_(ijk)' is used instead of `W_(ijk)'. The second iteration derives a grid `G_(ij)^1' in terms of the first grid `G_(ij)^0' and "analysis values" `f_k^0' calculated at the `(x_k,y_k)' using a formula analogous to that above. (Interpolation based on the first estimate of the grid `G_(ij)^0' can also be used to calculate `f_k^0', with equivalent results for a grid of sufficiently fine mesh.) In this iteration, however, the weighted average is based on the difference between the data and the gridded field, so that no further adjustment of the gridded field is done in regions where it is already close to through the observed values. The second estimate of the gridded field is given by sum_1^n W_(ijk)^1 (f_k - f_k^0) G_(ij)^1 = G_(ij)^0 + ------------------------------- sum_1^n W_(ijk)^1 where the weights `w_(ik,1)' are defined by analogy with `W_(ik)^0' except that `L_x' and `L_y' are replaced by `gamma^(1/2)L_x' and `gamma^(1/2)L_y'. The nondimensional parameter `gamma' (`0 tmp else if {"\.system." == "vax"} system awk/COMMANDS =\ "BEGIN { for (x = \xmin; x <= \xmax; x += \xinc) {print (x, \function)} \ } " \ /OUTPUT=TMP NL: end if open tmp read columns x y close tmp if {"\.system." == "unix"} system rm tmp else if {"\.system." == "vax"} system DELETE TMP.*;* end if if .must_clean_up_xmin. delete \xmin end if if .must_clean_up_xmax. delete \xmax end if if .must_clean_up_xinc. delete \xinc end if delete .must_clean_up_xmin. delete .must_clean_up_xmax. delete .must_clean_up_xinc. } `create image grayscale banded .band.' Make a banded grayscale with in units of .band. pixel values each. Thus, pixel values 0 to (.band. - 1) on the image will map to 0, while values from .band. to (2 * .band. - 1) will map to .band., etc. For example, .band. = 2 gives grayscale = (0 0 2 2 4 4 6 6 ... 252 252 254 254). { if {rpn \.words. 5 ==} \band = "\.word4" else show "ERROR: Require 4 words, but got \.words. words." show traceback quit end if system awk 'BEGIN \ { \ for (i = 0; i < 256; i++) \ { \ printf ("%d ", \band * int (i / \band)) \ } \ printf ("\n") \ }' \ > GRAYSCALE.TMP open GRAYSCALE.TMP read image grayscale close system rm GRAYSCALE.TMP delete \band } `create image greyscale banded .band.' Alternate spelling of grayscale. { if {rpn \.words. 5 ==} \band = "\.word4" else show "ERROR: Require 4 words, but got \.words. words." show traceback quit end if system awk 'BEGIN \ { \ for (i = 0; i < 256; i++) \ { \ printf ("%d ", \band * int (i / \band)) \ } \ printf ("\n") \ }' \ > GRAYSCALE.TMP open GRAYSCALE.TMP read image grayscale close system rm GRAYSCALE.TMP delete \band } `debug [.n.] | [clipped values in draw commands] | off' With no optional parameters, sets the value of `..debug..' to 1. (Normally, `..debug..' is 0.) You may use `..debug..' in if statements, etc. Note that `..debug..' is also set to 1 when gri is invoked with the commandline switch `-d'. With `.n.' specified, `..debug..' is set to `.n.'; a value of zero for `.n.' turns debugging off, while 1 turns it on. Higher values may be used for deeper debugging, if you choose: if \{rpn ..debug.. 2 <} # Code to do if ..debug.. is greater than 2. end if Note that you can assign to `..debug..' as you can to any other variable; `debug .n.' is equivalent to `..debug.. = .n.'. With the `clipped' option, Gri prints any clipped data encountered during any `draw ...' commands, EXCEPT in the case of `postscript' clipping, where no check is possible. (Note that `..debug..' is not affected.) All these forms of debugging are cancelled by `debug off'. { extern "C" bool debugCmd(void); } `delete {.variable. | \synonym [...]} | columns [{randomly .fraction.}|{where missing}] | grid | {[x|y] scale}' Delete some item or characteristic. `delete .variable.' Delete definition of variable `.variable.', making it undefined. `delete \synonym' Delete definition of synonym `\synonym', making it undefined. `delete columns' Delete column data. `delete columns randomly .fraction.' Randomly select fraction `.fraction.' of the non-missing column data, and designate them as being missing. `delete grid' Delete grid data. `delete scale' Delete scales for both x and y, so next `read columns' will set it. `delete x scale' Delete scales for x, so next `read columns' will set it. `delete y scale' Delete scales for y, so next `read columns' will set it. { extern "C" bool deleteCmd(void); } `differentiate {x|y wrt index|y|x} | {grid wrt x|y}' Differentiate column data or grid data. Only the `x' and `y' columns may be differentiated. They may be differentiated either with respect to ("wrt") the index (forming a first difference) or with respect to the other column. The derivative is done with the backwards-difference algorithm. Grid data may differentiated with respect to `x' direction or `y' direction. Grid differentiation is done with a centred difference, with endpoints being assigned the derivative of the neighboring interior point (so that the second derivative is zero at the edges of the grid). { extern "C" bool differentiateCmd(void); } `draw arc [filled] .xc_cm. .yc_cm. .r_cm. .angle_1. .angle_2.' Draw an "arc", that is, a portion of a circle. The center of the circle is at the coordinate (`.xc_cm.', `.yc_cm.'), and the circle radius is `.r_cm.', all three quantities being in cm on the page, _not_ in user-units. The arc starts at angle `.angle_1.', measured in degrees counterclockwise from a horizontal line, and extends to angle `.angle_2.', in the same units. If the keyword `filled' is present, the arc is filled with the current color. Otherwise it is drawn with the current "curve" linewidth. { extern "C" bool draw_arcCmd(void); } `draw arrow from .x0. .y0. to .x1. .y1. [cm]' With no optional parameters, draw an arrow from (`.x0.', `.y0.') to (`.x1.', `.y1.'), where coordinates are in user units. The arrow head will be at (`.x1.', `.y1.'), and its size is as set by most recent call to `set arrow size'. With the `cm' keyword present, the coordinates are in centimetres on the page. NOTE: This will not cause auto-drawing of axes. { extern "C" bool draw_arrow_from_toCmd(void); } `draw arrows' Draw a vector field consisting of arrows emanating from the coordinates stored in the (x, y) columns. The lengths and orientations of the arrows are stored in the (u, v) columns, and the scale for the (u,v) columns is set by `set u scale' and `set v scale'. SEE ALSO: (1) To set arrow size, use `set arrow size'. (2) To get a single arrow, for labelling plots, etc, use the `draw arrow from .x0. .y0. to .x1. .y1. [cm]' command. { extern "C" bool draw_arrowsCmd(void); } `draw axes if needed' Draw axes frame if required. Used within gri commands that auto-draw axes. NOTE: this should only be done by developers. { extern "C" bool draw_axes_if_needed(void); } `draw axes [.style.|frame|none]' With no style (`.style.') specified, draw x-y axes frame labelled at left and bottom. The value of `.style.' determines the style of axes: `.style. = 0' Draw x-y axes frame labelled at left and bottom `.style. = 1' Draw axes without tics at top and right `.style. = 2' Draw axes frame with no tics or labels With the keyword `frame' specified, draw axes frame with no tics or labels (just like `.style.' = 2). With the keyword `none' specified, prevent Gri from automatically drawing axes when drawing curves. { extern "C" bool draw_axesCmd(void); } `draw border box [.xleft. .ybottom. .xright. .ytop. .width_cm. .brightness.]' Draw gray box, as decoration or alignment key for pastup. The box, with outer lower left corner at (`.xleft.', `.ybottom.') and outer upper right corner at (`.xright'., `.ytop.') - both coordinates being in centimetres on the page - is drawn with thickness `.width_cm.' and with graylevel `.brightness.' (0 for black; 1 for white). The gray line is drawn inside the box. After drawing the gray line, a thin black line is drawn along the outside edge. If the geometry is not specified with `.xleft.' and the other parameters, then a reasonable margin is used around the present axes area, and the defaults (`.border.' = 0.2, `.brightness.' = 0.75) are used. NOTE: This command does not cause auto-drawing of axes. { if {rpn \.words. 3 ==} .xleft. = {rpn ..xmargin.. "M" width 5 * -} .ybottom. = {rpn ..ymargin.. "M" ascent 6 * -} .xright. = {rpn ..xmargin.. ..xsize.. + "M" width 2.0 * +} .ytop. = {rpn ..ymargin.. ..ysize.. + "M" width 2.0 * +} .width_cm. = 0.2 .brightness. = 0.75 else if {rpn \.words. 9 ==} .xleft. = \.word3. .ybottom. = \.word4. .xright. = \.word5. .ytop. = \.word6. .width_cm. = \.word7. .brightness. = \.word8. else show "ERROR: Require 3 or 9 words, but got \.words. words." show traceback quit end if # # Save old values of things that will be changed. .old_graylevel. = ..graylevel.. .old_linewidth. = ..linewidth.. set graylevel .brightness. set line width {rpn .width_cm. cmtopt} .tmp. = {rpn .ybottom. ..linewidth.. 2 / pttocm +} draw line from .xleft. .tmp. to .xright. .tmp. cm # lower edge .tmp. = {rpn .xleft. ..linewidth.. 2 / pttocm +} draw line from .tmp. .ybottom. to .tmp. .ytop. cm # left edge .tmp. = {rpn .ytop. ..linewidth.. 2 / pttocm -} draw line from .xleft. .tmp. to .xright. .tmp. cm # upper edge .tmp. = {rpn .xright. ..linewidth.. 2 / pttocm -} draw line from .tmp. .ybottom. to .tmp. .ytop. cm # right edge # # Draw thin black border. set line width 0.25 set graylevel black draw box .xleft. .ybottom. .xright. .ytop. cm # # Return to old values. set line width .old_linewidth. set graylevel .old_graylevel. # # Clean up local storage. delete .tmp. delete .old_graylevel. delete .old_linewidth. delete .brightness. delete .width_cm. delete .xleft. delete .ybottom. delete .xright. delete .ytop. } `draw box filled .xleft. .ybottom. .xright. .ytop. [cm|pt]' Draw filled box spanning indicated range, with lower-left corner at (`.xleft.', `.ybottom.') and upper-right corner at (`.xright.', `.ytop.'). The corners are specified in user coordinates, unless the optional `cm' or 'pt' keyword is present, in which case they are in centimetres or points on the page. An error will result if you specify user coordinates but they aren't defined yet. No checking is done on the rectangle; for example, there is no requirement that `.xleft.' be to the left of `.xright.' in your coordinate system. NOTE: if the box is specified in user units, this command will cause auto-drawing of axes, but not if the box is specified in cm or pt units. { extern "C" bool draw_box_filledCmd(void); } `draw box .xleft. .ybottom. .xright. .ytop. [cm|pt]' Draw box spanning indicated range, with lower-left corner at (`.xleft.', `.ybottom.') and upper-right corner at (`.xright.', `.ytop.'). The corners are specified in user coordinates, unless the optional `cm' or `pt' keyword is present, in which case they are in centimetres or points on the page. An error will result if you specify user coordinates but they aren't defined yet. No checking is done on the rectangle; for example, there is no requirement that `.xleft.' be to the left of `.xright.' in your coordinate system. { extern "C" bool draw_boxCmd(void); } `draw circle with radius .r_cm. at .x_cm. .y_cm.' Draw circle of specified radius (in cm) at the specified location (in cm on the page). { extern "C" bool draw_circleCmd(void); } `draw contour [{.value. [unlabelled|{labelled "\label"}]} | {.min. .max. .inc. [.inc_unlabelled.] [unlabelled]}]' This command draws contours based on the "grid" data previously read in by a `read grid data' command or created by gridding column data with a `create grid from columns' command. If the grid data don't exist, or if the x and y locations of the grid points do not exist (see `set x grid', `set y grid', `read grid x' and `read grid y'), Gri will complain. With no optional parameters, draw labelled contours at an interval that is picked automatically based on the range of the data. With a single numerical value (`.value.'), draw the indicated contour. With the addition of `labelled "\label"', put the indicated label instead of a numeric label. This can be useful, say, for using scientific notation instead of computer notation for exponents. For example, you might do something like `draw contour 1e-5 labelled "10$^\{-5}$"' or maybe `draw contour 1e-5 labelled "critical value"'. With (`.min.', `.max.' and `.inc.') given, draw contours for z(x,y) = `.min.', z(x,y) = `.min. + .inc.', z(x,y) = `.min. + 2*.inc.', ..., z(x,y) = `.max.' With the additional value `.inc_unlabelled.' specified, extra unlabelled contours are drawn at this finer interval. With the optional parameter `unlabelled' at the end of any form of this command (except the `labelled "\label"' variation, of course), Gri will not label the contour(s). *Hint:* It can be effective to draw contours at a certain interval with labels, and a thicker pen, e.g. set line width rapidograph 3x0 draw contour -2 5 1 0.25 set line width rapidograph 1 draw contour -2 5 1 { extern "C" bool draw_contourCmd(void); } `draw curve overlying' Like `draw curve', except that before drawing, the area underneath the curve (+/- one linewidth) is whited out. This clarifies graphs where curves overly other curves or the axes. SEE ALSO: `draw curve'. { state save set dash off set color white set line width {rpn ..linewidth.. 3 *} draw curve # clean space underneath state restore draw curve # draw actual curve } `draw curve filled [to {.y. y} | {.x. x}]' The form `draw curve filled ...' draws filled curves. If `to .value.' is not specified, fill the region defined by the x-y points using the current paint colour (see `set graylevel'). To complete the shape, an extra line is drawn from the first and last point. The form `draw curve filled to .y. y' fills the region between y(x) and y = `.y.'; do not connect the first and last points as in the case where `to .yvalue.' is not specified. The form `draw curve filled to .x. x' fills the region between x(y) and x = `.x.' { extern "C" bool draw_curveCmd(void); } `draw curve' Draws a curve connecting the points (x,y), which have been read in by a command like `read columns x y'. Line segments are drawn between all (x,y) points, except: (1) no line segments are drawn to any missing data (see `set missing value'), and (2) if clipping is turned on (see `set clip on'), no line segments are drawn outside the clipping region. SEE ALSO: `draw curve overlying' { extern "C" bool draw_curveCmd(void); } `draw essay "text"|reset' Draw indicated text on the page. Succeeding calls draw text further and further down the page, starting at the top. The current font size is used; to alter this, do `set font size' before calling `draw essay'. When `reset' is present instead of text, the drawing position is reset to the top of the page. Use this after a `new page' command to ensure that the next text lines will appear at the top of the page as expected. EXAMPLE: set font size 2 cm draw essay "Line 1, at top of page" draw essay "Line 2, below top line" { # Check for proper format, and give error message if not. if {rpn \.words. 3 ==} # Check to see if this is the first call; if so, initialize location. if {"\.word2." == "reset"} # Reset .top_of_page. and return. if ..landscape.. .top_of_page. = {rpn 8.5 2.54 * 1 -} else .top_of_page. = {rpn 11. 2.54 * 1 -} end if return end if # Last word is not `reset', so draw it. if {rpn ".top_of_page." defined !} # if ..landscape.. .top_of_page. = {rpn 8.5 2.54 * 1 -} else .top_of_page. = {rpn 11. 2.54 * 1 -} end if end if .top_of_page. -= {rpn ..fontsize.. pttocm 1.5 *} draw label "\.word2." at 1 .top_of_page. cm else show "ERROR: Require 3 words, but got \.words. words." show traceback quit end if } `draw gri logo .x_cm. .y_cm. .height_cm. .style. \fgcolor \bgcolor' .style. style ======= =================== 0 stroke curve 1 fill with color \fgcolor, no background 2 fill with color \fgcolor it in tight box of color \bgcolor 3 as 2 but in square box 4 draw in \fgcolor on top of shifted copy in \bgcolor { extern "C" bool draw_gri_logoCmd(void); } `draw grid' Draw plus-signs at locations where grid data are non-missing. { extern "C" bool draw_gridCmd(void); } `draw image palette [axisleft|axisright|axistop|axisbottom] [left .left. right .right. [increment .inc.]] [box .xleft_cm. .ybottom_cm. .xright_cm. .ytop_cm.]' With no optional parameters, draw palette for image, placed above the current top showing values ranging from `.min_value.' to `.max_value.' as given in `set image range'. Optional keywords (`axisleft', etc) control the orientation of the palette, the default being `axisbottom'. The optional parameters `.left.' and `.right.' may be used to specify the range to be drawn in the palette. If the additional optional parameter `.inc.' is present, it specifies the interval between tics on the scale; if not present, the tics are at increments of 2 * (`.right.' - `.left'.). (If `.inc.' has the wrong sign, it will be corrected without warning.) When the optional `box' parameters are present, they prescribe the bounding box to contain the palette. The units are centimetres on the page. If these parameters are not present, the box will be drawn above the image plot. HINT: It is a good idea to make the palette range `.left.' to `.right.' extend a little beyond the range of full white and full black, since otherwise neither pure white nor pure black will appear in the colorbar. For example: set image grayscale black 0 white 1 increment 0.1 draw image palette left -0.1 right 1.1 increment 0.1 { extern "C" bool draw_image_paletteCmd(void); } `draw image grayscale [left .left. right .right. [increment .inc.]] [box .xleft_cm. .ybottom_cm. .xright_cm. .ytop_cm.]' Old name for `draw image palette' { extern "C" bool draw_image_paletteCmd(void); } `draw image histogram [box .xleft_cm. .ybottom_cm. .xright_cm. .ytop_cm.]' With no optional parameters, draw histogram of all unmasked parts of the image, placing it above the current top of the plot. When the `box' options are present, they specify the box (in centimetre coordinates on the page) in which the histogram plot is to be done. { extern "C" bool draw_image_histogramCmd(void); } `draw image' Draw black/white image made by `convert grid to image' or by `read image'. { extern "C" bool draw_imageCmd(void); } #* @param .P_sigma. = reference pressure for density @default 0dbar #* @param .P_theta. = reference pressure for temperature @default 0dbar `draw isopycnal [unlabelled] .density. [.P_sigma. [.P_theta.]]' Draw isopycnal curve for a temperature-salinity diagram. This curve is the locus of temperature and salinity values which yield seawater of the indicated density, at the indicated pressure. The UNESCO equation of state is used. For the results to make sense, the x-axis should be salinity and the y-axis should be either in-situ temperature or potential temperature. The `.density.' unit is kg/m^3. If the supplied value exceeds 100 it will be taken to indicate the actual density; otherwise it will be taken to indicate density minus 1000 kg/m^3. (Thus, 1020 and 20 each correspond to an actual density of 1020 kg/m^3.) The reference pressure for density, `.P_sigma.', is in decibars (roughly corresponding to meters of water depth). If no value is supplied, a pressure of 0 dbar (i.e. atmospheric pressure) is used. The reference pressure for theta, `.P_theta.', is in decibars, and defaults to zero (i.e. atmospheric pressure) if not supplied. This option is used if the y-axis is potential temperature referenced to a pressure other than the surface. Normally the potential temperature is, however, referenced to the surface, so that specifying a value for `.P_theta.' is uncommon. By default, labels will be drawn on the isopycnal curve; this may be prevented by supplying the keyword `unlabelled'. If labels are drawn, they will be of order 1000, or of order 10 to 30, according to the value of `.density.' supplied (see above). The label format defaults to "%g" in the C-language format notation, and may be controlled by `set contour format'. The label position may be controlled by `set contour label position' command (bug: only non-centered style works). Setting label position is useful if labels collide with data points. Labels are drawn in the whiteunder mode, so they can white-out data below. For this reason it is common to draw data points after drawing isopycnals. If the y-axis is in-situ temperature, the command should be called without specifying `.P_sigma.', or, equivalently, with `.P_sigma.' = 0. That is, the resultant curve will correspond to the (S,T) solution to the equation .density. = RHO(S, T, 0) where `RHO=RHO(S,T,p' is the UNESCO equation of state for seawater. This is a curve of constant sigma_T. If the y-axis is potential temperature referenced to the surface, `.P_theta.' should not be specified, or should be specified to be zero. The resultant curve corresponds to a constant value of potential density referenced to pressure `.P_sigma.', i.e. the (S,theta) solution to the equation .density. = RHO(S, theta, .P_sigma.) For example, with `.P_sigma.=0' (the default), the result is a curve of constant sigma_theta. If the y-axis is potential temperature referenced to some pressure other than that at the surface, `.P_theta.' should be supplied. The resultant curve will be the (S,theta) solution to the equation .density. = RHO(S, T', .P_sigma.) where T'=THETA(S, theta, .P_theta., .P_sigma.) where `THETA=THETA(S,T,P,Pref)' is the UNESCO formula for potential temperature of a water-parcel moved to a reference pressure of `Pref'. Note that `theta', potential temperature referenced to pressure `.P_theta.', is the variable assumed to exist on the y-axis. { extern "C" bool draw_isopycnalCmd(void); } `draw isospice .spice. [unlabelled]' Draw an iso-spice line for a "TS" diagram, using (S, T) data stored in files in a subdirectory named `iso-spice0' in a directory named by the environment variable `GRI_EOS_DIR'. You must set this environment variable yourself, in the normal unix way. If `GRI_EOS_DIR' is not defined, Gri looks in the directory `/data/po/ocean/EOS/iso0'; of course, this will work only for people on the same machine as the author. Only certain iso-spice lines are stored in these files, so only certain values of `.spice.' are allowed. They are 21.75, 22.00, 22.25, ..., 30.75. You must supply `.density.' in exactly this format (with 2 decimal places), or else Gri will not find the appropriate TS file, and will give a "can't open file" error. NB: isopycnals ranging from about 23.00 to 26.00 cross a TS diagram spanning 34 \.words. 4 < |} show "ERROR: Require 3 or 4 words, but got \.words. words." show traceback quit end if # don't have 3 or 4 words get env \gri_eos_dir GRI_EOS_DIR if {rpn "\gri_eos_dir" "" ==} \eos_file = "/data/po/ocean/EOS/iso-spice0/spice0_\.word2." else \eos_file = "\gri_eos_dir/iso-spice0/spice0_\.word2." end if if ..trace.. show "Plotting iso-spice lines in \eos_file" end if # ..trace.. open \eos_file read columns x y close if ..num_col_data.. draw curve if {rpn \.words. 4 ==} if {"\.word3." == "unlabelled"} # no label else # improper final word show "ERROR: Bad 4th word \"\.word3.\"; expecting \"labelled\"" show traceback quit end if # improper final word else # not 4 words if {rpn ..xlast.. ..xright.. - ..ylast.. ..ytop.. - >} # Put label above. draw label "\.word2." at \ {rpn ..xlast.. xusertocm "\.word2." width 0.35 * -} \ {rpn ..ytop.. yusertocm ..fontsize.. pttocm 0.7 * +} cm else # label at right # Put label to right. draw label "\.word2." at \ {rpn ..xright.. xusertocm ..fontsize.. pttocm 0.7 * +} \ {rpn ..ylast.. yusertocm ..fontsize.. pttocm 0.4 * -} cm end if # label at right end if else # iso-spice not in region show "WARNING from `draw isospice ...': iso-spice \.word2. not in clip region." end if # iso-spice not in region delete \gri_eos_dir \eos_file } `draw label boxed "\string" at .xleft. .ybottom. [cm]' Draw boxed label for plot, located with lower-left corner at indicated (x,y) position (specified in user units, or in cm on the page). The current font size and pen color are used. The geometry derives from the current font size, with the label being centered within the box. { if {rpn "\.word4." "at" !=} show "ERROR: Fifth word must be \"at\", not \"\.word4.\"" show traceback quit end if new .x. .y. new .draw_boxed_labelR. new .draw_boxed_labelG. new .draw_boxed_labelB. .draw_boxed_labelR. = ..red.. .draw_boxed_labelG. = ..green.. .draw_boxed_labelB. = ..blue.. if {rpn \.words. 7 ==} .x. = {rpn \.word5. xusertocm} .y. = {rpn \.word6. yusertocm} else if {rpn \.words. 8 ==} if {rpn "\.word7." "cm" !=} show "ERROR: Require 7th word to be `cm'" show traceback quit end if .x. = \.word5. .y. = \.word6. else show "ERROR: Require 7 or 8 words, but got \.words. words." show traceback quit end if # Coordinates now in cm .draw_boxed_label_offset. = {rpn ..linewidth.. pttocm 4 *} draw box filled \ {rpn .x. .draw_boxed_label_offset. +} \ {rpn .y. .draw_boxed_label_offset. -} \ {rpn .x. "MM\.word3." width + .draw_boxed_label_offset. +} \ {rpn .y. "M" ascent 2 * + .draw_boxed_label_offset. -} cm set color white draw box filled \ .x. \ .y. \ {rpn .x. "MM\.word3." width +} \ {rpn .y. "M" ascent 2 * +} cm set color rgb .draw_boxed_labelR. .draw_boxed_labelG. .draw_boxed_labelB. draw box \ .x. \ .y. \ {rpn .x. "MM\.word3." width +} \ {rpn .y. "M" ascent 2 * +} cm draw label "\.word3." at \ {rpn .x. "M" width +} \ {rpn .y. "M" ascent 0.5 * +} cm delete .x. .y. delete .draw_boxed_labelR. delete .draw_boxed_labelG. delete .draw_boxed_labelB. } `draw label whiteunder "\string" at .xleft. .ybottom. [cm]' Draw label for plot, located with lower-left corner at indicated (x,y) position (specified in user units or in cm on the page). Whiteout is used to clean up the area under the label. BUGS: Cannot handle angled text; doesn't check for super/subscripts. { if {rpn "\.word4." "at" !=} show "ERROR: Fifth word must be \"at\", not \"\.word4.\"" show traceback quit end if new .x. .y. .space. .oldR. .oldG. .oldB. .oldR. = ..red.. .oldG. = ..green.. .oldB. = ..blue.. if {rpn \.words. 7 ==} .x. = {rpn \.word5. xusertocm} .y. = {rpn \.word6. yusertocm} else if {rpn \.words. 8 ==} if {rpn "\.word7." "cm" !=} show "ERROR: Require 7th word to be `cm'" show traceback quit end if .x. = \.word5. .y. = \.word6. else show "ERROR: Require 7 or 8 words, but got \.words. words." show traceback quit end if # Coordinates now in cm. Next, white out a box under the # text (and .space. centimetres beyond text), then draw label. .space. = 0.1 # cm set color white draw box filled \ {rpn .x. .space. -} \ {rpn .y. .space. -} \ {rpn .x. "\.word3." width + .space. +} \ {rpn .y. "M" ascent + .space. + } cm set color rgb .oldR. .oldG. .oldB. draw label "\.word3." at .x. .y. cm delete .x. .y. .space. .oldR. .oldG. .oldB. } `draw label for last curve "label"' Draw a label for the last curve drawn, using the `..xlast..' and `..ylast..' built-in variables. { if {rpn \.words. 6 ==} draw label "\.word5." at\ {rpn ..xlast.. xusertocm "M" width 0.5 * +} \ {rpn ..ylast.. yusertocm "M" ascent 0.5 * -} cm else show "ERROR: Require 6 words, but got \.words. words." show traceback quit end if } `draw label "\string" [centered|rightjustified] at .x. .y. [cm|pt] [rotated .deg.]' With no optional parameters, draw string at given location in USER units. With the `cm' or `pt' keyword is present, the location is in centimetres or points on the page. With the `rotated' keyword present, the angle in degrees from the horizontal, measured positive in the counterclockwise direction, is given. With the keyword `centered' present, the text is centered at the given location; similarly the keyword `rightjustified' makes the text end at the given location. { extern "C" bool draw_labelCmd(void); } `draw line from .x0. .y0. to .x1. .y1. [cm|pt]' With no optional parameters, draw a line from (`.x0.', `.y0.') to (`.x1.', `.y1'.), where coordinates are in user units. With the `cm' or 'pt' keyword present, the coordinates are in centimetres or points on the page. NOTE: This will not cause auto-drawing of axes. { extern "C" bool draw_line_from_toCmd(void); } `draw line legend "label" at .x. .y. [cm] [length .cm.]' Draw a legend identifying the current line type with the given label. A short horizontal line is drawn starting at the location (`.x.', `.y.'), which may be specified in centimetres or, the default, in user coordinates. The line length is normally 1 cm, but this length can be set by the last option. The indicated label string is drawn 0.25 cm to the right of the line. SEE ALSO `draw symbol legend ...'. EXAMPLE (of keeping track of the desired location for the legend) .offset. = 1 # cm to offset legends # ... get salinity data set line width 0.25 draw curve draw line legend "Salinity" at .x. .y. # ... get temperature data set line width 1.0 set dash 0.45 0.05 draw curve .y. += .offset. draw line legend "Temperature" at .x. .y. { # Check for too few or too many words. if {rpn \.words. 7 >} show "ERROR: Require 7 or more words, but got \.words. words." show traceback quit end if if {rpn \.words. 10 <} show "ERROR: Require 10 or fewer words, but got \.words. words." show traceback quit end if .tmp_len. = 1 # cm if {rpn \.words. 9 ==} .tmp_len. = \.word8. else if {rpn \.words. 10 ==} .tmp_len. = \.word9. end if if {"\.word7." == "cm"} # Position given in centimetres. draw line from \ \.word5. \ \.word6. \ to \ {rpn \.word5. .tmp_len. +} \ \.word6. \ cm draw label "\.word3." at\ {rpn \.word5. .tmp_len. + 0.25 +} \ {rpn \.word6. ..fontsize.. pttocm 0.4 * -} \ cm else # Position given in user units. draw line from \ \.word5. \ \.word6. \ to \ {rpn \.word5. xusertocm .tmp_len. + xcmtouser} \ \.word6. draw label "\.word3." at\ {rpn \.word5. xusertocm .tmp_len. + 0.25 + xcmtouser} \ {rpn \.word6. yusertocm ..fontsize.. pttocm 0.4 * - ycmtouser} end if } `draw lines {vertically .left. .right. .inc.} | {horizontally .bottom. .top. .inc.}' Draw several lines, either vertically or horizontally. This can be useful in drawing gridlines for axes, etc. The following example shows how to draw thin gray lines extending from the labelled tics on the x axis (ie, at 0, 0.1, 0.2, ... 1): set x axis 0 1 0.1 0.05 set y axis 10 20 10 draw axes set graylevel 0.75 set line width 0.5 draw lines vertically 0 1 0.1 set graylevel black { extern "C" bool draw_linesCmd(void); } `draw patches .width. .height. [cm]' With the optional `cm' keyword not present, draw column data z(x,y) as gray patches according to the grayscale as set by most recent `set image grayscale'. The patches are aligned along the horizontal, and have the indicated size in user units. With the optional keyword `cm' is present, the patch size is specified in centimetres. { extern "C" bool draw_patchesCmd(void); } `draw polygon [filled] .x0. .y0. .x1. .y1. .x2. .y2. [...]' Draw a polygon connecting the indicated points, specified in user units. The last point is joined to the first by a line segment. At least two points must be specified. If the `filled' keyword is present, the polygon is filled with the current pen color. { extern "C" bool draw_polygonCmd(void); } `draw regression line [clipped]' Fit a regression line to column data, of the form `y = ..coeff0.. + ..coeff1.. * x' (exporting `..coeff0..' and `..coeff1..' as global variables) and draw this line on the plot, for the range `..xleft.. <= x <= ..xright..' on the x-axis. Fit and draw a regression line to column data, of the form `y = ..coeff0.. + ..coeff1.. * x' (exporting `..coeff0..', `..coeff0_sig..', `..coeff1..' and `..coeff1_sig..' as global variables; see `regress'). Normally, the line is not clipped to the axes frame, but it will be if the keyword 'clipped' is given. HINT: to label the plot you might do the following: sprintf \label "y = %f + %f * x. R$^2$=%f" ..coeff0.. ..coeff1.. ..R2.. draw title "The linear fit is \label" SEE ALSO: `regress' { regress y vs x new .clipped. .xl. .xr. .yl. .yr. if {rpn \.words. 4 ==} if {rpn "\.word3." "clipped" ==} .clipped. = 1 else show "ERROR: 4-th word must be 'clipped', not '\.word3.'" show traceback quit end if else .clipped. = 0 end if .xl. = ..xleft.. .xr. = ..xright.. .yl. = {rpn .xl. ..coeff1.. * ..coeff0.. +} .yr. = {rpn .xr. ..coeff1.. * ..coeff0.. +} if .clipped. if {rpn .yl. ..ybottom.. > } .yl. = ..ybottom.. .xl. = {rpn .yl. ..coeff0.. - ..coeff1.. /} end if if {rpn .yl. ..ytop.. < } .yl. = ..ytop.. .xl. = {rpn .yl. ..coeff0.. - ..coeff1.. /} end if if {rpn .yr. ..ytop.. < } .yr. = ..ytop.. .xr. = {rpn .yr. ..coeff0.. - ..coeff1.. /} end if if {rpn .yr. ..ybottom.. > } .yr. = ..ybottom.. .xr. = {rpn .yr. ..coeff0.. - ..coeff1.. /} end if end if draw line from .xl. .yl. to .xr. .yr. draw axes if needed delete .clipped. .xl. .xr. .yl. .yr. } `draw symbol legend \symbol_name "label" at .x. .y. [cm]' Draw indicated symbol at indicated location, with the indicated label beside it. The label is drawn one M-space to the right of the symbol, vertically centered on the indicated `.y.' location. { # Note kludge in y position, because ascent is inaccurate as # of version 1.17 anyway if {rpn \.words. 8 ==} draw symbol \.word3. at \.word6. \.word7. draw label "\.word4." at\ {rpn \.word6. xusertocm "M" width +} \ {rpn \.word7. yusertocm "M" ascent 0.7 * 2 / -} cm else if {rpn \.words. 9 ==} if {rpn "\.word8." "cm" ==} draw symbol \.word3. at \.word6. \.word7. cm draw label "\.word4." at \ {rpn \.word6. "M" width +} \ {rpn \.word7. "M" ascent 0.7 * 2 / -} cm else show "ERROR: Can't understand [\.word8.]; expecting [cm]" show traceback quit end if else show "ERROR: Require 8 or 9 words, not \.words. as given." show traceback quit end if } `draw symbol [.code.|\name [at .x. .y. [cm|pt]] [graylevel z]|[colorrange .h.]|[color [hue z|.h.] [brightness z|.b.] [saturation z|.s.]]]' The "at" form `draw symbol .code.|\name at .x. .y. [cm|pt]' draws a single symbol at the named location. The non-"at" form draws symbols at the (x,y) data. If a z-column has been read with `read columns', then it's value codes the symbol to draw, according to the table below. (The value of z is first rounded to the nearest integer.) If no z-column has been read, the symbol X is drawn at each datum. With the optional numerical/name code specified, then the symbol of that number or name is drawn at each (x,y) datum, whether or not a z-column exists. The numerical/name codes are: # name description -- ---- ----------- 0 plus + 1 times x 2 box box 3 circ circle 4 diamond diamond 5 triangleup triangle with base at bottom 6 triangleright triangle with base at left 7 triangledown triangle with base at top 8 triangleleft triangle with base at right 9 asterisk * 10 star star of David 11 filledbox filled box 12 bullet filled circle 13 filleddiamond filled diamond 14 filledtriangleup filled triangleup 15 filledtriangleright filled triangleright 16 filledtriangledown filled triangledown 17 filledtriangleleft filled triangleleft With the optional `graylevel z' fields specified, the graylevel is given by the `z` column (0=black, 1=white). With the optional `colorrange .hue.` fields specified, the color model is in the form of (hue, saturation, brightness), with hue being fixed at the indicated value, and with saturation given by 1-z, and brightness by (1+2*z)/3. (This mode was contributed by Philip Eisenlohr.) With the optional `color' field specified, the color is specified, either directly in the command (the `hue .h.' form) or in the z column. For more information on color, refer to the `set color hsb ...' command. Examples: both `draw symbol bullet color' and `draw symbol bullet color hue z' draw bullets whose hue is given by the value in the z column. The hue (or the color, in other words) blends smoothly across the spectrum as the numerical value ranges from 0 to 1. The value 0yields red, 1/3 yields green, 2/3 yields blue, etc. If the `brightness' and the `saturation' are not specified, they both default to the value 1, which yields pure, bright colors. Example: `draw symbol bullet color hue 0.333 brightness 1 saturation 1' draws green dots. { extern "C" bool draw_symbolCmd(void); } `draw time stamp [fontsize .points. [at .x_cm. .y_cm. cm [with angle .deg.]]]' Draw the command-file name, PostScript file name, and time, at the top of graph. Normally, the timestamp is drawn at the top of the page, in a fontsize of 10 points. But the user can specify the fontsize, and additionally the location (in cm) and additionally the angle measured in degrees anticlockwise from the horizontal. NOTE: If you want to have the plot in landscape mode on the page, make sure that you do `set page landscape' before `draw time stamp.' { new .old_fontsize. .old_fontsize. = ..fontsize.. if {rpn \.words. 3 ==} # Just `draw time stamp' set font size 10 if ..landscape.. draw label "Gri-\.version. \.wd./\.command_file. (\.time.)" at \ 1.5 20.6 cm else draw label "Gri-\.version. \.wd./\.command_file. (\.time.)" at \ 1.5 27.0 cm end if else if {rpn \.words. 5 ==} # `draw time stamp fontsize .points.' # 0 1 2 3 4 set font size \.word4. if ..landscape.. draw label "Gri-\.version. \.wd./\.command_file. (\.time.)" at \ 1.5 20.6 cm else draw label "Gri-\.version. \.wd./\.command_file. (\.time.)" at \ 1.5 27.0 cm end if else if {rpn \.words. 9 ==} # `draw time stamp fontsize .points. at .x_cm. .y_cm. cm' # 0 1 2 3 4 5 6 7 8 set font size \.word4. draw label "Gri-\.version. \.wd./\.command_file. (\.time.)" at \ \.word6. \.word7. cm else if {rpn \.words. 12 ==} # `draw time stamp fontsize .points. at .x_cm. .y_cm. cm with angle .deg.' # 0 1 2 3 4 5 6 7 8 9 10 11 set font size \.word4. draw label "Gri-\.version. \.wd./\.command_file. (\.time.)" at \ \.word6. \.word7. cm rotated \.word11. else show "ERROR: Require 3, 5, 9 or 12 words, but got \.words. words." show traceback quit end if set font size .old_fontsize. delete .old_fontsize. } `draw title "\string"' Draw the indicated string above the plot. { extern "C" bool draw_titleCmd(void); } `draw values [.dx. .dy.] [\format] [separation .xcm. .ycm.]' Draw values of `z' column, at corresponding (`x', `y') locations. If the `separation' keyword is present, the distance between successive points is checked, and points are skipped unless the x and y separations exceed than the indicated distances. `draw values' Draw the values of `z(x,y)', positioned 1/2 M-space to the right of `(x,y)' and vertically centred on `y'. The values are written in a good general format known as `%g', in C terminology. `draw values %.2f' Draw values of `z(x,y)' positioned as described above, but using the indicated format string. This format string specifies that 2 numbers be used after the decimal place, and that floating point should be used. See any C manual for format codes. `draw values .dx. .dy.' Print values of `z(x,y)' at indicated offset vector (`.dx.',`.dy.'), measured in centimeters, from the values of `(x,y)' at which the data are defined. `draw values .dx. .dy. %.3f' Print values of `z(x,y)' at indicated distance from `(x,y)', indicated format. { extern "C" bool draw_valuesCmd(void); } `draw x axis [at bottom|top|{.y. [cm]} [lower|upper]]' Draw an x axis, optionally at a specified location and of a specified style. `draw x axis' Draw a lower x axis (ie, one with the numbers below the line) at the bottom of the box defined by `set y axis'. `draw x axis at bottom' Draw a lower x axis (ie, one with the numbers below the line) at the bottom of the box defined by `set y axis'. `draw x axis at top' Draw an upper x axis (ie, one with the numbers above the line) at the top of the box defined by `set y axis' (or above any existing stacked x axes there) `draw x axis at .y.' Draw a lower x axis at indicated value of `.y.'. `draw x axis at .y. upper' Draw an upper x axis at indicated value of .y. { extern "C" bool draw_x_axisCmd(void); } `draw x box plot at .y. [size .cm.]' Draw Tukey box plots (which give a summary of histogram properties). Box plots were invented by Tukey for eda (exploratory data analysis). The centre of the box is the median. The box edges show the first quartile (q1) and the third quartile (q3). The distance from q3 to q1 is called the inter-quartile range. The whiskers (i.e., the lines with crosses at the end) extend from q1 and q3 to the furthest data points which are still within a distance of 1.5 inter-quartile ranges from q1 and q3. Beyond the whiskers, all outliers are shown: open circles are used for data within a distance of 3 inter-quartile ranges beyond q1 and q3, and in closed circles beyond that. `draw x box plot at .y.' Draw Tukey's box plot, spreading in the x direction, centered at y=`.y.' and of default width 0.5 cm. `draw x box plot at .y. size .cm.' Draw Tukey's box plot, spreading in the x direction, centered at y=`.y.' and of width `.cm.' centimetres. { extern "C" bool draw_x_box_plotCmd(void); } `draw y axis [at left|right|{.x. cm} [left|right]]' Draw a y axis, optionally at a specified location and of a specified style. `draw y axis' Draw a left-hand-side y axis (ie, one with the numbers to the left of the line) at left of box defined by `set x axis' `draw y axis at left' Draw a left-hand-side y axis (ie, one with the numbers to the left of the line) at left of box defined by `set x axis'. `draw y axis at right' Draw a right-hand-side y axis (ie, one with the numbers to the right of the line) at right of box defined by `set x axis'. `draw y axis at .x.' Draw a left-hand-side y axis (ie, one with the numbers to the left of the line) at indicated value of `.x.' `draw y axis at .x. right' Draw a right-hand-side y axis (ie, one with the numbers to the right of the line) at indicated value of `.x.' { extern "C" bool draw_y_axisCmd(void); } `draw y box plot at .x. [size .cm]' Draw Tukey box plots (which give summary of histogram properties). `draw y box plot at .x.' Draw Tukey's box plot, spreading in the y direction, centered at x=`.x.' and of default width 0.5 cm. `draw y box plot at .x. size .cm.' Draw Tukey's box plot, spreading in the y direction, centered at x=`.x.' and of width `.cm.' centimetres. { extern "C" bool draw_y_box_plotCmd(void); } `draw zero line [horizontally|vertically]' Draw lines corresponding to x=0 or y=0. `draw zero line' Draw line y=0 if it's within axes. `draw zero line horizontally' Draw line y=0 if it's within axes. `draw zero line vertically' Draw line x=0 if it's within axes. { extern "C" bool draw_zero_lineCmd(void); } `end group ["\name"]' Ene a group, i.e. a collection of graphical objects. (NOT IMPLEMENTED YET. SYNTAX MAY CHANGE.) { extern "C" bool end_groupCmd(void); } `expecting version .n.' Show a list of incompatibilites since the named version. This protects you from being clobbered by changes made to Gri, since you will be assured of being warned of these changes. For example, if you are doing a lot of work with version 2.1.0, but want to move up to a higher version, you would include the line `expecting version 2.0100' in all your commandfiles. Once you are sure that your commandfile will not be affected by the newer version, you should change the version that is expected. Note: As of October 1996, Gri version numbers have been in the form `a.b.c'. Numerical version numbers are created by the formula `a + b/100 + c/10000'. For example, version `2.1.0' has a numerical value of `2.0100'. { extern "C" bool expectingCmd(void); } `filter column x|y|z|u|v recursively .a0. .a1. ... .b0. .b1. ...' Filter indicated column, using a two-pass recursive filter. The first pass runs from the start to the end, while the second pass runs from the end to the start; in this way, the phase shift inherent in this type of filter is removed entirely. The coefficients are used in the following formula (demonstrated on the `x' column): x_new[i] = b[0] * x[i] + b[1] * x[i-1] + b[2] * x[i-2] + ... - a[1] * x_new[i-1] - a[2] * x_new[i-2] - ... Thus, for example, setting `a[i]' = 0 results in a simple backwards-looking moving-average filter applied in two passes. The real power of this type of filter, however, comes when non-zero `a[i]' coefficients are given, thus adding recursion (i.e., `x_new[i]' depends on `x_new[i-...]'). See any standard reference on digital filters for an explanation. You might find that the Matlab command `butter' an easy way to design filter coefficients. Here are some examples: # Filter x column with simple 2-point moving average. filter column x recursively 0 0 0.5 0.5 # Use filter designed with the Matlab command butter(2,0.1), # which creates a 2nd order lowpass butterworth filter, with a cutoff # frequency of 0.1 (in units which have a frequency of 1 corresponding # to one-half the sampling rate). filter column x recursively 1 -1.561 0.6414 0.0201 0.0402 0.0201 { extern "C" bool filter_columnCmd(void); } `filter grid rows|columns recursively .a0. .a1. ... .b0. .b1. ...' Apply recursive filter (see `filter column ... recursively' for meaning of this filter) to the individual rows or columns of the grid data. For example, `filter grid columns recursively 0 0 .5 .5' applies a 2-point moving average filter across the columns, smoothing the grid in the x-direction. { extern "C" bool filter_gridCmd(void); } `filter image highpass|lowpass' `filter image highpass' Remove low-wavenumber components from image (ie, sharpen edges). Do this by subtracting a Laplacian smoothed version of the image. `filter image lowpass' Remove high-wavenumber components from image (ie, smooth shapes). Do this by Laplacian smoothing. { extern "C" bool filter_imageCmd(void); } `flip grid|image x|y' Flip image by relecting it about a horizontal or vertical centerline. `flip grid x' Flip grid so right-hand side becomes left-hand side. `flip grid y' Flip grid so bottom side becomes top side. `flip image x' Flip image so right-hand side becomes left-hand side. `flip image y' Flip image so bottom side becomes top side. { extern "C" bool flipCmd(void); } `get env \result \environment_variable' Get the value of an "environment variable" from the operating system, and store the result in the indicated synonym. This makes most sense on unix systems (hence the name, patterned after the unix command `getenv'). This command can be useful in making gri programs resistant to changes in data-file locations. Suppose, for example, there is a file called `data', normally in a local directory called `Bravo'. The line `open Bravo/data' will fail if the Bravo directory is moved. But if the name of the datafile is stored in an environment variable, `DIR_BRAVO' say, then the gri program will work no matter where the Bravo data are moved, so long as an appropriate environment variable is modified when the data are moved. Example: get env \dir DIR_BRAVO if \{rpn "\dir" "" ==} show "Cannot determine location of the Bravo data, which should" show "be stored in the environment-variable DIR_BRAVO. You should" show "do something like" show " export DIR_BRAVO='/users/dek/kelley/data/Bravo/'" show "in your ~/.environment file" quit end if open \dir/data ... { extern "C" bool get_envCmd(void); } `get options "LIST" [keep]' { extern "C" bool get_optionsCmd(void); } `group ["\name"]' Start a group, i.e. a collection of graphical objects. (NOT IMPLEMENTED YET. SYNTAX MAY CHANGE.) { extern "C" bool groupCmd(void); } `heal columns|{grid along x|y}' The `heal' command heals over gaps in either columnar or gridded data. This is done by linear interpolation across the missing-value gaps. * `heal columns' Fill in missing values in x, y, z, ... columns, by linear interpolation to neighboring valid data. All gaps in the data will get replaced by a linear function of index which matches the data at the indices just before and just after the gap. For example, if the y data were like 111 3 -9 -9 -9 7 333 where `-9' is the missing-value code, then they would get replace by 111 3 4 5 6 7 333 Notes: (1) This is done *independently* for all existing columns. (2) Gaps at the start and end of the columns are not filled in. * `heal grid along x' Scan in the x direction, filling in missing values by linearly interpolation. Since this uses the the x-grid, you must first have done `read grid x' or `set x grid'. * `heal grid along y' Scan in the y direction, filling in missing values by linearly interpolation. Since this uses the the y-grid, you must first have done `read grid y' or `set y grid'. { extern "C" bool healCmd(void); } `help [*|command_name|{- topic}]' Give help on a command or topic. `help' Print a general help message. `help *' Prints complete help info. `help command_name' Prints help on the command whose name begins with the string `command_name'. The string may be several words long; e.g. `help set' or `help set x axis'. `help - topic_name' The minus sign tells Gri that the string to follow it is a topic, not a command. Topics Gri knows about are listed by the one-word `help' request. { extern "C" bool helpCmd(void); } `if {[!] .flag.}|\flag|{{"string1" == "string2"}}' Control program flow. The `if' block is ended with a line containing `end if'. Optional `else' and `else if' blocks are allowed. Note that RPN expressions are allowed, and a special form of string comparison is allowed, as in the examples below. if .flag. # List of Gri commands to be done if .flag. is 1. # This list may extend across any number of lines. end if If the variable `.flag.' is not equal to 0, do the code between the `if' line and the `end if' line. if .flag. # Commands done if .flag. is 1 else # Commands done if .flag. is 0 end if If the variable `.flag.' is not equal to 0, do the code between the `if' line and the `else' line. If `.flag.' is equal to 0, do the code between the `else' line and the `end if' line. if ! .flag. # Commands done if .flag. is 0 end if If the variable `.flag.' is equal to 0, do the code between the `if' line and the `end if' line. if \{rpn .flag. 10 <} # Commands done if 10 is less than .flag. end if If the variable `.flag.' is less than 10, do the code between the `if' line and the `end if' line. if \smooth # Commands done if \smooth is 1 else # Commands done if \smooth is 0 end if If the number stored in the synonym `\smooth' is not equal to 0, do the code between the `if' line and the `else' line. If the synonym stores a representation of a number not equal to zero, do the `else' part. If the synonym contains text that does not decode to a number, generate error message. if \{"\item" == "Temperature"} # Commands done if the synonym \item is equal to the # indicated text string. end if If the synonym `\item' has the value `Temperature' stored in it, do the indicated code. if \{rpn "\item" "Temperature" ==} # Commands done if the synonym \item is equal to the # indicated text string. end if As above, but using the `rpn' calculator. { extern "C" bool null; } `ignore last .n.' Ignores last `.n.' lines read by `read columns'. { extern "C" bool ignoreCmd(void); } `input \ps_filename [.xcm. .ycm. [.xmag. .ymag. [.rot_deg.]]]' Input the named PostScript file directly into the Gri output PostScript file. (If the filename has punctuation, insert it in double quotes, e.g. `input "../thefile"'.) If no options are specified, the file is input at normal scale, with normal margins. (Aside to PostScript programmers: the named file is sandwiched between `gsave' and `grestore' commands.) If `.xcm.' and `.ycm.' are specified, then the origin is moved to the named location first. If, in addition, `.xmag.' and `.ymag.' are specified, then these are used as scale factors after translation. Finally, if `.rot_deg.' is specified in addition, then the indicated counterclockwise rotation is applied after translation and scaling. Hint: if the results look wrong, the first thing to do is to think carefully about the order of the (translation, scaling, rotation) operations. { extern "C" bool inputCmd(void); } `insert \filename' Insert instructions in named file into current file. This is useful as a way of sharing global information between several Gri programs. On unix systems, if a full filename is specified (i.e., a filename beginning with slash or period), then that particular file will be used. For filenames beginning with a letter or number, though, Gri will search for the file in the list of directories stored in your `GRIINPUTS' environment variable, or in the list (`.', `/usr/local/lib/gri') if that environment variable is not set. { extern "C" bool insertCmd(void); } `interpolate x|y grid to ...' The forms are interpolate x grid to .left. .right. .inc.|\{/.cols.} interpolate y grid to .bottom. .top. .inc.|\{/.rows.} Transform grid by interpolating between existing grid data, according to a new x or y grid specified in the manner of `set x grid' and `set y grid'. Note that the new grid is neccessarily regular, while the first grid needn't have been. The data of the new grid are constructed by interpolation, using the same interpolation algorithm as the `convert grid to image' command. { extern "C" bool interpolateCmd(void); } `list \command-syntax' List the source of a gri command. Often this is just the name of a C function internal to gri (try `list list' for an example), but when the command is written in the gri programming language the source will be more understandable (try `list set panel'). { extern "C" bool listCmd(void); } `ls [\file_specification]' List files in current directory. (The current directory can be printed by the gri command `pwd' and can be set by the gri command `cd'.) `ls \file_specification' lists files in current directory which match the file specification. Normal unix file specification options are understood. { extern "C" bool lsCmd(void); } `mask image [to {uservalue .u.}|{imagevalue .i.}]' Examine both the image and the mask pixel by pixel. For any pixels which have a mask value of 1 (which indicates an invalid region of the image), change the image value. If no `to' phrase is present, change the image value to 0 in pixel units. If the `to uservalue .u.' phrase is present, change the pixel to hold the imagevalue that corresponds to this uservalue (see `set image range' command for a discussion of this correspondance). If the `to imagevalue .i.', change the pixel to hold that imagevalue (in range 0 to 255 inclusive for 8-bit images). { extern "C" bool maskCmd(void); } `new page' Finish the present page, and start a new page. All settings (of linewidth, axes, landscape/portrait, etc.) and data are retained on the new page. { extern "C" bool new_pageCmd(void); } `new postscript file \name' Finish the present Postscript file, and start a new page with the given name. All settings (of linewidth, axes, landscape/portrait, etc.) and data are retained on the new file. { extern "C" bool new_postscript_fileCmd(void); } `new .variable_name.|\synonym_name [.variable_name.|\synonym_name [...]]' Set aside storage for new version of the named variable(s) and/or synonym(s). Any number of variables and synonyms may be specified. If a given variable/synonym already exists, this will create a new version of it, and future assignments will be stored in this new version *without* affecting the pre-existing version. If the variable/synonym is `delete'ed, the new version is deleted, making the old, unaltered, version accessible again. This command is used mostly for temporary use, to prevent clashing with existing values. Suppose you want to change the font size inside a new command or an if block. Then you might do the following, where the variable `.tmp.' is used to store the old font size. Note that the use of the `new/delete' statements prevents the assignment to the local version of the variable `.tmp.' from affecting the value known outside the `if' block, if in fact `.tmp.' happened to exist outside the block. set font size 10 draw label "This is in fontsize 10, before modification" at 10 2 cm if .want_title. new .tmp. # Get storage .tmp. = ..fontsize.. # Save old size set font size 22 # Set new size draw label "This is in fontsize 22" at 10 5 cm set font size .tmp. # Restore old size delete .tmp. # Clean up end if draw label "This is in fontsize 10, after modification" at 10 8 cm { extern "C" bool newCmd(void); } `open {\filename}|{"system command|"} {[binary [uchar|int|float|double|16bit]]}|{netCDF}' Possibilities are: `open \filename' `open \filename binary [uchar|int|float|double]' `open \filename netCDF' `open "SYSTEM-COMMAND |" [binary [uchar|int|float|double]]' The first three forms work on data files. Use double-quotes around filenames with punctuation in them (e.g. `open "../data"'). Files may be ascii (the default), binary or - on systems with the `netCDF' libraries installed - in the `netCDF' format. The `SYSTEM-COMMAND' form is used to work on a temporary file created by a system command. Several binary file types are allowed. The keywords `uchar', etc, can be used to specify the type of data in the file. If no keyword is given, Gri assumes that images use `unsigned char' (8 bits), columns use `float' (32 bits), and that grids use `float' (32 bits). In the `SYSTEM-COMMAND' form, the indicated system command is performed, with the output being inserted into a temporary file. Future `read', `close', etc, commands apply to to this temporary file. (The temporary file is automaticaly deleted by Gri, but if Gri fails for some reason you should scan `/usr/tmp/' for files that you own.) For example open "cat a.dat | awk '\{$1, $2 * 22}' |" read columns x y gets awk to multiply the y column by 22. The ability to use system commands in `open' statements lets you use familiar system tools like `head', `sed', `awk', `perl', etc, to work on your data. For example, if you store your data in compressed form, and do not wish to have temporary files sitting around, you might wish to do something like open "zcat myfile.dat.Z | " Files may be opened across the WWW (world-wide web). Here is a replacement for example1.gri: open "lynx -dump http://www.phys.ocean.dal.ca/~kelley/gri/examples/example1.dat | tail +2 |" read columns x y draw curve draw title "Example 1" Note: the `tail +2' removes the initial blank line that lynx generates. For complicated data manipulation, a system tool like `awk' or `perl' is ideal. For example, suppose x and y data are stored in Hour.minutesecond format, e.g. 12.2133 means hour 12, minute 21, second 33. Gri doesn't read HMS format, but gawk can be told to: open "cat datafile.HMS | \ awk '\{ \ split($1, hms, \".\"); \ h = hms[1]; \ m = int(hms[2] / 100); \ s = hms[2] - 100 * m; \ x = h + m / 60 + s / 3600; \ split($2, hms, \".\"); \ h = hms[1]; \ m = int(hms[2] / 100); \ s = hms[2] - 100 * m; \ y = h + m / 60 + s / 3600; \ print(x,y) \ }' | " read columns x y { extern "C" bool openCmd(void); } `postscript \string' Write the indicated string to the PostScript output file, after substitution of synonyms if there are any. Example: \angle = "45" \page_width = "8.5" postscript gsave \page_width 72 mul 0 translate \angle rotate # ... other code to do stuff postscript grestore Here is how to draw an image palette vertically instead of horizontally: \originX = "3" # cm \originY = "10" # cm \angle = "90" # degrees counterclockwise postscript gsave \originX 28.35 mul \originY 28.35 mul translate \angle rotate draw image palette box 0 0 10 1 # this is at user's origin postscript grestore NOTE: the `postscript' command is *very* dangerous, and should normally only be used by developers. Most of the code concerning this is in the file `doline.cc'; look for the string `postscriptCmd' to find the relevant code. { extern "C" bool postscriptCmd(void); } `pwd' Print current directory (which can be set by `cd'). { extern "C" bool pwdCmd(void); } `query \synonym|.variable ["\prompt" [("\default"|.default)]]' Ask the user for the value of a variable (number) or synonym (text string). Gri recognizes the type of the item being asked for, either a variable or synonym, by the presence of a dot or backslash in the second word of the command line. If a prompt string is given (in quotes), then this string is shown to the user. If a default is given (in parentheses), then it will be displayed also, and if the user types carriage-return, then that item will be assigned to the variable or synonym. If the default has more than one item, then Gri considers this a restrictive list of possibilities, and will demand that the answer be in that list, going into an infinite query loop until an item from the list (or carriage-return, meaning take first item) is found. The items in the list are to be separated by spaces, not commas or any other non-whitespace characters. NOTE: The `-y' command-line option bypasses all query commands, fooling Gri into thinking that the user typed a carriage-return to all questions. Thus the defaults, if they exist, are selected. { extern "C" bool queryCmd(void); } `quit [.exit_status.]' Exits the gri program. If an exit status (`.exit_status.') is specified, then Gri returns this value, rounded to the nearest integer, as the "exit status" (a concept meaningful mostly in the unix environment). { extern "C" bool quitCmd(void); } `read colornames from RGB {"/usr/lib/X11/rgb.txt" | \filename}' Read colornames from named file, which is in the X11 format. This format has 4 or more columns, the first three giving the red, green and blue values in the range 0 to 255, and the last columns giving the colorname (which may have more than one word). You can create colors yourself or read an X11 color file. In many cases you will want to `read colornames from RGB "/usr/lib/X11/rgb.txt"'. Full filenames must be used; the '~' syntax is not permitted. Once you have read in a colorname table, the named colors may be used as builtin colors (see also `set color'). To view the colors available on your particular system, use the Unix command `xcolors' or `excolors'; to see the RGB values for all colors on your system, use the `showrgb' Unix command. To view the names and RGB values of the colors Gri knows, including builtin ones and ones from `read colornames', use `show colornames'. { extern "C" bool read_colornamesCmd(void); } `read columns ...' Read numbers into columns. These columns have predefined meanings and names. For example, `read columns x y' instructs Gri to read data into columns called `x' and `y'; it is these data that Gri will use if you tell it to `draw curve'. Other columns are: `z', used for contouring a function `z=z(x,y)'; `weight', used for weighting data points; `u' and `v', used for arrow (vector) plots. If the keyword `appending' is given as the last word on the `read columns' line, then the new data will be appended to any existing columnar data; otherwise they will overwrite any existing data. * `read columns x y' Read `x' in column 1, `y' in column 2 until blank-line found. Only the first tow numbers on each line will be read; any extra numbers (or words) on the line will be ignored. * `read columns * y * * x' Read `x' in column 5, `y' in column 2. The `*' character is a spacer. It instructs Gri to skip the first, third, and fourth words on the data line. These words need not be numbers. This example illustrates a general mechanism of using the `*' character to skip over unwanted items in the data file. Note that there is no need to supply `*' characters for trailing extraneous words; Gri will skip them anywary. Finally, note that any order of `x' and `y' (and the other columns; see below) is allowed. * `read columns y=2 x=5' or `read columns x=5 y=2' As above; read `x' in column 5 and `y' in column 2. The column number may be specified in this manner for all the named column variables. No spaces are allowed before or after the `=' sign. The first column is called column 1. Whether this format is used or the `*' format is a matter of choice, except that numbered format also permits using a given number to fill several variables (e.g. `read columns x=1 y=2 u=1 v=2'). * `read columns x="netCDF name" ...' If the file is a `netCDF' file, opened by e.g. `open myfile.nc netCDF', then the `netCDF' variables for the columns, e.g. open latlon.nc netCDF read columns x="longitude" y="latitude" Note: the data *must* be stored as the `netCDF' "float" type. * `read columns y' Read `y' in column 1. Since `x' is not read from the file, it will be assigned the default values `x' = (0,1,2, `..num_col_data..'); that is, it will have the same number of elements as `y'. * `read columns * y z * x' Read `x' in column 5, `y' in column 2, and `z' in column 3. The `z' column is used for contouring. * `read columns x y u v' Read `x' and `y' in first two columns, and the "arrow" data `u' and `v' as third and fourth columns. * `read columns .rows. x y' Read `.rows.' rows of column data. NOTE FOR BINARY FILES: For ascii files, Gri will proceed to a new line after it has read the items requested; it skips any words appearing on the data line after the last object of interest. Thus `read columns x y' will read the first two columns and ignore any other columns that might be present. But for binary files, Gri has no way of knowing how to "skip" to the next line (see `skip' command), so you will have to flesh out the `read columns' command with as many spacers as are present in your data. For example, if you have four numbers in each data record and want to interpret the first two as `x' and `y', you would use `read columns x y * *' to read the data. RETURN VALUE: Sets `\.return_value' to `N rows N non-missing N inside-clip-region' { extern "C" bool read_columnsCmd(void); } `read grid {x [.rows.|{="name"}]}|{y [.cols.]{="name"}}|{data {[spacers] [.rows. .cols.] [spacers] [bycolumns]}|{="name"}}' "Read grid" commands read grid characteristics. (The "grid" is the object that is contoured.) For normal ascii or binary files, the commands to read the grid's x-locations, y-locations and data are: `read grid x [.rows.]' `read grid y [.rows.]' `read grid data [spacers] [.rows. .cols.] [spacers] [bycolumns]' For `netCDF' files, the commands are as follows (note that it is not possible to specify the number of data to read, nor to read the grid by columns). `read grid x = "variable name"' `read grid y = "variable name"' `read grid data = "variable name"' The data *must* be stored as the `netCDF' "float" type. The ordering of the y-grid data is the same as if they were read from a normal file: the first number is considered to be at the top of the plot. Details of the non-netCDF commands: * `read grid x [.cols.]' Read the `x' locations of the grid points, one number per line. If `.cols.' is supplied, then that many values will be read; otherwise, reading will stop at end-of-file or blank-line. * `read grid y [.rows.]' As above, but for y grid; `.rows.' is the number of rows. The first number to be read corresponds to the location of the *top* edge of the grid. Thus, if you were to view the column of numbers with a text editor, they would be oriented the same way as the corresponding elements will appear on the page. * `read grid data [.rows. .cols.]' Read data for a grid having `.rows.' and `.cols.' columns. (If `.rows.' and `.cols.' are not supplied, but the grid already exists, then those pre-existing values are used. If they are specified here, then they are checked for consistency with the pre-existing values if they exist.) Gri will read `.rows.' lines, each containing `.cols.' numbers. (Extra information in the file can be skipped; see discussion of the `*' keyword below.) Gri will interpret the first line it reads as the grid data corresponding to a value of y equal to `y[.rows.]'. Thus, file should be arranged like this: f(x[1], y[.rows.]) f(x[2], y[.rows.]) ... f(x[.cols.], y[.rows.]) . . . f(x[1], y[3]) f(x[2], y[3]) ... f(x[.cols], y[3]) f(x[1], y[2]) f(x[2], y[2]) ... f(x[.cols], y[2]) f(x[1], y[1]) f(x[2], y[1]) ... f(x[.cols], y[1]) * `read grid data [.rows. .cols.] bycolumns' As above, but the `bycolumns' keyword tells Gri to read the data one column at a time, instead of one row at a time. Each line is expected to contain `.rows.' numbers (as opposed to `.cols.' numbers, as in the format where the `bycolumns' keyword is not present). (Extra information in the file can be skipped; see discussion of the `*' keyword below). The first line of the data file contains the first column of the gridded data, corresponding to x equal to `x[1]'). The file should look like this: f(x[1], y[1]) f(x[1], y[2]) ... f(x[1], y[.cols.]) f(x[2], y[1]) f(x[2], y[2]) ... f(x[2], y[.cols.]) f(x[3], y[1]) f(x[3], y[2]) ... f(x[3], y[.cols.]) . . . f(x[.rows.],y[1]) f(x[.rows], y[2]) ... f(x[.rows.], y[.cols.]) * `read grid data * * [.rows. .cols.]' As `read grid data .rows. .cols.' except that the first two words on each line are skipped. As usual, trailing extraneous numbers are also skipped. The following example illustrates how to use these together. read grid x 3 --- results in the grid locations 1 4 1 2 3 4 5 5 0 *-------------------------*--------* 10 | | | read grid y 3 20 *-------------------------*--------* 0 30 | | | 20 40 *-------------------------*--------* 40 read grid data 3 3 --- fills in the grid as follows 9 1 2 3 4 5 1 2 3 4 5 6 7 8 0 9-------------------------1--------2 10 | | | 20 3-------------------------4--------5 30 | | | 40 6-------------------------7--------8 SEE ALSO: `set x grid', `set y grid' RETURN CODES: `read grid x' sets `\.return_value to `N cols' `read grid y' sets `\.return_value' to `N rows' `read grid data' sets `\.return_value to `N rows N cols' { extern "C" bool read_gridCmd(void); } `read image colorscale [rgb|hsb]' Read colorscale for image, from 256 lines each containing values for Red, Green, and Blue (or Hue, Saturation and Brightness), separated by whitespace. The values are expected to be in the range 0 to 1, and are clipped to these limits if not. For hints on how to create such an input file, see `read image grayscale'. If the example given there has the following code instead, open "awk 'BEGIN \{ \ for(i=0;i<256;i++) \{ \ print((i - 50)/50, 1, 1) \ } \ }' |" read image colorscale hsb then a full-color spectrum running from red at 10C to magenta at 15C is achieved. { extern "C" bool read_image_colorscaleCmd(void); } `read image grayscale' Read grayscale for image for image, from 256 lines each containing a single value. The values are expected to be in the range 0 to 1, and are clipped to these limits if not. For 8-bit images, Gri multiplies these values by 255, and uses this list for the grayscale mapping. Such a list is created by `write image grayscale'. As an example, the code fragment set image range 5 30.5 set image grayscale black 10 white 15 is equivalent to set image range 5 30.5 open "awk 'BEGIN\{for(i=0;i<256;i++) print(1-(i-50)/50)}' |" read image grayscale close because the image formula is Temperature = 5C + 0.1C * pixelvalue where the pixelvalue ranges from 0 to 255. Therefore, a temperature of 10C is a pixelvalue of 50, and 15C is 100. To get a grayscale ranging between these values, therefore, we create a linear function which maps the 50th pixelvalue into grayvalue 1, and the 100th pixelvalue into grayvalue 0. That is what the awk line does; to see the actual numbers, you could insert the line `write image grayscale to TMP' and look at the file `TMP' (bear in mind that Gri will clip the values to the range 0 to 1). Sometimes you will have a file, say named `map.dat', with RGB numbers in the range 0-255, rather than 0-1 as Gri requires. To read them, use the operating system to convert the numbers for you: open "cat map.dat | awk '\{print(($1+$2+$3)/3/255)}' |" read image grayscale close { extern "C" bool read_image_grayscaleCmd(void); } `read image greyscale' Alternate spelling of grayscale { extern "C" bool read_image_grayscaleCmd(void); } `read image mask rasterfile' Read image mask. The mask is associated with the image read in by the `read image' command in the following way. When computing image histograms, Gri ignores any pixels in the image for which the corresponding pixel in the mask is set to `1'. The image size is specified in the rasterfile file itself, so it is not specified. { extern "C" bool read_image_mask_rasterfileCmd(void); } `read image mask .rows. .cols.' Read image mask. The mask is associated with the image read in by the ` read image' command in the following way. When computing image histograms, Gri ignores any pixels in the image for which the corresponding pixel in the mask is set to `1'. The file must contain `.rows.*.cols.' binary data. Pixel order is the same as for images. { extern "C" bool read_image_maskCmd(void); } `read image pgm [box .xleft. .ybottom. .xright. .ytop.]' Read image in pgm (portable graymap) format. The image range must have previously have been set by `set image range'. The image width and height are specified in the image file itself. Both ascii and binary PGM formats are supported (that is, files with magic characters of P2 and P5). When the `box' option is specified, the geometry of the image, in user coordinates, is specified in terms of the cartesian coordinates of the lower-left corner (`.xleft.', `.ybottom.') and upper-right corner (`.xright.', `.ytop.'). If the `box' option is not specified, this geometry can be specified with either `read grid x' or `set x grid', plus either `read grid y' or `set y grid'. { extern "C" bool read_image_pgmCmd(void); } `read image rasterfile [box .xleft. .ybottom. .xright. .ytop.]' Read image in Sun rasterfile format. The image range must have previously have been set by `set image range'. The image width and height are specified in the rasterfile file itself. When the `box' option is specified, the geometry of the image, in user coordinates, is specified in terms of the cartesian coordinates of the lower-left corner (`.xleft.', `.ybottom.') and upper-right corner (`.xright.', `.ytop.'). If the `box' option is not specified, this geometry can be specified with either `read grid x' or `set x grid', plus either `read grid y' or `set y grid'. { extern "C" bool read_image_rasterfileCmd(void); } `read image .rows. .cols. [box .xleft. .ybottom. .xright. .ytop.] [bycolumns]' With no options specified (`read image .rows. .cols.'), read binary data defining an `image'. The image range must have previously have been set by `set image range'. The data are as written as "unsigned char" format in C. When the `box' option is specified, the geometry of the image, in user coordinates, is specified in terms of the cartesian coordinates of the lower-left corner (`.xleft.', `.ybottom.') and upper-right corner (`.xright.', `.ytop.'). If the `box' option is not specified, this geometry can be specified with either `read x grid' or `set x grid', plus either `read y grid' or `set y grid'. With the `bycolumns' keyword present, the image is read sweeping from top-to-bottom, then left-to-right, instead of the user order. { extern "C" bool read_imageCmd(void); } `read from \filename' Cause future `read' commands to read from the indicated file. If that file is not open, an error message will result. Use `read from \filename' to shuffle reading between several open files. { extern "C" bool read_from_filenameCmd(void); } `read line [raw] \synonym' Read the next line of the datafile (or commandfile) and then store the next line of datafile into the named synonym. Normally, comments are removed from the line first, but if the keyword "raw" is present, then comments are retained. { extern "C" bool read_lineCmd(void); } `read [raw] [* [*...]] \synonym|{.variable. [.variable. ...]}' As the same command without the "raw" keyword, except that in this instance comments are not removed from the line before reading. If the optional `raw' keyword is not present, comments are first trimmed from the data line. If `raw' is present, however, any comments are retained on the line. { extern "C" bool read_synonym_or_variableCmd(void); } `read [* [*...]] \synonym|{.variable. [.variable. ...]}' Read whitespace-separated words from datafile, assigning to any number of synonyms or variables as indicated. The token `*' indicates that the word in the datafile should be skipped. As usual, the datafile may be embedded in the commandfile. If the input file is in the netCDF format, the indicated item will be read. For example, `read \time:_MissingValue' reads the missing value for the variable called `time' (you might follow this by a line like `.missing. = \time:_MissingValue'). Similarly, `read \location' stores the value of the global attribute called `location' into the variable named `\location'. { extern "C" bool read_synonym_or_variableCmd(void); } `regress {y vs x [linear]}|{x vs y [linear]}' Perform linear regression of `y' as a function of `x' or `x' as a function of `y'. * `regress y vs x' Linear regression of y vs x. Several quantities are reported and also saved into builtin variables. The intercept is defined as `..coeff0..', it's 95 percent confidence limit is defined as `..coeff0_sig..'. Thus the confidence range is `..coeff0..-..coeff0_sig..' to `..coeff0..+..coeff0_sig..'. Similarly the slope and confidence limit are stored in `..coeff1..' and `..coeff1_sig..' The squared correlation coefficient is stored in `..R2..'. Historical note' prior to version 2.1.15, a different meaning was attached to `..coeff0_sig..' and `..coeff1_sig..'; they used be defined as standard error, without having been multiplied by the appropriate student-t coefficient. * `regress x vs y' Linear regression of x vs y; for notation see above. * `regress y vs x linear' Linear regression of y vs x; for notation see above. * `regress x vs y linear' Linear regression of x vs y; for notation see above. SEE ALSO `draw regression line' { extern "C" bool regressCmd(void); } `reorder columns randomly|{ascending in x|y|z}|{descending in x|y|z}' Reorder the columns in various ways. In the `randomly' style, the column data are shuffled randomly by index, retaining the correspondance between a given x and y. This is useful with `draw symbol' using colored dots -- it prevents the overpainting of one dot on another from biasing the color field to values that happened to occur near the end of the column data. If you prefer the overpainting to be done in random order, use this command to reorder the columns randomly. The random number is selected using the system `rand' call, with the seed being provided by the PID (process ID) of the job. The `ascending' and `descending' styles do what you'd expect. { extern "C" bool reorder_columnsCmd(void); } `rpnfunction \name "action"' Create a new keyword for use in RPN expressions. Inside any RPN expression which follows this line, the word `name' will be substituted with the indicated replacement words. For example, the following shows the definition and use of a function which computes the sine of twice an angle, by multiplying whatever is on the stack by `2', and then taking the sine of the result. rpnfunction sin2 2 * sin show "expect the number 1 to follow: " \{rpn 45 sin2} NOTE: The replacement words will have any synonyms in them translated first, unless they start with an underscore followed by a double backslash. Similarly, variables are substituted unless they start with an underscore. These exceptions are to allow the use of the `defined' operator. { extern "C" bool rpnfunctionCmd(void); } `rescale' Re-determine the scales for the x and y axes. Typically used after a column math operation, when you want the new data to be auto-scaled. (Note: this is not the default action after column mathematics, since Gri lets users add offsets, etc, without altering the axes scales.) { extern "C" bool rescaleCmd(void); } `resize x for maps' Resize the axes frame region in such a way that geographical objects appear in correct proportions. This assumes that y is degrees latitude and x is degrees latitude. `resize x for maps' Resize the plot width for maps, assuming that x represents longitude and y represents latitude. Before using this, you must have defined scales for both x and y, and a size for y (ie, you must have done `set x axis ...', `set y axis ...' and `set y size'); this command sets the x size, thus eliminating `set x size.' The result is that, at the central latitude (y), a centimetre on the page will correspond to an equal distance on the earth, in both the north-south and east-west directions. { set x size {rpn ..ysize.. ..xright.. ..xleft.. - * \ ..ybottom.. ..ytop.. - /\ ..ybottom.. ..ytop.. + 2 / cos * abs} } `resize y for maps' Resize the axes frame region in such a way that geographical objects appear in correct proportions. This assumes that y is degrees latitude and x is degrees latitude. `resize y for maps' Resize the plot height for maps, assuming that x represents longitude and y represents latitude. Before using this, you must have defined scales for both x and y, and a size for x (ie, you must have done `set x axis ...', `set y axis ...' and `set x size'); this command sets the y size, thus eliminating `set y size.' The result is that, at the central latitude (y), a centimetre on the page will correspond to an equal distance on the earth, in both the north-south and east-west directions. SEE ALSO `resize x for maps' command. { set y size {rpn ..xsize.. ..ybottom.. ..ytop.. - * \ ..xright.. ..xleft.. - /\ ..ybottom.. ..ytop.. + 2 / cos / abs} } `return' Return early from a user-defined function or an `insert' file. Or, in the main gri program, do the same thing as `quit'. { show "ERROR in `return' -- should not get here in gri.cmd" show traceback quit } `rewind [filename]' Rewind a data-file to the beginning. If no filename is given, this is done for the currently active file; otherwise the named file is rewound. { extern "C" bool rewindCmd(void); } #* @param .style. = style of axes @default 0 `set axes style .style. | {offset [.dist_cm.]} | rectangular | none | default' Tell Gri how you want axes to look. `set axes style 0' Set axes to be rectangular, with an x-y axes frame labelled at the left and bottom. `set axes style 1' As style `0' but only put tics on the lower and left axes. `set axes style 2' As style `0' but without labels or tics on any axis, i.e. just an axis frame. Set axes to be rectangular, with an x-y frame without tics or numbers on any side. `set axes style offset [.dist_cm.]' Set axes so that the actual x and y axes will be drawn with a space separating them from the data area. The space, if not set by the `.distance_cm.' option, will be equal to the current tic size (see `set tic size'). This command can be used together with any other `set axes style' command. It applies to both the `draw axes' command and with any `draw x|y axis' command in which the axis location is not explicitly given. `set axes style rectangular' Set axes to be rectangular, with an x-y axes frame labelled at the left and bottom. `set axes style none' Tell gri not to bother drawing axes before drawing curves, etc. `set axes style default' Same as `set axes style 0', and with `offset' turned off. { extern "C" bool set_axes_styleCmd(void); } #* @param .size. arrowhead half-width @unit cm @default 0.2 `set arrow size .size.|{as .num. percent of length}|default' Set the arrowsize (which is stored in the builtin variable `..arrowsize..'). `set arrow size .size.' Set the arrow size (ie, half-width of the arrowhead) to `.size.' centimetres. `set arrow size as .num. percent of length' Set the arrow size to be the indicated percentage of arrow length, as in "HWP" in the singles ads. (As a flag to this, `..arrowsize..' is set to the negative of the fractional size measured in percent.) `set arrow size default' Set the arrow size to the default of 0.2 cm. { extern "C" bool set_arrow_sizeCmd(void); } #* @param .type. 0 for 3-strokes, 1 for outline, 2 for filled swept-back @default 0 `set arrow type .which.' Set type of arrow. `.which.'=0 yields the default arrows, drawn with three line strokes, `.which.'=1 yields outline arrows, and `.which.'=2 yields swept-back filled arrows. { extern "C" bool set_arrow_typeCmd(void); } `set beep on|off' The command `set beep on' makes gri beep on errors and `query'. `set beep off' turns this beeping off. { extern "C" bool set_beepCmd(void); } `set bounding box .xleft. .ybottom. .xright. .ytop. [cm|pt]' Set the PostScript bounding box for graph to indicated value. The bounding box is used by some programs to determine the region of the page on which marks have been made. For example, LaTeX uses the bounding box to decide how to position figures in documents. Normally, the bounding box is computed automatically (unless the `-no_bounding_box' commandline option has been specified. But if `set bounding box' is done, the automatically computed value is ignored and the given box is used instead. Use this if Gri makes mistakes in its automatic selection of bounding box. The coordinates of the bounding box may be specified in (1) user coordinates, as defined *at the moment* the command is executed, or (2) in points on the page, measured from an origin at the lower-left (72 point per inch), or (3) in centimeters on the page. Which coordinate system is used depends on the last keyword - use `pt' for points, `cm' for centimeters, and nothing at all for user-units. The most common use is in points, since that is how many other application packages, e.g. LaTeX and dvips, specify the bounding box. If the box is specified in the user units, the user units in effect *at the moment* of executing the `set bounding box' command are used. This must be born in mind if the coordinate system is changing during the execution of the program, e.g. if margins are changing or the x and y axes are changing. For this reason it often makes sense to put this command at the end of the commandfile. { extern "C" bool set_bounding_boxCmd(void); } `set clip [postscript] {on [.xleft. .xright. .ybottom. .ytop.]}|{to curve}|off' Control clipping of following drawing commands. `set clip on' Don't plot data outside axes. `set clip on .xleft. .xright. .ybottom. .ytop.' Don't plot data outside indicated box. `set clip off' Plot all data, whether in axes or not. `set clip to curve' Set clip to the curve, as would be drawn by a `draw curve filled' command, i.e. to the polygon constructed by running along the xy points, in order, followed by a final segment from the last point back to the first point. This is a "postscript" clip, as explained in the next item. `set clip postscript on .xleft. .xright. .ybottom. .ytop.' Turn PostScript clipping on. This will prevent *any* drawing outside the named box. Note that it will also prevent axis drawing, so the recommended procedure is something like draw axes set clip postscript on 10 20 0 1 draw curve set clip postscript off `set clip postscript off' Turn PostScript clipping off. SEE ALSO: `set input data window' command. { extern "C" bool set_clipCmd(void); } `set color \name|{rgb .red. .green. .blue.}|{hsb .hue. .saturation. .brightness.}' Set the color of the "pen" used for drawing lines and text. Normally lines and text are drawn in the same color, but the text color can be specified independently if desired (see `set font color') this might be useful to get contour lines of one color and labels of another. In the `set colour \name' style, set the drawing color to the indicated name, either from the builtin list (`white', `LightGray', `darkslategray', `black', `red', `brown', `tan', `orange', `yellow', `green', `ForestGreen', `cyan', `blue', `skyblue', `magenta'), or from a list created by `read colornames'. In the latter case, if the colorname has more than one word in it, use quotes, e.g. `set color "ghost white"'. In the `set colour rgb ...' style, set the individual color components as indicated. The numbers `.red.', `.green.' and `.blue.' range from 0 (for no contribution of that color component to the final color) to 1 (for maximal contribution). Values less than 0 are clipped to 0; values greater than 1 are clipped to 1. EXAMPLES: set color rgb 0 0 0 # black set color rgb 1 1 1 # white set color rgb 1 0 0 # bright red set color rgb 0.5 0 0 # dark red (only 50 percent) set color rgb 0 1 0 # pure green set color rgb 1 1 0 # yellow: red + green In the `set colour hsb ...' style, set the individual color components as indicated. The numbers `.hue.', `.saturation.' and `.brightness.' range from 0 to 1. The color, represented by .hue., ranges from 0 for pure red, through 1/3 for pure green, and 2/3 for pure blue, and back to 1 again for pure red. The purity of the color, represented by .saturation., ranges from 0 (none of the hue is visible) to 1 (the maximal amount is present). The brightness of the color, represented by `.brightness.', ranges from 0 (black) to 1 (maximal brigntness). Values less than 0 are clipped to 0; values greater than 1 are clipped to 1. EXAMPLES: set color hsb 0 1 1 # pure, bright red set color hsb 0 1 0.5 # half black, half red set color hsb .333 1 1 # pure, bright green { extern "C" bool set_colorCmd(void); } `set colour \name|{rgb .red. .green. .blue.}|{hsb .hue. .saturation. .brightness.}' Alternate spelling of 'color'. { extern "C" bool set_colorCmd(void); } `set colorname \\name {rgb .red. .green. .blue.}|{hsb .hue. .saturation. .brightness.}' Create a colorname with the indicated color. The color components range from 0 to 1, and will be clipped to these values if they are outside this range. EXAMPLE (borrowing a color from /usr/lib/X11/rgb.txt): set colorname peachpuff rgb 1 \{rpn 218 255 /} \{rpn 185 255 /} draw box filled 2 2 3 3 cm { extern "C" bool set_colornameCmd(void); } #* @param \style for contour format @default %g `set contour format \style|default' Normally, Gri draws the numeric labels of contour using a format code called `%g' in the "C" language. You may specify any other "long" format using this command. For example, `set contour format %.1f' tells Gri to use one decimal place in the numbers, and also to prefer the "float" notation to the exponential notation. `set contour format default' resets to the default `%f' format. You may use quotes around the format if you need to, to make the item be a single word (e.g. `set contour format "%.1f m/s"'). { extern "C" bool set_contour_formatCmd(void); } `set contour label for lines exceeding .x. cm' Make it so contour lines shorter than `.x.' centimeters will not be labelled. { extern "C" bool set_contour_labelCmd(void); } `set contour label position {.start_cm. .between_cm.}|centered|default' By default, contour labels are drawn at the location where contours start (e.g., the boundary), and then at a uniform distance along the contour. By default, this uniform distance is the average dimension of the plotting area inside the axes. If `.start_cm.' and `.between_cm.' are specified, the first label is drawn at a distance `.start_cm.' from the start of the contour, and thereafter at a separation of `.between_cm.'. If the `centered' option is used, then the contour labels are centered along the length of the line. { extern "C" bool set_contour_labelCmd(void); } `set contour labels rotated|horizontal|whiteunder|nowhiteunder' The first two options control whether contour labels are rotated to line up with the contour lines, or whether they are horizontal (the default). The second two options control whether the region under contour labels is whited out before drawing the label. The default is `whiteunder', which has the visual effect of the label having been drawn on a piece of paper and then pasted on. This can look jarring when the material under the contour is an image. When `nowhiteunder' is specified, the contour line is broken to make space for the text, but no whiting out is done. { extern "C" bool set_contour_labelsCmd(void); } #* @param .type. style of dash to use (range 0 to 15) @default 2 -> 0.4 cm dashes and 0.1 cm blanks `set dash [.type.|{.dash_cm. .blank_cm. ...}|off]' Control dash-style for following `draw curve' and `draw line' commands. * `set dash' Set to dashed line (0.4cm dashes, 0.1cm blanks). * `set dash .type.' Set to indicated pre-defined dashed line, according to table: .n. dash/cm blank/cm 0 - - ... (Solid line) 1 0.2 0.1 2 0.4 0.1 3 0.6 0.1 4 0.8 0.1 5 1.0 0.1 10 w w 11 w 2w 12 w 3w 13 w 4w 14 w 5w 15 w 6w Where `w' is written, it indicates the current linewidth. Thus, types 10 through 15 give square-dotted lines. * `set dash .dash_cm. .blank_cm. .dash_cm. .blank_cm. ...' Set to indicated dashed line. The series of lengths `.dash_cm.' and `.blank_cm.' give the lengths of dash and blank portions (measured in centimeters). Any number of dash/blank lengths may be given. For example, `set dash 0.5 0.1 0.1 0.1' looks good. * `set dash off' Turn dashing off, setting to a solid line. { extern "C" bool set_dashCmd(void); } `set environment' Set environment (graylevel, axis length, etc) so that following plotting commands will make use of anything set by either a `set' command or by direct manipulation of builtin variables like `..xsize..', etc. NOTE: this should *only* be done by developers. { extern "C" bool set_environmentCmd(void); } `set error action to core dump' Make Gri dump core when any error is found, to facilitate debugging. { extern "C" bool set_error_actionCmd(void); } `set flag \name [off]' Set the indicated flag to YES. The name of the flag is contained in a single word, e.g. `set flag dan_28sep_test'. The action of the flags may change with time and is undocumented. This command is provided to enable selected users (e.g., the developer himself) to use test features of Gri before they are frozen into a fixed syntax and action. The keyword `off' turns the indicated flag off. NOTE: this should *only* be done by developers. FLAG DATE ACTION jinyu1 29sep94 'convert columns to grid' outputs (x,y,z,z_predicted) emulate_gre 9jun97 'E' format on axes yields scientific notation kelley1 17jun97 for kelley only - quit contour trace if hit nonlegit kelley2 17jun97 for kelley only - print out tons of info as trace contour { extern "C" bool set_flagCmd(void); } `set font color \name|{rgb .red. .green. .blue.}|{hsb .hue. .saturation. .brightness.}' The syntax is the same as `set color', except that this applies to text only. By default, text is drawn in the same color as lines, so text color is changed as line color is changed (e.g. by using the `set color' or `set graylevel' commands)). However, once `set font color' is used in a Gri program, the font thereafter maintains a separate color from the lines. { extern "C" bool set_font_colorCmd(void); } `set font colour \name|{rgb .red. .green. .blue.}|{hsb .hue. .saturation. .brightness.}' Alternate spelling of 'color'. { extern "C" bool set_font_colorCmd(void); } `set font encoding PostscriptStandard | isolatin1' Permits one to control the so-called ``font encoding'' used in text. The default font encoding is ISO-Latin-1, which is best for English and other European languages. If the so-called `Postscript Standard'' font encoding is required, this command permits changing the encoding. Note: few users will ever need this command. If you don't even know what ``font encoding'' is about, ignore this command! { extern "C" bool set_font_encodingCmd(void); } #* @param .size. of font @unit point @default 12 @variable ..fontsize.. `set font size {.size. [cm]}|default' Set the size of the font for drawing of text. `set font size .size.' Set font size to `.size.' points. (A point is 1/72 of an inch, or 1/28 of a centimetre.) `set font size .size. cm' Set font size to `.size.' centimetres. `set font size default' Set font size to default = 12 pts. { extern "C" bool set_font_sizeCmd(void); } #* @param \fontname of font @default Helvetica `set font to \fontname' Set font to named style. Note that the backslash is *not* to be written, but here merely means that this word has several alternatives. For example, one might say `set font to Courier'. The allowed fontnames are: `Courier', a typewriter font; `Helvetica', a sans-serif font commonly used in drafting scientific graphs; `HelveticaBold', a bold version of Helvetica; `Times' (also called `TimesRoman'), a font used in most newspapers; `Palatino' (also called `PalatinoRoman'), similar to Times, but somewhat more elegant; `ZapfChancery', a font akin to the TeX caligraphic font; `Symbol', included for completeness, is a mathematical font in which "a" becomes $\alpha$ of the math mode, etc. For reference on these fonts see any book on PostScript. The default font is `Helvetica'. { extern "C" bool set_font_toCmd(void); } #* @param .brightness. of ink with 0 for black and 1 for white @default 0=black `set graylevel .brightness.|white|black' Set graylevel for lines to indicated numerical value between 0=black and 1=white, or to the named color. Note: if your diagram is to be reproduced by a journal, it is unlikely that the reproduction will be able to distinguish between any two graylevels which differ by less than 0.2. Also, graylevels less than 0.2 may appear as pure black, while those of 0.8 or more may appear as pure white. These guidelines are as specified by American Geophysical Union (publishers of J. Geophysical Res.), as of 1997. { extern "C" bool set_graylevelCmd(void); } `set greylevel .brightness.|white|black' Alternate spelling of graylevel. { extern "C" bool set_graylevelCmd(void); } `set grid missing {above|below .intercept. .slope.}|{inside curve}' The style `set grid missing above|below .intercept. .slope' sets grid to missing value for all points above/below the line defined by y = .intercept. + .slope. * x The style `set grid missing inside curve' sets the grid to the missing value throughout an area described by the curve last read in with `read columns'. This is useful for e.g. excluding land areas while contouring ocean properties. The curve may contain several "islands," each tracing (clockwise) a region inside of which the grid is to considered missing. If the first point in an island doesn't match the last, then an imaginary line is assumed which connects them. Multiple islands may be separated by missing-value codes. { extern "C" bool set_grid_missingCmd(void); } `set ignore initial newline [off]' Make Gri ignore a newline if it occurs as the first character of the next data file. This is used for files made by FORTRAN programs on VAX/VMS computers. { extern "C" bool set_ignore_initial_newlineCmd(void); } `set ignore error eof' Stop Gri from considering that to encounter an end of file in future `read' commands consitutes an error; Gri will simply warn about future EOFs. { extern "C" bool set_ignoreCmd(void); } `set image colorscale ...' set image colorscale hsb .h. .s. .b. .im_value. hsb .h. .s. .b. .im_value. [increment .im_value.] set image colorscale rgb .r. .g. .b. .im_value. rgb .r. .g. .b. .im_value. [increment .im_value.] set image colorscale \name .im_value. \name .im_value. [increment .im_value.] Set colorscale mapping for image, using HSB (hue, saturation, brightness) specification, RGB (red, green, blue) color specification, or named colors. The image range must have previously have been set by `set image range', so that the `.im_value.' values will have meaning. Two pairs of (color, image-value) are given, and possibly an increment. Normally the colors are smoothly blended between the endpoints, but if an increment is supplied, the colors are quantized. The HSB method allows creation of spectral palettes, while the other two methods create simple blending between the two endpoints. EG: To get a spectrum ranging between pure red (H=0) for image value of -10.0, and pure blue (H=2/3) for image value of 10.0, do this: set image colorscale hsb 0 1 1 -10.0 hsb .66666 1 1 10.0 EG: To get a scale running from pure red (at image-value 10.0) into pure blue (at image-value 25.1), but with the colors blending intuitively in between (i.e., blending as paint might), use `rgb' color specification, as follows: set image colorscale rgb 1 0 0 10.0 rgb 0 0 1 25.1 EG: To get a quantized blend between the X11 colors `skyblue' at image value of 0 and `tan' at image value of 20, and with steps at image values incrementing by 5, do this: set image colorscale skyblue 0 tan 20 increment 5 Note that the traversal is through RGB space, so it is intuitive, not spectral. See `set color' for a list of X11 colors known to Gri. { extern "C" bool set_image_colorscaleCmd(void); } `set image colourscale ...' Alternate spelling of colorscale. { extern "C" bool set_image_colorscaleCmd(void); } `set image grayscale using histogram [black .bl. white .wh.]' Create a grayscale mapping using linearized cumulative histogram enhancement. The image range must have previously have been set by `set image range'. This creates maximal contrast in each range of graylevels, and is useful for tracing subtle features between different images (for example, it makes it easier to trace fronts between successive satellite images). The entire histogram is expanded, from the smallest value in the image to the largest. With no options specified, the histogram is done from 0 in the image to 255 in the image. If the black/white options are specified, the histogram is done between these values. { extern "C" bool set_image_grayscale_using_histogram(void); } `set image greyscale using histogram [black .bl. white .wh.]' Alternate spelling of grayscale { extern "C" bool set_image_grayscale_using_histogramCmd(void); } `set image grayscale [black .bl. white .wh. [increment .inc.]]' With no optional parameters, create a grayscale mapping for the current image, scaling it from black for the mininum value in the image to white for the maximum value. The image range must have previously have been set by `set image range'. The optional parameters `.wh.' and `.bl.' specify the values to be drawn in white and black in the image, with smooth linear blending in between. Normally the blending from white to black is smooth (linear), but if the additional optional parameter `.inc.' is specified, the blending is quantized, jumping to darker values at (`.wh.' + `.inc.'), (`.wh.' + 2* `.inc.'), etc. (The sign of `.inc.' will be altered, if necessary, to ensure that (`.wh.' + `.inc.') is between `.wh.' and `.inc.'.) The colour switches to pure white at the value `.wh.', and remains pure white everywhere on the "white" side of this value. Similarly, the transition to pure black occurs at the value `.bl.'. In other words, neither pure white nor pure black is present inside the interval from `.wh.' to `.bl.'. Therefore, when drawing grayscales with the `draw image palette' command, you might want to extend the range by one increment so as to get an example of both pure white and pure black. .w. = 0 .b. = 1 .i. = 0.2 set image grayscale white .w. black .b. increment .i. draw image palette left \{rpn .w. .i. -} right \{rpn .b. .i. +} increment .i. { extern "C" bool set_image_grayscaleCmd(void); } `set image greyscale [black .bl. white .wh. [increment .inc.]]' Alternate spelling of grayscale. { extern "C" bool set_image_grayscaleCmd(void); } `set image missing value color to white|black|{graylevel .brightness.}{rgb .red. .green. .blue.}' Set the color of "missing" pixels (white by default). The image range must have previously have been set by `set image range'. Pixels with missing values can result from creating images from grids which have missing values; see the `convert grid to image' command. The `.brightness.' parameter in the `graylevel' style ranges from 0 for black to 1 for white. The `rgb' parameter allows specification in colour. { extern "C" bool set_image_missingCmd(void); } `set image missing value colour to white|black|{graylevel .brightness.}' Alternate spelling of color. { extern "C" bool set_image_missingCmd(void); } `set image range .min_value. .max_value.' Specify maximum possible range of values that images can hold, in user units. Gri needs to know this because it stores images in a limited format capable of holding only 256 distinct values. Unlike some other programs, Gri encourages (forces) the user to specify things in terms of user-units, not image-units. This has the advantage of working regardless of the number of bits per pixel. Thus, for example, `set image grayscale', `set image colorscale', `draw image grayscale', etc, all use *user* units. When an image is created by `convert grid to image', values outside the range spanned by `.0value.' and `.255value.' are clipped. (There is no need, however, for `.0value.' to be less than `.255value.'.) This clipping discards information, so make sure the range you give is larger than the range of data in the grid. EXAMPLE: consider a satellite image in which an internal value of 0 is meant to correspond to 0 degrees Celsius, and an internal value of 255 corresponds to 25.5 degrees. (This is a common scale.) Then Gri command `set image range 0 25.5' would establish the required range. If this range were combined with a linear grayscale mapping (see `set image grayscale'), the resultant granularity in the internal representation of the user values would be (25.5-0)/255 or 0.1 degrees Celsius; temperature variations from pixel to pixel which were less than 0.1 degrees would be lost. All other image commands *require* that the range has been set. Thus, all these commands fail unless `set image range' has been done: `draw image', `draw image palette', `read image', `convert grid to image', `set image grayscale', and `set image colorscale'. NOTE: If a range already exists when `set image range' is used, then the settings are altered. Thoughtless usage can therefore lead to confusing results. (The situation is like setting an axis scale, plotting a curve with no axes, then altering the scale and plotting the new axes. It's legal but not necessarily smart.) { extern "C" bool set_image_rangeCmd(void); } `set input data window x|y {.min. .max.}|off' Create a data window for following `read' statements. `set input data window x .min. .max.' For future reading commands, ignore all data with x < `.min.' or x > `.max.' The data not in the interval will not be read in at all. This will hold until `set data window x off' is done, in which case all data will be read in. `set input data window x off' Return to normal conditions, in which all data are read in. `set input data window y .min. .max.' Analogous to command for x. `set input data window y off' Analagous to command for x. EXAMPLE: To set the input data window as the current x axis plus a border of 5 centimetres to left and right, do the following: set input data window x \{rpn ..xleft.. xusertocm 5 - xcmtouser} \ \{rpn ..xright.. xusertocm 5 + xcmtouser} SEE ALSO `set clip' command. { extern "C" bool set_input_data_windowCmd(void); } `set input data separator TAB|default' Set the separator between data items. The `default' method is to assume that data items are separated by one or more spaces or tabs, and also to ignore any spaces or tabs at the start of a data line. In the TAB method the data are assumed to be separated by a SINGLE tab character. (Multiple tabs will result in null values being assigned to items -- almost certainly not what you want!) Also, initial spaces and tabs on lines are NOT skipped. Use the TAB method only after thinking carefully about the above, since the assignment of null values is problematic. { extern "C" bool set_input_data_separatorCmd(void); } `set line cap .type.' Set the type of ends (caps) of lines. Use `.type.' of value 0 for square ends, cut off precisely at the end of line, or 1 for round ends which overhang half the line width, or 2 for square ends which overhang half the line width. The selected style is used for the ends of line segments, as well as at corners. In PostScript parlance, therefore, this command sets both the linecap and the linejoin parameters. This command only applies to lines drawn with `draw curve', `draw line' and `draw polygon'. Axes are always drawn with a line cap of 0. { extern "C" bool set_line_capCmd(void); } `set line join .type.' Set the type of intersection of lines. Use `.type.' of value 0 for mitered joins (pointy ends that may extend beyond the data points), a value of 1 for rounded ends (the default), or a value of 2 for bevelled (squared-off) ends. See the `setlinejoin' command in any text on the PostScript language for more information. This command only applies to lines drawn with `draw curve', `draw line' and `draw polygon'. Axes are always drawn with a line join of 0. { extern "C" bool set_line_joinCmd(void); } #* @param .width_pt. @unit point @default 0.709 @variable ..linewidth.. `set line width [axis|symbol|all] .width_pt.|{rapidograph \name}|default' Set the width of lines used to draw curves (default), axes, symbols, or all of the above. The width may be set to a value specified in points (conversion: 72 pt = 1 inch), to a named rapidograph width, or to the default value. The initial default values are: 0.709pt (or rapidograph 3x0) for curves; 0.369pt (or rapidograph 6x0) for axes; 0.369pt (or rapidograph 6x0) for symbols. The rapidograph settings match the standard set of widths used in technical fountain pens. The table below gives width names along with the width in points and centimetres, as given in the specifications supplied with Rapidograph technical fountain pens. Names marked by the symbol `*' are in sequence increasing by the factor root(2). Texts on technical drawing often suggest using linewidths in the ratio of 2 or root(2). On many printers, the variation in width from root(2) increase is too subtle to see, so the factor-of-2 rule may be preferable. To get sizes in a sequence doubling in width, pick from the list (`6x0', `3x0', `1', `3.5' `7'). To get a sequence increasing in width by root(2), pick from the list (`6x0', `4x0', `3x0', `0', `1', `2.5', `3.5', `6', `7'). The eye can distinguish curves with linewidths differing by a factor of root(2) if the image is of high quality, but a factor of 2 is usually better. Similarly, for overhead projections and projected slides, one would do well to use linewidths differing by a factor of 4. This is the list of `rapidograph' linewidths: Name pt cm ==== ===== ===== * 6x0 0.369 0.013 * 4x0 0.510 0.018 * 3x0 0.709 0.025 00 0.850 0.03 * 0 0.992 0.035 * 1 1.417 0.05 2 1.701 0.06 * 2.5 1.984 0.07 3 2.268 0.08 * 3.5 2.835 0.1 4 3.402 0.12 * 6 3.969 0.14 * 7 5.669 0.2 { extern "C" bool set_line_widthCmd(void); } #* @param .value. to be considered missing @default 1.0e22 @variable ..missingvalue.. `set missing value .value.' Set missing-value code (stored in the builtin variable `..missingvalue..' and builtin synonym `\.missingvalue..') to `.value.', which mean that data within 0.1 percent of this value are ignored. The initial default is 1.0e22. { extern "C" bool set_missing_valueCmd(void); } `set postscript filename "\string"' Set name of PostScript file, over-riding the present name. { extern "C" bool set_postscript_filenameCmd(void); } `set page size letter|legal|folio|tabloid|A0|A1|A2|A3|A4|A5' Prevent bounding box from extending outside the indicated page domain. { extern "C" bool set_page_sizeCmd(void); } `set page portrait|landscape|{factor .mag.}|{translate .xcm. .ycm.}' Control orientation or scaling of what is drawn on the paper. * `set page portrait' Print graph normally (default). * `set page landscape' Print graph sideways. * `set page factor .mag.' Scale everything to be drawn on the paper by the indicated magnification factor. This *must* be called before any drawing commands. * `set page translate .xcm. .ycm.' Translate everything to be drawn on the paper by the indicated x/y distances. This *must* be called before any drawing commands. *Note*: The order of the factor/translate commands matters, so you may need to experiment. For example, set page translate 2 1 set page factor 0.5 moves anything that would have been drawn at the lower-left corner of the paper onto the point 2cm from the left side and 1cm from the bottom side of the paper, and then applies the multiplication factor. Reversing the order gives quite different results. PostScript gurus should note that the following two commands are inserted into the PostScript file: 56.900000 28.450000 translate 0.500000 0.500000 scale { extern "C" bool set_pageCmd(void); } `set panel .row. .col.' Establish geometry for the panel in the indicated row and column. The bottom row has .row. = 1, and the leftmost column has .col. = 1. This must be used only after using `set panels .row. .col. .dx_cm. .dy_cm.' { if {rpn \.words. 4 !=} show "ERROR: `\.proper_usage.' needs 3 words" quit 1 end if new .row. .col. .row. = \.word2. .col. = \.word3. set x margin {rpn .col. 1 - .panel_xsize. .panel_dx. + * .panel_xmargin. +} set y margin {rpn .row. 1 - .panel_ysize. .panel_dy. + * .panel_ymargin. +} set x size .panel_xsize. set y size .panel_ysize. delete .row. .col. } `set panels .rows. .cols. [.dx_cm. .dy_cm.]' Set up for multipanel plots, with spacing .dx_cm. between the columns and .dy_cm. between the rows. If the spacings are not supplied, 2cm is used. The panels fill the rectangle which would otherwise contain the single axis frame, as set by `set x size' and `set x margin', etc. The global variables .panel_dx., .panel_dy., .panel_xmargin., .panel_ymargin., .panel_xsize., and .panel_ysize are created, to be used by later calls to `set panel'. EXAMPLE # Draw 2 panels across, 3 up the page. # The Panel interiors will be in region cornered # by (2,2), (12,22) cm set x margin 2 set y margin 2 set x size 10 set y size 20 set panels 2 3 # Create dummy scale set x axis 0 1 set y axis 0 1 # Draw blank axes set panel 1 1 draw axes set panel 1 2 draw axes set panel 1 3 draw axes set panel 2 1 draw axes set panel 2 2 draw axes set panel 2 3 draw axes SEE ALSO `set panel .row. .col.' { # creates globals # .panel_dx. .panel_dy. # .panel_xmargin. .panel_ymargin. # .panel_xsize. .panel_ysize. if {rpn \.words. 4 ==} .panel_dx. = 2 .panel_dy. = 2 else if {rpn \.words. 6 ==} .panel_dx. = \.word4. .panel_dy. = \.word5. else show "ERROR: `\.proper_usage.' needs 5 words" quit 1 end if new .rows. .cols. # local storage .rows. = \.word2. .cols. = \.word3. if {rpn .panel_dx. 0 >} show "ERROR: `\.proper_usage.' needs .dx. to be non-negative" quit 1 end if if {rpn .panel_dy. 0 >} show "ERROR: `\.proper_usage.' needs .dy. to be non-negative" quit 1 end if .panel_xmargin. = ..xmargin.. .panel_ymargin. = ..ymargin.. .panel_xsize. = {rpn ..xsize.. .panel_dx. .cols. 1 - * - .cols. /} .panel_ysize. = {rpn ..ysize.. .panel_dy. .rows. 1 - * - .rows. /} delete .rows. .cols. } #* @param \path for data or command files @default "." `set path to "\path"|default for data|commands' Set directory path for finding data files or command files. The default is ".", the current directory. { extern "C" bool set_pathCmd(void); } #* @param .diameter_cm. diameter size of symbols @unit cm @default 0.1 `set symbol size .diameter_cm.|default' Control the size (diameter) of symbols drawn by `draw symbol' command. `set symbol size .diameter_cm.' Make symbol size (diameter) be `.diameter_cm.' centimeters. `set symbol size default' Set to default diameter of 0.1 cm. { extern "C" bool set_symbol_sizeCmd(void); } #* @param $.size. of axes tics @unit cm @default 0.2 `set tic size .size.|default' Control size of tics on axes. `set tic size .size.' Set tic size to `.size.' centimetres. `set tic size default' Set tic size to default of 0.2 cm { extern "C" bool set_tic_sizeCmd(void); } `set tics in|out' Make axis tics point inward or outward. The default is outward. { extern "C" bool set_ticsCmd(void); } `set trace [on|off]' Control printing of command lines as they are processed. `set trace' Make Gri print command lines as they are processed. `set trace on' Same as `set trace'. `set trace off' Prevent printing command lines (default). { extern "C" bool set_traceCmd(void); } `set transparency .transparency.' Set the transparency of drawn items, 0 for opaque and 1 for invisibly faint. { extern "C" bool set_transparencyCmd(void); } `set u scale .cm_per_unit.|{as x}' Set scale for x-component of arrows. `set u scale .cm_per_unit.' Set scale for `u' component of arrows. `set u scale as x' Set scale for u component of arrows to be the same as the x-scale. Equivalent to `set u scale as \{rpn ..xsize.. ..xright.. ..xleft.. - /}'. NOTE: this only works if the x-scale is LINEAR (see `set x type'). { extern "C" bool set_u_scaleCmd(void); } `set v scale .cm_per_unit.|{as y}' Set scale for y-component of arrows. `set v scale .cm_per_unit.' Set scale for `v' component of arrows. `set v scale as y' Set scale for v component of arrows to be the same as the y-scale. Equivalent to `set v scale as \{rpn ..ysize.. ..ytop.. ..ybottom.. - /}'. NOTE: this only works if the y-scale is LINEAR (see `set y type'). { extern "C" bool set_v_scaleCmd(void); } `set x axis top|bottom|increasing|decreasing|{.left. .right. [.incBig. [.incSml.]]}|{labels [add] .pos. "label" [...]}|{labels automatic}||unknown' Control various things about the x axis. `set x axis top' Make next x-axis to be drawn have labels above the axis. `set x axis bottom' Make next x-axis to be drawn have labels below the axis. `set x axis increasing' Make next x-axis to be drawn have numeric labels increasing to the right. This applies only if autoscaling is done; otherwise, the supplied values (`.left. .right. [.incBig. [.incSml.]]') are used. `set x axis decreasing' ke next x-axis to be drawn have numeric labels decreasing to the right. This applies only if autoscaling is done; otherwise, the supplied values (`.left. .right. [.incBig. [.incSml.]]') are used. `set x axis unknown' Make Gri forget any existing scale for the x axis, whether set by another `set x axis' command or automatically, during reading of data. This is essentially a synonym for `delete x scale'. `set x axis .left. .right.' Make x-axis range from `.left.' to `.right.' `set x axis .left. .right. .incBig.' Make x-axis range from `.left.' to `.right.', with labelled increments at `.incBig.' Note: In the case of log axes, and provided that `set x type log' has been called previously, the `.incBig.' parameter has a different meaning: it is the interval, in decades, between numbered labels; the default is 1. `set x axis .left .right. .incBig. .incSml.' Make x-axis range from `.left.' to `.right.', with labelled increments at `.incBig.', and small tics at `.incSml.' NOTE: if the axis is logarithmic, the value of `.incSml.' takes on a special meaning: if it is positive then small tics are put at values 2, 3, 4, etc. between the decades, but if `.incSml.' is negative then no such small tics are used. `set x axis labels [add] .position. "label" [.position. "label" [...]]' Override the automatic labelling at axis tics, and instead put the indicated labels at the indicated x values. For example, a day-of-week axis can be created by the code: set x axis 0 7 1 set x axis labels 0.5 "Mon" 1.5 "Tue" 2.5 "Wed" \ 3.5 "Thu" 4.5 "Fri" 5.5 "Sat" \ 6.5 "Sun" The command replaces any existing labels, unless the `add' keyword is present, in which case the new label information is appended to any existing information. `set x axis labels automatic' Return to automatically-generated axis labels, undoing the command of the previous item. { extern "C" bool set_x_axisCmd(void); } #* @param \format for axis numbers in C notation @default %g `set x format \format|default|off' Set format for numbers on x axis. The format is specified in the manner of the "C" programming language. The "C" formats (i.e., `%f', `%e' and `%g') are permitted. For example, `set x format %.1f' tells Gri to use 1 decimal place, and to prefer the "float" notation to the exponential notation. The form `set x format off' tells Gri not to write numbers on the axis. To get spaces in your format, enclose the format string in double-quotes, e.g., you might use `set x format "%.0f$\circ$ W"' for a map, or `set x format "%f "' to make the numbers appear to the left of their normal location. The default format is `%lg'. { extern "C" bool set_x_formatCmd(void); } `set x grid .left. .right. .inc.|{/.cols.}' Create x-grid for contour or image. `set x grid .left. .right. .inc.' Create x-grid ranging from the value `.left.' at the left to `.right.' at the right, stepping by an increment of `.inc.'. `set x grid .left. .right. /.cols.' Create x-grid with `.cols.' points, ranging from the value `.left.' at the left to `.right.' at the right. { extern "C" bool set_x_gridCmd(void); } #* @param .size. of x margin @unit cm @default 6 @variable ..xmargin.. `set x margin {[bigger|smaller] .size.} | default' Control x margin, that is, the space between the left-hand side of the page and the left-hand side of the plotting area. (Note that axis labels are drawn inside the margin; the margin extends to the axis line, not to the labels.) `set x margin .size.' Set left margin to `.size.' cm. It is permissible to have negative margins, with the expected effect. `set x margin bigger .size.' Increases left margin by `.size.' cm. `set x margin smaller .size.' Decreases left margin by `.size.' cm. `set x margin default' Set left margin to default = 6 cm. { extern "C" bool set_x_marginCmd(void); } #* @param \name of x axis @default "" `set x name "\name"|default' Set name of x-axis to the indicated string. An empty string (`set x name ""') causes the x axis to be unlabelled. The `default' is `"x"'. { extern "C" bool set_x_nameCmd(void); } #* @param .width_cm. of axis @unit cm @default 10 @variable ..xsize.. `set x size .width_cm.|default' Set the width of the plotting area. This does not include axis labels, only the interior part of the plot. `set x size .width_cm.' Set width of x-axis in centimeters. `set x size default' Set width of x-axis to default = 10 cm. { extern "C" bool set_x_sizeCmd(void); } `set x type linear|log|{map E|W|N|S}' Control transformation function mapping user units to centimetres on the page. * `set x type linear' Set to linear axis. * `set x type log' Set to log axis. To avoid clashes in the linear to log transform, this command should precede the creation of an axis scale, either explicitly through the `set x axis .left. .right. ...' command or implicitly through the `read columns' command. * `set x type map E|W|N|S' Set to be a map. This means that whole numbers on the axis will have a degree sign written after them (and then the letter `E', etc) and that numbers which are multiples of 1/60 will be written in degree-minute format, and that similarly numbers which are divisible by 1/3600 will be in degree-minute-second format. If none of these things apply, the axis labels will be written in decimal degrees. Note that this command overrides any format set by `set x format'. BUG: this only has an effect if the axis is not already of type `log'. SEE ALSO: `set map projection', to set to non-rectangular axes for various map projections. { extern "C" bool set_x_typeCmd(void); } `set y axis left|right|increasing|decreasing|{.bottom. .top. [.incBig. [.incSml.]]}|{labels [add] .pos. "label" [...]}|{labels automatic}|{name vertical|horizontal}|unknown' Control various things about the y axis. `set y axis left' Make next y-axis to be drawn have labels to the left of the axis. `set y axis right' Make next y-axis to be drawn have labels to the right of the axis. `set y axis increasing' Make next y-axis to be drawn have numeric labels increasing up the page. This applies only if autoscaling is done; otherwise, the supplied values (`.left. .right. [.incBig. [.incSml.]]') are used. `set y axis decreasing' Make next y-axis to be drawn have numeric labels decreasing up the page. This applies only if autoscaling is done; otherwise, the supplied values (`.left. .right. [.incBig. [.incSml.]]') are used. `set y axis unknown' Make Gri forget any existing scale for the y axis, whether set by another `set y axis' command or automatically, during reading of data. This is essentially a synonym for `delete y scale'. `set y axis .bottom. .top.' Make y-axis range from `.bottom.' to `.top.' `set y axis .bottom. .top. .incBig.' Make y-axis range from `.bottom.' to `.top.', with labelled increments at `.incBig.' `set y axis .bottom. .top. .incBig. .incSml.' Make y-axis range from `.bottom.' to `.top.', with labelled increments at `.incBig.', and small tics at `.incSml.' NOTE: if the axis is logarithmic, the value of `.incSml.' takes on a special meaning: if it is positive then small tics are put at values 2, 3, 4, etc. between the decades, but if `.incSml.' is negative then no such small tics are used. `set y axis labels [add] .position. "label" [.position. "label" [...]]' Override the automatic labelling at axis tics, and instead put the indicated labels at the indicated y values. For example, a day-of-week axis can be created by the code: set y axis 0 1 0.5 set y axis labels 0.25 "Weak" 0.75 "Strong" The command replaces any existing labels, unless the `add' keyword is present, in which case the new label information is appended to any existing information. `set y axis labels automatic' Return to automatically-generated axis labels, undoing the command of the previous item. `set y axis name vertical' Cause future y axes to be drawn with the name aligned vertically (the default). `set y axis name horizontal' Cause future y axes to be drawn with the name aligned horizontally. { extern "C" bool set_y_axisCmd(void); } #* @param \format for axis numbers in C notation @default %g `set y format \format|default|off' Set format for numbers on y axis. The format is specified in the manner of the "C" programming language. The "C" formats (i.e., `%f', `%e' and `%g') are permitted. For example, `set y format %.1f' tells Gri to use 1 decimal place, and to prefer the "float" notation to the exponential notation. The form `set y format off' tells Gri not to write numbers on the axis. To get spaces in your format, enclose the format string in double-quotes, e.g., you might use `set y format "%.0f$\circ$ N"' for a map, or `set y format " %f"' to make the numbers appear to the right of their normal location. The default format is `%lg'. { extern "C" bool set_y_formatCmd(void); } `set y grid .bottom. .top. .inc.|{/.rows.}' Create y-grid for contour or image. `set y grid .bottom. .top. .inc.' Create y-grid ranging from the value `.bottom.' at the bottom to `.top.' at the top, stepping by an increment of `.inc.'. `set y grid .bottom. .top. /.rows.' Create y-grid with `.rows.' points, ranging from the value `.bottom.' at the bottom to `.top.' at the top. { extern "C" bool set_y_gridCmd(void); } #* @param .size. of y margin @unit cm @default 6 @variable ..ymargin.. `set y margin {[bigger|smaller] .size.} | default' Control y margin, that is, the space between the bottom side of the page and the bottom of the plotting area. (Note that axis labels are drawn inside the margin; the margin extends to the axis line, not to the labels.) `set y margin .size.' Set bottom margin to `.size.' centimeters. It is permissible to have negative margins, with the expected effect. `set y margin bigger .size.' Increases bottom margin by `.size.' centimeters. `set y margin smaller .size.' Decreases bottom margin by `.size.' centimeters. `set y margin default' Set bottom margin to default = 6 cm. { extern "C" bool set_y_marginCmd(void); } #* @param \name of y axis @default "y" `set y name "\name"|default' Set name of y-axis to the indicated string. An empty string (`set y name ""') causes the y axis to be unlabelled. The `default' is `"y"'. { extern "C" bool set_y_nameCmd(void); } #* @param .height_cm. of y axis @unit cm @default 10 @variable ..ysize.. `set y size .height_cm.|default' Set the width of the plotting area. This does not include axis labels, only the interior part of the plot. `set y size .height_cm.' Set height of y-axis in centimeters. `set y size default' Set width of y-axis to default = 10 cm. { extern "C" bool set_y_sizeCmd(void); } `set y type linear|log|{map N|S|E|W}' Control transformation function mapping user units to centimetres on the page. * `set y type linear' Set to linear axis. * `set y type log' Set to log axis. To avoid clashes in the linear to log transform, this command should precede the creation of an axis scale, either explicitly through the `set y axis .left. .right. ...' command or implicitly through the `read columns' command. * `set y type map N|S|E|W' Set to be a map. This means that whole numbers on the axis will have a degree sign written after them (and then the letter `N', etc), and that numbers which are multiples of 1/60 will be written in degree-minute format, and that similarly numbers which are divisible by 1/3600 will be in degree-minute-second format. If none of these things apply, the axis labels will be written in decimal degrees. Note that this command overrides any format set by `set y format'. BUG: this only has an effect if the axis is not already of type `log'. SEE ALSO: `set map projection', to set to non-rectangular axes for various map projections. { extern "C" bool set_y_typeCmd(void); } `set z missing above|below .intercept. .slope.' Set `z' column to be missing whenever the associated `y' and `x' columns are above/below the line defined by y = .intercept. + .slope. * x { extern "C" bool set_z_missingCmd(void); } `set "..."' { extern "C" bool setCmd(void); } `show all' Show lots of information about plot. { extern "C" bool show_allCmd(void); } `show axes' Show information about axes. { extern "C" bool show_axesCmd(void); } `show color' Show the current pen color used for lines and text. This is not to be confused with image color, which is independent. { extern "C" bool show_colorCmd(void); } `show colornames' Show all colors known by name, as defined by `read colornames' command and also the builtin colors defined automatically (e.g. `white', `black', `red', etc). { extern "C" bool show_colornamesCmd(void); } `show columns [statistics]' `show columns' Show x, y, z, u, v column data. `show columns statistics' Show means, std devs, etc for columns. { extern "C" bool show_columnsCmd(void); } `show flags' Show values of all flags. (Developers only.) { extern "C" bool show_flagsCmd(void); } `show grid [mask]' Show grid data (used for contouring), or show the grid mask (1 if data are acceptable for contouring, or 0 if contours will not extend into this region). { extern "C" bool show_gridCmd(void); } `show hint of the day' Show a Gri hint for today, randomly selected from a list of hints maintained on the Gri WWW site. Hints are cached, so that today's your hint will only be dowloaded once, and stored in your ~/.gri-hint-cache file. { extern "C" bool show_hintCmd(void); } `show image' Show information about image, such as a histogram of values, and, if the image is small enough, the actual data. { extern "C" bool show_imageCmd(void); } `show license' Show license, allowing copying of Gri { extern "C" bool show_licenseCmd(void); } `show misc' Show miscellaneous information about the plot, the data, etc. { extern "C" bool show_miscCmd(void); } `show next line' Show next line of data-file. { extern "C" bool show_next_lineCmd(void); } `show traceback' Show traceback (i.e., the tree of commands being done at this instant). { extern "C" bool show_tracebackCmd(void); } `show stopwatch' Show elapsed time since first call to this command in the given Gri program. { extern "C" bool show_stopwatchCmd(void); } `show synonyms' Show values of all synonyms, whether built-in or user-defined. { extern "C" bool show_synonymsCmd(void); } `show time' Show the current time. { extern "C" bool show_timeCmd(void); } `show variables' Show values of all variables, whether built-in or user-defined. { extern "C" bool show_variablesCmd(void); } `show .value. | {rpn ...} | "\text" [.value.|{rpn ...}|text [...]]' `show .value.' Show value of indicated variable. `show \{rpn ...}' Show result of computing indicated expression. `show "some text"' Print the indicated string. `show "time=" .time. "; depth=" .depth.' Print strings and values as indicated. If the last item is ellipses (three dots with no spaces between them), then no newline is printed; this makes the next `show' statement print on the same line. { extern "C" bool show_expression_or_stringCmd(void); } `skip [forward|backward] [.n.]' `skip' For ascii files, skip forward 1 line in the data file. For binary files, skip forward 1 byte. `skip backward' For ascii files, skip backward 1 line in the data file. For binary files, skip backward 1 byte. `skip .n.' `skip forward .n.' For ascii files, skip forward `.n.' lines in the data file. For binary files, skip forward `.n.' bytes. `skip backward .n.' For ascii files, skip backward `.n.' lines in the data file. For binary files, skip backward `.n.' bytes. { extern "C" bool skipCmd(void); } `sleep .sec.' Cause Gri to sleep for the indicated number of seconds, which should be a positive integer. This command is ignored if `.sec.' is zero or negative, and the value of `.sec.' is first rounded to the nearest integer. Normally, this command is used only be the developer, as a way to slow down Gri execution, to allow easier monitoring for debugging purposes. Beware: it is tricky to kill a sleeping job! { extern "C" bool sleepCmd(void); } `smooth {x [.n.]} | {y [.n.]} | {grid data [.f.|{along x|y}]}' All these smoothing commands ignore the *location* of the data. For equispaced data these algorithms have the standard interpretation in terms of digital filters. For non-equispaced data, the interpretation is up to the user. The `smooth x' command does smoothing by the following formula x[i-1] x[i] x[i+1] ------ + ---- + ------ 4 2 4 The `smooth x .n.' command does boxcar smoothing using centred boxcars `.n.' points wide. The `smooth y' command does the same as `smooth x', but on the `y' column. There are several methods of smoothing grid data. Note that isolated missing values are filled in by each method. (Let the author know if you'd like that `feature' to be an option.) The `smooth grid data' command smooths gridded data, by weighted average in a plus-shaped window about each gridpoint. The smoothing algorithm replaces each interior gridpoint value `z[i][j]' by z[i][j] z[i-1][j] + z[i+1][j] + z[i][j-1] + z[i][j+1] ------- + --------------------------------------------- 2 8 Points along the edges are smoothed by the same formula, after inventing image points outside the domain by planar extrapolation. The `smooth grid data .f.' command performs partial smoothing. A temporary fully-smoothed grid `zSMOOTH[i][h]' is constructed as above, and a linear combination of this grid and the original grid is used as the replacement grid: z[i][j] = (1-f) * z[i][j] + f * zSMOOTH[i][j] where `f' is the value indicated on the command line. Thus, `smooth grid data 0' performs no smoothing at all, while `smooth grid data 1' is equivalent to `smooth grid data'. The `smooth grid data along x' command smooths the grid data along `x' (i.e., horizontally), by replacing each value `z[i][j]' with the value z[i][j] z[i-1][j] + z[i+1][j] ------- + --------------------- 2 4 Points along the edges are smoothed by the same formula, after inventing image points outside the domain by linear extrapolation. The `smooth grid data along y' command does the same thing as `smooth grid data along x', but the smoothing is along `y'. SEE ALSO: `filter', a generalization of `smooth x|y' which allows for more sophisticated filters. { extern "C" bool smoothCmd(void); } `source \filename' Insert instructions in named file into current file. This is useful as a way of sharing global information between several Gri programs. On unix systems, if a full filename is specified (i.e., a filename beginning with slash or period), then that particular file will be used. { extern "C" bool sourceCmd(void); } `sprintf \synonym "format" .variable. [.variable. [...]]' Write numbers into a synonym (text string). This is useful for labelling plots. `sprintf \out "a = %f b = %.2f" .a. .b.' - Create a synonym called `\out', and print the values of the variables `.a.' and `.b.' into it. If `.a.' = 1 and `.b.' = 0.112, then `\out' will be `"a = 1 b = 0.11"' Formatting codes are as in the C programming language, eg: %.2f -- Use floating point notation with 2 decimal places. %9.2f -- As above, but specify the number to occupy 9 characters. %e -- Use exponential notation. WARNING: Variables are stored in the "double" storage type of the "C" programming language, so "long" formats must be used in `sprintf'. { extern "C" bool sprintfCmd(void); } `state save|restore|display' The `save' operation pushes a record of the graphics state (pen and font characteristics, margins, axis lengths, min/max/inc values on axes, etc) onto a stack. The `restore' operation replaces the present state with whatever is on top of the stack, and then pops the stack. Use the `display' operation to see some of the state properties. The `state' command is useful for temporary changes of axis properties, etc. BUG: only line characteristics (width, color) and font characteristics (font, size, color) are saved so far. In fact, the full list of what should be saved has not yet been finalized by the author. { extern "C" bool stateCmd(void); } `superuser' Allow extra debugging information and commands. Normally, this command and the corresponding commandline flag -superuser are only used by programmers altering the Gri source. These are the flags and their meanings: 1 Print cmdline before/after substituting synonyms 2 Print cmdline before/after substituting rpn expressions 4 Print all new commands as they are being defined 8 Print system commands and `open "...|"' commands before they are passed to the system Note that all flags are equal to 2 raised to an integer power. Since the flag values are detected by a bitwise OR, you can combine glags by adding; thus specifying a flag of 5 yields flags 1 and 4 together. { extern "C" bool superuserCmd(void); } `system \system-command' Tell the operating system to perform the indicated action. Whatever string follows the word `system' is passed directly to the operating system, *after* substitution of synonyms if any exist. Note that `rpn' expressions are not evaluated, and variable values are not substituted before passing the string to the operating system. The exit status is stored in the builtin variable `..exit_status..'. There are two ways to use the system: * *Assign output to synonym*: The form `\synonym = system ...' does the system command and then inserts the output from that command into the indicated synonym.) * *Just run a command*: The command `system ls' will list the files in the current directory. For long commands, there are two approaches, the second preferred: * *Use continuation lines*: String a lot of information onto one effective system line, using the `\' line-continuation character at the ends of lines. The problem is that it's very easy to lose one of these backslashes. The next method is better. * *Here-is syntax* The here-is syntax of many unix shells is also provided. If the system command contains the characters `<<' followed by a word (with no space between!) then Gri will issue a system command which includes not only this line but also all succeeding lines, until a line is found which matches the indicated word precisely (with no leading space allowed). The `<< "WORD"' syntax is also supported, meaning that the operating system is being told not to mess with the dollar-signs - needed in perl. *Note:* Be carefull using this inside a new-command. Gri Recognizes the end of the body of a new-command by a line with `}' in the *first column*, and no non-white characters thereafter. If you system command happens to use a line with a curly brace (as in a loop in perl, for example), you must put whitespace before the brace. This won't affect the system command, but it will let Gri correctly realize that this is *not* the end of the new-command. For more information on new-commands. *Caution:* Before sending the string to the system, Gri first translates any synonyms present. Be careful with this, since system commands calling awk, etc, very often use backslashes for the newline character `\n' within strings. If you have a synonym whose name starts with `\n', you can get a conflict. For example, the awk command `print "foo\nbar";' should print a line with `foo' on it, followed by a line with `bar' on it, but it will instead print a single line with `fooMISTAKE', if you had previously defined a synonym as `\nbar = "MISTAKE"'. One way to avoid this mistake is to make sure any `\n' characters appear at the end of strings, and then simply avoid having a synonym named `\n'. Here is a Perl example. \message = "Foo bar" system perl <<"EOF" $a = 100; print "foo bar is \message, and a is $a\nQ: was a 100?\n"; print "BETTER: foo bar is \message, and a is $a\n"; print "Q: was a 100?\n"; EOF which, written more safely (partially avoiding the string `\n'), is \message = "Foo bar" system perl <<"EOF" $a = 100; print "foo bar is \message, and a is $a\n"; print "Q: was a 100?\n"; EOF Here is an Awk example. Note that the commandline flags `-f -' are required to force awk to take commands from standard input. Note also the absence of a final newline in the string; Awk does not require one, while Perl does. (Finally, as usual, note that the synonym `awk' is being used instead of `awk', to ensure portability.) \message = "Foo bar" system awk -f - <<"EOF" BEGIN \{ a = 100; print "foobar is \message, and a is ", a, "\nQ: was a 100?"; } EOF which, written more safely (avoiding the string `\n'), is \message = "Foo bar" system awk -f - <<"EOF" BEGIN\{ a = 100; print "foobar is \message, and a is ", a; print "Q: was a 100?"; } EOF *Some more examples*: * To get the first 10 lines of a file called `foo.dat' inserted into another file called `bar.dat', you might do the following. Only the first method works; the second will fail because `.n.' will not be translated before passing to the operating system. \num = "-10" system head \num foo.dat > bar.dat # Following fails since .num. will not be translated .num. = -10 system head .num. foo.dat > bar.dat * Issue a unix command to get a listing of files in the current working directory, and pipe them into the `more' system command. system ls -l *c | more * Store the date and time into a synonym, and use it in a title: \time = system date ... draw title "Plotted at time \time" * Use `awk' to prepare a two-column table of x, ranging from 0 to 1 in steps of 0.1, and sin(x). The table is stored in a file whose suffix is the process ID of the Gri job. This file is then opened, and the data plotted. Finally, a system command is issued to remove the temporary file. system awk 'BEGIN \{ \ for (x=0; x<1; x+=0.1) \{ \ printf("%f %f\n", x, sin(x)) \ } \ }' > tmp.\.pid. open tmp.\.pid. read columns x y close system rm tmp.\.pid. draw curve quit NOTE Under unix, this command calls the Bourne shell, not the C-shell that is often used interactively. For many simple uses, the only difference from normal interactive use will be that `~' is not expanded to the home directory. For example, you'd do system awk -f $HOME/foo/bar/cmd.gawk instead of the system awk -f ~/foo/bar/cmd.gawk that you might expect from interactive C-shell usage. RETURN VALUE: Sets `\.return_value' to system status, `N status' { extern "C" bool systemCmd(void); } `while .test.|{rpn ...}' Perform statements in loop while the value of `.test.' or the RPN expression is nonzero. The end of the loop designated by a line containing the words `end while'. The value `.test.' may be an RPN expression. To leave the loop prematurely, use a `break' statement. Upon encountering a `break' statement, Gri jumps to the line immediately following the loop. If the `-chatty' option is nonzero, a notification is printed every 1000 passes through the loop, as a debugging measure to catch unintended infinite loops. *Examples*: * Loop forever, printing a message over and over. while 1 show "DANGER: This loop goes on forever. You need a break statement!" end while * Repeatedly read two numbers, and plot a bullet at the indicated location. If (or, hopefully, "when") the end of the file is encountered, break out of the loop; otherwise continue plotting forever. while 1 read .x. .y. if ..eof.. break end if draw symbol bullet at .x. .y. end while * Loop 10 times, printing the values of `.i.' as they range 0, 1, ..., 9. After exiting from the loop, `.i.' will equal 10. Be *careful* to use the correct RPN greater-than test to avoid an infinite loop. .i. = 0 while \{rpn .i. 10 >} show .i. .i. += 1 end while { extern "C" bool whileCmd(void); } `write columns to \filename' Append data columns to the end of the indicated file. { extern "C" bool writeCmd(void); } `write contour .value. to \filename' As corresponding `draw contour' command, but don't actually draw the contours; instead, write to the indicated file, starting at the EOF of the file if it is nonempty (thus, appending to the end of the file.) The first line of output is a header line, containing two numbers: the contour value and the missing value. Then the xy pairs are written a line at a time, with missing values being used to indicate ends of segments. A blank line is written after the last data pair. For example, if the contour contained two closed regions, Gri would output a pair of missing values as one of the xy pairs, to denote the separation of the two curves. You could read and plot the output as in this example write contour 10 to contour.out write contour 20 to contour.out open contour.out read .contour_value. .missing. set missing value .missing. read columns x y draw curve { extern "C" bool writeCmd(void); } `write grid to \filename [bycolumns]' Append grid to the end of the named file. Storage is in `%f' format, and is in normal image order. If the keyword `bycolumns' is present, then the grid is transposed first, in such a way that `read grid data bycolumns' performed on that file will read back the original grid data. { extern "C" bool writeCmd(void); } `write image colorscale to \filename' Append image colorscale transform to the end of the named file. Storage is a series of 256 lines, each containing 3 numbers (for Red, Green and Blue) in the range 0 to 1. The file is suitable for reading with the `read image colorscale' command. */ { extern "C" bool writeCmd(void); } `write image grayscale to \filename' Append image grayscale transform to the end of the named file. Storage is a series of 256 lines, each containing a number in the range 0 to 1. The file is suitable for reading with the `read image grayscale' command. */ { extern "C" bool writeCmd(void); } `write image greyscale to \filename' Alternate spelling of grayscale { extern "C" bool writeCmd(void); } `write image mask [pgm|rasterfile] to \filename' `write image mask to mask.dat' Append image mask to the end of the named file. Storage is by unsigned-char, and is in normal image order. There is no header. `write image mask rasterfile to mask.dat' Append image mask to the end of the named file, in Sun Rasterfile format. `write image mask pgm to mask.dat' Append image mask to the end of the named file, in PGM 'rawbits' format. { extern "C" bool writeCmd(void); } `write image [pgm|rasterfile] to \filename' `write image to image.dat' Append image to the end of the named file. Storage is by unsigned-char, and is in normal image order. There is no header. `write image rasterfile to image.dat' Append image to the end of the named file, in Sun Rasterfile format. `write image pgm to image.dat' Append image to the end of the named file, in PGM 'rawbits' format. { extern "C" bool writeCmd(void); } `unlink \filename' Delete a filename and possibly the file to which it refers. On non-unix machines, this simply means to delete the file. On unix machines, the action is more subtle. The unix OS permits several processes to use a given file at once. Therefore, `unlink' doesn't immediately remove the file, but instead waits until other processes are done with it. Most users will never realize the difference, however, and it is safe to think of `unlink' as simply removing the file. To learn more, type `man unlink' in a unix shell. A common use of `unlink' is to remove files that were created with the `tmpname' facility, e.g. \tmp = tmpname # do some system commands to put data into this file open \tmp read columns x y draw curve unlink \tmp { extern "C" bool unlinkCmd(void); } `?draw axes exploded' Fragment to draw the xy axes at left and bottom, offset 0.2 cm from a simple axis frame. { draw axes frame # Draw frame draw x axis at {rpn ..ymargin.. 0.2 -} cm lower # X axis below frame draw y axis at {rpn ..xmargin.. 0.2 -} cm left # Y axis left of frame } `?contour xyz data' Fragment to read xyz data (from a file called "file.dat"), then interpolate these xyz data onto a uniform grid (of size 30x30, chosen to span the data), and then draw contours (at levels selected by autoscaling the data). For reference, dots are also drawn at the data locations. Adjustments: filename, grid characteristics, method/details of converting columns to grid. { open input.dat # You'll want to change the filename read columns x y z # Can read in any order, e.g '... y x z' close # Close this file set x grid ..xleft.. ..xright.. / 30 # Spans data, 30 wide set y grid ..ybottom.. ..ytop.. / 30 # Spans data, 30 high convert columns to grid # Uses default "objective" method draw contour # Levels selected automatically draw symbol bullet # Put dots at data locations } `?set axes' { set x margin 2 # 2cm at left of axis frame set x margin 2 # 2cm at left of axis frame set x size 12 # Axis frame 12cm wide set y size 12 # Axis frame 12cm high set x name "x" # Name of x axis set y name "y" # Name of y axis } `?draw image BW raster' Fragment to read/draw a Sun rasterfile image in BW, blown up to full size on (portrait orientation) 8.5x11 paper. No axes are drawn. A palette is drawn, assuming that the limits of the image value are 0 and 1. Main adjustable parameters marked with '*' in comment. { \file = "A.rs" # * filename .min. = 0 # * lowest possible value .max. = 1 # * largest possible value set image range .min. .max. open \file binary read image rasterfile # ALTERNATIVE: # read image pgm close .margin. = 1 # * margin space in cm set x margin .margin. set y margin .margin. set x axis 0 ..image_width.. ..image_width.. set y axis 0 ..image_height.. ..image_height.. set font size 10 # * font size set x size {rpn 8.5 2.54 * .margin. 2 * -} set y size {rpn ..xsize.. ..image_width.. / ..image_height.. *} # Want 2cm for palette .left_over. = {rpn 11 2.54 * ..ysize.. - .margin. 2 * -} if {rpn .left_over. 2 >} set y size {rpn 11 2.54 * .margin. 2 * - 2 -} set x size {rpn ..ysize.. ..image_height.. / ..image_width.. *} end if draw axes none draw image draw image palette left .min. right .max. box \ {rpn ..xmargin..} \ {rpn ..ymargin.. ..ysize.. + 1.0 +} \ {rpn ..xmargin.. ..xsize.. +} \ {rpn ..ymargin.. ..ysize.. + 2.0 +} } rpnfunction e 2.7182818284590452354 rpnfunction pi 3.14159265358979323846 # The following assume stack containing four numbers, 'x0 y0 x1 y', # and return the slope and intercept of the line joining the points. rpnfunction linear_slope exch roll_right - roll_right exch - / rpnfunction linear_intercept exch dup roll_left roll_left roll_left dup roll_right - roll_right exch - / roll_left * - # /----------------------------------------------------------------\ # |The following material is for the benefit of the Emacs gri mode | # \----------------------------------------------------------------/ # # @variable ..R2.. squared correlation coefficient (defined if regression has been done) # @variable ..coeff0.. intercept in linear regression (defined if regression has been done) # @variable ..coeff0_sig.. 95% C.I. on intercept in linear regression (defined if regression has been done) # @variable ..coeff1.. slope in linear regression (defined if regression has been done) # @variable ..coeff1_sig.. 95% C.I. on slope in linear regression (defined if regression has been done) # @variable ..num_col_data.. number of column data # @variable ..num_col_data_missing.. number of missing column data # @variable ..arrowsize.. size of arrow heads @unit cm @default 0.2 # @variable ..batch.. is Gri in batch mode? @default 0 # @variable ..debug.. debugging flag @default 0 # @variable ..fontsize.. size of font @unit point @default 12 # @variable ..graylevel.. graylevel of pen (0 means black) @default 0 # @variable ..linewidth.. width of curves @unit point @default 0.709 # @variable ..linewidthaxis.. width of axis lines @unit point @default 0.369 # @variable ..linewidthsymbol.. width of symbol lines @unit point @default 0.369 # @variable ..missingvalue.. missing value @default 1e+22 # @variable ..symbolsize.. size of symbols @unit point @default 0.1 # @variable ..superuser.. superuser flag @default 0 # @variable ..trace.. are executed commands printed? @default 0 # @variable ..tic_direction.. direction of tics (0 means out and 1 means in) @default 0 # @variable ..tic_size.. size of tic marks @unit cm @default 0.2 # @variable ..xmargin.. margin to left of axis area @unit cm @default 6 # @variable ..xsize.. width of axis area @unit cm @default 10 # @variable ..ymargin.. margin below axis area @unit cm @default 6 # @variable ..ysize.. height of axis area @unit cm @default 10 # @variable ..red.. red-ness of pen (0 to 1) @default 0 # @variable ..blue.. blue-ness of pen (0 to 1) @default 0 # @variable ..green.. green-ness of pen (0 to 1) @default 0 # @variable ..exit_status.. exit status used for OS @default 0 # @variable ..xleft.. x-value at left of axis area @default 0 # @variable ..xright.. x-value at right of axis area @default 10 # @variable ..ybottom.. y-value at bottom of axis area @default 0 # @variable ..ytop.. y-value at top of axis area @default 10 # @variable ..use_default_for_query.. use default for query statements? (0 or 1) @default 0 # @variable ..words_in_dataline.. number of words in data line @default 0 # @variable ..eof.. at end of data file yet? (0 or 1) @default 0 # @variable ..landscape.. is the graph in landscape mode? (0 or 1) @default 0 # @variable ..publication.. use publication quality? (0 or 1) @default 0 # @variable ..xlast.. last value of x column @default 0 # @variable ..ylast.. last value of y column @default 0 # @variable ..image_width.. pixel width of image @default 0 # @variable ..image_height.. pixel height of image @default 0 # @variable \.missingvalue. missing value code @default "1e22" # @variable \.return_value. return value from last command # @variable \.version. version of gri being used # @variable \.pid. process id of this job # @variable \.wd. present working directory # @variable \.time. day, date and time # @variable \.user. name of user who started this job # @variable \.host. name of computer on which job is running # @variable \.system. name of operating system # @variable \.home. name of this users home directory # @variable \.lib_dir. directory that holds gri library files # @variable \.command_file. name of command file for this job # @variable \.readfrom_file. name of file being read for data # @variable \.ps_file. name of PostScript file being created # @variable \.path_data. directory path for finding data @default "." # @variable \.path_commands. directory path for finding commands @default "." # BEGIN deprecated commands # @deprecated 2.10.0 `set y axis label horizontal|vertical' # END deprecated commands ����������������������������������������������������������������������������������������������������������������gri/src/grcntour.cc���������������������������������������������������������������������������������0000644�0001750�0001750�00000057072�13147557614�012774� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define DEBUG_CONTOUR #include #include #include #include "gr.hh" #include "private.hh" #include "errors.hh" #include "GMatrix.hh" #include "GriPath.hh" // globals to this file static double Contour_space_first; static double Contour_space_later; static double Contour_minlength; static bool Center_labels; static bool Whiteunder_labels = true; // always set anyway static bool Label_contours = true; // always set anyway static bool Rotate_labels = false; // always set anyway static int nx_1, ny_1, iGT, jGT, iLE, jLE; static void free_space_for_curve(); static void get_space_for_curve(); static void draw_the_contour(FILE * out_file, const GriColor &line_color, const GriColor &label_color, /*const*/ GriString &label); static bool trace_contour(double z0, const double x[], const double y[], /*const*/ GriMatrix &z, /*const*/ GriMatrix &legit, FILE *out_file, const GriColor &line_color, const GriColor &label_color, /*const*/ GriString &label); static int FLAG(int ni, int nj, int ind); static int append_segment(double xr, double yr, double zr, bool OKr, double xs, double ys, double zs, bool OKs, double z0); // Space for curve, shared by several routines static double *xcurve, *ycurve; static bool *legitcurve; #define INITIAL_CURVE_SIZE 100 static int num_in_curve, max_in_curve; static bool curve_storage_exists = false; void free_space_for_curve() { if (curve_storage_exists) { delete [] xcurve; delete [] ycurve; delete [] legitcurve; curve_storage_exists = false; } num_in_curve = 0; } void get_space_for_curve() { max_in_curve = INITIAL_CURVE_SIZE; if(curve_storage_exists) { gr_Error("storage is messed up (internal error)"); return; // will not execute } xcurve = new double [max_in_curve]; ycurve = new double [max_in_curve]; legitcurve = new bool [max_in_curve]; curve_storage_exists = true; num_in_curve = 0; } // gr_contour() -- draw contour line for gridded data // // DESCRIPTION: Draws a contour for the value z0, through data z[i][j] defined // on the rectangular grid x[i] and y[j] (where 0<=i &z, /*const*/ GriMatrix &legit, int nx, int ny, double z0, const char *lab, bool rotate_labels, bool whiteunder_labels, bool center_labels, const GriColor &line_color, const GriColor &label_color, double contour_minlength, double contour_space_first, double contour_space_later, FILE *out_file) { register int i, j; // Test for errors if (nx <= 0) gr_Error("nx<=0 (internal error)"); if (ny <= 0) gr_Error("ny<=0 (internal error)"); // Header for output file if (out_file != NULL) fprintf(out_file, "%f %g\n", z0, gr_currentmissingvalue()); // Save some globals nx_1 = nx - 1; ny_1 = ny - 1; Contour_space_first = contour_space_first; Contour_space_later = contour_space_later; Contour_minlength = contour_minlength; Rotate_labels = rotate_labels; Whiteunder_labels = whiteunder_labels; GriString label; if (lab) label.fromSTR(lab); else label.fromSTR(""); // Save some flags Center_labels = center_labels; Label_contours = (contour_space_later > 0.1) ? true : false; // Clear all switches. FLAG(nx, ny, -1); // Get space for the curve. get_space_for_curve(); // Search for a contour intersecting various places on the grid. Whenever // a contour is found to be between two grid points, call trace_contour() // after defining the global variables iLE,jLE,iGT,jGT so that // z[iLE]jLE] <= z0 < z[iGT][jGT], where legit[iLE][jLE]==true // and legit[iGT][jGT]==true. // // NOTE: always start a contour running upwards (to greater j), between // two sideways neighboring points (same j). Later, in trace_contour(), // test 'locate' for value 5. If it's 5, it means that the same geometry // obtains, so set a flag and check whether already set. If already // set, it means we've traced this contour before, so trace_contour() // knows to stop then. // Search bottom #ifdef DEBUG_CONTOUR if (get_flag("kelley2")) printf("Search bottom...\n"); #endif for (i = 1; i < nx; i++) { j = 0; while (j < ny_1) { // move north to first legit point while (j < ny_1 && !(legit(i, j) == true && legit(i - 1, j) == true) ) { j++; } // trace a contour if it hits here if (j < ny_1 && z(i, j) > z0 && z(i - 1, j) <= z0) { iLE = i - 1; jLE = j; iGT = i; jGT = j; trace_contour(z0, x, y, z, legit, out_file, line_color, label_color, label); } // Space through legit points, that is, skipping through good // data looking for another island of bad data which will // thus be a new 'bottom edge'. while (j < ny_1 && legit(i, j) == true && legit(i - 1, j) == true) j++; } } #ifdef DEBUG_CONTOUR if (get_flag("kelley2")) printf("Search right edge ...\n"); #endif // search right edge for (j = 1; j < ny; j++) { i = nx_1; while (i > 0) { // move west to first legit point while (i > 0 && !(legit(i, j) == true && legit(i, j - 1) == true)) i--; // trace a contour if it hits here if (i > 0 && z(i, j) > z0 && z(i, j - 1) <= z0) { iLE = i; jLE = j - 1; iGT = i; jGT = j; trace_contour(z0, x, y, z, legit, out_file, line_color, label_color, label); } // space through legit points while (i > 0 && legit(i, j) == true && legit(i, j - 1) == true) i--; } } #ifdef DEBUG_CONTOUR if (get_flag("kelley2")) printf("Search top edge ...\n"); #endif // search top edge for (i = nx_1 - 1; i > -1; i--) { j = ny_1; while (j > 0) { while (j > 0 && !(legit(i, j) == true && legit(i + 1, j) == true)) j--; // trace a contour if it hits here if (j > 0 && z(i, j) > z0 && z(i + 1, j) <= z0) { iLE = i + 1; jLE = j; iGT = i; jGT = j; trace_contour(z0, x, y, z, legit, out_file, line_color, label_color, label); } // space through legit points while (j > 0 && legit(i, j) == true && legit(i + 1, j) == true) j--; } } #ifdef DEBUG_CONTOUR if (get_flag("kelley2")) printf("Search left edge ...\n"); #endif // search left edge for (j = ny_1 - 1; j > -1; j--) { i = 0; while (i < nx_1) { while (i < nx_1 && !(legit(i, j) == true && legit(i, j + 1) == true)) i++; // trace a contour if it hits here if (i < nx_1 && z(i, j) > z0 && z(i, j + 1) <= z0) { iLE = i; jLE = j + 1; iGT = i; jGT = j; trace_contour(z0, x, y, z, legit, out_file, line_color, label_color, label); } // space through legit points while (i < nx_1 && legit(i, j) == true && legit(i, j + 1) == true) i++; } } #ifdef DEBUG_CONTOUR if (get_flag("kelley2")) printf("Search interior ...\n"); #endif // Search interior. Pass up from bottom (starting at left), through all // interior points. Look for contours which enter, with high to right, // between iLE on left and iGT on right. for (j = 1; j < ny_1; j++) { int flag_is_set; for (i = 1; i < nx; i++) { // trace a contour if it hits here flag_is_set = FLAG(i, j, 0); if (flag_is_set < 0) gr_Error("ran out of storage (internal error)"); if (!flag_is_set && legit(i, j) == true && z(i, j) > z0 && legit(i - 1, j) == true && z(i - 1, j) <= z0) { iLE = i - 1; jLE = j; iGT = i; jGT = j; trace_contour(z0, x, y, z, legit, out_file, line_color, label_color, label); } } } // Free up space. free_space_for_curve(); FLAG(nx, ny, 2); // Trailer for output file if (out_file != NULL) fprintf(out_file, "\n"); } // trace_contour() -- trace_contour a contour line with high values of z to // it's right. Stores points in (*xcurve, *ycurve) and the legit flag is // stored in *legitcurve; initially these must be empty; you must also free // them after this call, so that the next call will work OK. static bool trace_contour(double z0, const double x[], const double y[], /*const*/ GriMatrix &z, /*const*/ GriMatrix &legit, FILE *out_file, const GriColor &line_color, const GriColor &label_color, /*const*/ GriString &label) { int i, ii, j, jj; double zp, vx, vy, zcentre; int locate; // locate tells where delta-grid point is. It codes as follows to // i_test[] and j_test[] 6 7 8 3 4 5 0 1 2 static int i_test[9] = { 0, 1, 1, // 6 7 8 0, 9, 0, // 3 4 5 -1, -1, 0 // 0 1 2 }; static int j_test[9] = { -1, 0, 0, // 6 7 8 -1, 9, 1, // 3 4 5 0, 0, 1 // 0 1 2 }; static int dtest[9] = { 0, 1, 0, // 6 7 8 1, 0, 1, // 3 4 5 0, 1, 0 // 0 1 2 }; #ifdef DEBUG_CONTOUR if (get_flag("kelley2")) { printf("trace_contour() iLE=%d jLE=%d iGT=%d jGT=%d\n",iLE,jLE,iGT,jGT); printf("\tLE (%.2f %.2f %.2f) %d\n", x[iLE],y[jLE],z(iLE,jLE),legit(iLE,jLE)); printf("\tGT (%.2f %.2f %.2f) %d\n", x[iGT],y[jGT],z(iGT,jGT),legit(iGT,jGT)); } #endif // Trace the curve, storing results with append_segment() into *xcurve, // *ycurve, *legitcurve. When done, call draw_the_contour(), which draws // the contour stored in these arrays and draws labels. while (true) { append_segment(x[iLE], y[jLE], z(iLE, jLE), legit(iLE, jLE), x[iGT], y[jGT], z(iGT, jGT), legit(iGT, jGT), z0); // Find the next point to check through a table lookup. locate = 3 * (jGT - jLE) + (iGT - iLE) + 4; i = iLE + i_test[locate]; j = jLE + j_test[locate]; #ifdef DEBUG_CONTOUR if (get_flag("kelley2")) printf("iLE=%d jLE=%d iGT=%d jGT=%d locate=%d -> i=%d j=%d\n",iLE,jLE,iGT,jGT,locate,i,j); #endif // Did it hit an edge? if (i > nx_1 || i < 0 || j > ny_1 || j < 0) { draw_the_contour(out_file, line_color, label_color, label); #ifdef DEBUG_CONTOUR if (get_flag("kelley2")) printf("Hit edge\n"); #endif return true; // all done } // Test if retracing an existing contour. See explanation // above, in grcntour(), just before search starts. if (locate == 5) { #ifdef DEBUG_CONTOUR if (get_flag("kelley2")) printf("locate==5 ... "); #endif int already_set = FLAG(iGT, jGT, 1); if (already_set < 0) { gr_Error("ran out of storage (internal error)"); return false; } if (already_set) { #ifdef DEBUG_CONTOUR if (get_flag("kelley2")) printf("so draw it\n"); #endif draw_the_contour(out_file, line_color, label_color, label); return true; // all done } #ifdef DEBUG_CONTOUR if (get_flag("kelley2")) printf("didn't draw it\n"); #endif } #ifdef DEBUG_CONTOUR if (get_flag("kelley2")) { printf("\tnew i=%d j=%d\n", i, j); printf("\t (legit there is %d)\n", legit(i,j)); } #endif // Following new for 2.1.13 if (!legit(i,j)) { #ifdef DEBUG_CONTOUR if (get_flag("kelley2")) printf("not legit at i=%d j=%d, so drawing\n",i,j); #endif draw_the_contour(out_file, line_color, label_color, label); return true; // all done } if (!dtest[locate]) { zp = z(i, j); if (zp > z0) iGT = i, jGT = j; else iLE = i, jLE = j; continue; } vx = (x[iGT] + x[i]) * 0.5; vy = (y[jGT] + y[j]) * 0.5; locate = 3 * (jGT - j) + iGT - i + 4; // Fourth point in rectangular boundary ii = i + i_test[locate]; jj = j + j_test[locate]; bool legit_diag = (legit(iLE, jLE) == true && legit(iGT, jGT) == true && legit(i, j) == true && legit(ii, jj) == true) ? true : false; zcentre = 0.25 * (z(iLE, jLE) + z(iGT, jGT) + z(i, j) + z(ii, jj)); #ifdef DEBUG_CONTOUR if (get_flag("kelley2")) { printf("ii=%d jj=%d. legit_diag=%d (zcenter=%f)\n",ii,jj,legit_diag,zcentre); if (!legit_diag) printf("-- will [for kelley_contour1] consider this an 'edge', probably\n"); } #endif if (get_flag("kelley1") && !legit_diag) { printf("\n*** flag_kelley1: hit missing-value region, so stopping contour trace\n"); draw_the_contour(out_file, line_color, label_color, label); return true; // all done } if (zcentre <= z0) { append_segment(x[iGT], y[jGT], z(iGT, jGT), legit(iGT, jGT), vx, vy, zcentre, legit_diag, z0); if (z(ii, jj) <= z0) { iLE = ii, jLE = jj; continue; } append_segment(x[ii], y[jj], z(ii, jj), legit(ii, jj), vx, vy, zcentre, legit_diag, z0); if (z(i, j) <= z0) { iGT = ii, jGT = jj; iLE = i, jLE = j; continue; } append_segment(x[i], y[j], z(i, j), legit(i, j), vx, vy, zcentre, legit_diag, z0); iGT = i, jGT = j; continue; } append_segment(vx, vy, zcentre, legit_diag, x[iLE], y[jLE], z(iLE, jLE), legit(iLE, jLE), z0); if (z(i, j) > z0) { iGT = i, jGT = j; continue; } append_segment(vx, vy, zcentre, legit_diag, x[i], y[j], z(i, j), legit(i, j), z0); if (z(ii, jj) <= z0) { append_segment(vx, vy, zcentre, legit_diag, x[ii], y[jj], z(ii, jj), legit(ii, jj), z0); iLE = ii; jLE = jj; continue; } iLE = i; jLE = j; iGT = ii; jGT = jj; } } // append_segment() -- append a line segment on the contour static double xplot_last, yplot_last; static int append_segment(double xr, double yr, double zr, bool OKr, double xs, double ys, double zs, bool OKs, double z0) { if (zr == zs) gr_Error("Contouring problem: zr = zs, which is illegal"); double frac = (zr - z0) / (zr - zs); if (frac < 0.0) gr_Error("Contouring problem: frac < 0"); if (frac > 1.0) gr_Error("Contouring problem: frac > 1"); double xplot = xr - frac * (xr - xs); double yplot = yr - frac * (yr - ys); // Avoid replot, which I suppose must be possible, given this code if (num_in_curve > 0 && xplot == xplot_last && yplot == yplot_last) return 1; if (num_in_curve > max_in_curve - 1) { // Get new storage if running on empty. Better to // do this with an STL vector class max_in_curve *= 2; int i; double *tmp = new double [num_in_curve]; if (!tmp) OUT_OF_MEMORY; for (i = 0; i < num_in_curve; i++) tmp[i] = xcurve[i]; delete [] xcurve; xcurve = new double [max_in_curve]; if (!xcurve) OUT_OF_MEMORY; for (i = 0; i < num_in_curve; i++) xcurve[i] = tmp[i]; for (i = 0; i < num_in_curve; i++) tmp[i] = ycurve[i]; delete [] ycurve; ycurve = new double [max_in_curve]; if (!ycurve) OUT_OF_MEMORY; for (i = 0; i < num_in_curve; i++) ycurve[i] = tmp[i]; delete [] tmp; bool *tmpl = new bool [num_in_curve]; if (!tmpl) OUT_OF_MEMORY; for (i = 0; i < num_in_curve; i++) tmpl[i] = legitcurve[i]; delete [] legitcurve; legitcurve = new bool [max_in_curve]; if (!legitcurve) OUT_OF_MEMORY; for (i = 0; i < num_in_curve; i++) legitcurve[i] = tmpl[i]; delete [] tmpl; } // A segment is appended only if both the present point and the last // point came by interpolating between OK points. xcurve[num_in_curve] = xplot; ycurve[num_in_curve] = yplot; if (!inside_box(xcurve[num_in_curve], ycurve[num_in_curve])) { legitcurve[num_in_curve] = false; } else { if (OKr == true && OKs == true) legitcurve[num_in_curve] = true; else legitcurve[num_in_curve] = false; } num_in_curve++; xplot_last = xplot; yplot_last = yplot; #ifdef DEBUG_CONTOUR if (get_flag("kelley2")) { printf("\nin append_segment... curve is now\n"); for (int i = 0; i < num_in_curve; i++) printf("\t%.2f %.2f legit=%d\n", xcurve[i], ycurve[i], legitcurve[i]); } #endif return 1; } // Draw contour stored in (xcurve[],ycurve[],legitcurve[]), possibly with // labels (depending on global Label_contours). // // Trick: if out_file is not NULL, then don't actually draw the contour; rather, // print out the pairs of numbers (ended by blank line), after a header line // containing three numbers: // // CONTOUR_VALUE MISSING_VALUE #define FACTOR 3.0 // contour must be FACTOR*len long to be labelled static void draw_the_contour(FILE * out_file, const GriColor &line_color, const GriColor &label_color, /*const*/ GriString &label) { if (num_in_curve == 1) { num_in_curve = 0; return; } register int i; bool first_label, first_point; double contour_length = 0.0; double xcmlast = 0.0, ycmlast = 0.0; // values over-ridden double x, xcm, y, ycm; double cumdist; double half_height = (gr_currentCapHeight_cm() + gr_thinspace_cm()) / 2.0; double angle = 0.0; double width_cm, ascent_cm, descent_cm; // See if being tricked into just printing the contour (x,y) locations. if (NULL != out_file) { double miss = gr_currentmissingvalue(); for (i = 0; i < num_in_curve; i++) { if (legitcurve[i] == true) { fprintf(out_file, "%f %f\n", xcurve[i], ycurve[i]); } else { fprintf(out_file, "%g %g\n", miss, miss); } } fprintf(out_file, "%g %g\n", miss, miss); // end off num_in_curve = 0; return; } GriPath p(num_in_curve); p.push_back(xcurve[0], ycurve[0], 'm'); for (i = 1; i < num_in_curve; i++) { p.push_back(xcurve[i], ycurve[i], legitcurve[i] ? 'l' : 'm'); } p.trim(); p.stroke(units_user); // Figure total length of contour line first_point = true; for (i = 0; i < num_in_curve; i++) { if (legitcurve[i] == false) continue; gr_usertocm(xcurve[i], ycurve[i], &xcm, &ycm); if (first_point) { xcmlast = xcm; ycmlast = ycm; first_point = false; } contour_length += sqrt((xcm - xcmlast) * (xcm - xcmlast) + (ycm - ycmlast) * (ycm - ycmlast)); xcmlast = xcm; ycmlast = ycm; } // Return right away, if contour too short if (contour_length < 0.0) { num_in_curve = 0; return; } gr_stringwidth(label.getValue(), &width_cm, &ascent_cm, &descent_cm); if (contour_length < FACTOR * width_cm || contour_length < Contour_minlength) { num_in_curve = 0; return; } if (Label_contours) { if (Center_labels) { // Centered labels double half_length = contour_length / 2.0; cumdist = 0.0; first_point = true; for (i = 0; i < num_in_curve; i++) { if (legitcurve[i] == false) continue; gr_usertocm(xcurve[i], ycurve[i], &xcm, &ycm); if (first_point) { xcmlast = xcm; ycmlast = ycm; first_point = false; } cumdist += sqrt((xcm - xcmlast) * (xcm - xcmlast) + (ycm - ycmlast) * (ycm - ycmlast)); if (cumdist > half_length) { if (Rotate_labels) { // Rotate the angle, making sure that text reads from // left-to-right. angle = DEG_PER_RAD * atan2(ycm - ycmlast, xcm - xcmlast); if (angle > 90.0 || angle < -90.0) angle += 180.0; } gr_cmtouser(xcm, ycm - half_height, &x, &y); if (Whiteunder_labels) { GriColor white; white.setRGB(1.0, 1.0, 1.0); gr_show_in_box(label, label_color, white, xcm, ycm - half_height, angle); } else { double xxcm, yycm; gr_usertocm(x, y, &xxcm, &yycm); label.draw(xxcm, yycm, TEXT_CENTERED, angle); } break; // done now } xcmlast = xcm; ycmlast = ycm; } } else { // Not centered. cumdist = 0.0; first_point = true; first_label = true; for (i = 0; i < num_in_curve; i++) { if (legitcurve[i] == false) continue; gr_usertocm(xcurve[i], ycurve[i], &xcm, &ycm); if (first_point) { xcmlast = xcm; ycmlast = ycm; first_point = false; } cumdist += sqrt((xcm - xcmlast) * (xcm - xcmlast) + (ycm - ycmlast) * (ycm - ycmlast)); if ((first_label && (cumdist > Contour_space_first)) || (!first_label && (cumdist > Contour_space_later))) { if (Rotate_labels) { // Rotate the angle, making sure that text reads from // left-to-right. angle = DEG_PER_RAD * atan2(ycm - ycmlast, xcm - xcmlast); if (angle > 90.0 || angle < -90.0) angle += 180.0; } gr_cmtouser(xcm, ycm - half_height, &x, &y); if (Whiteunder_labels) { GriColor white; white.setRGB(1.0, 1.0, 1.0); gr_show_in_box(label, label_color, white, xcm, ycm - half_height, angle); } else { double xxcm, yycm; gr_usertocm(x, y, &xxcm, &yycm); label.draw(xxcm, yycm, TEXT_CENTERED, angle); } cumdist = 0.0; first_label = false; } xcmlast = xcm; ycmlast = ycm; } } } // Invalidate the data, so that next curve will use same storage. num_in_curve = 0; } // FLAG() -- check flag for gr_contour() and trace_contour() // ni = row (or, if ind==-1, number of rows) // nj = col (or, if ind==-1, number of cols) // if (ind == -1), get flag storage space; initialize flags to 0 // if (ind == 1), check flag and then set it // if (ind == 2), clear the flag storage space // if (ind == 0), check flag, return value // RETURN VALUE: Normally, the flag value (0 or 1). If the storage is // exhausted, return a number <0. #define NBITS 32 static int FLAG(int ni, int nj, int ind) { static bool flag_storage_exists = false; static unsigned long *flag, mask[NBITS]; static int size; static int ni_max; // x-dimension is saved int i, ipos, iword, ibit, return_value; switch (ind) { case -1: // Allocate storage for flag array if (flag_storage_exists) gr_Error("storage is messed up (internal error)"); size = 1 + ni * nj / NBITS; // total storage array length flag = new unsigned long [size]; if (!flag) OUT_OF_MEMORY; // Create mask mask[0] = 1; for (i = 1; i < NBITS; i++) mask[i] = 2 * mask[i - 1]; for (i = 0; i < size; i++) // Zero out flag flag[i] = 0; ni_max = ni; // Save for later flag_storage_exists = true; return 0; case 2: if (!flag_storage_exists) gr_Error("No flag storage exists"); delete [] flag; flag_storage_exists = false; return 0; default: if (!flag_storage_exists) gr_Error("No flag storage exists"); break; } // ind was not -1 or 2 // Find location of bit. ipos = nj * ni_max + ni; iword = ipos / NBITS; ibit = ipos - iword * NBITS; // Check for something being broken here, causing to run out of space. // This should never happen, but may as well check. if (iword >= size) return (-99); // no space // Get flag. return_value = (0 != (*(flag + iword) & mask[ibit])); // If ind=1 and flag wasn't set, set the flag if (ind == 1 && !return_value) flag[iword] |= mask[ibit]; // Return the flag value return return_value; } #undef NBITS ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/rpn.cc��������������������������������������������������������������������������������������0000644�0001750�0001750�00000017442�13147557614�011725� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include "gr.hh" #include "extern.hh" #define BEGIN_MATH "{" #define END_MATH "}" extern int rpn(unsigned int nw, char **w, char ** result); // in rpncalc.cc bool rpnfunctionCmd() { if (_nword < 3) { demonstrate_command_usage(); err("Need some action for this rpn function"); return false; } rpn_create_function(_word[1], &_word[2], _nword - 2); return true; } /* copy below from rpncalc.c */ /* Return codes: */ #define NO_ERROR 0 /* everything is OK */ #define BAD_WORD 1 /* not operator, operand, column, function */ #define STACK_UNDERFLOW 2 /* missing operators */ #define STACK_OVERFLOW 3 /* extra stuff */ #define DIV_BY_ZERO 4 /* cannot divide by zero */ #define OUT_OF_STORAGE 5 /* computer limitation */ #define ILLEGAL_TYPE 6 /* cannot do with given operand(s) */ #define NEED_GE_0 7 /* need operand >= 0 */ #define NEED_GT_0 8 /* need operand > 0 */ #define RANGE_1 9 /* need operand in range -1 to 1 */ #define NEED_GT_1 10 /* need operand > 1 */ #define COMPUTER_LIMITATION 11 /* can't do on this machine */ #define GENERAL_ERROR 12 /* some other error */ /* * Substitute an rpn expression. Return TRUE if we found an expression and it * parsed properly. This is called repeatedly by other functions, until it * returns FALSE, at which time all the rpn expressions will have been * converted. * * NOTE: nesting is not permitted. */ bool substitute_rpn_expressions(const char *s, char *sout) { void erase_rpn_stack(); erase_rpn_stack(); if (((unsigned) superuser()) & FLAG_RPN) printf("DEBUG %s:%d substitute_rpn_expressions(%s,...)\n", __FILE__,__LINE__,s); // To speed action, maintain a buffer in which 's' will be copied, // prior to chopping into words. BUG: this buffer is only cleaned // up at exit() time, since I never free() it. unsigned int space_needed = 1 + strlen(s); static char* copy = NULL; static unsigned int copy_len = 0; if (copy_len == 0) { copy_len = space_needed; copy = (char*)malloc(copy_len * sizeof(char)); //printf(" RPN started with space of %d\n", copy_len); if (!copy) { gr_Error("Out of memory in `rpn'"); } //printf("RPN initially got space for %d new bytes of memory, to copy `%s'\n", space_needed, s); } else { if (copy_len < space_needed) { copy_len = space_needed; copy = (char*)realloc(copy, copy_len * sizeof(char)); //printf(" RPN increased space to %d\n", copy_len); if (!copy) { gr_Error("Out of memory in `rpn'"); } //printf("RPN got space for %d new bytes of memory, to copy `%s'\n", space_needed, s); } } strcpy(copy, s); //printf("substitute_rpn_expressions(%s,...)\n",s); bool found = false; int rpn_start, rpn_end; // Copy s to a buffer, to avoid destroying it when chopping into words unsigned int nword; chop_into_words(copy, _Words2, &nword, MAX_nword); if (nword < 2) { strcpy(sout, _Words2[0]); return false; } strcpy(sout, ""); // initialize /* Search for `BEGIN_MATH rpn ... END_MATH' */ for (unsigned int i = 0; i < nword; i++) { char *result; unsigned int ii; rpn_start = -1; rpn_end = -1; // If at beginning of expression, parse it and put result into next // word of sout. if (!strcmp(_Words2[i], BEGIN_MATH)) { int error; rpn_start = i; /* Check for { "string" == "string" } or {\syn == "string"} etc */ if ((i + 4) <= nword && !strcmp(_Words2[i + 2], "==")) { char *p1, *p2; int len; p1 = _Words2[i + 1]; p2 = _Words2[i + 3]; /* * Give warning msg if detect statement of the form `if {\syn * == "string"}' */ if (*p1 == '\\' || *p2 == '\\') { err("Synonyms must be contained in quotes to compare them to strings."); return false; } if (*p1 == '"') p1++; if (*(p1 + (len = strlen(p1)) - 1) == '"') *(p1 + len - 1) = '\0'; if (*p2 == '"') p2++; if (*(p2 + (len = strlen(p2)) - 1) == '"') *(p2 + len - 1) = '\0'; if (!strcmp(p1, p2)) strcat(sout, "1"); else strcat(sout, "0"); for (i += 5; i < nword; i++) { /* bug: change when * generalized */ strcat(sout, _Words2[i]); strcat(sout, " "); } return true; } else if ((i + 3 > nword) || strcmp(_Words2[i + 1], "rpn")) { /* It's not an rpn expression. */ strcpy(sout, s); return false; } /* Find the matching END_MATH bug: can't nest () in math */ for (ii = rpn_start + 2; ii < nword; ii++) { if (!strcmp(_Words2[ii], END_MATH)) { rpn_end = ii; break; } } /* Assure that END_MATH existed. */ if (rpn_end < 0) { err("Missing close-brace on RPN expression. Proper: { rpn ... }"); _error_in_cmd = true; return false; } //printf("about to call rpn(%d,...)\n",rpn_end-rpn_start-2); error = rpn(rpn_end - rpn_start - 2, &_Words2[rpn_start + 2], &result); if (((unsigned) superuser()) & FLAG_RPN) printf("%s:%d error= %d\n",__FILE__,__LINE__,error); switch (error) { case BAD_WORD: err("unknown item in rpn expression"); _error_in_cmd = true; return false; case STACK_UNDERFLOW: err("\ final rpn stack has no operands. Did you give an extra operator?"); _error_in_cmd = true; return false; case STACK_OVERFLOW: err("\ final rpn stack has more than 1 operand. Did you forget an operator?"); print_rpn_stack(); _error_in_cmd = true; return false; case DIV_BY_ZERO: err("rpn cannot divide by 0."); _error_in_cmd = true; return false; case OUT_OF_STORAGE: err("rpn calculation ran out of storage. Too many words in rpn expression."); _error_in_cmd = true; return false; case ILLEGAL_TYPE: err("rpn inappropriate operator for operand[s] on the stack"); _error_in_cmd = true; return false; case NEED_GE_0: err("rpn operator requires operand >= 0"); _error_in_cmd = true; return false; case NEED_GT_0: err("rpn operator requires operand > 0"); _error_in_cmd = true; return false; case RANGE_1: err("rpn operator requires operand in range -1 to 1 inclusive"); _error_in_cmd = true; return false; case NEED_GT_1: err("rpn operator requires operand >= 1"); _error_in_cmd = true; return false; case COMPUTER_LIMITATION: err("rpn: acosh(),asinh(),atanh() not available on this machine"); _error_in_cmd = true; return false; case GENERAL_ERROR: err("rpn: general error"); _error_in_cmd = true; return false; } // Everything is OK. Compute value, change it to, a character // string, and put it as next word of sout. Then increment it to // point to next word after the `END_MATH'. strcat(sout, result); if (result != (char*)NULL) delete [] result; // was allocated in rpn function strcat(sout, " "); i = rpn_end; found = true; } else { strcat(sout, _Words2[i]); strcat(sout, " "); } } if (((unsigned) superuser()) & FLAG_RPN) printf("substitute_expressions returning %s\n", found ? "TRUE" : "FALSE"); return found; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/command.hh����������������������������������������������������������������������������������0000644�0001750�0001750�00000003005�13147557614�012544� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #if !defined(_command_h_) #define _command_h_ #include #include "gr.hh" int cmd_being_done(void); bool is_system_command(const char *cmdline); bool is_create_new_command(const char *cmdline); bool get_command_line(void); bool massage_command_line(const char *cmdline); int match_gri_syntax(const char *cmdline, int flag); bool perform_gri_program(void); int perform_gri_cmd(int cmd); void pop_command_word_buffer(void); void pop_cmd_being_done_stack(void); void push_command_word_buffer(void); void push_cmd_being_done_stack(int cmd); #endif // _command_h_ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/startup.debian������������������������������������������������������������������������������0000644�0001750�0001750�00000000522�13147557614�013454� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� gri - scientific graphic program (version VERSION) Copyright (c) 2017 Dan E. Kelley. Type `help' to view list of commands, or type `show license' to view license. Access the `gri' INFO node for the online manual, or install the package gri-html-doc for an HTML version. Visit http://gri.sourceforge.net for updates and resources. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/GriPath.hh����������������������������������������������������������������������������������0000644�0001750�0001750�00000004142�13147557614�012467� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // GriPath -- store PostScript path #if !defined(_GriPath_hh_) #define _GriPath_hh_ #include "types.hh" #include "gr_coll.hh" class GriPath { public: enum type {moveto, lineto}; GriPath(); GriPath(unsigned capacity); ~GriPath(); void clear(); // Allows reuse without realloc void expand(); // Get more space void push_back(double xx, double yy, char aa); // Append at end unsigned size(); // Return length of path void trim(); // remove extraneous moveto commands void stroke(units u, double width = -1, bool closepath = false); // Stroke the path void stroke_or_fill(char s_or_f, units u, double width = -1, bool closepath = false); // Stroke or fill void fill(units u, bool closepath = false); // Fill path in void print(); // Mostly for debugging void translate(double dx, double dy); // Only makes sense if units_cm void scale(double enlargement); // Only makes sense if units_cm void rotate(double degrees); // Rotate anticlockwise double get_x(unsigned offset) {return x[offset];} // bug: no checking double get_y(unsigned offset) {return y[offset];} // no checking rectangle bounding_box(units u); private: unsigned int depth; // Length of path unsigned int capacity; // Max elements in path; see expand\(\) double *x; // Data double *y; // Data type *action; // 'm' or 'l' }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/close.cc������������������������������������������������������������������������������������0000644�0001750�0001750�00000003373�13147557614�012231� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include "extern.hh" #include "private.hh" #include "DataFile.hh" bool closeCmd() { if (((unsigned) superuser()) & FLAG_AUT1)printf("\nDEBUG: %s:%d closing a datafile. Before doing that, datafile stack_len= %d\n",__FILE__,__LINE__,int(_dataFILE.size())); if ((_dataFILE.back()).get_type() == DataFile::from_cmdfile) { err("`close' ignored: no data file open"); return false; } int file = _dataFILE.size() - 1; std::string fname; switch (_nword) { case 1: break; case 2: fname.assign(_word[1]); un_double_quote(fname); file = data_file_index(fname.c_str()); if (file < 0) { extern char _grTempString[]; sprintf(_grTempString, "`close' cannot close `%s' since it is not open", _word[1]); err(_grTempString); return false; } break; default: demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } pop_data_file(file); clear_eof_flag_on_data_file(); return true; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/popt/���������������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�13147560320�011555� 5����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/popt/poptconfig.c���������������������������������������������������������������������������0000644�0001750�0001750�00000006456�13147557614�014120� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING file accompanying popt source distributions, available from ftp://ftp.redhat.com/pub/code/popt */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #if HAVE_ALLOCA_H # include #endif #include "popt.h" #include "poptint.h" static void configLine(poptContext con, char * line) { int nameLength = strlen(con->appName); char * opt; struct poptAlias alias; char * entryType; char * longName = NULL; char shortName = '\0'; if (strncmp(line, con->appName, nameLength)) return; line += nameLength; if (!*line || !isspace(*line)) return; while (*line && isspace(*line)) line++; entryType = line; while (!*line || !isspace(*line)) line++; *line++ = '\0'; while (*line && isspace(*line)) line++; if (!*line) return; opt = line; while (!*line || !isspace(*line)) line++; *line++ = '\0'; while (*line && isspace(*line)) line++; if (!*line) return; if (opt[0] == '-' && opt[1] == '-') longName = opt + 2; else if (opt[0] == '-' && !opt[2]) shortName = opt[1]; if (!strcmp(entryType, "alias")) { if (poptParseArgvString(line, &alias.argc, &alias.argv)) return; alias.longName = longName, alias.shortName = shortName; poptAddAlias(con, alias, 0); } else if (!strcmp(entryType, "exec")) { con->execs = realloc(con->execs, sizeof(*con->execs) * (con->numExecs + 1)); if (longName) con->execs[con->numExecs].longName = strdup(longName); else con->execs[con->numExecs].longName = NULL; con->execs[con->numExecs].shortName = shortName; con->execs[con->numExecs].script = strdup(line); con->numExecs++; } } int poptReadConfigFile(poptContext con, char * fn) { char * file, * chptr, * end; char * buf, * dst; int fd, rc; int fileLength; fd = open(fn, O_RDONLY); if (fd < 0) { if (errno == ENOENT) return 0; else return POPT_ERROR_ERRNO; } fileLength = lseek(fd, 0, SEEK_END); lseek(fd, 0, 0); file = alloca(fileLength + 1); if ((fd = read(fd, file, fileLength)) != fileLength) { rc = errno; close(fd); errno = rc; return POPT_ERROR_ERRNO; } close(fd); dst = buf = alloca(fileLength + 1); chptr = file; end = (file + fileLength); while (chptr < end) { switch (*chptr) { case '\n': *dst = '\0'; dst = buf; while (*dst && isspace(*dst)) dst++; if (*dst && *dst != '#') { configLine(con, dst); } chptr++; break; case '\\': *dst++ = *chptr++; if (chptr < end) { if (*chptr == '\n') dst--, chptr++; /* \ at the end of a line does not insert a \n */ else *dst++ = *chptr++; } break; default: *dst++ = *chptr++; } } return 0; } int poptReadDefaultConfig(poptContext con, int useEnv) { char * fn, * home; int rc; if (!con->appName) return 0; rc = poptReadConfigFile(con, "/etc/popt"); if (rc) return rc; if (getuid() != geteuid()) return 0; if ((home = getenv("HOME"))) { fn = alloca(strlen(home) + 20); strcpy(fn, home); strcat(fn, "/.popt"); rc = poptReadConfigFile(con, fn); if (rc) return rc; } return 0; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/popt/README���������������������������������������������������������������������������������0000644�0001750�0001750�00000001527�13147557614�012456� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is the popt command line option parsing library. While it is similiar to getopt(3), it contains a number of enhancements, including: 1) popt is fully reentrant 2) popt can parse arbitrary argv[] style arrays while getopt(2) makes this quite difficult 3) popt allows users to alias command line arguments 4) popt provides convience functions for parsting strings into argv[] style arrays popt is used by rpm, the Red Hat install program, and many other Red Hat utilities, all of which provide excellent examples of how to use popt. Complete documentation on popt is available in popt.ps (included in this tarball), which is excerpted with permission from the book "Linux Application Development" by Michael K. Johnson and Erik Troan (availble from Addison Wesley in May, 1998). Comments on popt should be addressed to ewt@redhat.com. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/popt/findme.h�������������������������������������������������������������������������������0000644�0001750�0001750�00000000406�13147557614�013204� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING file accompanying popt source distributions, available from ftp://ftp.redhat.com/pub/code/popt */ #ifndef H_FINDME #define H_FINDME char * findProgramPath(char * argv0); #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/popt/Makefile.in����������������������������������������������������������������������������0000644�0001750�0001750�00000040305�13147560320�013624� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/popt ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libgripopt_a_AR = $(AR) $(ARFLAGS) libgripopt_a_LIBADD = am_libgripopt_a_OBJECTS = findme.$(OBJEXT) popt.$(OBJEXT) \ poptconfig.$(OBJEXT) popthelp.$(OBJEXT) poptparse.$(OBJEXT) libgripopt_a_OBJECTS = $(am_libgripopt_a_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libgripopt_a_SOURCES) DIST_SOURCES = $(libgripopt_a_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ $(top_srcdir)/mkinstalldirs README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) VPATH = @srcdir@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ CXX = $(CC) CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS_TEMPLATE = @EXTRA_CFLAGS_TEMPLATE@ GREP = @GREP@ HAVE_CONVERT = @HAVE_CONVERT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PROGS = @PROGS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ # gri/src/popt/ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LIBRARIES = libgripopt.a EXTRA_DIST = README libgripopt_a_SOURCES = findme.c popt.c poptconfig.c popthelp.c poptparse.c \ findme.h popt.h poptint.h all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/popt/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/popt/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libgripopt.a: $(libgripopt_a_OBJECTS) $(libgripopt_a_DEPENDENCIES) $(EXTRA_libgripopt_a_DEPENDENCIES) $(AM_V_at)-rm -f libgripopt.a $(AM_V_AR)$(libgripopt_a_AR) libgripopt.a $(libgripopt_a_OBJECTS) $(libgripopt_a_LIBADD) $(AM_V_at)$(RANLIB) libgripopt.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findme.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/popt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poptconfig.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/popthelp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poptparse.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/popt/popt.h���������������������������������������������������������������������������������0000644�0001750�0001750�00000010312�13147557614�012721� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING file accompanying popt source distributions, available from ftp://ftp.redhat.com/pub/code/popt */ #ifndef H_POPT #define H_POPT #include /* for FILE * */ #define POPT_OPTION_DEPTH 10 #define POPT_ARG_NONE 0 #define POPT_ARG_STRING 1 #define POPT_ARG_INT 2 #define POPT_ARG_LONG 3 #define POPT_ARG_INCLUDE_TABLE 4 /* arg points to table */ #define POPT_ARG_CALLBACK 5 /* table-wide callback... must be set first in table; arg points to callback, descrip points to callback data to pass */ #define POPT_ARG_MASK 0x0000FFFF #define POPT_ARGFLAG_ONEDASH 0x80000000 /* allow -longoption */ #define POPT_ARGFLAG_DOC_HIDDEN 0x40000000 /* don't show in help/usage */ #define POPT_CBFLAG_PRE 0x80000000 /* call the callback before parse */ #define POPT_CBFLAG_POST 0x40000000 /* call the callback after parse */ #define POPT_CBFLAG_INC_DATA 0x20000000 /* use data from the include line, not the subtable */ #define POPT_ERROR_NOARG -10 #define POPT_ERROR_BADOPT -11 #define POPT_ERROR_OPTSTOODEEP -13 #define POPT_ERROR_BADQUOTE -15 /* only from poptParseArgString() */ #define POPT_ERROR_ERRNO -16 /* only from poptParseArgString() */ #define POPT_ERROR_BADNUMBER -17 #define POPT_ERROR_OVERFLOW -18 /* poptBadOption() flags */ #define POPT_BADOPTION_NOALIAS (1 << 0) /* don't go into an alias */ /* poptGetContext() flags */ #define POPT_CONTEXT_NO_EXEC (1 << 0) /* ignore exec expansions */ #define POPT_CONTEXT_KEEP_FIRST (1 << 1) /* pay attention to argv[0] */ #define POPT_CONTEXT_POSIXMEHARDER (1 << 2) /* options can't follow args */ struct poptOption { const char * longName; /* may be NULL */ char shortName; /* may be '\0' */ int argInfo; void * arg; /* depends on argInfo */ int val; /* 0 means don't return, just update flag */ char * descrip; /* description for autohelp -- may be NULL */ char * argDescrip; /* argument description for autohelp */ }; struct poptAlias { char * longName; /* may be NULL */ char shortName; /* may be '\0' */ int argc; char ** argv; /* must be free()able */ }; extern struct poptOption poptHelpOptions[]; #define POPT_AUTOHELP { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptions, \ 0, "Help options", NULL }, typedef struct poptContext_s * poptContext; #ifndef __cplusplus typedef struct poptOption * poptOption; #endif enum poptCallbackReason { POPT_CALLBACK_REASON_PRE, POPT_CALLBACK_REASON_POST, POPT_CALLBACK_REASON_OPTION }; typedef void (*poptCallbackType)(poptContext con, enum poptCallbackReason reason, const struct poptOption * opt, const char * arg, void * data); poptContext poptGetContext(char * name, int argc, char ** argv, const struct poptOption * options, int flags); void poptResetContext(poptContext con); /* returns 'val' element, -1 on last item, POPT_ERROR_* on error */ int poptGetNextOpt(poptContext con); /* returns NULL if no argument is available */ char * poptGetOptArg(poptContext con); /* returns NULL if no more options are available */ char * poptGetArg(poptContext con); char * poptPeekArg(poptContext con); char ** poptGetArgs(poptContext con); /* returns the option which caused the most recent error */ char * poptBadOption(poptContext con, int flags); void poptFreeContext(poptContext con); int poptStuffArgs(poptContext con, char ** argv); int poptAddAlias(poptContext con, struct poptAlias alias, int flags); int poptReadConfigFile(poptContext con, char * fn); /* like above, but reads /etc/popt and $HOME/.popt along with environment vars */ int poptReadDefaultConfig(poptContext con, int useEnv); /* argv should be freed -- this allows ', ", and \ quoting, but ' is treated the same as " and both may include \ quotes */ int poptParseArgvString(char * s, int * argcPtr, char *** argvPtr); const char * poptStrerror(const int error); void poptSetExecPath(poptContext con, const char * path, int allowAbsolute); void poptPrintHelp(poptContext con, FILE * f, int flags); void poptPrintUsage(poptContext con, FILE * f, int flags); void poptSetOtherOptionHelp(poptContext con, const char * text); const char * poptGetInvocationName(poptContext con); #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/popt/findme.c�������������������������������������������������������������������������������0000644�0001750�0001750�00000002337�13147557614�013204� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING file accompanying popt source distributions, available from ftp://ftp.redhat.com/pub/code/popt */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #ifdef __NeXT /* access macros are not declared in non posix mode in unistd.h - don't try to use posix on NeXTstep 3.3 ! */ #include #endif #if HAVE_ALLOCA_H # include #endif #include "findme.h" char * findProgramPath(char * argv0) { char * path = getenv("PATH"); char * pathbuf; char * start, * chptr; char * buf; /* If there is a / in the argv[0], it has to be an absolute path */ if (strchr(argv0, '/')) return strdup(argv0); if (!path) return NULL; start = pathbuf = alloca(strlen(path) + 1); buf = malloc(strlen(path) + strlen(argv0) + 2); strcpy(pathbuf, path); chptr = NULL; do { if ((chptr = strchr(start, ':'))) *chptr = '\0'; sprintf(buf, "%s/%s", start, argv0); if (!access(buf, X_OK)) return buf; if (chptr) start = chptr + 1; else start = NULL; } while (start && *start); free(buf); return NULL; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/popt/copyright������������������������������������������������������������������������������0000644�0001750�0001750�00000003765�13147557614�013537� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is the Debian GNU/Linux prepackaged version of the popt library. popt was written by Erik Troan . The package was put together by Enrique Zanardi , from sources obtained from: ftp://ftp.redhat.com/pub/redhat/code/popt/popt-1.1.1.tar.gz Version 1.6.2 from ftp://ftp.rpm.org/pub/rpm/dist/rpm-4.0.x/ The copyright on this package is inconsistent, but both licences are free. The popt.3 manpage says: It may be redistributed under either the GNU General Public License or the GNU Library General Public License, at the distributor's discretion. (Both the GPL and LGPL can be found on a Debian system in /usr/share/common-licenses/) However, the COPYING file contains the X licence: Copyright (c) 1998 Red Hat Software Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of the X Consortium shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the X Consortium. �����������gri/src/popt/poptparse.c����������������������������������������������������������������������������0000644�0001750�0001750�00000003474�13147557614�013762� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING file accompanying popt source distributions, available from ftp://ftp.redhat.com/pub/code/popt */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "popt.h" int poptParseArgvString(char * s, int * argcPtr, char *** argvPtr) { char * buf = strcpy(alloca(strlen(s) + 1), s); char * bufStart = buf; char * src, * dst; char quote = '\0'; int argvAlloced = 5; char ** argv = malloc(sizeof(*argv) * argvAlloced); char ** argv2; int argc = 0; int i; src = s; dst = buf; argv[argc] = buf; memset(buf, '\0', strlen(s) + 1); while (*src) { if (quote == *src) { quote = '\0'; } else if (quote) { if (*src == '\\') { src++; if (!*src) { free(argv); return POPT_ERROR_BADQUOTE; } if (*src != quote) *buf++ = '\\'; } *buf++ = *src; } else if (isspace(*src)) { if (*argv[argc]) { buf++, argc++; if (argc == argvAlloced) { argvAlloced += 5; argv = realloc(argv, sizeof(*argv) * argvAlloced); } argv[argc] = buf; } } else switch (*src) { case '"': case '\'': quote = *src; break; case '\\': src++; if (!*src) { free(argv); return POPT_ERROR_BADQUOTE; } /* fallthrough */ default: *buf++ = *src; } src++; } if (strlen(argv[argc])) { argc++, buf++; } dst = malloc(argc * sizeof(*argv) + (buf - bufStart)); argv2 = (void *) dst; dst += argc * sizeof(*argv); memcpy(argv2, argv, argc * sizeof(*argv)); memcpy(dst, bufStart, buf - bufStart); for (i = 0; i < argc; i++) { argv2[i] = dst + (argv[i] - bufStart); } free(argv); *argvPtr = argv2; *argcPtr = argc; return 0; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/popt/Makefile.am����������������������������������������������������������������������������0000644�0001750�0001750�00000000423�13147557614�013624� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Process this file with automake to produce Makefile.in # gri/src/popt/ srcdir = @srcdir@ VPATH = @srcdir@ noinst_LIBRARIES = libgripopt.a EXTRA_DIST = README libgripopt_a_SOURCES = findme.c popt.c poptconfig.c popthelp.c poptparse.c \ findme.h popt.h poptint.h CXX=$(CC) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/popt/popt.c���������������������������������������������������������������������������������0000644�0001750�0001750�00000035465�13147557614�012734� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING file accompanying popt source distributions, available from ftp://ftp.redhat.com/pub/code/popt */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #if HAVE_ALLOCA_H # include #endif #include "findme.h" #include "popt.h" #include "poptint.h" #ifndef HAVE_STRERROR static char * strerror(int errno) { extern int sys_nerr; extern char * sys_errlist[]; if ((0 <= errno) && (errno < sys_nerr)) return sys_errlist[errno]; else return POPT_("unknown errno"); } #endif void poptSetExecPath(poptContext con, const char * path, int allowAbsolute) { if (con->execPath) free(con->execPath); con->execPath = strdup(path); con->execAbsolute = allowAbsolute; } static void invokeCallbacks(poptContext con, const struct poptOption * table, int post) { const struct poptOption * opt = table; poptCallbackType cb; while (opt->longName || opt->shortName || opt->arg) { if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { invokeCallbacks(con, opt->arg, post); } else if (((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK) && ((!post && (opt->argInfo & POPT_CBFLAG_PRE)) || ( post && (opt->argInfo & POPT_CBFLAG_POST)))) { cb = opt->arg; cb(con, post ? POPT_CALLBACK_REASON_POST : POPT_CALLBACK_REASON_PRE, NULL, NULL, opt->descrip); } opt++; } } poptContext poptGetContext(char * name, int argc, char ** argv, const struct poptOption * options, int flags) { poptContext con = malloc(sizeof(*con)); memset(con, 0, sizeof(*con)); con->os = con->optionStack; con->os->argc = argc; con->os->argv = argv; if (!(flags & POPT_CONTEXT_KEEP_FIRST)) con->os->next = 1; /* skip argv[0] */ con->leftovers = malloc(sizeof(char *) * (argc + 1)); con->options = options; con->finalArgv = malloc(sizeof(*con->finalArgv) * (argc * 2)); con->finalArgvAlloced = argc * 2; con->flags = flags; con->execAbsolute = 1; if (getenv("POSIXLY_CORRECT") || getenv("POSIX_ME_HARDER")) con->flags |= POPT_CONTEXT_POSIXMEHARDER; if (name) con->appName = strcpy(malloc(strlen(name) + 1), name); invokeCallbacks(con, con->options, 0); return con; } void poptResetContext(poptContext con) { con->os = con->optionStack; con->os->currAlias = NULL; con->os->nextCharArg = NULL; con->os->nextArg = NULL; con->os->next = 1; /* skip argv[0] */ con->numLeftovers = 0; con->nextLeftover = 0; con->restLeftover = 0; con->doExec = NULL; con->finalArgvCount = 0; } /* Only one of longName, shortName may be set at a time */ static int handleExec(poptContext con, char * longName, char shortName) { int i; i = con->numExecs - 1; if (longName) { while (i >= 0 && (!con->execs[i].longName || strcmp(con->execs[i].longName, longName))) i--; } else { while (i >= 0 && con->execs[i].shortName != shortName) i--; } if (i < 0) return 0; if (con->flags & POPT_CONTEXT_NO_EXEC) return 1; if (!con->doExec) { con->doExec = con->execs + i; return 1; } /* We already have an exec to do; remember this option for next time 'round */ if ((con->finalArgvCount + 1) >= (con->finalArgvAlloced)) { con->finalArgvAlloced += 10; con->finalArgv = realloc(con->finalArgv, sizeof(*con->finalArgv) * con->finalArgvAlloced); } i = con->finalArgvCount++; con->finalArgv[i] = malloc((longName ? strlen(longName) : 0) + 3); if (longName) sprintf(con->finalArgv[i], "--%s", longName); else sprintf(con->finalArgv[i], "-%c", shortName); return 1; } /* Only one of longName, shortName may be set at a time */ static int handleAlias(poptContext con, char * longName, char shortName, char * nextCharArg) { int i; if (con->os->currAlias && con->os->currAlias->longName && longName && !strcmp(con->os->currAlias->longName, longName)) return 0; if (con->os->currAlias && shortName == con->os->currAlias->shortName) return 0; i = con->numAliases - 1; if (longName) { while (i >= 0 && (!con->aliases[i].longName || strcmp(con->aliases[i].longName, longName))) i--; } else { while (i >= 0 && con->aliases[i].shortName != shortName) i--; } if (i < 0) return 0; if ((con->os - con->optionStack + 1) == POPT_OPTION_DEPTH) return POPT_ERROR_OPTSTOODEEP; if (nextCharArg && *nextCharArg) con->os->nextCharArg = nextCharArg; con->os++; con->os->next = 0; con->os->stuffed = 0; con->os->nextArg = con->os->nextCharArg = NULL; con->os->currAlias = con->aliases + i; con->os->argc = con->os->currAlias->argc; con->os->argv = con->os->currAlias->argv; return 1; } static void execCommand(poptContext con) { char ** argv; int pos = 0; char * script = con->doExec->script; argv = malloc(sizeof(*argv) * (6 + con->numLeftovers + con->finalArgvCount)); if (!con->execAbsolute && strchr(script, '/')) return; if (!strchr(script, '/') && con->execPath) { argv[pos] = alloca(strlen(con->execPath) + strlen(script) + 2); sprintf(argv[pos], "%s/%s", con->execPath, script); } else { argv[pos] = script; } pos++; argv[pos] = findProgramPath(con->os->argv[0]); if (argv[pos]) pos++; argv[pos++] = ";"; memcpy(argv + pos, con->finalArgv, sizeof(*argv) * con->finalArgvCount); pos += con->finalArgvCount; if (con->numLeftovers) { argv[pos++] = "--"; memcpy(argv + pos, con->leftovers, sizeof(*argv) * con->numLeftovers); pos += con->numLeftovers; } argv[pos++] = NULL; #ifdef __hpux setresuid(getuid(), getuid(),-1); #else setreuid(getuid(), getuid()); /*hlauer: not portable to hpux9.01 */ #endif execvp(argv[0], argv); } static const struct poptOption * findOption(const struct poptOption * table, const char * longName, const char shortName, poptCallbackType * callback, void ** callbackData, int singleDash) { const struct poptOption * opt = table; const struct poptOption * opt2; const struct poptOption * cb = NULL; while (opt->longName || opt->shortName || opt->arg) { if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { opt2 = findOption(opt->arg, longName, shortName, callback, callbackData, singleDash); if (opt2) { if (*callback && !*callbackData) *callbackData = opt->descrip; return opt2; } } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK) { cb = opt; } else if (longName && opt->longName && (!singleDash || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) && !strcmp(longName, opt->longName)) { break; } else if (shortName && shortName == opt->shortName) { break; } opt++; } if (!opt->longName && !opt->shortName) return NULL; *callbackData = NULL; *callback = NULL; if (cb) { *callback = cb->arg; if (!(cb->argInfo & POPT_CBFLAG_INC_DATA)) *callbackData = cb->descrip; } return opt; } /* returns 'val' element, -1 on last item, POPT_ERROR_* on error */ int poptGetNextOpt(poptContext con) { char * optString, * chptr, * localOptString; char * longArg = NULL; char * origOptString; long aLong; char * end; const struct poptOption * opt = NULL; int done = 0; int i; poptCallbackType cb; void * cbData; int singleDash; while (!done) { while (!con->os->nextCharArg && con->os->next == con->os->argc && con->os > con->optionStack) con->os--; if (!con->os->nextCharArg && con->os->next == con->os->argc) { invokeCallbacks(con, con->options, 1); if (con->doExec) execCommand(con); return -1; } if (!con->os->nextCharArg) { origOptString = con->os->argv[con->os->next++]; if (con->restLeftover || *origOptString != '-') { con->leftovers[con->numLeftovers++] = origOptString; if (con->flags & POPT_CONTEXT_POSIXMEHARDER) con->restLeftover = 1; continue; } /* Make a copy we can hack at */ localOptString = optString = strcpy(alloca(strlen(origOptString) + 1), origOptString); if (!optString[0]) return POPT_ERROR_BADOPT; if (optString[1] == '-' && !optString[2]) { con->restLeftover = 1; continue; } else { optString++; if (*optString == '-') singleDash = 0, optString++; else singleDash = 1; if (handleAlias(con, optString, '\0', NULL)) continue; if (handleExec(con, optString, '\0')) continue; chptr = optString; while (*chptr && *chptr != '=') chptr++; if (*chptr == '=') { longArg = origOptString + (chptr - localOptString) + 1; *chptr = '\0'; } opt = findOption(con->options, optString, '\0', &cb, &cbData, singleDash); if (!opt && !singleDash) return POPT_ERROR_BADOPT; } if (!opt) con->os->nextCharArg = origOptString + 1; } if (con->os->nextCharArg) { origOptString = con->os->nextCharArg; con->os->nextCharArg = NULL; if (handleAlias(con, NULL, *origOptString, origOptString + 1)) { origOptString++; continue; } if (handleExec(con, NULL, *origOptString)) continue; opt = findOption(con->options, NULL, *origOptString, &cb, &cbData, 0); if (!opt) return POPT_ERROR_BADOPT; origOptString++; if (*origOptString) con->os->nextCharArg = origOptString; } if (opt->arg && (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_NONE) *((int *)opt->arg) = 1; else if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE) { if (longArg) { con->os->nextArg = longArg; } else if (con->os->nextCharArg) { con->os->nextArg = con->os->nextCharArg; con->os->nextCharArg = NULL; } else { while (con->os->next == con->os->argc && con->os > con->optionStack) con->os--; if (con->os->next == con->os->argc) return POPT_ERROR_NOARG; con->os->nextArg = con->os->argv[con->os->next++]; } if (opt->arg) { switch (opt->argInfo & POPT_ARG_MASK) { case POPT_ARG_STRING: *((char **) opt->arg) = con->os->nextArg; break; case POPT_ARG_INT: case POPT_ARG_LONG: aLong = strtol(con->os->nextArg, &end, 0); if (*end) return POPT_ERROR_BADNUMBER; if (aLong == LONG_MIN || aLong == LONG_MAX) return POPT_ERROR_OVERFLOW; if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_LONG) { *((long *) opt->arg) = aLong; } else { if (aLong > INT_MAX || aLong < INT_MIN) return POPT_ERROR_OVERFLOW; *((int *) opt->arg) =aLong; } break; default: fprintf(stdout, POPT_("option type (%d) not implemented in popt\n"), opt->argInfo & POPT_ARG_MASK); exit(1); } } } if (cb) cb(con, POPT_CALLBACK_REASON_OPTION, opt, con->os->nextArg, cbData); else if (opt->val) done = 1; if ((con->finalArgvCount + 2) >= (con->finalArgvAlloced)) { con->finalArgvAlloced += 10; con->finalArgv = realloc(con->finalArgv, sizeof(*con->finalArgv) * con->finalArgvAlloced); } i = con->finalArgvCount++; con->finalArgv[i] = malloc((opt->longName ? strlen(opt->longName) : 0) + 3); if (opt->longName) sprintf(con->finalArgv[i], "--%s", opt->longName); else sprintf(con->finalArgv[i], "-%c", opt->shortName); if (opt->arg && (opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE) con->finalArgv[con->finalArgvCount++] = strdup(con->os->nextArg); } return opt->val; } char * poptGetOptArg(poptContext con) { char * ret = con->os->nextArg; con->os->nextArg = NULL; return ret; } char * poptGetArg(poptContext con) { if (con->numLeftovers == con->nextLeftover) return NULL; return (con->leftovers[con->nextLeftover++]); } char * poptPeekArg(poptContext con) { if (con->numLeftovers == con->nextLeftover) return NULL; return (con->leftovers[con->nextLeftover]); } char ** poptGetArgs(poptContext con) { if (con->numLeftovers == con->nextLeftover) return NULL; /* some apps like [like RPM ;-) ] need this NULL terminated */ con->leftovers[con->numLeftovers] = NULL; return (con->leftovers + con->nextLeftover); } void poptFreeContext(poptContext con) { int i; for (i = 0; i < con->numAliases; i++) { if (con->aliases[i].longName) free(con->aliases[i].longName); free(con->aliases[i].argv); } for (i = 0; i < con->numExecs; i++) { if (con->execs[i].longName) free(con->execs[i].longName); free(con->execs[i].script); } for (i = 0; i < con->finalArgvCount; i++) free(con->finalArgv[i]); free(con->leftovers); free(con->finalArgv); if (con->appName) free(con->appName); if (con->aliases) free(con->aliases); if (con->otherHelp) free(con->otherHelp); free(con); } int poptAddAlias(poptContext con, struct poptAlias newAlias, int flags) { int aliasNum = con->numAliases++; struct poptAlias * alias; /* SunOS won't realloc(NULL, ...) */ if (!con->aliases) con->aliases = malloc(sizeof(newAlias) * con->numAliases); else con->aliases = realloc(con->aliases, sizeof(newAlias) * con->numAliases); alias = con->aliases + aliasNum; *alias = newAlias; if (alias->longName) alias->longName = strcpy(malloc(strlen(alias->longName) + 1), alias->longName); else alias->longName = NULL; return 0; } char * poptBadOption(poptContext con, int flags) { struct optionStackEntry * os; if (flags & POPT_BADOPTION_NOALIAS) os = con->optionStack; else os = con->os; return os->argv[os->next - 1]; } #define POPT_ERROR_NOARG -10 #define POPT_ERROR_BADOPT -11 #define POPT_ERROR_OPTSTOODEEP -13 #define POPT_ERROR_BADQUOTE -15 /* only from poptParseArgString() */ #define POPT_ERROR_ERRNO -16 /* only from poptParseArgString() */ const char * poptStrerror(const int error) { switch (error) { case POPT_ERROR_NOARG: return POPT_("missing argument"); case POPT_ERROR_BADOPT: return POPT_("unknown option"); case POPT_ERROR_OPTSTOODEEP: return POPT_("aliases nested too deeply"); case POPT_ERROR_BADQUOTE: return POPT_("error in paramter quoting"); case POPT_ERROR_BADNUMBER: return POPT_("invalid numeric value"); case POPT_ERROR_OVERFLOW: return POPT_("number too large or too small"); case POPT_ERROR_ERRNO: return strerror(errno); default: return POPT_("unknown error"); } } int poptStuffArgs(poptContext con, char ** argv) { int i; if ((con->os - con->optionStack) == POPT_OPTION_DEPTH) return POPT_ERROR_OPTSTOODEEP; for (i = 0; argv[i]; i++); con->os++; con->os->next = 0; con->os->nextArg = con->os->nextCharArg = NULL; con->os->currAlias = NULL; con->os->argc = i; con->os->argv = argv; con->os->stuffed = 1; return 0; } const char * poptGetInvocationName(poptContext con) { return con->os->argv[0]; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/popt/poptint.h������������������������������������������������������������������������������0000644�0001750�0001750�00000002356�13147557614�013445� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING file accompanying popt source distributions, available from ftp://ftp.redhat.com/pub/code/popt */ #ifndef H_POPTINT #define H_POPTINT struct optionStackEntry { int argc; char ** argv; int next; char * nextArg; char * nextCharArg; struct poptAlias * currAlias; int stuffed; }; struct execEntry { char * longName; char shortName; char * script; }; struct poptContext_s { struct optionStackEntry optionStack[POPT_OPTION_DEPTH], * os; char ** leftovers; int numLeftovers; int nextLeftover; const struct poptOption * options; int restLeftover; char * appName; struct poptAlias * aliases; int numAliases; int flags; struct execEntry * execs; int numExecs; char ** finalArgv; int finalArgvCount; int finalArgvAlloced; struct execEntry * doExec; char * execPath; int execAbsolute; char * otherHelp; }; #ifdef HAVE_LIBINTL_H #include #endif #ifdef HAVE_GETTEXT #define _(foo) gettext(foo) #else #define _(foo) (foo) #endif #ifdef HAVE_DGETTEXT #define POPT_(foo) dgettext("popt", foo) #else #define POPT_(foo) (foo) #endif #define N_(foo) (foo) #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/popt/popthelp.c�����������������������������������������������������������������������������0000644�0001750�0001750�00000015372�13147557614�013600� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING file accompanying popt source distributions, available from ftp://ftp.redhat.com/pub/code/popt */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "popt.h" #include "poptint.h" static void displayArgs(poptContext con, enum poptCallbackReason foo, struct poptOption * key, const char * arg, void * data) { if (key->shortName== '?') poptPrintHelp(con, stderr, 0); else poptPrintUsage(con, stderr, 0); exit(0); } struct poptOption poptHelpOptions[] = { { NULL, '\0', POPT_ARG_CALLBACK, &displayArgs, '\0', NULL }, { "help", '?', 0, NULL, '?', N_("Show this help message") }, { "usage", '\0', 0, NULL, 'u', N_("Display brief usage message") }, { NULL, '\0', 0, NULL, 0 } } ; static const char * getArgDescrip(const struct poptOption * opt) { if (!(opt->argInfo & POPT_ARG_MASK)) return NULL; if (opt == (poptHelpOptions + 1) || opt == (poptHelpOptions + 2)) if (opt->argDescrip) return POPT_(opt->argDescrip); if (opt->argDescrip) return _(opt->argDescrip); return POPT_("ARG"); } static void singleOptionHelp(FILE * f, int maxLeftCol, const struct poptOption * opt) { int indentLength = maxLeftCol + 5; int lineLength = 79 - indentLength; const char * help = _(opt->descrip); int helpLength; const char * ch; char format[10]; char * left = alloca(maxLeftCol + 1); const char * argDescrip = getArgDescrip(opt); *left = '\0'; if (opt->longName && opt->shortName) sprintf(left, "-%c, --%s", opt->shortName, opt->longName); else if (opt->shortName) sprintf(left, "-%c", opt->shortName); else if (opt->longName) sprintf(left, "--%s", opt->longName); if (!*left) return ; if (argDescrip) { strcat(left, "="); strcat(left, argDescrip); } if (help) fprintf(f," %-*s ", maxLeftCol, left); else { fprintf(f," %s\n", left); return; } helpLength = strlen(help); while (helpLength > lineLength) { ch = help + lineLength - 1; while (ch > help && !isspace(*ch)) ch--; if (ch == help) break; /* give up */ while (ch > (help + 1) && isspace(*ch)) ch--; ch++; sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help), indentLength); fprintf(f, format, help, " "); help = ch; while (isspace(*help) && *help) help++; helpLength = strlen(help); } if (helpLength) fprintf(f, "%s\n", help); } static int maxArgWidth(const struct poptOption * opt) { int max = 0; int this; const char * s; while (opt->longName || opt->shortName || opt->arg) { if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { this = maxArgWidth(opt->arg); if (this > max) max = this; } else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) { this = opt->shortName ? 2 : 0; if (opt->longName) { if (this) this += 2; this += strlen(opt->longName) + 2; } s = getArgDescrip(opt); if (s) this += strlen(s) + 1; if (this > max) max = this; } opt++; } return max; } static void singleTableHelp(FILE * f, const struct poptOption * table, int left) { const struct poptOption * opt; opt = table; while (opt->longName || opt->shortName || opt->arg) { if ((opt->longName || opt->shortName) && !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) singleOptionHelp(f, left, opt); opt++; } opt = table; while (opt->longName || opt->shortName || opt->arg) { if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { if (opt->descrip) fprintf(f, "\n%s\n", _(opt->descrip)); singleTableHelp(f, opt->arg, left); } opt++; } } static int showHelpIntro(poptContext con, FILE * f) { int len = 6; char * fn; fprintf(f, POPT_("Usage:")); if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) { fn = con->optionStack->argv[0]; if (strchr(fn, '/')) fn = strchr(fn, '/') + 1; fprintf(f, " %s", fn); len += strlen(fn) + 1; } return len; } void poptPrintHelp(poptContext con, FILE * f, int flags) { int leftColWidth; showHelpIntro(con, f); if (con->otherHelp) fprintf(f, " %s\n", con->otherHelp); else fprintf(f, " %s\n", POPT_("[OPTION...]")); leftColWidth = maxArgWidth(con->options); singleTableHelp(f, con->options, leftColWidth); } static int singleOptionUsage(FILE * f, int cursor, const struct poptOption * opt) { int len = 3; char shortStr[2]; const char * item = shortStr; const char * argDescrip = getArgDescrip(opt); if (opt->shortName) { if (!(opt->argInfo & POPT_ARG_MASK)) return cursor; /* we did these already */ len++; *shortStr = opt->shortName; shortStr[1] = '\0'; } else if (opt->longName) { len += 1 + strlen(opt->longName); item = opt->longName; } if (len == 3) return cursor; if (argDescrip) len += strlen(argDescrip) + 1; if ((cursor + len) > 79) { fprintf(f, "\n "); cursor = 7; } fprintf(f, " [-%s%s%s%s]", opt->shortName ? "" : "-", item, argDescrip ? (opt->shortName ? " " : "=") : "", argDescrip ? argDescrip : ""); return cursor + len + 1; } int singleTableUsage(FILE * f, int cursor, const struct poptOption * table) { const struct poptOption * opt; opt = table; while (opt->longName || opt->shortName || opt->arg) { if ((opt->longName || opt->shortName) && !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) cursor = singleOptionUsage(f, cursor, opt); else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) cursor = singleTableUsage(f, cursor, opt->arg); opt++; } return cursor; } static int showShortOptions(const struct poptOption * opt, FILE * f, char * str) { char s[300]; /* this is larger then the ascii set, so it should do just fine */ if (!str) { str = s; memset(str, 0, sizeof(str)); } while (opt->longName || opt->shortName || opt->arg) { if (opt->shortName && !(opt->argInfo & POPT_ARG_MASK)) str[strlen(str)] = opt->shortName; else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) showShortOptions(opt->arg, f, str); opt++; } if (s != str || !*s) return 0; fprintf(f, " [-%s]", s); return strlen(s) + 4; } void poptPrintUsage(poptContext con, FILE * f, int flags) { int cursor; cursor = showHelpIntro(con, f); cursor += showShortOptions(con->options, f, NULL); singleTableUsage(f, cursor, con->options); if (con->otherHelp) { cursor += strlen(con->otherHelp) + 1; if (cursor > 79) fprintf(f, "\n "); fprintf(f, " %s", con->otherHelp); } fprintf(f, "\n"); } void poptSetOtherOptionHelp(poptContext con, const char * text) { if (con->otherHelp) free(con->otherHelp); con->otherHelp = strdup(text); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/rewind.cc�����������������������������������������������������������������������������������0000644�0001750�0001750�00000003262�13147557614�012411� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include "extern.hh" #include "DataFile.hh" bool rewindCmd() { if (_nword == 1) { if (_dataFILE.back().get_type() != DataFile::ascii) { err("`rewind' ignored: no data file open (and can't rewind keyboard)"); return false; } rewind(_dataFILE.back().get_fp()); clearerr(_dataFILE.back().get_fp()); _dataFILE.back().set_line(1); clear_eof_flag_on_data_file(); } else if (_nword == 2) { std::string fname(_word[1]); un_double_quote(fname); int i = data_file_index(fname.c_str()); if (i >= 0) { rewind(_dataFILE[i].get_fp()); clearerr(_dataFILE[i].get_fp()); _dataFILE[i].set_line(1); clear_eof_flag_on_data_file(); } else { err("cannot `rewind' file named `\\", _word[1], "' since it is not open.", "\\"); return false; } } else { err("`rewind [\filename]' takes no additional parameters"); return false; } return true; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/doline.cc�����������������������������������������������������������������������������������0000644�0001750�0001750�00000077537�13147557614�012413� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define USE_BACKTIC 0 // keep code just in case //#define DEBUG_DOLLAR_PAREN 1 #include #include #include #include #include "gr.hh" #include "extern.hh" #include "command.hh" #include "superus.hh" void display_cmd_being_done_stack(void); extern char _grTempString[]; extern char *_griVersion_name; #if USE_BACKTIC static bool sub_backtic(const char *n, char *out); #endif static bool sub_dollar_paren(const char *n, std::string& out); static int dollar_paren(const char *s, std::string& res); bool get_cmd(char *buf, int max, FILE * fp); bool postscriptCmd(void); static void check_usage(const char *s); bool tracing() { // ?? this could be speeded up a lot ?? double trace; get_var("..trace..", &trace); return (trace ? true : false); } // do_command_line() -- get, massage, and perform command line // RETURN false if no more command lines. (Set _done=1 if no // more command lines and the cmd-file stack empties.) bool do_command_line() { //printf("at start of do_command_line() _cmdLine is <%s>\n",_cmdLine); // *** Get command line, storing it in the global _cmdLine *** if (!get_command_line()) { _cmdFILE.pop_back(); if (_cmdFILE.size() == 0) { _done = 1; return false; } return false; } //printf("DEBUG cmdline '%s'\n",_cmdLine); // Remove comments, do math expansions, substitute synonyms, etc. massage_command_line(_cmdLine); // Handle "return" as special case if ((_nword > 0) && (!strcmp(_word[0], "return")) && (!skipping_through_if())) { _cmdFILE.pop_back(); if (_cmdFILE.size() == 0) { _done = 1; return false; } else { return false; } } else { // Do what the command instructs. perform_command_line(NULL, true); return true; } } // Insert command line as a comment in the PostScript file, after // removing newpage character to blank, (since latex2e/epsfig breaks // on newpage). // // The 'note' is helpful in debugging. void insert_cmd_in_ps(const char *cmd, const char *note) { extern bool _private; if (!_private) { extern bool _store_cmds_in_ps; // DEFINED IN startup.c if (!_store_cmds_in_ps) return; unsigned int first_nonwhite = 0; while (isspace(*(cmd + first_nonwhite))) first_nonwhite++; #if 0 // removed 2001-feb-22 for SF bug #133135 if (!strncmp(cmd + first_nonwhite, "insert", 6)) return; // don't want 'insert' commands (confusing eh) #endif strcpy(_grTempString, "gri:"); int ii = 4; // where to start insert int len = strlen(cmd); for (int i = 0; i < len; i++) { if (cmd[i] == PASTE_CHAR) break; if (cmd[i] != char(12)) // newpage _grTempString[ii++] = cmd[i]; } _grTempString[ii] = '\0'; if (_grTempString[strlen(_grTempString) - 1] == '\n') _grTempString[strlen(_grTempString) - 1] = '\0'; if (*note != '\0') { strcat(_grTempString, " # "); strcat(_grTempString, note); } gr_comment(_grTempString); } } #if 1 // used only if -s256 set void insert_source_indicator(char *cl) { // BUG must not let overrun unsigned int len = strlen(cl); char line[1024]; sprintf(line, " \"%s:%d\"", _cmdFILE.back().get_name(), _cmdFILE.back().get_line()); strcat(cl, line); if (len > 0 && cl[len - 1] == '\n') cl[len - 1] = PASTE_CHAR; else cl[len] = PASTE_CHAR; } #endif // get_command_line() -- get a command line (skip full-line C comments) bool get_command_line(void) { /*#ifndef HAVE_LIBREADLINE*/ write_prompt(); /*#endif*/ stop_replay_if_error(); // get a line from a file. if (_cmdFILE.back().get_interactive()) { //printf("DEBUG. interactive. before, had <%s>\n",_cmdLine); // Cmd-file is interactive (from keyboard) if (!gr_textget(_cmdLine, LineLength_1)) { _done = 1; return false; } //printf("DEBUG. interactive. after, have <%s>\n",_cmdLine); } else { // Cmd-file is non-interactive. if (true == get_cmd(_cmdLine, LineLength_1, _cmdFILE.back().get_fp())) { if (strlen(_cmdLine) < 1) { if (((unsigned) superuser()) & FLAG_AUT2) printf("%s:%d debug 2\n",__FILE__,__LINE__); return false; } else { warning("Missing newline at end of command file."); } } // Now ready to do something. if (!is_create_new_command(_cmdLine)) { // Print trace info if desired if (tracing()) { if (skipping_through_if()) printf("X "); else printf("%s", _margin.c_str()); printf("%s\n", _cmdLine); } } } _cmdFILE.back().increment_line(); // BUG line numbers wrong BUG if (_cmdFILE.back().get_save2ps()) insert_cmd_in_ps(_cmdLine/*, "doline.cc:154"*/); if (((unsigned) superuser()) & FLAG_AUT1) { insert_source_indicator(_cmdLine); } if (((unsigned) superuser()) & FLAG_AUT2) printf("%s:%d get_command_line returning [%s]\n",__FILE__,__LINE__,_cmdLine); return true; } // Insert PostScript directly into file. bool postscriptCmd() { extern FILE *_grPS; fprintf(_grPS, "%s\n", _cmdLine + skip_space(_cmdLine) + strlen("postscript ")); check_psfile(); return true; } // Remove comments, expand rpn, substitute synonyms, etc. // Return 1 if not end-of-file, or 0 if end-of-file. bool remove_source_indicator(char *cmd) { extern char source_indicator[]; int len = strlen(cmd); source_indicator[0] = '\0'; for (int i = 0; i < len; i++) { if (cmd[i] == PASTE_CHAR) { int cut_here = i; i++; while (isspace(*(cmd + i)) && i < len) // skip whitespace if any i++; if (cmd[i] == '"') strcpy(source_indicator, cmd + i + 1); cmd[cut_here] = '\0'; int len = strlen(source_indicator); if (source_indicator[len - 1] == '"') source_indicator[len - 1] = '\0'; return true; } } return false; } bool massage_command_line(char *cmd) { _nword = 0; if (((unsigned) superuser()) & FLAG_AUT1) { remove_source_indicator(cmd); } remove_comment(cmd); if (!is_system_command(cmd)) check_usage(cmd); strcpy(_cmdLineCOPY, cmd + skip_space(cmd)); // For system commands, just substitute synonyms. if (is_system_command(cmd)) { strcpy(cmd, _cmdLineCOPY); std::string cmd_sub; substitute_synonyms_cmdline(cmd, cmd_sub, false); strcpy(_cmdLineCOPY, cmd_sub.c_str()); strcpy(cmd, _cmdLineCOPY); // Chop into words. Note: chop_into_words() destroys it's string, so // use a copy. chop_into_words(_cmdLineCOPY, _word, &_nword, MAX_nword); return true; } // Don't massage further if it's a `create new command' or a `postscript' // command. if (is_create_new_command(cmd)) { if (((unsigned) superuser()) & FLAG_NEW) printf("[%s]\n", cmd); return true; } // Expand blanks, by separating words, but only in certain circumstances. if (!re_compare(_cmdLine, "\\s*cd\\s*.*") && !re_compare(_cmdLine, "\\s*delete\\s*.*") && !re_compare(_cmdLine, "\\s*ls\\s*.*") && !re_compare(_cmdLine, "\\s*insert\\s*.*") && !re_compare(_cmdLine, "\\s*close\\s*.*") && !re_compare(_cmdLine, "\\s*open\\s*.*") // removed 2.5.5; re-inserted 2.6.0 && !re_compare(_cmdLine, "\\s*postscript\\s*.*") ) { expand_blanks(cmd); } remove_trailing_blanks(cmd); _error_in_cmd = false; if (strlen(cmd) < 1) { _nword = 0; return true; } strcpy(_cmdLineCOPY, cmd + skip_space(cmd)); strcpy(cmd, _cmdLineCOPY); if (strlen(cmd) < 1) { _nword = 0; return true; } // Copy back into cmd. This must be done before substituting synonyms, // so that code like `defined (\syn)' will work. if (!re_compare(_cmdLine, "\\s*postscript\\s*.*") && !re_compare(_cmdLine, "\\s*new\\s*.*")) { strcpy(cmd, _cmdLineCOPY); } // Substitute synonyms; copy back into cmd. if (((unsigned) superuser()) & FLAG_SYN) printf("[%s]\n", cmd); // Don't substitute synonyms for these commands: `new \syn ...' `delete // \syn ...' if (re_compare(_cmdLine, "\\s*open\\s*.*")) { std::string cmd_sub; substitute_synonyms_cmdline(cmd, cmd_sub, false); strcpy(cmd, cmd_sub.c_str()); } else { if (!re_compare(_cmdLine, "\\s*new\\s*.*") && !re_compare(_cmdLine, "\\s*delete\\s*.*") #if 0 // 1999-dec-12 && !re_compare(_cmdLine, "\\s*read\\s+line\\s*.*") #else // && !re_compare(_cmdLine, "\\s*read\\s*.*") #endif && !re_compare(_cmdLine, "\\s*get\\s+env\\s*.*") ) { std::string cmd_sub; substitute_synonyms_cmdline(cmd, cmd_sub, true); strcpy(cmd, cmd_sub.c_str()); remove_trailing_blanks(cmd); } } if (((unsigned) superuser()) & FLAG_SYN) printf("DEBUG %s:%d line is now '%s'\n",__FILE__,__LINE__,cmd); // Substitute backtic and dollar-paren expressions #if USE_BACKTIC sub_backtic(cmd, _cmdLineCOPY); strcpy(cmd, _cmdLineCOPY); #endif std::string tmp; sub_dollar_paren(cmd, tmp); strcpy(cmd, tmp.c_str()); // Substitute rpn expressions one by one, recopying back to cmd after // each if (((unsigned) superuser()) & FLAG_RPN) printf("[%s]\n", cmd); if (!re_compare(_cmdLine, "\\s*postscript\\s*.*") && !re_compare(_cmdLine, "\\s*new\\s*.*") && !re_compare(_cmdLine, "\\s*while\\s*.*") ) { if (((unsigned) superuser()) & FLAG_FLOW) printf("DEBUG %s:%d about to substitute rpn in '%s' skipping_through_if= %d\n",__FILE__,__LINE__,cmd,skipping_through_if()); if (!skipping_through_if()) { while (substitute_rpn_expressions(cmd, _cmdLineCOPY)) { strcpy(cmd, _cmdLineCOPY); } if (_error_in_cmd) { err("Error in RPN expression"); } } remove_trailing_blanks(cmd); if (strlen(cmd) < 1) return true; strcpy(_cmdLineCOPY, cmd); } stop_replay_if_error(); strcpy(cmd, _cmdLineCOPY); if (((unsigned) superuser()) & FLAG_RPN) printf(" --> [%s]\n", cmd); // Finally, chop up into words. The words (_word) and number of words // (_nword) are used all over the place in other functions. chop_into_words(_cmdLineCOPY, _word, &_nword, MAX_nword); return true; } // Do what command line instructs. // RETURN true if OK, NO if error bool perform_command_line(FILE *fp, bool is_which) { //if (((unsigned) superuser()) & FLAG_FLOW) printf("\nDEBUG %s:%d begin of perform_command_line\n",__FILE__,__LINE__); if (strlen(_cmdLine) < 1) return true; // was ok, just blank // If it's definition of a new gri command, do that. if (is_create_new_command(_cmdLine)) { if (is_which) create_new_command(_cmdFILE.back().get_fp(), _cmdLine); else create_new_command(fp, _cmdLine); return true; } // Handle `return' if (_nword > 0 && !strcmp(_word[0], "return") && !skipping_through_if()) { _done = 2; return true; } if (((unsigned) superuser()) & FLAG_FLOW) printf("DEBUG %s:%d perform_command_line() has command '%s'\n", __FILE__, __LINE__, _cmdLine); if (((unsigned) superuser()) & FLAG_FLOW) printf("DEBUG %s:%d skipping_through_if is %d (STEP 1)\n", __FILE__, __LINE__, skipping_through_if()); // Handle `end' and `else' if (handle_if_block()) { if (((unsigned) superuser()) & FLAG_FLOW) printf("DEBUG: %s:%d returning early\n",__FILE__,__LINE__); return true; } if (((unsigned) superuser()) & FLAG_FLOW) printf("DEBUG %s:%d skipping_through_if is %d (STEP 2)\n", __FILE__, __LINE__, skipping_through_if()); // Process line if not skipping if (!skipping_through_if()) { // First, handle de-referenced synonyms as lvalues (to left // an assignment operator) std::string w0(_word[0]); // de_reference(w0); BUG: MAY PUT BACK LATER char *cp = strdup(w0.c_str()); _word[0] = cp; // Handle `\name = "value"' command if (w0[0] == '\\') { if (_nword > 2 && is_assignment_op(_word[1])) { assign_synonym(); free(cp); return true; } } // Handle math command, e.g. // .var. = 1 // x += 1 // grid data += 1 // image += 1 // etc., permitting various assignment operators, // including '=', '+=', etc. if (word_is(0, "x") || word_is(0, "y") || word_is(0, "z") || word_is(0, "u") || word_is(0, "v") || word_is(0, "image") || word_is(0, "grid") || is_var(w0)) { if (_nword == 3) { if(word_is(1, "=") || word_is(1, "-=") || word_is(1, "+=") || word_is(1, "*=") || word_is(1, "/=") || word_is(1, "^=") || word_is(1, "_=")) { //printf("DOING mathCmd\n"); for (int ii=0;ii<_nword;ii++) printf("\t<%s>\n",_word[ii]); mathCmd(); free(cp); return true; } } else if (_nword == 4 && word_is(0, "grid") && (word_is(1, "data") || word_is(1, "x") || word_is(1, "y")) ) { mathCmd(); free(cp); return true; } else if (_nword == 4 && word_is(0, "image") && (word_is(1, "grayscale") || word_is(1, "greyscale") || word_is(1, "colorscale") || word_is(1, "colourscale"))) { mathCmd(); free(cp); return true; } else { err("Unknown command. Were you trying to manipulate `\\", _word[0], "' mathematically?", "\\"); free(cp); return false; } } // Figure out what command, and do it. int cmd; if (0 != (cmd = match_gri_syntax(_cmdLine, 0))) { // Do the command. push_cmd_being_done_stack(cmd - 1); if (!perform_gri_cmd(cmd - 1)) { err("Can't perform/parse following command"); free(cp); return false; } pop_cmd_being_done_stack(); free(cp); return true; } else { // No syntax registered for this command. Check special cases, // where it's a stray "break," or "continue" if (word_is(0, "break")) { err("Cannot have `break' outside loops"); free(cp); return false; } else if (word_is(0, "continue")) { err("Cannot have `continue' outside loops"); free(cp); return false; } else if (string_is_blank(_word[0])) { free(cp); return true; } else { err("Unknown command encountered."); free(cp); return false; } } free(cp); } return true; } // Stop replay if previous command instructed so (because _error_in_cmd set // to 1 because of error in last command). bool stop_replay_if_error() { if (_error_in_cmd && !_cmdFILE.back().get_interactive()) { ShowStr(" Bad command: `"); ShowStr(_cmdLine); ShowStr("'\n"); display_cmd_being_done_stack(); fatal_err(NULL); } return true; // never actually reached } // is_system_command() - return 1 if it's a system command bool is_system_command(const char *s) { // First, check if '\s*system ...' s += skip_space(s); if (!strncmp(s, "system", 6) ? true : false) return true; // Second, check if '\s*\\name\s*=\s*system ...' s += skip_nonspace(s); // name s += skip_space(s); // space s += skip_nonspace(s); // = s += skip_space(s); // space if (!strncmp(s, "system", 6) ? true : false) return true; return false; } // systemCmd() - handle request for system command. Certain translations are // done first. (1) \\n is translated into \n so that commands like the // following will work: // // system gawk 'BEGIN { printf("line1\n") ; printf("line2\n");}' // // The problem is that the previous parsing, PRESUMING that NEWLINE is not the name // of a user synonym, will replace "\n" by "\\n" so that the system would // otherwise be given the string // // system gawk 'BEGIN { printf("line1\\n") ; printf("line2\\n");}' // // to process. Furthermore, the shell < 1 && (s[len - 1] == '\n' || s[len - 1] == '\r')) s[--len] = '\0'; #endif bool is_continued = false; if (len > 1 && s[len - 1] == '\\' && s[len - 2] == '\\') is_continued = true; // Discard comment on end if (len > 0) { bool in_dquote = false; bool in_squote = false; for (int i = 0; i < len; i++) { if (s[i] == '"' && (i == 0 || s[i-1] != '\\')) { //printf("got s[%d]=\". with in_dquote=%s in_squote=%s\n",i,in_dquote?"T":"F",in_squote?"T":"F"); if (!in_squote) in_dquote = !in_dquote; continue; } if (s[i] == '\'' && (i == 0 || s[i-1] != '\\')) { if (!in_dquote) in_squote = !in_squote; continue; } if (!in_dquote && !in_squote && ((s[i] == '/' && s[i+1] == '/') || s[i] == '#')) { //printf("remove_comment [%s] ->\n", s); s[i] = '\0'; //printf(" [%s]\n", s); if (is_continued) { s[i++] = '\\'; s[i++] = '\\'; } len = i; break; } } // Set a flag if there is now nothing but whitespace. for (int ii = 0; ii < len; ii++) { //printf("\tEXAMINE [%c]\n", s[ii]); if (!isspace(s[ii])) { //printf("\t\tRETURNING non-BOTTOM false [%s]\n", s); return false; } } //printf("\t\tRETURNING true [%s]\n", s); return true; } //printf("\t\tRETURNING BOTTOM false [%s]\n", s); return false; } static void check_usage(const char *s) { if (s[0] == '`') return; // defining new command #if 0 // 2.5.5 allows e.g \.argv[0]. register int i, len; int inquote = 0; len = strlen(s); for (i = 0; i < len; i++) { if (s[i] == '"') inquote = !inquote; if (!inquote && s[i] == '[' && !(i == 0 || s[i - 1] == '\\')) { sprintf(_grTempString, "\ Warning: '[' character found in command. This character is in the\n\ manual to indicate optional items, and is not allowed in commands\n\ except inside system calls\n\ Command: '%s'\n", s); ShowStr(_grTempString); sprintf(_grTempString, "\ "); ShowStr(_grTempString); int j; for (j = 0; j <= i; j++) { _grTempString[j] = ' '; } _grTempString[j] = '\0'; strcat(_grTempString, "^ Bad character\n"); ShowStr(_grTempString); } } #endif } #if USE_BACKTIC // Substitute backtic style system expressions, as in Bourne and // Bourne-again shells. Assume string 'out' is long enough. static bool sub_backtic(const char *in, char *out) { #if !defined(HAVE_POPEN) err("Cannot substitute backtics because computer lacks popen() C subroutine"); #else int len = strlen(in); int out_index = 0; if (len < 2) { strcpy(out, in); return true; } char *cmd = new char[LineLength]; if (!cmd) OUT_OF_MEMORY; for (int i = 0; i < len; i++) { if (in[i] == '`') { // Search for closing backtic for (int j = i + 1; j < len; j++) { if (in[j] == '`') { strcpy(cmd, in + i + 1); cmd[j - i - 1] = '\0'; if (((unsigned) superuser()) & FLAG_SYS) { ShowStr("The `` mechanism is sending this to the OS:\n"); ShowStr(cmd); ShowStr("\n"); } FILE *pipefile = (FILE *) popen(cmd, "r"); if (pipefile) { char *result = new char[LineLength]; if (!result) OUT_OF_MEMORY; char *thisline = new char[LineLength]; if (!thisline) OUT_OF_MEMORY; strcpy(result, ""); while (NULL != fgets(thisline, LineLength_1, pipefile)) strcat(result, thisline); pclose(pipefile); // Skip null and possible final newline int len_result = strlen(result); if (result[len_result - 1] == '\n') len_result--; for (int k = 0; k < len_result; k++) out[out_index++] = result[k]; delete [] result; delete [] thisline; } else { err("The `` system call failed. Cannot access system."); delete [] cmd; return false; } i = j; break; } else { if (j == len - 1) { // If got to end, then was not a backtic // command after all, so copy the input strcpy(out, in); delete [] cmd; return true; } } } } else { out[out_index++] = in[i]; } } // i; out[out_index] = '\0'; delete [] cmd; return true; #endif } #endif // Substitute $() style system expressions, as shells static bool sub_dollar_paren(const char *in, std::string& out) { #ifdef DEBUG_DOLLAR_PAREN printf("sub_dollar_paren('%s', ...)\n", in); #endif unsigned int len = strlen(in); if (len < 3) { out = in; return true; } out = ""; std::string in_copy(in); bool inserted_something = false; #ifdef DEBUG_DOLLAR_PAREN printf("LEN=%d\n",len); #endif while (1) { std::vector start; // where \$( sequences start std::vector depth; // depth of these sequences int level = 0, max_level = 0; unsigned int i; for (i = 3; i < len; i++) { #ifdef DEBUG_DOLLAR_PAREN printf("in_copy[%d,...] = '%s'\n", i, in_copy.c_str()+i); #endif if (in_copy[i] == '(' && in_copy[i - 1] == '$' && in_copy[i - 2] == '\\') { start.push_back(i - 2); depth.push_back(++level); #ifdef DEBUG_DOLLAR_PAREN printf(" got \\$( at i=%d\n",i); #endif } else if (in_copy[i] == ')' && in_copy[i-1] != '\\') { level--; #ifdef DEBUG_DOLLAR_PAREN printf(" got ) at i=%d\n",i); #endif } if (level > max_level) max_level = level; } #ifdef DEBUG_DOLLAR_PAREN printf("after loop, start.size() = %d max_level= %d\n", start.size(), max_level); #endif if (max_level == 0) break; for (i = 0; i < start.size(); i++) { #ifdef DEBUG_DOLLAR_PAREN printf("%s:%d in loop. depth[%d] = %d start[i]= %d '%s'\n",__FILE__,__LINE__,i,depth[i], start[i], in_copy.substr(start[i]).c_str()); #endif if (depth[i] == max_level) { inserted_something = true; // Process this one, the left-most maximumally nested case std::string res; int skip = dollar_paren(in_copy.c_str() + start[i], res); std::string tmp(in_copy.substr(0, start[i])); #ifdef DEBUG_DOLLAR_PAREN printf("1. tmp='%s' in_copy='%s' start[%d]=%d\n", tmp.c_str(),in_copy.c_str(),i,start[i]); #endif tmp = tmp + res; #ifdef DEBUG_DOLLAR_PAREN printf("2. tmp '%s'\n", tmp.c_str()); #endif tmp = tmp + (in_copy.c_str() + start[i] + skip); in_copy = tmp; len = in_copy.size(); for (i = 0; i < start.size(); i++) { start.pop_back(); depth.pop_back(); } break; } } } if (inserted_something == false) out = in; else out = in_copy; return true; } // Evaluate a single \$(CMD) sequence, *assumed* to not be nested. // // On input, 's' points to the starting backslash. // On output, 'res' holds the result and the return value indicates // the how many characters to skip in the input string, to // get to the matching ) character. // // BUG: 'res' is *assumed* to be long enough to hold system output static int dollar_paren(const char *s, std::string& res) { #if !defined(HAVE_POPEN) err("Cannot do \\$(CMD) because computer lacks popen() C subroutine"); return 0; #else #ifdef DEBUG_DOLLAR_PAREN printf("dollar_paren(%s,...)\n",s); #endif // Search for closing paren std::string ss(s + 3); // so can insert null-terminate within unsigned int i; #ifdef DEBUG_DOLLAR_PAREN printf("%s:%d error: dollar_paren() should count ( and then check ) in case sys command has some [%s]\n",__FILE__,__LINE__,ss.c_str()); #endif for (i = 0; i < ss.length(); i++) { if (ss[i] == ')') { ss.STRINGERASE(i); if (((unsigned) superuser()) & FLAG_SYS) { ShowStr("The $() mechanism is sending this to the OS:\n"); ShowStr(ss.c_str()); ShowStr("\n"); } FILE *pipefile = (FILE *) popen(ss.c_str(), "r"); if (!pipefile) { err("The $() system call failed. Cannot access system."); return -1; } char *thisline = new char[LineLength]; // assume enough space (without checking) if (!thisline) OUT_OF_MEMORY; while (NULL != fgets(thisline, LineLength_1, pipefile)) res += thisline; pclose(pipefile); remove_trailing_blanks(res); delete [] thisline; break; // done with this system-cmd } else if (i == ss.length() - 1) { err("Got to end-of-line with no ')' to match '\\$('"); return -1; } } #ifdef DEBUG_DOLLAR_PAREN printf("NOTE: dollar_paren returning %d [%s]\n",i+4,res.c_str()); #endif return int(i + 4); // 4 chars in embracing sequence #endif } // expand_blanks() -- place 1 blank before each math token void expand_blanks(char *s) { int inquote = 0; char *sp; // points to src char *cp; // points to modified copy char last = '\0'; // last character sp = s; cp = _grTempString; while (*sp != '\0') { if (*sp == '"') { if (inquote) inquote--; else inquote++; } #if 1 // 2.060 // Handle special case of synonym name with brace, // e.g. \{some name} or \{time:unit} (as in netCDF) if (*sp == '{' && last == '\\') { do *cp++ = *sp++; while (*sp != '}' && *sp && *sp != '\n'); *cp++ = *sp++; last = *sp; continue; } #endif // Handle e.g. ==, _-, <=, etc if (!inquote && *(sp+1) == '=' && (*sp == '=' || *sp == '_' || *sp == '^' || *sp == '<' || *sp == '>' || *sp == '!' || *sp == '/' )) { *cp++ = ' '; // insert space before *cp++ = *sp++; // the prefix char *cp++ = *sp; // the '=' char *cp++ = ' '; // insert space after } else if (!inquote && *sp == '=' && *(sp + 1) == '"') { // e.g. read columns x="lon" *cp++ = ' '; *cp++ = *sp++; *cp++ = ' '; *cp++ = *sp; inquote++; } else if (!inquote && (*sp == '+' || *sp == '-') && (last != 'e' && last != 'E' && last != 'd' && last != 'D')) { *cp++ = ' '; *cp++ = *sp; if (*(sp + 1) == '=') { // += or -= *cp++ = '='; sp++; } else if (!isdigit(*(sp + 1)) && *(sp + 1) != '.') { // No extra space if next is a number *cp++ = ' '; // modified 20 Apr 1995, vsn 2.036 } } else if (!inquote && ( *sp == '{' || *sp == '}' || *sp == '!' || *sp == ',')) { *cp++ = ' '; *cp++ = *sp; *cp++ = ' '; } else { *cp++ = *sp; } last = *sp; sp++; } *cp = '\0'; strcpy(s, _grTempString); } bool superuserCmd() { PUT_VAR("..superuser..", 1.0); return true; } bool unsuperuserCmd() { PUT_VAR("..superuser..", 0.0); return true; } // Get command line from file, storing result in null-terminated string (even // if EOF). The line is considered to end at a NEWLINE. // Return true if got EOF bool get_cmd(char *buf, int max, FILE *fp) { int i = 0; int thisc, lastc = 0; bool in_quote = false; // Scan characters one by one do { thisc = fgetc(fp); if (thisc == '"' && lastc != '\\') in_quote = in_quote ? false : true; // Check for EOF if (thisc == EOF) { *(buf + i) = '\0'; if (((unsigned) superuser()) & FLAG_AUT2) printf("%s:%d get_cmd hit EOF, now returning TRUE with [%s]\n",__FILE__,__LINE__,buf); return true; } // See if NEWLINE (even if quoted) if (thisc == '\n') { // Is newline to be ignored, for continuation? if (lastc == '\\') { i -= 2; _cmdFILE.back().increment_line(); continue; } else { // 2006-11-15 (thanks to SL for the patch) #if defined(IS_OPENBSD) *(buf + i) = '\0'; #else if (*(buf + i - 1) == '\r') { // fix DOS *(buf + i - 1) = '\0'; } else { *(buf + i) = '\0'; } #endif if (((unsigned) superuser()) & FLAG_AUT2) printf("%s:%d get_cmd IN MIDDLE returning FALSE with [%s]\n",__FILE__,__LINE__,buf); return false; } } // Assign ordinary character *(buf + i) = thisc; lastc = thisc; } while (i++ < max); *(buf + i - 1) = '\0'; // didn't get to end - bad printf("%s:%d get_cmd AT END returning FALSE with [%s]\n",__FILE__,__LINE__,buf); return false; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/stats.cc������������������������������������������������������������������������������������0000644�0001750�0001750�00000005610�13147557614�012256� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include // for sort #include // part of STL #include #include "gr.hh" #include "private.hh" extern char _grTempString[]; static double array_at_i(const std::vector& x, double idouble, int n); void moment(double *data, int n, double *ave, double *adev, double *sdev, double *svar, double *skew, double *kurt) { if (n < 2) *ave = *adev = *sdev = *svar = *skew = *kurt = 0.0; else { int ngood = 0, i; double s = 0.0, p; for (i = 0; i < n; i++) if (!gr_missing((double) (*(data + i)))) { s += *(data + i); ngood++; } *ave = s / ngood; *adev = (*svar) = (*skew) = (*kurt) = 0.0; for (i = 0; i < n; i++) { if (!gr_missing((double) (*(data + i)))) { *adev += fabs(s = *(data + i) - (*ave)); *svar += (p = s * s); *skew += (p *= s); *kurt += (p *= s); } } *adev /= ngood; *svar /= (ngood - 1); *sdev = sqrt(*svar); if (*svar) { *skew /= (ngood * (*svar) * (*sdev)); *kurt = (*kurt) / (ngood * (*svar) * (*svar))/* -3.0*/; } } } // calculate q1, q2 = median, and q3 for n data in x void histogram_stats(const double* x, unsigned int n, double *q1, double *q2, double *q3) { //void sort(vector::iterator, vector::iterator); if (n < 2) *q1 = *q2 = *q3 = 0.0; else { unsigned int ngood = 0; std::vector xcopy; for (unsigned int i = 0; i < n; i++) if (!gr_missing(*(x + i))) xcopy.push_back(*(x + i)); ngood = xcopy.size(); std::sort(xcopy.begin(), xcopy.end()); *q1 = array_at_i(xcopy, 0.25 * (ngood - 1), ngood); *q2 = array_at_i(xcopy, 0.50 * (ngood - 1), ngood); *q3 = array_at_i(xcopy, 0.75 * (ngood - 1), ngood); } PUT_VAR("..q1..", *q1); PUT_VAR("..q2..", *q2); PUT_VAR("..q3..", *q3); } static double array_at_i(const std::vector& x, double idouble, int n) { int i = int(floor(idouble)); if (i < 0) return x[0]; else if (i >= n) return x[n - 1]; else { double r = idouble - i; return (x[i + 1] * r + x[i] * (1.0 - r)); } } ������������������������������������������������������������������������������������������������������������������������gri/src/while.cc������������������������������������������������������������������������������������0000644�0001750�0001750�00000010115�13147557614�012224� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // #define DEBUG_WHILE #include #include #include #include "private.hh" #include "extern.hh" #include "gr.hh" bool whileCmd(void); static bool test_is_true(const std::string& t); bool whileCmd(void) { std::string test(6 + strstr(_cmdLine, "while")); if (re_compare(test.c_str(), " *")) { err("`while .test.|{rpn ...}' missing the test part"); return false; } int loop_level = 1; int lines = 0; //printf("=============== in while cmd. '%s' test '%s'\n",_cmdLine,test.c_str()); test_is_true(test); // to catch syntax errors on this line // Store lines until end while into the buffer std::string buffer; while (1) { if (!get_command_line()) { err("Missing `end while'"); return false; } lines++; // Search for matching end while if (re_compare(_cmdLine, "\\s*while.*")) { loop_level++; } else { // Search for `end while', but first make a copy // without the source_indicator char *copy = (char*)malloc((1 + strlen(_cmdLine)) * sizeof(char)); if (!copy) OUT_OF_MEMORY; strcpy(copy, _cmdLine); int len = strlen(copy); for (int i = 0; i < len; i++) { if (copy[i] == PASTE_CHAR) { copy[i] = '\0'; break; } } if (re_compare(copy, "\\s*end\\s+while.*")) { loop_level--; if (loop_level < 1) { break; } } free(copy); } buffer.append(_cmdLine); buffer.append("\n"); } perform_while_block(buffer.c_str(), test.c_str(), lines); return true; } #define DEBUG 1 const int NOTIFY = 1000; bool perform_while_block(const char *buffer, const char *test, int lines) { //printf("^^^^^^^^^^^^ perform_while_block(...,%s,...)\n",test); std::string filename; int fileline; int passes = 0; std::string t(test); while (test_is_true(t)) { // Check to see if test is now false if (block_level() > 0) { filename.assign(block_source_file()); fileline = block_source_line() + 2; #ifdef DEBUG_WHILE printf("Register while AT BLOCKLEVEL = %d at %s:%d lines=%d\n", block_level(), block_source_file(), block_source_line() + 2, block_line()); #endif } else { filename.assign(what_file()); fileline = what_line() - lines + 1; #ifdef DEBUG_WHILE printf("Register OUT OF BLOCK while at %s:%d\n", what_file(), what_line() - lines + 1); #endif } if (!perform_block(buffer, filename.c_str(), fileline)) { // got break break; } passes++; if (_chatty > 0 && !(passes % NOTIFY)) { char msg[100]; sprintf(msg, "`while' performed %d passes\n", passes); gr_textput(msg); } } #ifdef DEBUG_WHILE printf("\nFINISHED WITH LOOP\n"); #endif return true; } static bool test_is_true(const std::string& t) { std::string tt; substitute_synonyms(t.c_str(), tt, true); clean_blanks_quotes(tt); // Catch "! SOMETHING" form bool negate = false; if (tt[0] == '!') { negate = true; tt.STRINGERASE(0, 1); clean_blanks_quotes(tt); } char res[100]; // BUG: fixed size substitute_rpn_expressions(tt.c_str(), res); //printf(" + '%s' -> '%s'\n", t.c_str(),tt.c_str()); double value; if (is_var(res)) { getdnum(res, &value); } else { sscanf(res, "%lf", &value); } if (negate) return ((value != 0.0) ? false : true); else return ((value != 0.0) ? true : false); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/file.cc�������������������������������������������������������������������������������������0000644�0001750�0001750�00000021256�13147557614�012043� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include "extern.hh" #include "private.hh" #include "gr.hh" #include "types.hh" #include "files.hh" #include "DataFile.hh" #include "superus.hh" // Push a new cmd file onto the stack. Return NO if cannot load the file. bool push_cmd_file(const char* fname, bool interactive, bool allow_warning, const char* status) { if (!fname) gr_Error("empty command-file name"); CmdFile cf; FILE *the_fp; // Open file, unless it's "stdin", which is already open if (!strcmp(fname, "stdin")) { the_fp = stdin; } else { FILE *thefile = fopen(fname, status); if (thefile) { // Can open file the_fp = thefile; } else { // Cannot open file if (allow_warning) { warning("Can't open command-file `\\", fname, "'", "\\"); } return false; } } cf.set(fname, the_fp, interactive, 0); _cmdFILE.push_back(cf); return true; } #if !defined(MSDOS) static bool is_compressed_file(std::string& fname) { if (fname.size() < 3) return false; std::string last_three(fname, fname.size()-3, fname.size()-1); if (last_three == ".gz") return true; return false; } #endif // Push a new data file onto the stack. // The 'delete_when_close' is just a suggestion (true for output // from system commands). Even if it is false, if we detect // here that a system command must be called, we'll still // remove the file when done. bool push_data_file(const char* name, DataFile::type the_type, const char* status, bool delete_when_close) { if (((unsigned) superuser()) & FLAG_AUT1)printf("\n DEBUG %s:%d push_data_file(%s,...) ...\n",__FILE__,__LINE__,name); if (the_type == DataFile::bin_netcdf) { #if !defined(HAVE_LIBNETCDF) // This may be redundant; see openCmd err("`open ... netCDF' impossible since Gri not compiled with netCDF library"); return false; #else ncopts = NC_VERBOSE; // Set external flag to live if error int file_id = ncopen(name, NC_NOWRITE); if (file_id == -1) return false; DataFile df((FILE*)NULL, name, file_id, the_type, delete_when_close); _dataFILE.push_back(df); #endif } else { #if defined(MSDOS) // For MSDOS binary files, status must be of the form "rb" char status2[10]; strcpy(status2, status); if (the_type != DataFile::ascii) strcat(status2, "b"); FILE *fp = fopen(name, status2); if (NULL == fp) return false; DataFile df(fp, name, 0, the_type, delete_when_close); _dataFILE.push_back(df); #else std::string sname(name); if (is_compressed_file(sname)) { std::string pipecmd("zcat "); pipecmd.append(sname); pipecmd.append(" > "); std::string tmpfile_name(tmp_file_name()); pipecmd.append(tmpfile_name); call_the_OS(pipecmd.c_str(), __FILE__, __LINE__); FILE *fp = fopen(tmpfile_name.c_str(), status); if (NULL == fp) { err("Cannot open file `\\", tmpfile_name.c_str(), "'.", "\\"); return false; } DataFile df(fp, tmpfile_name.c_str(), 0, the_type, true); _dataFILE.push_back(df); } else { FILE *fp = fopen(name, status); if (NULL != fp) { DataFile df(fp, name, 0, the_type, delete_when_close); _dataFILE.push_back(df); } else { //printf("DEBUG: %s:%d ... error is '%s'\n", __FILE__, __LINE__, strerror(errno)); if (errno == EMFILE) { // ref: 'man errno' err("Cannot open file `\\", name, "' since there are too many open files.", "\\"); return false; } #if !defined(HAVE_ACCESS) return false; // just give up then #else std::string sname(name); sname.append(".gz"); if (0 != access(sname.c_str(), R_OK)) { warning("Cannot access file `\\", name, "'", " or a compressed version `", sname.c_str(), "'", "\\"); return false; // failure } warning("`open' can't find `\\", name, "' so using `", sname.c_str(), "' instead.", "\\"); std::string pipecmd("zcat "); pipecmd.append(sname); std::string tmpfile_name(tmp_file_name()); pipecmd.append(" > "); pipecmd.append(tmpfile_name); call_the_OS(pipecmd.c_str(), __FILE__, __LINE__); fp = fopen(tmpfile_name.c_str(), status); if (NULL == fp) { //printf("%s:%d 2222 Cannot open. err is '%s'\n", __FILE__, __LINE__, strerror(errno)); return false; } DataFile df(fp, tmpfile_name.c_str(), 0, the_type, true); _dataFILE.push_back(df); #endif } } #endif } update_readfrom_file_name(); return true; } int data_file_index(const char* name) { std::string completefilename(name); resolve_filename(completefilename, true, 'd'); for (unsigned int i = 0; i < _dataFILE.size(); i++) if (_dataFILE[i].get_name() == completefilename) return i; return -1; } // Reorder data-file stack so named file is ready for reading bool push_data_file_to_top(const char* filename) { int i = data_file_index(filename); if (((unsigned) superuser()) & FLAG_AUT1)printf("\n DEBUG: %s:%d push_data_file_to_top(%s). This is the %d file stack_len= %d\n",__FILE__,__LINE__,filename, i, int(_dataFILE.size())); if (i == -1) return false; DataFile n(_dataFILE.back()); _dataFILE.back() = _dataFILE[i]; _dataFILE[i] = n; return true; } // Remove a file from the data-file stack. bool pop_data_file(int file) { if (((unsigned) superuser()) & FLAG_AUT1)printf("\n DEBUG: %s:%d pop_data_file(file= %3d) fp= %lx stack_len= %d\n",__FILE__,__LINE__,file, (long unsigned int)_dataFILE[file].get_fp(), int(_dataFILE.size())); if (file < 0) { err("No such data file exists"); return false; } if (_dataFILE[file].get_type() == DataFile::from_cmdfile) { err("Internal gri error [file.c][pop_data_file]: No data file open"); return false; } if (file > int(_dataFILE.size())) { err("Internal gri error [file.cc/pop_data_file()]: Data stack overflow"); return false; } if (_dataFILE[file].get_type() == DataFile::bin_netcdf) { #if defined(HAVE_LIBNETCDF) int success = ncclose(_dataFILE[file].get_netCDF_id()); if (success == -1) { err("Internal gri error: cannot close netCDF file `\\", _dataFILE[file].get_name(), "'", "\\"); return false; } #else err("Gri internal error: attempting to use nonexistent netCDF library"); return false; #endif } else { if (_dataFILE[file].get_fp() == stdin) { fatal_err("pop_data_file() is trying to close stdin"); exit(1); } else { if (EOF == fclose(_dataFILE[file].get_fp())) { fatal_err("pop_data_file() cannot close a data file reason \"\\", strerror(errno), "\".", "\\"); exit(1); } } } if (_dataFILE[file].get_delete_when_close()) { if (_chatty > 1) { std::string msg("Deleting temporary file named `"); msg.append(_dataFILE[file].get_name()); msg.append("'"); ShowStr(msg.c_str()); } std::string sys_cmd("rm -f "); sys_cmd.append(_dataFILE[file].get_name()); call_the_OS(sys_cmd.c_str(), __FILE__, __LINE__); } //display_data_stack("BEFORE the erasure of a file\n"); _dataFILE.erase(_dataFILE.begin() + file); //display_data_stack("AFTER the erasure\n"); return true; } void display_data_stack(const char* s) { printf("%s", s); unsigned int n = _dataFILE.size(); if (n == 0) printf("Data file stack is empty\n"); else { printf("Data file stack is as follows:\n"); for (unsigned int i = 0; i < n; i++) printf(" file name= '%s' type= %d delete_when_close= %d fp= %lx\n", _dataFILE[i].get_name(), int(_dataFILE[i].get_type()),int(_dataFILE[i].get_delete_when_close()), (unsigned long int)_dataFILE[i].get_fp()); } } void display_cmd_stack(const char* s) { unsigned int i, n = _cmdFILE.size(); printf("%s Command file stack is as follows:\n", s); for (i = 0; i < n; i++) printf("%s file [%s]\n", s, _cmdFILE[i].get_name()); } void close_data_files() { int n = _dataFILE.size(); if (((unsigned) superuser()) & FLAG_AUT1)printf("\n DEBUG: %s:%d in close_data_files() about to dispose %d files\n",__FILE__,__LINE__,n); for (int i = n - 1; i >= 0; i--) { if (_dataFILE[i].get_type() != DataFile::from_cmdfile) { pop_data_file(i); } } if (!_drawingstarted) delete_ps_file(); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/mask.cc�������������������������������������������������������������������������������������0000644�0001750�0001750�00000005542�13147557614�012057� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include "gr.hh" #include "extern.hh" #include "image_ex.hh" bool maskCmd(void); /* `mask image [to {uservalue .u.}|{imagevalue .i.}]' */ bool maskCmd() { if (!_image.storage_exists) { demonstrate_command_usage(); err("First `read image' or `convert grid to image'"); return false; } if (_imageMask.ras_width < 1) { demonstrate_command_usage(); err("No image mask exists yet"); return false; } if (!_imageTransform_exists) { demonstrate_command_usage(); err("First `set image grayscale'"); return false; } unsigned int i, j; unsigned int width, height; unsigned char replacement; int imagevalue; double uservalue; /* `mask image [to {uservalue .u.}|{imagevalue .i.}]' */ switch (_nword) { case 2: /* `mask image */ replacement = 0; break; case 5: /* `mask image [to {uservalue .u.}|{imagevalue .i.}]' */ if (!word_is(2, "to")) { demonstrate_command_usage(); err("Third word must be `to'"); return false; } if (word_is(3, "uservalue")) { if (!getdnum(_word[4], &uservalue)) { demonstrate_command_usage(); err("Can't read .uservalue."); return false; } replacement = value_to_image(uservalue); } else if (word_is(3, "imagevalue")) { if (!getinum(_word[4], &imagevalue)) { demonstrate_command_usage(); err("Can't read .imagevalue."); return false; } if (imagevalue < 0 || imagevalue > 255) { demonstrate_command_usage(); err("Require .imagevalue. to be in range 0-255 inclusive"); return false; } replacement = imagevalue; } else { demonstrate_command_usage(); err("Fourth word must be `uservalue' or `imagevalue'"); return false; } break; default: demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } /* replace pixel by pixel */ height = _image.ras_height; width = _image.ras_width; for (j = 0; j < height; j++) { for (i = 0; i < width; i++) { if (*(_imageMask.image + i * height + j) == 1) { *(_image.image + i * height + j) = replacement; } } } return true; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/GriColor.hh���������������������������������������������������������������������������������0000644�0001750�0001750�00000005063�13147557614�012654� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef _gricolor_h_ #define _gricolor_h_ #include #include #include "types.hh" class GriColor { public: enum type {rgb, hsv, cmyk}; GriColor() { t = rgb; transparency = a = b = c = d = 0.0;}; GriColor(const GriColor& c); ~GriColor(); GriColor& operator=(const GriColor& c); void setHSV(double H, double S, double V); void setRGB(double R, double G, double B); void setCMYK(double C, double M, double Y, double K); bool isRGB() const {return t == rgb;} void set_type(type tt) {t = tt;} void set_transparency(double tr) {transparency = tr;} type get_type() const {return t;} void getRGB(double *R, double *G, double *B) const; void getCMYK(double *C, double *M, double *Y, double *K) const; double getT() const {return transparency;} void setT(double tr) { transparency = tr;} double getR() const {return a;} double getG() const {return b;} double getB() const {return c;} double getH() const {return a;} double getS() const {return b;} double getV() const {return c;} double getC() const {return a;} double getM() const {return b;} double getY() const {return c;} double getK() const {return d;} std::string get_hexcolor() const; protected: type t; double transparency; // transparency double a; // red, hue, or cyan double b; // green, saturation, or magenta double c; // blue, brightness, or yellow double d; // k=blackness }; class GriNamedColor : public GriColor { public: GriNamedColor(); ~GriNamedColor(); GriNamedColor(const char *n, double R, double G, double B); GriNamedColor(const GriNamedColor& C); GriNamedColor& operator=(const GriNamedColor& C); void setNameRGB(const char *n, double R, double G, double B); const std::string get_name(void) const {return name;} private: std::string name; }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/gri_merge�����������������������������������������������������������������������������������0000755�0001750�0001750�00000014064�13147557614�012502� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/perl $usage = " PURPOSE: Strings Gri PostScript files together. BUGS: With old versions, of gri, make sure to match each `set clip postscript on' with a `set clip postscript off'. USAGE (style 1): gri_merge [OPTIONS] CxR a.ps b.ps ... > merged_file.ps Merges the files onto one page, in 'C' columns and 'R' rows. The C*R files are given in the order of words on a page. The page is presumed to be 8.5x11 in size, as are all the input files, and the input files are sized to fit, and kept in natural scale. USAGE (style 2): gri_merge [OPTIONS] xcm ycm enlarge a.ps [b.ps ...] > merged_file.ps Where `enlarge' is a scale factor applied after offsetting `xcm' to the right and `ycm' upward. EXAMPLE (style 2): The following gri_merge 2 12 .5 a.ps \\ 12 12 .5 b.ps \\ 2 2 .5 c.ps \\ 12 2 .5 d.ps > all.ps produces 4 panels from gri plots done using margins and sizes as specified in the following lines in a gri commandfile set x margin 2 set x size 15 set y margin 2 set y size 15 The OPTIONS, available if your 'perl' has 'getopts' library, are: -u graylevel -- set graylevel for underlay beneath panels, by default 0.75. Values range from 0 (black) to 1 (white), although a value of precisely 1 means do NOT draw underlay. -b graylevel -- Set value for background under individual panels, again 0 for black to 1 for white, with 1 meaning no drawing. -h -- Print this help message and quit. "; eval { use Getopt::Std; ; }; my $use_getopts = $@ ? 0 : 1; $underlay_gray = 0.9; $opt_u = -1; # illegal value $background_gray = 1; $opt_b = -1; # illegal value if ($use_getopts) { &getopts('hu:b:'); if ($opt_h) { print "$usage"; exit 0; } } $underlay_gray = $opt_u if $opt_u != -1; $underlay_gray = 0 if ($underlay_gray < 0); $underlay_gray = 1 if ($underlay_gray > 1); $background_gray = $opt_b if $opt_b != -1; $background_gray = 0 if ($background_gray < 0); $background_gray = 1 if ($background_gray > 1); $width_in = 8.5; $height_in = 11.0; $width = $width_in * 2.54; # Page width $height = $height_in * 2.54; # Page height # See if RowXColumn format ($columns, $rows) = split("[xX]", $ARGV[0]); if ($rows) { # # Style 1 $xfac = 1 / $columns; $yfac = 1 / $rows; $mag = ($xfac < $yfac) ? $xfac : $yfac; $i = 1; $xmarg = 72 / 2.54 * ($width - $width * $columns * $mag) / 2; $ymarg = 72 / 2.54 * ($height - $height * $rows * $mag) / 2; for ($r = $rows - 1; $r > -1; $r--) { for ($c = 0; $c < $columns && $i <= $#ARGV; $c ++) { last if ($i > $#ARGV); $done_prolog = 0; $xcm = $width * $mag * $c; $ycm = $height * $mag * $r; $xoff = $xcm * 72 / 2.54 + $xmarg; $yoff = $ycm * 72 / 2.54 + $ymarg; print STDERR "Panel '$file' origin = ($xcm, $ycm) cm, magnified $mag\n"; open (FILE, "$ARGV[$i]") || die "Can't open $i-th file $ARGV[$i]\n"; while() { next if /^\/origstate save def/; # This data-explorer line messes up next if /^origstate restore/; # This data-explorer line messes up next if /^%%Page:/; # These mess things up if (/showpage/) { print "grestore % gri_merge\n"; last if ($i != $#ARGV); } if ($i == 1 || $done_prolog) { if (/%%BoundingBox: (atend)/) { print "%%BoundingBox: 0 0 612 792\n"; } elsif (/%%BoundingBox:/) { ; } else { print; } } if (/%%EndProlog/) { $done_prolog = 1; &grey_page if ($i == 1); &white_panel; } } $i++; } } } else { # # Style 2 $nargs = $#ARGV + 1; die "$usage. ERROR: need 4, 8, 12, ..., arguments, not $nargs as given.\n" if ($nargs < 4 || $nargs%4); for($i = 0; $i < $nargs; $i += 4) { $done_prolog = 0; $xcm = $ARGV[$i + 0]; $ycm = $ARGV[$i + 1]; $xoff = 28.45 * $xcm; $yoff = 28.45 * $ycm; $mag = $ARGV[$i + 2]; $file = $ARGV[$i + 3]; print STDERR "Panel $i: '$file' origin = ($xcm, $ycm) cm, magnified $mag\n"; open (FILE, "$file") || die "Cannot open PostScript file $file\n"; while() { next if /^\/origstate save def/; # See above next if /^origstate restore/; # See above next if /^%%Page:/; if (/showpage/) { print "grestore % gri_merge\n"; last if ($i != ($nargs - 4)); } if ($i == 0 || $done_prolog) { if (/^%%BoundingBox: (atend)/) { print "%%BoundingBox: 0 0 612 792\n"; } elsif (/^%%BoundingBox:/) { ; } else { print; } } if (/%%EndProlog/) { $done_prolog = 1; &grey_page if ($i == 0); &white_panel; } } } } sub grey_page { return if $underlay_gray == 1; print "% gri_merge: `$ARGV[$i]' offset by ($xcm, $ycm) and scaled by $mag\n"; print "newpath % gri_merge\n"; if ($background_gray != 1) { print "$underlay_gray setgray % gri_merge\n"; print "0 0 moveto % gri_merge\n"; print "$width_in 72 mul 0 lineto % gri_merge\n"; print "$width_in 72 mul $height_in 72 mul lineto % gri_merge\n"; print "0 $height_in 72 mul lineto % gri_merge\n"; print "closepath % gri_merge\n"; print "fill % gri_merge\n"; } } sub white_panel { print "% gri_merge: `$ARGV[$i]' offset by ($xcm, $ycm) and scaled by $mag\n"; print "gsave % gri_merge\n"; print "$xoff $yoff translate % gri_merge\n"; print "$mag $mag scale % gri_merge\n"; if ($background_gray != 1) { print "newpath % gri_merge\n"; print "$background_gray setgray % gri_merge\n"; print "0 0 moveto % gri_merge\n"; print "$width_in 72 mul 0 lineto % gri_merge\n"; print "$width_in 72 mul $height_in 72 mul lineto % gri_merge\n"; print "0 $height_in 72 mul lineto % gri_merge\n"; print "closepath % gri_merge\n"; print "fill % gri_merge\n"; } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/install-sh����������������������������������������������������������������������������������0000755�0001750�0001750�00000011243�13147557614�012614� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" tranformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/grinterp.cc���������������������������������������������������������������������������������0000644�0001750�0001750�00000013403�13147557614�012751� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include "private.hh" #include "gr.hh" extern double _grMissingValue;/* defined in gr.c */ int number_good_xyz(const std::vector& x, const std::vector& y, const std::vector& f, int n); #define root_of_2 1.414213562 int number_good_xyz(const std::vector& x, const std::vector& y, const std::vector& f, int n) { int good = 0; for (int i = 0; i < n; i++) if (!gr_missingx(x[i]) && !gr_missingy(y[i]) && !gr_missing(f[i])) good++; return good; } /* * gr_grid1: objective analysis of 2d field * * DESCRIPTION: Given f[i] defined at points (x[i],y[i]), where 0<=i &x, const std::vector &y, const std::vector &f, double x0, double y0, double xr, double yr, int method, unsigned int neighbors, int enlargements, double *fOut) { unsigned int n = x.size(); double dx, dy; int enlarge = 0; unsigned int i; unsigned int nn, num_in_rect; double d2; /* squared distance */ double sumw; /* sum of weights */ double sumfw; /* sum of weighted values */ double w; /* weight of f[i] */ /* Check for obvious errors */ if (n <= 0 || neighbors == 0) { *fOut = _grMissingValue; return 0; } nn = number_good_xyz(x, y, f, n); if (neighbors > nn) neighbors = nn; /* * Search the rectangle, increasing its size if necessary. */ do { num_in_rect = 0; sumw = sumfw = 0.0; switch (method) { case 0: for (i = 0; i < n; i++) { dx = x0 - x[i]; if (-xr <= dx && dx <= xr) { dy = y0 - y[i]; if (-yr <= dy && dy <= yr) { sumw += 1.0; sumfw += f[i]; num_in_rect++; } } } break; case 1: for (i = 0; i < n; i++) { dx = GRI_ABS(x0 - x[i]); if (dx <= xr) { dy = GRI_ABS(y0 - y[i]); if (dy <= yr) { dx /= xr; dy /= yr; d2 = dx * dx + dy * dy; /* note 0<=d2<=2 */ w = (2.0 - d2) / (2.0 + d2); sumw += w; sumfw += f[i] * w; num_in_rect++; } } } break; case 2: for (i = 0; i < n; i++) { dx = GRI_ABS(x0 - x[i]); if (dx <= xr) { dy = GRI_ABS(y0 - y[i]); if (dy <= yr) { dx /= xr; dy /= yr; d2 = dx * dx + dy * dy; /* note 0<=d2<=2 */ w = (2.0 - d2) / (2.0 + d2); w *= w; sumw += w; sumfw += f[i] * w; num_in_rect++; } } } break; case 3: for (i = 0; i < n; i++) { dx = GRI_ABS(x0 - x[i]); if (dx <= xr) { dy = GRI_ABS(y0 - y[i]); if (dy <= yr) { dx /= xr; dy /= yr; d2 = dx * dx + dy * dy; /* note 0<=d2<=2 */ w = (2.0 - d2) / (2.0 + d2); w *= w; w *= w; sumw += w; sumfw += f[i] * w; num_in_rect++; } } } break; default: return 0; /* unknown method! */ } xr *= root_of_2; yr *= root_of_2; } while ((++enlarge <= enlargements || enlargements < 0) && num_in_rect < neighbors); if (num_in_rect > 0) { *fOut = sumfw / sumw; return num_in_rect; } else { *fOut = _grMissingValue; return 0; } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/gri_unpage����������������������������������������������������������������������������������0000755�0001750�0001750�00000003527�13147557614�012664� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/perl $usage = " PURPOSE: Chop multipage Gri PostScript file into one file per page. USAGE: gri_unpage name.ps -- create files name-1.ps, name-2.ps, etc, one for each page of name.ps. gri_unpage -h -- print this help message -l -- set bounding box to letter page 612x792 BUGS: 1. Bounding box is always the same for all pages. 2. Assumes that all Gri fonts are used even if they aren't. "; eval { use Getopt::Std; ; }; my $use_getopts = $@ ? 0 : 1; if ($use_getopts) { &getopts('hl'); if ($opt_h) { print "$usage"; exit 0; } } if ($#ARGV != 0) { die "Wrong number of arguments.\n$usage\n"; } # Scan for BoundingBox to use that for each page. if (! $use_getopts || ! $opt_l) { open(IN, $ARGV[0]) || die "Cannot open input file `$ARGV[0]'\n"; while() { if (/%%BoundingBox: [0-9 ]+/) { $boundingBox = $_; chop($boundingBox); last; } } close(IN); } if (! defined($boundingBox)) { $boundingBox = "%%BoundingBox: 0 0 612 792"; } $file = $ARGV[0]; $file =~ s/\.ps$//; open(IN, $ARGV[0]) || die "Cannot open input file `$ARGV[0]'\n"; $prologue = ""; while() { $prologue .= $_; last if (/%%EndProlog/); } $epilog = " %%Trailer $boundingBox %%DocumentFonts: Courier Helvetica Palatino-Roman Palatino-Italic Symbol Times-Roman %%Pages: 1 "; $page = 0; while() { if (/%%Page:/) { $page++; if ($page < 10) { $name = sprintf("$file-0%d.ps", $page); } else { $name = sprintf("$file-%d.ps", $page); } if ($page != 1) { print OUT $epilog; close(OUT); } print STDERR "Creating file $name\n"; open(OUT, ">$name") || die "Cannot open output file `$name'\n"; print OUT $prologue; } else { print OUT; } } close OUT if ($page != 0); �������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/G_string.hh���������������������������������������������������������������������������������0000644�0001750�0001750�00000002405�13147557614�012705� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #if 0 #if !defined(_GString_hh_) #define _GString_hh_ #include #include "types.hh" class G_string : public string { public: bool line_from_FILE(FILE *fp); // Get Line from file, true if EOF #if 0 bool word_from_FILE(FILE *fp); // Get a word from file, true if EOF #endif #if 0 void draw(double xcm, double ycm, gr_textStyle s, double angle) const; #endif #if 0 void sed(const char *cmd); // Modify by (limited) sed command #endif }; #endif #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/skip.cc�������������������������������������������������������������������������������������0000644�0001750�0001750�00000011125�13147557614�012064� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include "gr.hh" #include "private.hh" #include "extern.hh" #include "gr_coll.hh" #include "DataFile.hh" extern bool _ignore_error; bool skip_forwardCmd(int n); bool skip_backwardCmd(int n); // skipCmd() -- control skipping in data file bool skipCmd() { double tmp; bool old_ignore_error = _ignore_error; if (_dataFILE.back().get_type() == DataFile::from_cmdfile) { err("`skip' ignored: no data file open"); return false; } if (_dataFILE.back().get_type() == DataFile::bin_netcdf) { warning("`skip' ignored: cannot do this for netCDF file"); return false; } if (_nword == 1) return skip_forwardCmd(1); _ignore_error = true; if (getdnum(_word[1], &tmp)) { skip_forwardCmd(int(floor(0.5 + tmp))); _ignore_error = old_ignore_error; return true; } if (!strcmp(_word[1], "forward")) { if (_nword == 2) return skip_forwardCmd(1); else { double tmp; if (!getdnum(_word[2], &tmp)) { err("invalid # to 'skip forward'"); _ignore_error = old_ignore_error; return false; } return skip_forwardCmd(int(floor(0.5 + tmp))); } } else if (!strcmp(_word[1], "backward")) { if (_nword == 2) return skip_backwardCmd(1); else { if (!getdnum(_word[2], &tmp)) { err("invalid # to 'skip backward'"); return false; } return skip_backwardCmd(int(floor(0.5 + tmp))); } } else { err("Unknown 'skip' parameter;\nvalid choices: forward/backward"); _ignore_error = old_ignore_error; return true; } } bool skip_forwardCmd(int n) { Require(n >= 0, err("Require positive (or zero) number of lines to skip")); if (_dataFILE.back().get_type() == DataFile::from_cmdfile) { warning("Cannot `skip' when data are embedded in command-file"); return true; } while (n-- > 0) { if (_dataFILE.back().get_type() != DataFile::ascii) { // type=0 ascii, others binary unsigned char tmpB; if (1 != fread((char *) & tmpB, sizeof(tmpB), 1, _dataFILE.back().get_fp())) { warning("I/O error while skip forward in binary file."); return false; } if (feof(_dataFILE.back().get_fp())) { set_eof_flag_on_data_file(); warning("`skip forward' at end-of-file on file `\\", _dataFILE.back().get_name(), "'", "\\"); break; } } else { // Ascii file GriString inLine(128); // Start short if (inLine.line_from_FILE(_dataFILE.back().get_fp())) { set_eof_flag_on_data_file(); warning("`skip forward' at end-of-file on file `\\", _dataFILE.back().get_name(), "'", "\\"); return true; } _dataFILE.back().increment_line(); } } return true; } bool skip_backwardCmd(int n) { Require(n >= 0, err("Require positive (or zero) number of lines to skip")); if (_dataFILE.back().get_type() == DataFile::from_cmdfile) { warning("Cannot `skip' when data are embedded in command-file"); return true; } if (_dataFILE.back().get_type() != DataFile::ascii) { warning("Can't `skip forward' in binary files"); return false; } unsigned int present_line = _dataFILE.back().get_line(); //printf("back skip %d was at present_line=%d\n",n,present_line); rewind(_dataFILE.back().get_fp()); _dataFILE.back().set_line(0); clearerr(_dataFILE.back().get_fp()); if (n > int(present_line)) { warning("Too few lines to skip that far; instead, rewinding the file."); return true; } GriString inLine(128); // Start short int num_to_advance = present_line - n; printf("*** num_to_advance %d\n",num_to_advance); for (int l = 0; l < num_to_advance; l++) { //printf(" skip\n"); if (inLine.line_from_FILE(_dataFILE.back().get_fp())) { set_eof_flag_on_data_file(); warning("`skip back' hit end-of-file on file `\\", _dataFILE.back().get_name(), "'", "\\"); break; } _dataFILE.back().increment_line(); } return true; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/open.cc�������������������������������������������������������������������������������������0000644�0001750�0001750�00000020425�13147557614�012062� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include #include "extern.hh" #include "files.hh" #include "superus.hh" extern char *egetenv(const char *item); bool lsCmd(void); bool open_file(DataFile::type type); bool openCmd(void); bool openCmd() { if (((unsigned) superuser()) & FLAG_AUT1)printf("DEBUG: %s:%d opening file named '%s'. Before doing that, datafile stack_len= %d\n",__FILE__,__LINE__, _word[1], int(_dataFILE.size())); switch (_nword) { case 2: open_file(DataFile::ascii); break; case 3: if (!strcmp(_word[2], "netCDF") || !strcmp(_word[2], "netcdf")) { #if defined(HAVE_LIBNETCDF) open_file(DataFile::bin_netcdf); #else err("`open ... netCDF' impossible since Gri not compiled with netCDF library"); return false; #endif } else if (!strcmp(_word[2], "binary")) { open_file(DataFile::bin_unknown); } else { err("\ `open filename' can't understand final word `\\", _word[_nword - 1], "'.", "\\" ); return false; } break; case 4: // open filename binary type if (strcmp(_word[2], "binary")) { err("\ Third word of `open filename' must be \"binary\", not `\\", _word[2], "' as given.", "\\" ); return false; } if (!strcmp(_word[3], "uchar")) open_file(DataFile::bin_uchar); else if (!strcmp(_word[3], "16bit")) open_file(DataFile::bin_16bit); else if (!strcmp(_word[3], "int")) open_file(DataFile::bin_int); else if (!strcmp(_word[3], "float")) open_file(DataFile::bin_float); else if (!strcmp(_word[3], "double")) open_file(DataFile::bin_double); else { err("\ `open filename' can't understand final word `\\", _word[_nword - 1], "'.", "\\" ); return false; } break; default: err("`open' needs a file name"); return false; } clear_eof_flag_on_data_file(); return true; } bool open_file(DataFile::type type) { put_syn("\\.return_value.", "", true); // Must decode filename, which may have "/" in it which got expanded to " // / " by expand_blanks(). // If filename is quoted, either read from a pipe (if last nonblank // character is '|') or just ignore the quotes if (*_word[1] == '"') { // Quoted filename. First check to see endquote exists. remove_esc_quotes(_word[1]); int len = strlen(_word[1]); if (len < 2) { err("`open' needs a proper filename"); return false; } if (*(_word[1] + len - 1) != '"') { err("Missing quote on end of file/pipe name."); return false; } // Check for URL if (!strncmp(_word[1], "\"http://", 8)) { std::string cmd("wget "); cmd.append(_word[1] + 1); cmd.STRINGERASE(cmd.size() - 1); cmd.append(" --output-document="); std::string tmpfile_name(tmp_file_name()); cmd.append(tmpfile_name); cmd.append(" --output-file=/dev/null"); //printf("WILL RUN <%s>\n", cmd.c_str()); call_the_OS(cmd.c_str(), __FILE__, __LINE__); if (!push_data_file(tmpfile_name.c_str(), type, "r", true)) { err("`open' can't find file `\\", tmpfile_name.c_str(), "'", "\\"); return false; } return true; } // Now check for a pipe for (int i = len - 2; i > -1; i--) { if (*(_word[1] + i) == '|') { // It's a pipe std::string pipecmd; if (type == DataFile::bin_netcdf) { err("`open' cannot have a pipe that is netCDF type"); return false; } // Copy string for system command, and then // erase regular expression \s*|\s*"$ pipecmd.assign(_word[1] + 1);// skip the initial quote if (pipecmd[pipecmd.size() - 1] == '"') pipecmd.STRINGERASE(pipecmd.size() - 1); while (isspace(pipecmd[pipecmd.size() - 1])) pipecmd.STRINGERASE(pipecmd.size() - 1); if (pipecmd[pipecmd.size() - 1] == '|') pipecmd.STRINGERASE(pipecmd.size() - 1); while (isspace(pipecmd[pipecmd.size() - 1])) pipecmd.STRINGERASE(pipecmd.size() - 1); pipecmd.append(" > "); std::string tmpfile_name(tmp_file_name()); pipecmd.append(tmpfile_name.c_str()); call_the_OS(pipecmd.c_str(), __FILE__, __LINE__); if (!push_data_file(tmpfile_name.c_str(), type, "r", true)) { err("`open' can't find file `\\", tmpfile_name.c_str(), "'", "\\"); return false; } break; } else if (!isspace(*(_word[1] + i))) { // Presume quoted string ... but check to be sure! std::string filename; if (*_word[1] == '"' && *_word[1] != '\0') filename.assign(1 + _word[1]); else filename.assign(_word[1]); if (filename.size() < 1) { err("`open' needs a filename; \"\" won't do!"); return false; } if (filename[filename.size() - 1] == '"') filename.STRINGERASE(filename.size() - 1, filename.size()); // Determine actual filename (substituting for ~ etc). std::string completefilename(filename); resolve_filename(completefilename, true, 'd'); if (!push_data_file(completefilename.c_str(), type, "r", false)) { err("`open' can't find file `\\", completefilename.c_str(), "'", "\\"); return false; } break; } } } else { // Normal filename if (!strlen(_word[1])) { err("`open' needs a filename"); return false; } std::string completefilename(_word[1]); resolve_filename(completefilename, true, 'd'); if (!push_data_file(completefilename.c_str(), type, "r", false)) { err("`open' can't find (or successfully open) file `\\", completefilename.c_str(), "' due to system error `", strerror(errno), "'.", "\\"); return false; } put_syn("\\.return_value.", completefilename.c_str(), true); } return true; } bool cdCmd() { #if defined(HAVE_GETENV) char * home = egetenv("HOME"); switch (_nword) { case 1: // `cd' means move to home directory _current_directory.assign(home); break; case 2: if (!strcmp(_word[1], ".")) { // "." _current_directory.assign("."); } else if (!strncmp(_word[1], "..", 2)) { // "../LOCATION" _current_directory.append("/"); _current_directory.append(_word[1]); } else if (!strcmp(_word[1], "~")) { // "~" _current_directory.assign(home); } else if (!strcmp(_word[1], "$HOME")) { // "$HOME" _current_directory.assign(home); } else if (*_word[1] == '~') { // "~/LOCATION" char tmp[1000]; sprintf(tmp, "%s%s", home, _word[1] + 1); _current_directory.assign(tmp); } else if (!strncmp(_word[1], "$HOME", 5)) { // "$HOME/LOCATION" char tmp[1000]; sprintf(tmp, "%s%s", home, _word[1] + 5); _current_directory.assign(tmp); } else if (!strncmp(_word[1], "/", 1)) { // "/LOCATION" _current_directory.assign(_word[1]); } else { // "LOCATION" _current_directory.append("/"); _current_directory.append(_word[1]); } break; default: demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } return true; #else err("`cd' requires \"environment variables\", which this computer lacks."); return false; #endif } bool pwdCmd() { // `cd' means move to home directory gr_textput(_current_directory.c_str()); gr_textput("\n"); return true; } bool lsCmd() { #if defined(VMS) warning("`ls' not implemented in VMS version."); return true; #else // `cd' means move to home directory char command[100]; switch (_nword) { case 1: sprintf(command, "ls -CF %s/", _current_directory.c_str()); call_the_OS(command, __FILE__, __LINE__); break; case 2: sprintf(command, "ls -CF %s/%s", _current_directory.c_str(), _word[1]); call_the_OS(command, __FILE__, __LINE__); break; default: demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } return true; #endif } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/timer.cc������������������������������������������������������������������������������������0000644�0001750�0001750�00000003362�13147557614�012242� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include #include "gr.hh" void gr_textput(const char *s); #include "macro.hh" #include "GriTimer.hh" bool show_stopwatchCmd(void); bool show_stopwatchCmd(void) { char msg[100]; static bool first = true; static time_t last; if (first == true) { time(&last); first = false; sprintf(msg, "Elapsed time = 0 s\n"); } else { double elapsed; static time_t now; time(&now); elapsed = now - last; sprintf(msg, "Elapsed time = %.0f s\n", elapsed); } ShowStr(msg); return true; } GriTimer::GriTimer() { time(&start); //printf("TIMER:INIT: start= %ld\n",start); } char* GriTimer::now_ascii() { SECOND_TYPE sec; time(&sec); return(asctime(localtime(&sec))); } double GriTimer::elapsed_time() { static time_t now; time(&now); //printf("TIMER:ELAPSED: now=%d start= %d elapsed= %d\n",now,start,now-start); return double(now - start); } // Main ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/gr.hh���������������������������������������������������������������������������������������0000644�0001750�0001750�00000035310�13147557614�011542� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // gr.h -- header file for gr and gri (Copyright 1993 Dan Kelley) You must // #include "gr.h" at start of any C program which uses the gr library. #ifndef _grh_ #define _grh_ #include #include #include #include #include // For getpid etc. #if HAVE_UNISTD_H #include #include #endif // Possibly include debugging malloc header file. #ifdef USE_DBMALLOC #ifdef __linux__ #include #else #include #endif #endif // Standard libraries, malloc, etc (this confuses me) #include #if STDC_HEADERS #else #if !defined(MSDOS) && !defined(IS_FREEBSD) #include #endif #endif // Doesn't have stdlib // Should not really need these, but on gcc 2.5.8 on my sparc // machine, they are not prototyped. I only prototyping them // for GNU cc because e.g. alpha compiler chokes on a // disagreement with /usr/include/stdlib.h #if 0 // removed 1999-mar-07 to port to AIX #if defined(__GNUC__) extern "C" { int pclose(FILE *stream); } #endif #endif #include "types.hh" #include "gr_coll.hh" #include "GriColor.hh" #include "GMatrix.hh" // Useful things to know. #define _grTempStringLEN 32768 // = 2^15 (was 4096 until 2001-feb-17) #define PASTE_CHAR char(255) // output file type enum output_file_type { postscript = 0, svg = 1, gif = 2 }; // Geometrical things. #define PI_VALUE 3.14159265358979323846 // Postscript things. #define GR_POINTS_IN_PS_PATH 1499 // really 1500, but be safe #define PT_PER_IN 72.27 // points per inch #define PT_PER_CM 28.45 // points per centimetre #define CM_PER_IN 2.54 // BUG: more digits? #define DEG_PER_RAD 57.29577951 // degrees per radian // An io buffer that resorts to file i/o only if a buffer is exhausted. Used // by gr_textget() and gr_textsave(). typedef struct { FILE *fp; // file to read if buffer exhausted char *buf; // the buffer int buf_capacity; // chars in buffer int buf_position; // next char to read in buffer } FBUFFER; // Axis properties typedef enum { gr_axis_BOTTOM = 1, gr_axis_TOP = 0, gr_axis_LEFT = 1, gr_axis_RIGHT = 0, gr_axis_LOG = 0, gr_axis_LINEAR = 1 } gr_axis_properties; typedef struct { double width_pt; // width of pen } gr_pen; // Font numbers. To add new fonts, use 'extract_font_widths' perlscript to // get size info, then incorporate into grstring.c, in a list before the // gr_charwidth_cm() function. // DO NOT change the =0 below, or you'll mess everything up in grstring (esp in // the gr_drawstring() function). typedef enum { gr_font_Courier = 0, // Courier gr_font_CourierOblique, // Courier-Oblique gr_font_CourierBold, // Courier-Bold gr_font_CourierBoldOblique, // Courier-BoldOblique gr_font_Helvetica, // Helvetica gr_font_HelveticaOblique, // Helvetica-Oblique gr_font_HelveticaBold, // Helvetica-Bold gr_font_HelveticaBoldOblique, // Helvetica-BoldOblique gr_font_PalatinoRoman, // Palatino-Roman gr_font_PalatinoItalic, // Palatino-Italic gr_font_PalatinoBold, // Palatino-Bold gr_font_PalatinoBoldItalic, // Palatino-BoldItalic gr_font_Symbol, // Symbol gr_font_Century, // called NewCenturySchoolbook sometimes (I guess) gr_font_TimesRoman, // Times-Roman gr_font_TimesItalic, // Times-Italic gr_font_TimesBold, // Times-Bold gr_font_TimesBoldItalic, // Times-BoldItalic gr_font_end_of_list } gr_fontID; typedef struct { gr_fontID id; char *name; } gr_font_info; // used grstring.c:63 for font_list enum gr_font_encoding { font_encoding_standard, font_encoding_isolatin1}; typedef struct { gr_fontID id; gr_font_encoding encoding; double size_pt; } gr_font; // Symbol numbers enum gr_symbol_type { gr_unknown_symbol = -1, gr_plus_symbol, gr_times_symbol, gr_box_symbol, gr_circ_symbol, gr_diamond_symbol, gr_triangleup_symbol, gr_triangleright_symbol, gr_triangledown_symbol, gr_triangleleft_symbol, gr_asterisk_symbol, gr_star_symbol, gr_filledbox_symbol, gr_bullet_symbol, gr_filleddiamond_symbol, gr_filledtriangleup_symbol, gr_filledtriangleright_symbol, gr_filledtriangledown_symbol, gr_filledtriangleleft_symbol, gr_filledhalfmoonup_symbol, gr_filledhalfmoondown_symbol }; // Color. Is this used?? typedef enum { bw_model, rgb_model, hsb_model } gr_color_model; typedef struct { double red; double green; double blue; double hue; double saturation; double brightness; gr_color_model color_model; } gr_color; // Function headers. void abort_gri(void); bool delete_ps_file(void); void gr_begin(int specifications); bool gr_buffgets(char *s, unsigned int most, FBUFFER * fbuf); void gr_cmtouser(double x_cm, double y_cm, double *x, double *y); void gr_comment(const char *message); void gr_contour(const double x[], const double y[], /*const*/ GriMatrix &z, /*const*/ GriMatrix &legit, int nx, int ny, double z0, const char *lab, bool rotate_labels, bool whiteunder_labels, bool center_labels, const GriColor& line_color, const GriColor& text_color, double contour_minlength, double contour_space_first, double contour_space_later, FILE * out_file); gr_fontID gr_currentfont(void); gr_font_encoding gr_current_font_encoding(); double gr_currentCapHeight_cm(void); // From font metric info double gr_currentXHeight_cm(void); // From font metric info double gr_currentAscender_cm(void); // From font metric info double gr_currentDesscender_cm(void); // From font metric info double gr_currentfontsize_pt(void); #define gr_currentfontsize_cm() (gr_currentfontsize_pt() / PT_PER_CM) double gr_currentmissingvalue(void); char *gr_currentPSfilename(void); FILE *gr_currentPSFILEpointer(void); bool gr_current_ps_landscape(void); double gr_currentsymbolsize_pt(void); #define gr_currentsymbolsize_cm() (gr_currentsymbolsize_pt() / PT_PER_CM) double gr_currentticsize_cm(void); void gr_drawimage_svg(unsigned char *im, unsigned char *imTransform, gr_color_model color_model, unsigned char *mask, double mask_r, double maskg, double mask_b, int imax, int jmax, double llx_cm, double lly_cm, double urx_cm, double ury_cm, bool insert_placer); void gr_drawimage(unsigned char *im, unsigned char *imTransform, gr_color_model color_model, unsigned char *mask, double mask_r, double maskg, double mask_b, int imax, int jmax, double llx_cm, double lly_cm, double urx_cm, double ury_cm, bool insert_placer); void gr_draw_arc_cm(bool filled, double xc, double yc, double r, double angle1, double angle2); void gr_drawarrow_cm(double x, double y, double xend, double yend, double halfwidth); void gr_drawarrow2_cm(double x, double y, double xend, double yend, double halfwidth); void gr_drawarrow3_cm(double x, double y, double xend, double yend, double halfwidth); void gr_drawerrorbars(double x, double xmin, double xmax, double y, double ymin, double ymax, int type); void gr_drawsymbol(double xcm, double ycm, gr_symbol_type symbol_name); void gr_drawxaxis(double y, double xl, double xinc, double xr, double xlabeling, gr_axis_properties side); void gr_drawxyaxes(double xl, double xinc, double xr, double yb, double yinc, double yt); // FIXME need the starts here void gr_drawyaxis(double x, double yb, double yinc, double yt, double ylabelling, gr_axis_properties side); void gr_end(const char *filename); void gr_error(const char *lab); // // Gridding routines. int gr_grid1(const std::vector &x, const std::vector &y, const std::vector &f, double x0, double y0, double xRadius, double yRadius, int method, unsigned int neighbors, int enlargements, double *fOut); void gr_hsv2rgb(double h, double s, double br, double *r, double *g, double *b); void gr_lastxy(double *x, double *y); bool gr_missing(double x); bool gr_missingx(double x); bool gr_missingy(double y); void gr_moveto_cm(double x_cm, double y_cm); bool gr_multiple(double x, double d, double precision); bool gr_onxpage_cm(double x_cm); bool gr_onypage_cm(double y_cm); double gr_quad_cm(); // width of "M" void gr_record_handle(double x_cm, double y_cm); void gr_record_scale(void); bool gr_reopen_postscript(const char *new_name); void gr_rgb2cmyk(double R[], double G[], double B[], unsigned int n, double c[], double m[], double y[], double k[]); void gr_rgb2hsb(double r, double g, double b, double *h, double *s, double *br); void gr_rmoveto_cm(double rx_cm, double ry_cm); void gr_rmoveto_pt(double rx_pt, double ry_pt); void gr_rotate_xy(double x, double y, double angle, double *xx, double *yy); void gr_save_postscript(const char *PS_name, int normal_scale); void gr_scale125(double xl, double xr, int n, double *xlr, double *xrr, int *nr); // Routines to set various things void gr_set_clip_ps_curve(const double *xc, const double *yc, unsigned int len); void gr_set_clip_ps_rect(double ll_x_pt, double ll_y_pt, double ur_x_pt, double ur_y_pt); void gr_set_clip_ps_off(); bool gr_set_dash(std::vector dash); void gr_setfont(gr_fontID newID, bool force = false); #define gr_setfontsize_cm(f) (gr_setfontsize_pt(f * PT_PER_CM)) void gr_setfontsize_pt(double new_fontsize_pt); void gr_set_font_encoding(gr_font_encoding encoding); bool gr_using_missing_value(); void gr_set_missing_value(double missingvalue); void gr_set_missing_value_none(); void gr_setscale(double xfactor, double yfactor); #define gr_setsymbolsize_cm(s) (gr_setsymbolsize_pt(s * PT_PER_CM)) void gr_setsymbolsize_pt(double size_pt); void gr_setticdirection(bool tics_point_in); void gr_setticsize_cm(double newsize_cm); void gr_settranslate(double xcm, double ycm); void gr_setup_creatorname(const char *s); void gr_setup_ps_filename(const char *new_name); void gr_setup_ps_landscape(void); void gr_setup_ps_portrait(void); void gr_setup_ps_scale(double xfactor, double yfactor); void gr_setxaxisstyle(int xstyle); void gr_setxlabel(const char *xlab); void gr_setxnumberformat(const char *xformat); void gr_setxpagesize_cm(double x_cm); void gr_setxscale(double xl_cm, double xr_cm, double xl, double xr); void gr_setxsubdivisions(int num); void gr_setxtransform(gr_axis_properties xstyle); void gr_setyaxisstyle(int ystyle); void gr_setylabel(const char *ylab); void gr_setynumberformat(const char *yformat); void gr_setypagesize_cm(double y_cm); void gr_setyscale(double yb_cm, double yt_cm, double yb, double yt); void gr_setysubdivisions(int num); void gr_setytransform(gr_axis_properties ystyle); void gr_show_at(/*const*/ char *lab, double xcm, double ycm, gr_textStyle style, double angle); void gr_show_in_box(/*const */GriString &s, const GriColor& text_color, const GriColor& box_color, double x, double y, double angle_deg); void gr_showpage(void); bool gr_smootharray(double dx, double dy, double dt, GriMatrix &z, GriMatrix &zS, GriMatrix &legit, GriMatrix &legitS, int nx, int ny, int method); void gr_stringwidth(const char *s, double *x_cm, double *ascent_cm, double *descent_cm); bool gr_textget(char *s, int max); bool gr_textsave(const char *s); void gr_textput(const char *s); double gr_thinspace_cm(); // 1/6 width of "M" void gr_usertocm(double x, double y, double *x_cm, double *y_cm); double gr_usertocm_x(double x, double y); double gr_usertocm_y(double x, double y); void gr_usertopt(double x, double y, double *x_pt, double *y_pt); // Equation of state double rho(double S, double T, double p); double pot_temp(double S, double t, double p, double pref); double lapse_rate(double S, double t, double p); // Macros // Pin number to a range #if !defined(pin0_1) #define pin0_1(x) ((x) < 0 ? 0 : ((x) < 1 ? (x) : 1)) #endif #if !defined(pin0_255) #define pin0_255(x) ((x) < 0 ? 0 : ((x) < 255 ? (x) : 255)) #endif // Allocate storage, printing file/line if cannot #if !defined(GET_STORAGE) #define GET_STORAGE(var, type, num) \ { \ if ((num) > 0) { \ if (! ((var) = ( type *) malloc( (num) * sizeof(type)))) { \ gr_Error("Out of memory"); \ } \ } else { \ gr_Error("Cannot allocate zero or fewer bytes of storage"); \ } \ } #endif #define interpolate_linear(x, x0, y0, x1, y1) \ ((y0) + ((x) - (x0)) * ((y1) - (y0)) / ((x1) - (x0))) // Take care of the fact that the standard c++ library CHANGED the name // of the string::remove to string::erase, as evidenced by the change // in g++ from versions 2.7.x to 2.8.x (early 1998). #if defined(HAVE_OLD_STRING) #define STRINGERASE remove #define STRING_NPOS NPOS #else #define STRINGERASE erase #define STRING_NPOS std::string::npos #endif // Time type (time_t, int, or long) varies per machine (ug). #if defined(VMS) || defined(MSDOS) || defined(IS_DEC_ALPHA) || defined(AIX) || defined(IS_FREEBSD) || defined(IS_NETBSD) || defined(IS_OPENBSD) #define SECOND_TYPE time_t #else #if defined(__DECCXX) #define SECOND_TYPE int #else #define SECOND_TYPE long #endif #endif #endif // not _gr_ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/extern.hh�����������������������������������������������������������������������������������0000644�0001750�0001750�00000013617�13147557614�012445� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #if !defined(_extern_h_) #define _extern_h_ #include #include // part of STL #if defined(IS_MINGW32) #include #endif #include "private.hh" #include "gr.hh" #include "errors.hh" #include "gr_coll.hh" #include "GMatrix.hh" #include "GriState.hh" #include "Variable.hh" #include "Synonym.hh" #include "macro.hh" #define AXES_RECTANGULAR 0 // normal axes style (rect) using namespace std; // needed for g++-3 extern GriState _griState; // <-> gri.cc // The following globals have symbolic names associated with them, and // MUST be updated whenever these names are assigned to. See the note in // put_var() in variable.c. The reason for the parallel C storage is that // the following are accessed for every data point plotted. Certain other // symbolic variables (like ..publication.. for example) are not accessed // frequently, and hence have no parallel C storage as the following do. Thus // they are safe against breakage. extern output_file_type _output_file_type; extern bool _user_gave_bounding_box; extern rectangle _page_box; extern rectangle _bounding_box_user; extern rectangle _bounding_box; extern bool _user_set_x_axis; extern bool _user_set_y_axis; extern double _xleft; // ..xleft.. extern double _xright; // ..xright.. extern double _x_labelling; // ..xlabelling.. extern bool _x_gave_labelling; // extern double _ybottom; // ..ybottom.. extern double _ytop; // ..ytop.. extern double _y_labelling; // ..ylabelling.. extern bool _y_gave_labelling; // // Column data extern GriColumn _colU; extern GriColumn _colV; extern GriColumn _colX; extern GriColumn _colY; extern GriColumn _colZ; extern GriColumn _colWEIGHT; extern bool _uscale_exists; extern bool _vscale_exists; extern bool _columns_exist; extern std::string _xFmt; extern std::string _yFmt; extern double _clipxleft, _clipxright, _clipybottom, _clipytop; extern double _clip_ps_xleft, _clip_ps_xright, _clip_ps_ybottom, _clip_ps_ytop; extern bool _clipping_postscript, _clipping_is_postscript_rect; // Axes extern double _cm_per_u; extern double _cm_per_v; extern gr_axis_properties _xtype; extern double _xinc; extern bool _xscale_exists; extern bool _need_x_axis; extern bool _xatbottom; extern bool _xincreasing; extern int _xsubdiv; extern vector _x_labels; extern vector _x_label_positions; extern gr_axis_properties _ytype; extern double _yinc; extern bool _yscale_exists; extern bool _need_y_axis; extern bool _yatleft; extern bool _yincreasing; extern int _ysubdiv; extern vector _y_labels; extern vector _y_label_positions; // Data/Command file stacks extern std::vector _dataFILE; extern std::vector _cmdFILE; // Pointers to variables and synonyms, for & syntax extern std::vector variablePointer; extern std::vector variableStack; extern std::vector synonymPointer; extern std::vector synonymStack; // Grid data extern GriMatrix _f_xy; extern double _f_min, _f_max, *_xmatrix, *_ymatrix; extern GriMatrix _legit_xy; extern bool _xgrid_exists; extern bool _xgrid_increasing; extern bool _ygrid_exists; extern bool _ygrid_increasing; extern bool _grid_exists; // Commands extern char *_cmd_being_done_IP[]; extern int _cmd_being_done_code[]; extern int _cmd_being_done; extern char *_cmdLine; extern char *_cmdLineCOPY; extern char *_word[]; extern char *_Words2[]; extern char *_Words3[]; // Misc extern std::string _contourFmt; extern std::string _current_directory; extern char *_errorMsg; extern int _error_action; extern std::string _lib_directory; extern std::string _margin; extern std::string _prompt; extern double *_dstack; extern double _gri_eof; extern double _top_of_plot; extern double _axes_offset; extern int _axesStyle; extern bool _gri_beep; extern int _braceLevel; extern int _chatty; extern int _clipData; extern int _debugFlag; extern int _done; extern bool _drawingstarted; extern bool _error_in_cmd; extern int _exit_value; extern bool _first; extern gr_font _font; extern bool _ignore_eof; extern bool _ignore_error; extern int _arrow_type; extern bool _warn_offpage; extern std::vector _dash; // Numbers of things. extern int _num_command; extern unsigned int _num_xmatrix_data; extern unsigned int _num_ymatrix_data; extern unsigned int _nword; // Version number. extern double _version; // this version extern double _version_expected; // expected version (if any) // Flags indicating whether things exist yet. extern bool _use_default_for_query; // Command stack #define COMMAND_STACK_SIZE 1000 typedef struct { char *syntax; // The 'name' of command char *help; // Help, if any char *procedure; // Commands to do char *filename; // Where defined int fileline; // Where defined } GRI_COMMAND; extern GRI_COMMAND _command[COMMAND_STACK_SIZE]; extern int _function_indent; #endif // _extern_h_ �����������������������������������������������������������������������������������������������������������������gri/src/state.cc������������������������������������������������������������������������������������0000644�0001750�0001750�00000007273�13147557614�012247� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // #define DEBUG_STATE #include #include "gr.hh" #include "extern.hh" #include "GriState.hh" bool state_save(); bool state_restore(); bool state_display(); static std::vector stateStack; bool stateCmd() { switch (_nword) { case 2: if (word_is(1, "save")) return state_save(); else if (word_is(1, "restore")) return state_restore(); else if (word_is(1, "display")) return state_display(); else { demonstrate_command_usage(); err("Second word must be `save', `restore', or `display'"); return false; } // NOT REACHED default: demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } } bool state_save() { //printf("state_save() before push, the dash is size %d\n",_dash.size()); stateStack.push_back(_griState); return true; } bool state_restore() { if (stateStack.size() < 1) { warning("Ignoring `state restore' because no `state save' done yet"); return true; } if (stateStack.size() > 0) { _griState = stateStack.back(); stateStack.pop_back(); } // Set these since used globally (see e.g. draw_axes) gr_setfontsize_pt(_griState.font().size_pt); gr_setfont(_griState.font().id); _dash = _griState.dash(); gr_set_dash(_dash); #ifdef DEBUG_STATE printf("restored dash ... size %d\n",_dash.size()); #endif PUT_VAR("..fontsize..", _griState.font().size_pt); return true; } bool state_display() { int d = stateStack.size(); if (d < 1) { warning("No `state' stack exists yet. Do `state save' first."); return true; } char msg[200]; for (int i = d - 1; i >= 0; i--) { if (i == d - 1) sprintf(msg, "State at top of stack (most recent):\n"); else sprintf(msg, "State at distance %d from top of stack:\n", d - i); ShowStr(msg); sprintf(msg, " line width (curve) = %f pt\n", stateStack[i].linewidth_line()); ShowStr(msg); sprintf(msg, " line width (axis) = %f pt\n", stateStack[i].linewidth_axis()); ShowStr(msg); sprintf(msg, " line width (symbol) = %f pt\n", stateStack[i].linewidth_symbol()); ShowStr(msg); if ((stateStack[i].color_text()).isRGB() == true) { sprintf(msg, " color (font) = (%f,%f,%f) rgb\n", (stateStack[i].color_text()).getR(), (stateStack[i].color_text()).getG(), (stateStack[i].color_text()).getB()); } else { sprintf(msg, " color (font) = (%f,%f,%f) hsb\n", (stateStack[i].color_text()).getH(), (stateStack[i].color_text()).getS(), (stateStack[i].color_text()).getV()); } ShowStr(msg); if ((stateStack[i].color_line()).isRGB() == true) { sprintf(msg, " color (font) = (%f,%f,%f) rgb\n", (stateStack[i].color_line()).getR(), (stateStack[i].color_line()).getG(), (stateStack[i].color_line()).getB()); } else { sprintf(msg, " color (font) = (%f,%f,%f) hsb\n", (stateStack[i].color_line()).getH(), (stateStack[i].color_line()).getS(), (stateStack[i].color_line()).getV()); } ShowStr(msg); } return true; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/interp.cc�����������������������������������������������������������������������������������0000644�0001750�0001750�00000010357�13147557614�012425� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include #include "extern.hh" #include "files.hh" #include "superus.hh" // `interpolate x grid to .left. .right. .inc.|{/.cols.}' // `interpolate y grid to .bottom. .top. .inc.|{/.rows.}' bool interpolateCmd() { bool is_x = false; if (word_is(1, "x")) is_x = true; else if (!word_is(1, "y")) { err("Second word must be `x' or `y'"); } int num; double start, stop, increment; if (is_x) { Require(getdnum(_word[4], &start), READ_WORD_ERROR(".left.")); Require(getdnum(_word[5], &stop), READ_WORD_ERROR(".right.")); } else { Require(getdnum(_word[4], &start), READ_WORD_ERROR(".bottom.")); Require(getdnum(_word[5], &stop), READ_WORD_ERROR(".top.")); } switch (_nword) { case 7: if (is_x) { Require(getdnum(_word[6], &increment), READ_WORD_ERROR(".cols.")); } else { Require(getdnum(_word[6], &increment), READ_WORD_ERROR(".rows.")); } num = int(1 + (stop - start) / increment); break; case 8: Require(word_is(6, "/"), err("6-th word must be `/'")); Require(getinum(_word[7], &num), READ_WORD_ERROR(".inc.")); if (num < 2) { err("Increment .inc. must exceed 1"); return false; } increment = (stop - start) / (num - 1); break; } if (num < 0) { err("Sign of increment disagrees with start and stop values"); return false; } // // The grid must already exist if (!_grid_exists) { err("Cannot `convert grid to image' since no grid data exist yet"); return false; } if (!_xgrid_exists) { err("Cannot `convert grid to image' since x-grid doesn't exist yet"); return false; } if (!_ygrid_exists) { err("Cannot `convert grid to image' since y-grid doesn't exist yet"); return false; } increment *= 0.9999999; // to avoid overflow double znew; GriMatrix _f_xy_new; if (is_x) { std::vector ygrid((size_t)_num_ymatrix_data, 0.0); _f_xy_new.set_size(num, _num_ymatrix_data); unsigned int i, j; j = _num_ymatrix_data - 1; do { ygrid[j] = _ymatrix[j]; double xnew = start; for (i = 0; i < (unsigned int)num; i++) { grid_interp(xnew, _ymatrix[j], &znew); _f_xy_new(i, j) = znew; xnew += increment; } } while (j-- != 0); // Dump into official storage allocate_grid_storage(num, _num_ymatrix_data); allocate_xmatrix_storage(num); for (i = 0; i < (unsigned int)num; i++) _xmatrix[i] = start + i * increment; for (j = 0; j < _num_ymatrix_data; j++) _ymatrix[j] = ygrid[j]; for (j = 0; j < _num_ymatrix_data; j++) { for (i = 0; i < (unsigned int)num; i++) { _f_xy(i, j) = _f_xy_new(i, j); _legit_xy(i, j) = true; } } } else { std::vector xgrid((size_t)_num_xmatrix_data, 0.0); _f_xy_new.set_size(_num_xmatrix_data, num); unsigned int i, j; for (i = 0; i < _num_xmatrix_data; i++) { xgrid[i] = _xmatrix[i]; double ynew = start; for (j = 0; j < (unsigned int)num; j++) { grid_interp(_xmatrix[i], ynew, &znew); _f_xy_new(i, j) = znew; ynew += increment; } } // Dump into official storage allocate_grid_storage(_num_xmatrix_data, num); allocate_ymatrix_storage(num); for (i = 0; i < _num_xmatrix_data; i++) _xmatrix[i] = xgrid[i]; for (j = 0; j < (unsigned int) num; j++) _ymatrix[j] = start + j * increment; for (i = 0; i < _num_xmatrix_data; i++) { for (j = 0; j < (unsigned int)num; j++) { _f_xy(i, j) = _f_xy_new(i, j); _legit_xy(i, j) = true; } } } return true; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/rescale.cc����������������������������������������������������������������������������������0000644�0001750�0001750�00000002373�13147557614�012541� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include "gr.hh" #include "extern.hh" extern char _grTempString[]; bool rescaleCmd() { if (_nword == 1) { if (_chatty > 2) { sprintf(_grTempString, "Rescaling x/y axes\n"); ShowStr(_grTempString); } _need_x_axis = true; _need_y_axis = true; create_x_scale(); create_y_scale(); } else { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } return true; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/scales.cc�����������������������������������������������������������������������������������0000644�0001750�0001750�00000011642�13147557614�012374� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include "gr.hh" #include "extern.hh" #include "private.hh" // Return NO if cannot make a scale bool create_x_scale() { int nsegs; double min, mint, max; //printf("DEBUG [create_x_scale() %s:%d] _need_x_axis=%d _user_set_x_axis=%d\n",__FILE__,__LINE__,_need_x_axis,_user_set_x_axis); if (_need_x_axis && !_user_set_x_axis) { //extern double _grMissingValue; //extern bool _grMissingValueUsed; //printf("DEBUG [create_x_scale %s:%d] gr_missing(%le)=%d _grMissingValue=%le _grMissingValueUsed=%d\n",__FILE__,__LINE__,_colX.min(),gr_missing(_colX.min()),_grMissingValue,_grMissingValueUsed); if (_colX.size() > 0 && !gr_missing(mint = _colX.min())) { min = mint; max = _colX.max(); //printf("%s:%d min= %lf max= %lf\n",__FILE__,__LINE__,min,max); } else { if (_xgrid_exists) { min = max = _xmatrix[0]; for (unsigned int i = 1; i < _num_xmatrix_data; i++) { if (_xmatrix[i] < min) min = _xmatrix[i]; if (_xmatrix[i] > max) max = _xmatrix[i]; } } else { return false; } } if (_xtype == gr_axis_LINEAR) { int nsegs_est; double xsize; if (!get_var("..xsize..", &xsize)) xsize = 10.0; /* guess */ nsegs_est = 1 + (int) (xsize / 2.0); // ??? Should use fontsize if (_xincreasing) gr_scale125(min, max, nsegs_est, &_xleft, &_xright, &nsegs); else gr_scale125(min, max, nsegs_est, &_xright, &_xleft, &nsegs); _xinc = (_xright - _xleft) / nsegs; PUT_VAR("..xleft..", _xleft); PUT_VAR("..xright..", _xright); PUT_VAR("..xinc..", _xinc); } else { // LOG axis if (min <= 0.0 || max <= 0.0) { // log data not OK int nsegs_est; double xsize; warning("Have non-positive data -- switching to linear x axis"); if (!get_var("..xsize..", &xsize)) xsize = 10.0; /* guess */ nsegs_est = 1 + (int) (xsize / 2.0); _xtype = gr_axis_LINEAR; gr_scale125(min, max, nsegs_est, &_xleft, &_xright, &nsegs); _xinc = ((double) _xright - (double) _xleft) / nsegs; PUT_VAR("..xleft..", _xleft); PUT_VAR("..xright..", _xright); PUT_VAR("..xinc..", _xinc); } else { _xinc = 1.0; PUT_VAR("..xleft..", _xleft = pow(10.0, floor(log10((double) min)))); PUT_VAR("..xright..", _xright = pow(10.0, ceil(log10((double) max)))); PUT_VAR("..xinc..", _xinc); } } _xscale_exists = true; } return true; } // Return NO if cannot make a scale bool create_y_scale() { int nsegs; double min, mint, max; if (_need_y_axis && !_user_set_y_axis) { if (_colY.size() > 0 && !gr_missing(mint = _colY.min())) { min = mint; max = _colY.max(); } else { if (_ygrid_exists) { min = max = _ymatrix[0]; for (unsigned int i = 1; i < _num_ymatrix_data; i++) { if (_ymatrix[i] < min) min = _ymatrix[i]; if (_ymatrix[i] > max) max = _ymatrix[i]; } } else { return false; } } if (_ytype == gr_axis_LINEAR) { int nsegs_est; double ysize; if (!get_var("..ysize..", &ysize)) ysize = 10.0; // guess nsegs_est = 1 + (int) (ysize / 2.0); if (_yincreasing) gr_scale125(min, max, nsegs_est, &_ybottom, &_ytop, &nsegs); else gr_scale125(min, max, nsegs_est, &_ytop, &_ybottom, &nsegs); _yinc = (_ytop - _ybottom) / nsegs; PUT_VAR("..ybottom..", _ybottom); PUT_VAR("..ytop..", _ytop); PUT_VAR("..yinc..", _yinc); } else { // LOG axis if (min <= 0.0 || max <= 0.0) { // log data not OK int nsegs_est; double ysize; warning("Have non-positive data -- switching to linear y axis"); if (!get_var("..ysize..", &ysize)) ysize = 10.0; // guess nsegs_est = 1 + (int) (ysize / 2.0); _ytype = gr_axis_LINEAR; gr_scale125(min, max, nsegs_est, &_ybottom, &_ytop, &nsegs); _yinc = (_ytop - _ybottom) / nsegs; PUT_VAR("..ybottom..", _ybottom); PUT_VAR("..ytop..", _ytop); PUT_VAR("..yinc..", _yinc); } else { _yinc = 1.0; PUT_VAR("..ybottom..", _ybottom = pow(10.0, floor(log10(min)))); PUT_VAR("..ytop..", _ytop = pow(10.0, ceil(log10(max)))); PUT_VAR("..yinc..", _yinc); } } _yscale_exists = true; } return true; } ����������������������������������������������������������������������������������������������gri/src/set.cc��������������������������������������������������������������������������������������0000644�0001750�0001750�00000347223�13147557614�011724� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// vim: noexpandtab tabstop=8 softtabstop=8 shiftwidth=8 /* Gri - A language for scientific graphics programming Copyright (C) 2010 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include #include "gr.hh" #include "extern.hh" #include "image_ex.hh" #include "defaults.hh" #include "files.hh" #include "superus.hh" #include "gr_coll.hh" #include "GriState.hh" static inline bool between(double x, double lim0, double lim1); extern char _grTempString[]; void reset_top_of_plot(void); bool ignore_initial_newline(void); bool set_ignore_initial_newlineCmd(void); bool set_image_colorscaleCmd(void); bool set_image_grayscaleCmd(void); bool set_image_grayscale_using_hist(void); bool set_image_missingCmd(void); bool set_image_rangeCmd(void); bool set_grid_missingCmd(void); bool set_grid_missing_curve(bool inside); bool mask_an_island(double *x, double *y, unsigned int n); bool set_y_axis_nameCmd(void); // following shared with read.c double _input_data_window_x_min = 1.0; double _input_data_window_x_max = -1.0; double _input_data_window_y_min = 1.0; double _input_data_window_y_max = -1.0; bool _input_data_window_x_exists = false; bool _input_data_window_y_exists = false; static bool already_landscape = false; static double xleft, xright, xinc, ybottom, ytop, yinc; static double tmp, tmp2; static inline bool between(double x, double lim0, double lim1) { if (lim0 <= x && x < lim1) return true; if (lim1 <= x && x < lim0) return true; return false; } void reset_top_of_plot() { double margin, size; get_var("..ymargin..", &margin); get_var("..ysize..", &size); _top_of_plot = margin + size; } static bool ignore_initial_newline_flag = false; bool set_ignore_initial_newlineCmd() { switch (_nword) { case 4: ignore_initial_newline_flag = true; break; case 5: if (!strcmp(_word[4], "off")) { ignore_initial_newline_flag = false; return true; } else { demonstrate_command_usage(); return false; } default: demonstrate_command_usage(); return false; } return false; } bool ignore_initial_newline() { return ((ignore_initial_newline_flag) ? true : false); } bool set_axes_styleCmd() { if (_nword < 3) { err("Too few words in `set axes'"); return false; } if (strcmp(_word[2], "style")) { err("Third word of `set axes' must be \"style\"."); return false; } if (_nword < 4) { err("`set axes style' to what?"); return false; } // `set axes style offset [.distance_cm.]' if (_nword >= 4 && !strcmp(_word[3], "offset")) { double tmp; if (_nword == 5) { if (!getdnum(_word[4], &tmp)) { READ_WORD_ERROR(".distance_cm."); return false; } _axes_offset = tmp; } else if (!get_var("..tic_size..", &tmp)) { err("Can't remember the tic size."); return false; } _axes_offset = tmp; return true; } switch (_nword) { case 4: // `set axes style .style.|rectangular|default|none' if (!strcmp(_word[3], "default")) { _axesStyle = 0; _axes_offset = 0.0; return true; } else if (!strcmp(_word[3], "none")) { _need_x_axis = false; _need_y_axis = false; } else if (!strcmp(_word[3], "rectangular")) { // `set axes style rectangular' _axesStyle = 0; return true; } else { // `set axes style .style.' if (!getdnum(_word[3], &tmp)) return false; if (tmp < 0.0 || tmp > 2.0) { err("Ignoring bad axes type <0 or >2"); return false; } _axesStyle = (int) floor(0.5 + tmp); return true; } break; default: NUMBER_WORDS_ERROR; return false; } return true; } // Set arrow head halfwidth into ..arrowsize..; a positive value indicates // size in cm; a negative value bool set_arrow_sizeCmd() { if (_nword < 3) { err("`set arrow' what?"); return false; } if (!strcmp(_word[2], "size")) { if (_nword < 4) { err("`set arrow size' what?"); return false; } switch (_nword) { case 4: // set arrow size .size.|default if (!strcmp(_word[3], "default")) { PUT_VAR("..arrowsize..", ARROWSIZE_DEFAULT); return true; } else { if (!getdnum(_word[3], &tmp)) { err("Can't read arrow size"); return false; } if (tmp < 0.0) { err("Ignoring bad (negative) arrow size."); return false; } PUT_VAR("..arrowsize..", tmp); return true; } // NOT REACHED case 8: // `set arrow size as .num. percent of length' if (word_is(5, "percent") && word_is(6, "of") && word_is(7, "length")) { Require(getdnum(_word[4], &tmp), err("Can't read percentage")); Require(tmp >= 0.0, err("Ignoring bad (negative) percentage arrow size.")); PUT_VAR("..arrowsize..", -tmp / 100.0); return true; } else { demonstrate_command_usage(); err("Cannot understand command"); return false; } // NOT REACHED default: demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } } else { err("`set arrow' what?"); return false; } // NOT REACHED } bool set_arrow_typeCmd() { if (_nword != 4) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } double tmp; if (!getdnum(_word[3], &tmp)) { READ_WORD_ERROR(".which."); return false; } _arrow_type = int(floor(0.5 + tmp)); if (_arrow_type != 0 && _arrow_type != 1 && _arrow_type != 2) { err("Valid arrow types are 0, 1, and 2"); return false; } return true; } bool set_beepCmd() { if (_nword == 2 || !strcmp(_word[2], "on")) _gri_beep = true; else if (!strcmp(_word[2], "off")) _gri_beep = false; else { err("`set beep' what?"); return false; } return true; } //`set bounding box .xleft. .ybottom. .xright. .ytop. [cm|pt]' bool set_bounding_boxCmd() { // Set to _bounding_box_user double ll_x, ll_y, ur_x, ur_y; // user-units double ll_x_cm=0.0, ll_y_cm=0.0, ur_x_cm=10.0, ur_y_cm=10.0; // page-units if (_nword != 7 && _nword != 8) err("Must specify .xleft. .ybottom. .xright. .ytop. [cm]"); if (!getdnum(_word[3], &ll_x)) { demonstrate_command_usage(); err("Can't read .xleft. in `\\", _word[3], "'.", "\\"); return false; } if (!getdnum(_word[4], &ll_y)) { demonstrate_command_usage(); err("Can't read .ybottom. in `\\", _word[4], "'.", "\\"); return false; } if (!getdnum(_word[5], &ur_x)) { demonstrate_command_usage(); err("Can't read .xright. in `\\", _word[5], "'.", "\\"); return false; } if (!getdnum(_word[6], &ur_y)) { demonstrate_command_usage(); err("Can't read .ytop. in `\\", _word[6], "'.", "\\"); return false; } if (_nword == 7) { // user-units double xmargin = XMARGIN_DEFAULT; double ymargin = YMARGIN_DEFAULT; double xsize = XSIZE_DEFAULT; double ysize = YSIZE_DEFAULT; if (!get_var("..xmargin..", &xmargin)) warning("(set_environment) ..xmargin.. undefined so using default"); if (!get_var("..ymargin..", &ymargin)) warning("(set_environment) ..ymargin.. undefined so using default"); if (!get_var("..xsize..", &xsize)) warning("(set_environment) ..xsize.. undefined so using default"); if (!get_var("..ysize..", &ysize)) warning("(set_environment) ..ysize.. undefined so using default"); gr_setxtransform(_xtype); gr_setxscale(xmargin, xmargin + xsize, _xleft, _xright); gr_setytransform(_ytype); gr_setyscale(ymargin, ymargin + ysize, _ybottom, _ytop); gr_usertocm(ll_x, ll_y, &ll_x_cm, &ll_y_cm); gr_usertocm(ur_x, ur_y, &ur_x_cm, &ur_y_cm); } else if (_nword == 8) { bool in_pt = false; if (word_is(7, "cm")) { in_pt = false; } else if (word_is(7, "pt")) { in_pt = true; } else { err("`set bounding box ...' expecting keyword `pt' or `cm' but got `\\", _word[7], "'", "\\"); return false; } if (!getdnum(_word[3], &ll_x_cm)) { demonstrate_command_usage(); err("Can't read .xleft. in `\\", _word[3], "'.", "\\"); return false; } if (!getdnum(_word[4], &ll_y_cm)) { demonstrate_command_usage(); err("Can't read .ybottom. in `\\", _word[4], "'.", "\\"); return false; } if (!getdnum(_word[5], &ur_x_cm)) { demonstrate_command_usage(); err("Can't read .xright. in `\\", _word[5], "'.", "\\"); return false; } if (!getdnum(_word[6], &ur_y_cm)) { demonstrate_command_usage(); err("Can't read .ytop. in `\\", _word[6], "'.", "\\"); return false; } if (in_pt) { ll_x_cm /= PT_PER_CM; // convert points to cm ll_y_cm /= PT_PER_CM; ur_x_cm /= PT_PER_CM; ur_y_cm /= PT_PER_CM; } } else { err("Must specify .xleft. .ybottom. .xright. .ytop. [cm|pt]"); } _bounding_box_user.set(ll_x_cm, ll_y_cm, ur_x_cm, ur_y_cm); _user_gave_bounding_box = true; return true; } // set clip to curve [4 words] bool set_clipCmd() { Require(_nword > 2, err("Must specify `set clip on' or `set clip off'")); if (_nword == 4 && word_is(2, "to") && word_is(3, "curve")) { unsigned int xlen = _colX.size(); if (xlen < 1) { warning("`set clip to curve' noticed that no curve exists"); return true; } unsigned int ylen = _colY.size(); if (xlen != ylen) { warning("`set clip to curve' noticed that curve's x and y lengths disagree"); return true; } double *xp = _colX.begin(); double *yp = _colY.begin(); gr_set_clip_ps_curve(xp, yp, xlen); return true; } else { if (!strcmp(_word[2], "postscript")) { // PostScript clipping if (_nword < 4) { err("`set clip postscript ...' needs >= 4 words."); return false; } if (!strcmp(_word[3], "off")) { gr_set_clip_ps_off(); return true; } else if (!strcmp(_word[3], "on")) { double xl, xr, yb, yt; if (_nword == 4) { // set clip postscript on xl = _xleft; xr = _xright; yb = _ybottom; yt = _ytop; /*DEK*/ // printf("DEBUG: will try to set clip to xl=%f xr=%f yb=%f yt=%f\n",xl,xr,yb,yt); /*DEK*/ } else if (_nword == 8) { // set clip postscript on .llx. ... if (!getdnum(_word[4], &xl)) { demonstrate_command_usage(); err("Can't read .xleft. in `\\", _word[4], "'.", "\\"); return false; } if (!getdnum(_word[5], &xr)) { demonstrate_command_usage(); err("Can't read .xright. in `\\", _word[5], "'.", "\\"); return false; } if (!getdnum(_word[6], &yb)) { demonstrate_command_usage(); err("Can't read .ybottom. in `\\", _word[6], "'.", "\\"); return false; } if (!getdnum(_word[7], &yt)) { demonstrate_command_usage(); err("Can't read .ytop. in `\\", _word[7], "'.", "\\"); return false; } } else { NUMBER_WORDS_ERROR; demonstrate_command_usage(); return false; } set_environment(); double llx, lly, urx, ury; gr_usertopt(xl, yb, &llx, &lly); gr_usertopt(xr, yt, &urx, &ury); gr_set_clip_ps_rect(llx, lly, urx, ury); return true; } } else if (!strcmp(_word[2], "on")) { // Non-PostScript clipping if (_nword == 3) _clipData = -1; else if (_nword == 7) { if (!getdnum(_word[3], &tmp)) { READ_WORD_ERROR(".xleft."); _clipData = 0; _clipxleft = _clipxright = _clipybottom = _clipytop = 0.0; return false; } _clipxleft = tmp; if (!getdnum(_word[4], &tmp)) { READ_WORD_ERROR(".xright."); _clipData = 0; _clipxleft = _clipxright = _clipybottom = _clipytop = 0.0; return false; } _clipxright = tmp; if (!getdnum(_word[5], &tmp)) { READ_WORD_ERROR(".ybottom."); _clipData = 0; _clipxleft = _clipxright = _clipybottom = _clipytop = 0.0; return false; } _clipybottom = tmp; if (!getdnum(_word[6], &tmp)) { READ_WORD_ERROR(".ytop."); _clipData = 0; _clipxleft = _clipxright = _clipybottom = _clipytop = 0.0; return false; } _clipytop = tmp; _clipData = 1; } else err("`set clip on' takes 4 parameters"); } else if (!strcmp(_word[2], "off")) { gr_set_clip_ps_off(); _clipData = 0; } else { err("Must specify `set clip on' or `set clip off'"); return false; } } return true; } #define CHECK_RGB_RANGE(item) { \ if ((item) < 0.0) { \ warning("`set color rgb' value being clipped to range 0-1"); \ (item) = 0.0; \ } else if ((item) > 1.0) { \ warning("`set color rgb' value being clipped to range 0-1"); \ (item) = 1.0; \ } \ } #define CHECK_HSB_RANGE(item) { \ if ((item) < 0.0) { \ warning("`set color hsb' value being clipped to range 0-1"); \ (item) = 0.0; \ } else if ((item) > 1.0) { \ warning("`set color hsb' value being clipped to range 0-1"); \ (item) = 1.0; \ } \ } bool set_colorCmd() { double red, green, blue; std::string cname; GriColor c; switch (_nword) { case 3: cname.assign(_word[2]); un_double_quote(cname); if (!look_up_color(cname.c_str(), &red, &green, &blue)) { unsigned int rhex, ghex, bhex; if (cname.size() == 6 && 1 == sscanf(cname.substr(0,2).c_str(), "%x", &rhex) && 1 == sscanf(cname.substr(2,2).c_str(), "%x", &ghex) && 1 == sscanf(cname.substr(4,2).c_str(), "%x", &bhex)) { red = rhex / 255.0; green = ghex / 255.0; blue = bhex / 255.0; } else { err("`set color' given unknown colorname `\\", cname.c_str(), "'. Use command `show colornames' to see available colors.", "\\"); return false; } } PUT_VAR("..red..", red); PUT_VAR("..green..", green); PUT_VAR("..blue..", blue); c.setRGB(red, green, blue); _griState.set_color_line(c); if (_griState.separate_text_color() == false) _griState.set_color_text(c); return true; case 6: if (!strcmp(_word[2], "rgb")) { // `set color rgb .red. .green. .blue.' Require(getdnum(_word[3], &red), READ_WORD_ERROR(".red.")); Require(getdnum(_word[4], &green), READ_WORD_ERROR(".green.")); Require(getdnum(_word[5], &blue), READ_WORD_ERROR(".blue.")); // Clip if necessary CHECK_RGB_RANGE(red); CHECK_RGB_RANGE(green); CHECK_RGB_RANGE(blue); PUT_VAR("..red..", red); PUT_VAR("..green..", green); PUT_VAR("..blue..", blue); c.setRGB(red, green, blue); _griState.set_color_line(c); if (_griState.separate_text_color() == false) _griState.set_color_text(c); return true; } else if (!strcmp(_word[2], "hsb")) { // `set color hsb .hue. .saturation. .brightness.' double hue, saturation, brightness; Require(getdnum(_word[3], &hue), READ_WORD_ERROR(".hue.")); Require(getdnum(_word[4], &saturation), READ_WORD_ERROR(".saturation.")); Require(getdnum(_word[5], &brightness), READ_WORD_ERROR(".brightness.")); // Clip if necessary CHECK_HSB_RANGE(hue); CHECK_HSB_RANGE(saturation); CHECK_HSB_RANGE(brightness); gr_hsv2rgb(hue, saturation, brightness, &red, &green, &blue); PUT_VAR("..red..", red); PUT_VAR("..green..", green); PUT_VAR("..blue..", blue); c.setHSV(hue, saturation, brightness); _griState.set_color_line(c); if (_griState.separate_text_color() == false) _griState.set_color_text(c); return true; } else { err("Can't understand command."); demonstrate_command_usage(); return false; } default: NUMBER_WORDS_ERROR; demonstrate_command_usage(); return false; } } // `set colorname \name {rgb .red. .green. .blue.}|{hsb .hue. .saturation. .brightness.} bool set_colornameCmd() { double red, green, blue; switch (_nword) { case 7: if (strEQ(_word[3], "rgb")) { Require(getdnum(_word[4], &red), READ_WORD_ERROR(".red.")); Require(getdnum(_word[5], &green), READ_WORD_ERROR(".green.")); Require(getdnum(_word[6], &blue), READ_WORD_ERROR(".blue.")); } else if (strEQ(_word[3], "hsb")) { double hue, saturation, brightness; Require(getdnum(_word[4], &hue), READ_WORD_ERROR(".hue.")); Require(getdnum(_word[5], &saturation), READ_WORD_ERROR(".saturation.")); Require(getdnum(_word[6], &brightness), READ_WORD_ERROR(".brightness.")); hue = pin0_1(hue); saturation = pin0_1(saturation); brightness = pin0_1(brightness); gr_hsv2rgb(hue, saturation, brightness, &red, &green, &blue); } else { demonstrate_command_usage(); err("word must be `rgb' or `hsb', not `\\", _word[3], "' as given.", "\\"); return false; } red = pin0_1(red); green = pin0_1(green); blue = pin0_1(blue); create_color(_word[2], red, green, blue); //printf("set colorname '%s' %f %f %f\n", _word[2], red, green, blue); break; default: NUMBER_WORDS_ERROR; return false; } return true; } bool set_x_typeCmd() { extern char _xtype_map; switch (_nword) { case 5: if (word_is(3, "map")) { if (word_is(4, "E")) { _xtype_map = 'E'; } else if (word_is(4, "W")) { _xtype_map = 'W'; } else if (word_is(4, "S")) { _xtype_map = 'S'; } else if (word_is(4, "N")) { _xtype_map = 'N'; } else { err("X map type must be `E', `W', `S' or `N'"); return false; } } else { err("Type must be `linear', `log', or `map'"); return false; } break; case 4: if (!strcmp(_word[3], "linear")) { _xtype = gr_axis_LINEAR; _xtype_map = ' '; } else if (!strcmp(_word[3], "log")) { _xtype_map = ' '; if (_xtype == gr_axis_LOG) // only change if necessary return true; if (!_xscale_exists) { _xtype = gr_axis_LOG; gr_setxtransform(_xtype); return true; } if ((_xright > _xleft) && (_xleft > 0.0) && (_xright > 0.0)) { _xinc = 1; PUT_VAR("..xleft..", _xleft = pow(10.0, floor(0.5 + log10(_xleft)))); PUT_VAR("..xright..", _xright = pow(10.0, floor(0.5 + log10(_xright)))); PUT_VAR("..xinc..", _xinc); _xtype = gr_axis_LOG; } else { err("\ Can't convert from linear x axis, present x axis has numbers <= 0.\n\ First `delete x scale', then `set x type log'."); } } else { err("Type must be `linear', `log', or `map'"); return false; } break; default: NUMBER_WORDS_ERROR; return false; } gr_setxtransform(_xtype); return true; } bool set_y_typeCmd() { extern char _ytype_map; switch (_nword) { case 5: if (word_is(3, "map")) { if (word_is(4, "N")) { _ytype_map = 'N'; } else if (word_is(4, "S")) { _ytype_map = 'S'; } else if (word_is(4, "E")) { _ytype_map = 'E'; } else if (word_is(4, "W")) { _ytype_map = 'W'; } else { err("Y map type must be `E', `W', `S' or `N'"); return false; } } else { err("Type must be `linear', `log', or `map'"); return false; } break; case 4: if (!strcmp(_word[3], "linear")) { _ytype_map = ' '; _ytype = gr_axis_LINEAR; } else if (!strcmp(_word[3], "log")) { _ytype_map = ' '; if (_ytype == gr_axis_LOG) { // only change if necessary return true; } if (!_yscale_exists) { _ytype = gr_axis_LOG; gr_setytransform(_ytype); return true; } if ((_ytop > _ybottom) && (_ytop > 0.0) && (_ybottom > 0.0)) { _yinc = 1; PUT_VAR("..ybottom..", _ybottom = pow(10.0, floor(0.5 + log10(_ybottom)))); PUT_VAR("..ytop..", _ytop = pow(10.0, floor(0.5 + log10(_ytop)))); PUT_VAR("..yinc..", _yinc); _ytype = gr_axis_LOG; } else { err("\ Can't convert from linear y axis, present x axis has numbers <= 0.\n\ First `delete y scale', then `set y type log'."); } } else { err("Type must be `linear', `log', or `map'"); return false; } break; default: NUMBER_WORDS_ERROR; return false; } gr_setytransform(_ytype); return true; } // `set z missing above|below .intercept. .slope.' bool set_z_missingCmd() { double slope, intercept; typedef enum { above, below, dont_know } WHERE; WHERE where = dont_know; switch (_nword) { case 6: if (!getdnum(_word[4], &intercept)) return false; if (!getdnum(_word[5], &slope)) return false; if (word_is(3, "above")) where = above; else if (word_is(3, "below")) where = below; break; default: NUMBER_WORDS_ERROR; return false; } if (_colX.size() < 1) { err("First `read columns ... x'"); return false; } if (_colY.size() < 1) { err("First `read columns ... y'"); return false; } if (_colZ.size() < 1) { err("First `read columns ... z'"); return false; } double missing = gr_currentmissingvalue(); switch (where) { case above: for (unsigned int i = 0; i < _colX.size(); i++) { if (_colY[i] > intercept + slope * _colX[i]) _colZ[i] = missing; } break; case below: for (unsigned int i = 0; i < _colX.size(); i++) { if (_colY[i] < intercept + slope * _colX[i]) _colZ[i] = missing; } break; default: demonstrate_command_usage(); err("Fourth word must be `above' or `below'"); return false; } return true; } bool set_font_colorCmd() { double red, green, blue; GriColor c; switch (_nword) { case 4: if (!look_up_color(_word[3], &red, &green, &blue)) { err("`set font color' given unknown colorname `\\", _word[3], "'. Use command `show colornames' to see available colors.", "\\"); return false; } c.setRGB(red, green, blue); _griState.set_color_text(c); _griState.set_separate_text_color(true); return true; case 7: if (strEQ(_word[3], "rgb")) { // `set color rgb .red. .green. .blue.' Require(getdnum(_word[4], &red), READ_WORD_ERROR(".red.")); Require(getdnum(_word[5], &green), READ_WORD_ERROR(".green.")); Require(getdnum(_word[6], &blue), READ_WORD_ERROR(".blue.")); // Clip if necessary if (red < 0.0) { warning("`set color rgb' value being clipped to 0"); red = 0.0; } else if (red > 1.0) { warning("`set color rgb' value being clipped to 0"); red = 1.0; } if (green < 0.0) { warning("`set color rgb' .green. value being clipped to 0"); green = 0.0; } else if (green > 1.0) { warning("`set color rgb' value being clipped to 0"); green = 1.0; } if (blue < 0.0) { warning("`set color rgb' value being clipped to 0"); blue = 0.0; } else if (blue > 1.0) { warning("`set color rgb' value being clipped to 0"); blue = 1.0; } _griState.set_separate_text_color(true); c.setRGB(red, green, blue); _griState.set_color_text(c); return true; } else if (strEQ(_word[3], "hsb")) { // `set color hsb .hue. .saturation. .brightness.' double hue, saturation, brightness; Require(getdnum(_word[4], &hue), READ_WORD_ERROR(".hue.")); Require(getdnum(_word[5], &saturation), READ_WORD_ERROR(".saturation.")); Require(getdnum(_word[6], &brightness), READ_WORD_ERROR(".brightness.")); // Clip if necessary if (hue < 0.0) { warning("`set color hsb' value being clipped to 0"); hue = 0.0; } else if (hue > 1.0) { warning("`set color hsb' value being clipped to 0"); hue = 1.0; } if (saturation < 0.0) { warning("`set color hsb' value being clipped to 0"); saturation = 0.0; } else if (saturation > 1.0) { warning("`set color hsb' value being clipped to 0"); saturation = 1.0; } if (brightness < 0.0) { warning("`set color hsb' value being clipped to 0"); brightness = 0.0; } else if (brightness > 1.0) { warning("`set color hsb' value being clipped to 0"); brightness = 1.0; } c.setHSV(hue, saturation, brightness); _griState.set_color_text(c); _griState.set_separate_text_color(true); return true; } else { err("Can't understand command."); demonstrate_command_usage(); return false; } default: NUMBER_WORDS_ERROR; demonstrate_command_usage(); return false; } } // set font encoding PostscriptStandard|isolatin1 bool set_font_encodingCmd() { if (_nword < 4) { demonstrate_command_usage(); err("`set font encoding' needs to know which method to use ('PostscriptStandard' or 'isolatin1')"); return false; } if (!strcmp(_word[3], "PostscriptStandard")) { gr_set_font_encoding(font_encoding_standard); return true; } else if (!strcmp(_word[3], "isolatin1")) { gr_set_font_encoding(font_encoding_isolatin1); return true; } else if (!strcmp(_word[3], "isolatinl")) { demonstrate_command_usage(); err("`set font encoding' spelling error. Did you mean `isolatin1' with a `one' at the end??"); return false; } else { demonstrate_command_usage(); err("`set font encoding' doesn't understand encoding method. Choices are `PostscriptStandard' and `isolatin1'"); return false; } } bool set_font_sizeCmd() { if (_nword < 3) { err("`set font' what?"); return false; } if (!strcmp(_word[2], "size")) { if (_nword < 4) { err("`set font size' what?"); return false; } if (_nword > 5) { err("extra words in `set font size' command"); return false; } if (!strcmp(_word[3], "default")) { PUT_VAR("..fontsize..", FONTSIZE_PT_DEFAULT); gr_setfontsize_pt(FONTSIZE_PT_DEFAULT); return false; } if (!getdnum(_word[3], &tmp)) return false; if (_nword == 5) { if (!strcmp(_word[4], "cm")) tmp *= PT_PER_CM; else { err("last word in `set font size' unknown"); return false; } } if (tmp < 0.0 || tmp > 200.0) { err("ignoring bad font size <0 or >200 cm"); return false; } PUT_VAR("..fontsize..", tmp); gr_setfontsize_pt(tmp); } else { err("`set font' what?"); return false; } return true; } bool set_font_toCmd() { if (_nword != 4) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (!strcmp(_word[3], "Courier")) gr_setfont(gr_font_Courier); else if (!strcmp(_word[3], "Helvetica")) gr_setfont(gr_font_Helvetica); else if (!strcmp(_word[3], "HelveticaBold")) gr_setfont(gr_font_HelveticaBold); else if (!strcmp(_word[3], "Palatino") || !strcmp(_word[3], "PalatinoRoman")) gr_setfont(gr_font_PalatinoRoman); else if (!strcmp(_word[3], "Symbol")) gr_setfont(gr_font_Symbol); else if (!strcmp(_word[3], "Century")) gr_setfont(gr_font_Century); else if (!strcmp(_word[3], "Times")) gr_setfont(gr_font_TimesRoman); else if (!strcmp(_word[3], "TimesRoman")) gr_setfont(gr_font_TimesRoman); else if (!strcmp(_word[3], "TimesBold")) gr_setfont(gr_font_TimesBold); else if (*_word[3] == '\\') { demonstrate_command_usage(); err("Font name, specified as `\\", _word[3], "' should not have a backslash at the start.", "\\"); return false; } else { demonstrate_command_usage(); err("Unknown font `\\", _word[3], "'.\n Available fonts: Courier, Helvetica, HelveticaBold, Palatino, PalatinoRoman, Symbol, Times, TimesRoman, TimesBold", "Century", "\\"); return false; } return true; } bool set_dashCmd() { // Start by clearing existing dash list _dash.erase(_dash.begin(), _dash.end()); // go to solid // Solid line if (word_is(_nword - 1, "off")) { // solid line return gr_set_dash(_dash); // BUG: needed? (set in GriPath anyway) #if 0 fprintf(_grPS, "[] 0 d\n"); #endif return true; // solid line } if (_nword == 2) { // `set dash' _dash.push_back(0.2); _dash.push_back(0.1); return gr_set_dash(_dash); // BUG: needed? (set in GriPath anyway) return true; } if (_nword == 3) { // `set dash .num.' if (!getdnum(_word[2], &tmp)) { demonstrate_command_usage(); READ_WORD_ERROR(".n."); return false; } switch ((int) (0.5 + fabs((double) tmp))) { case 0: return gr_set_dash(_dash); // BUG: needed? (set in GriPath anyway) case 1: _dash.push_back(0.2); _dash.push_back(0.1); return gr_set_dash(_dash); // BUG: needed? (set in GriPath anyway) case 2: _dash.push_back(0.4); _dash.push_back(0.1); return gr_set_dash(_dash); // BUG: needed? (set in GriPath anyway) case 3: _dash.push_back(0.6); _dash.push_back(0.1); return gr_set_dash(_dash); // BUG: needed? (set in GriPath anyway) case 4: _dash.push_back(0.8); _dash.push_back(0.1); return gr_set_dash(_dash); // BUG: needed? (set in GriPath anyway) case 5: _dash.push_back(1.0); _dash.push_back(0.1); return gr_set_dash(_dash); // BUG: needed? (set in GriPath anyway) case 10: _dash.push_back(_griState.linewidth_line() / PT_PER_CM); _dash.push_back(_griState.linewidth_line() / PT_PER_CM); return gr_set_dash(_dash); // BUG: needed? (set in GriPath anyway) case 11: _dash.push_back(_griState.linewidth_line() / PT_PER_CM); _dash.push_back(2.0 * _griState.linewidth_line() / PT_PER_CM); return gr_set_dash(_dash); // BUG: needed? (set in GriPath anyway) case 12: _dash.push_back(_griState.linewidth_line() / PT_PER_CM); _dash.push_back(3.0 * _griState.linewidth_line() / PT_PER_CM); return gr_set_dash(_dash); // BUG: needed? (set in GriPath anyway) case 13: _dash.push_back(_griState.linewidth_line() / PT_PER_CM); _dash.push_back(4.0 * _griState.linewidth_line() / PT_PER_CM); return gr_set_dash(_dash); // BUG: needed? (set in GriPath anyway) case 14: _dash.push_back(_griState.linewidth_line() / PT_PER_CM); _dash.push_back(5.0 * _griState.linewidth_line() / PT_PER_CM); return gr_set_dash(_dash); // BUG: needed? (set in GriPath anyway) case 15: _dash.push_back(_griState.linewidth_line() / PT_PER_CM); _dash.push_back(6.0 * _griState.linewidth_line() / PT_PER_CM); return gr_set_dash(_dash); // BUG: needed? (set in GriPath anyway) default: _dash.push_back(0.2); _dash.push_back(0.1); return gr_set_dash(_dash); // BUG: needed? (set in GriPath anyway) } return gr_set_dash(_dash); // BUG: need this? (set in GriPath anyway) } else { // Long list of values for (unsigned int i = 0; i < _nword - 2; i++) { double tmp; if (!getdnum(_word[2 + i], &tmp)) { demonstrate_command_usage(); err("Cannot read all dash/blank values"); return false; } _dash.push_back(tmp); } } #if 0 fprintf(_grPS, "["); for (unsigned int i = 0; i < _dash.size(); i++) fprintf(_grPS, "%.3f ", _dash[i] * PT_PER_CM); fprintf(_grPS, "] %d d\n", int(_dash.size())); #endif return gr_set_dash(_dash); // BUG: need this? (set in GriPath anyway) } bool gr_set_dash(const std::vector dash) { extern FILE *_grPS; fprintf(_grPS, "["); for (unsigned int i = 0; i < dash.size(); i++) fprintf(_grPS, "%.3f ", dash[i] * PT_PER_CM); fprintf(_grPS, "] %d d\n", int(dash.size())); _griState.set_dash(dash); //printf("DEBUG: gr_set_dash() stored a dash of length %ud\n",dash.size()); return true; } bool set_ignoreCmd() { switch (_nword) { case 4: if (!strcmp(_word[1], "ignore") && !strcmp(_word[2], "error") && !strcmp(_word[3], "eof")) { _ignore_eof = true; } else { demonstrate_command_usage(); err("Can't understand command."); } break; default: demonstrate_command_usage(); NUMBER_WORDS_ERROR; break; } return false; } bool set_input_data_windowCmd() { double minval, maxval; switch (_nword) { case 6: // set input data window x|y off if (strcmp(_word[5], "off")) { demonstrate_command_usage(); err("In this context, the last word must be `off'."); return false; } if (!strcmp(_word[4], "x")) _input_data_window_x_exists = false; else if (!strcmp(_word[4], "y")) _input_data_window_y_exists = false; else { demonstrate_command_usage(); err("In this context, the fifth word must be \"x\" or \"y\"."); return false; } break; case 7: if (!strcmp(_word[4], "x")) { if (!getdnum(_word[5], &minval)) { demonstrate_command_usage(); err("Can't read x window .min."); return false; } if (!getdnum(_word[6], &maxval)) { demonstrate_command_usage(); err("Can't read x window .max."); return false; } if (minval == maxval) { demonstrate_command_usage(); err("Can't have input data window of zero width."); return false; } if (minval < maxval) { _input_data_window_x_min = minval; _input_data_window_x_max = maxval; } else { _input_data_window_x_min = maxval; _input_data_window_x_max = minval; } _input_data_window_x_exists = true; } else if (!strcmp(_word[4], "y")) { if (!getdnum(_word[5], &minval)) { demonstrate_command_usage(); err("Can't read y window .min."); return false; } if (!getdnum(_word[6], &maxval)) { demonstrate_command_usage(); err("Can't read y window .max."); return false; } if (minval == maxval) { demonstrate_command_usage(); err("Can't have input data window of zero width."); return false; } if (minval < maxval) { _input_data_window_y_min = minval; _input_data_window_y_max = maxval; } else { _input_data_window_y_min = maxval; _input_data_window_y_max = minval; } _input_data_window_y_exists = true; } else { demonstrate_command_usage(); err("In this context, the fifth word must be \"x\" or \"y\"."); return false; } break; default: demonstrate_command_usage(); err("Can't understand command."); return false; } return true; } bool set_input_data_separatorCmd() { if (_nword < 5) { demonstrate_command_usage(); err("Must specify an input separator (either `TAB' or `default')."); return false; } if (_nword > 5) { demonstrate_command_usage(); err("Too many words in `set input data separator' command"); return false; } if (!strcmp(_word[4], "default")) { extern char _input_data_separator; _input_data_separator = ' '; return true; } else if (!strcmp(_word[4], "TAB")) { extern char _input_data_separator; _input_data_separator = '\t'; return true; } else { demonstrate_command_usage(); err("`set input data separator' only understands `TAB' and `default', not ``\\", _word[4], "' as given", "\\"); return false; } } bool set_contour_formatCmd() { if (_nword < 4) { err("Must specify a format for `set contour format'"); return false; } if (!strcmp(_word[3], "default")) { _contourFmt.assign(CONTOUR_FMT_DEFAULT); } else { if (*_word[3] == '"') { int len = strlen(_word[3]); if (len <= 1) { _contourFmt.assign(CONTOUR_FMT_DEFAULT); } else { if (*(_word[3] + len - 1) == '"') _contourFmt.assign(_word[3] + 1, len - 2); else _contourFmt.assign(_word[3] + 1, len - 1); } } else { _contourFmt.assign(_word[3]); } } return true; } // `set contour label position {.start_cm. .between_cm.}|default|centered' // 0 1 2 3 4 5 6 // `set contour label for lines exceeding .x. cm' // 0 1 2 3 4 5 6 7 bool set_contour_labelCmd() { extern double _contour_space_first, _contour_space_later, _contour_minlength; // <-> draw.c extern bool _contour_space_centered; // <-> draw.c if (word_is(3, "for")) { // `set contour label for lines exceeding .x. cm' Require(_nword == 8, NUMBER_WORDS_ERROR); Require(getdnum(_word[6], &tmp), READ_WORD_ERROR(".x.")); _contour_minlength = tmp; } else { // `set contour label position ...' switch (_nword) { case 5: if (word_is(4, "default")) { _contour_space_first = -1.0; _contour_space_later = -1.0; } else if (word_is(4, "centered") || word_is(4, "centred")) { _contour_space_centered = true; } else { demonstrate_command_usage(); err("Expecting `default', not '\\", _word[4], "'", "\\"); return false; } break; case 6: Require(getdnum(_word[4], &tmp), READ_WORD_ERROR(".start_cm.")); Require(getdnum(_word[5], &tmp2), READ_WORD_ERROR(".between_cm.")); _contour_space_first = tmp; _contour_space_later = tmp2; _contour_space_centered = false; break; default: demonstrate_command_usage(); err("Can't understand command."); return false; } } return true; } // `set contour labels rotated|horizontal' // `set contour labels whiteunder|nowhiteunder' // 0 1 2 3 bool set_contour_labelsCmd() { extern bool _contour_label_rotated; // <-> draw.c startup.c extern bool _contour_label_whiteunder; // <-> grcntour.c startup.c Require(_nword == 4, NUMBER_WORDS_ERROR); if (word_is(3, "rotated")) _contour_label_rotated = true; else if (word_is(3, "horizontal")) _contour_label_rotated = false; else if (word_is(3, "whiteunder")) _contour_label_whiteunder = true; else if (word_is(3, "nowhiteunder")) _contour_label_whiteunder = false; else { err("Last word of `set contour labels' must be `rotated|horizontal|whiteunder|nowhiteunder'"); return false; } return true; } // Flags for `set flag' #define NFLAG 100 typedef struct { std::string name; bool value; } FLAG; FLAG flag[NFLAG]; unsigned int num_flags = 0; bool set_flagCmd() { if (_nword != 3 && _nword != 4) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } bool turn_on = true; if (_nword == 4 && word_is(3, "off")) turn_on = false; unsigned int i; for (i = 0; i < num_flags; i++) { if (flag[i].name == _word[2]) { flag[i].value = turn_on; return true; } } // It is a new flag if (i >= NFLAG) OUT_OF_MEMORY; num_flags = i; flag[num_flags].name = _word[2]; flag[num_flags].value = turn_on; num_flags++; return true; } bool get_flag(const char *name) { for (unsigned int i = 0; i < num_flags; i++) if (flag[i].name == name) return flag[i].value; return false; // unknown flag } void show_flags() { extern char _grTempString[]; if (num_flags) { for (unsigned int i = 0; i < num_flags; i++) { sprintf(_grTempString, "Flag `%s' is %d\n", flag[i].name.c_str(), flag[i].value); gr_textput(_grTempString); } } else { gr_textput("No flags exist\n"); } } // set error action ... bool set_error_actionCmd() { // set error action to core dump // 0 1 2 3 4 5 if (_nword == 6 && word_is(2, "action") && word_is(3, "to") && word_is(4, "core") && word_is(5, "dump")) { _error_action = 1; return true; } else { demonstrate_command_usage(); err("Wrong syntax"); return false; } } bool set_graylevelCmd() { double tmp; if (_nword != 3) { err("`set graylevel' requires 1 parameter"); return false; } if (word_is(2, "black")) { tmp = 0.0; } else if (word_is(2, "white")) { tmp = 1.0; } else if (!getdnum(_word[2], &tmp)) { READ_WORD_ERROR(".brightness."); return false; } if (tmp < 0.0 || tmp > 1.0) { err("Ignoring bad graylevel <0 or >1"); return false; } PUT_VAR("..graylevel..", tmp); PUT_VAR("..red..", tmp); PUT_VAR("..green..", tmp); PUT_VAR("..blue..", tmp); GriColor c; c.setRGB(tmp, tmp, tmp); _griState.set_color_line(c); if (_griState.separate_text_color() == false) _griState.set_color_text(c); return true; } // If x is very close to xmin or xmax, assign to same double tweak_to_limit(double x, double xmin, double xmax) { double range = fabs(xmax - xmin); if (fabs(x - xmin) < range / 1.0e4) return xmin; if (fabs(x - xmax) < range / 1.0e4) return xmax; return x; } // set image colorscale hsb .h. .s. .b. .im_value. hsb .h. .s. .b. .im_value. // [increment .value.] // // set image colorscale rgb .r. .g. .b. .im_value. rgb .r. .g. .b. .im_value. // [increment .value.] // // set image colorscale \name .im_value. \name .im_value. [increment .im_value.] // // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 // 14 bool set_image_colorscaleCmd() { double rA, rB, gA, gB, bA, bB, hA, hB, sA, sB, brA, brB; double r, g, b, h, s, br; double valA, valB, indexA, indexB, inc, delta_image = 0.0; int i, levels = 0; GriColor::type color_model; // rgb hsv cmyk (GriColor.hh) bool gave_increment = false; // check number of words, for the 2 forms and with/without increment if (_nword != 13 && _nword != 15 && _nword != 7 && _nword != 9) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (!image_range_exists()) { err("First `set image range'"); return false; } // Extract endpoint values. if (_nword == 7) { // `set image colorscale \name .im_value. \name .im_value.' if (!look_up_color(_word[3], &rA, &gA, &bA)) { err("Unknown colorname `\\", _word[3], "'. Use command `show colornames' to see available colors.", "\\"); return false; } if (!getdnum(_word[4], &valA)) return false; if (!look_up_color(_word[5], &rB, &gB, &bB)) { err("Unknown colorname `\\", _word[5], "'. Use command `show colornames' to see available colors.", "\\"); return false; } if (!getdnum(_word[6], &valB)) return false; gave_increment = false; color_model = GriColor::rgb; // default } else if (_nword == 9) { // `set image colorscale \name .im_value. \name .im_value. increment // .im_value. if (!look_up_color(_word[3], &rA, &gA, &bA)) { err("Unknown colorname `\\", _word[3], "'. Use command `show colornames' to see available colors.", "\\"); return false; } if (!getdnum(_word[4], &valA)) return false; if (!look_up_color(_word[5], &rB, &gB, &bB)) { err("Unknown colorname `\\", _word[5], "'. Use command `show colornames' to see available colors.", "\\"); return false; } if (!getdnum(_word[6], &valB)) return false; if (!getdnum(_word[8], &inc)) return false; gave_increment = true; color_model = GriColor::rgb; // default } else { // BUG: will need to check word number if add cmyk // Didn't give named color. Must be rgb or hsb specification if (word_is(3, "rgb")) { if (!getdnum(_word[4], &rA)) return false; if (!getdnum(_word[5], &gA)) return false; if (!getdnum(_word[6], &bA)) return false; if (!getdnum(_word[7], &valA)) return false; color_model = GriColor::rgb; } else if (word_is(3, "hsb")) { if (!getdnum(_word[4], &hA)) return false; if (!getdnum(_word[5], &sA)) return false; if (!getdnum(_word[6], &brA)) return false; if (!getdnum(_word[7], &valA)) return false; color_model = GriColor::hsv; } else { err("Cannot understand first color specification `\\", _word[3], "'.", "\\"); return false; } // Insist that rgb and hsb not be intermixed, since that's how to // decide on the blending algorithm if (word_is(8, "rgb")) { if (color_model != GriColor::rgb) { err("Cannot mix color specifications, e.g. `rgb' with `hsb'"); return false; } if (!getdnum(_word[9], &rB)) return false; if (!getdnum(_word[10], &gB)) return false; if (!getdnum(_word[11], &bB)) return false; if (!getdnum(_word[12], &valB)) return false; if (rA < 0.0 || rA > 1.0 || gA < 0.0 || gA > 1.0 || bA < 0.0 || bA > 1.0) { err("Require all RGB values to be in range 0.0 to 1.0"); return false; } } else if (word_is(8, "hsb")) { if (color_model != GriColor::hsv) { err("Cannot mix color specifications, e.g. `rgb' with `hsb'"); return false; } if (!getdnum(_word[9], &hB)) return false; if (!getdnum(_word[10], &sB)) return false; if (!getdnum(_word[11], &brB)) return false; if (!getdnum(_word[12], &valB)) return false; if (hB < 0.0 || hB > 1.0 || sB < 0.0 || sB > 1.0 || brB < 0.0 || brB > 1.0) { err("Require all HSB values to be in range 0.0 to 1.0"); return false; } } else { err("Cannot understand color specification `\\", _word[3], "'.", "\\"); return false; } // Get increment value if it exists. if (word_is(13, "increment")) { // then last word is the increment value if (!getdnum(_word[14], &inc)) return false; gave_increment = true; } } // Check that endpoints distinct if (valA == valB) { err("Can't have equal image values at endpoints of `set colorscale'"); return false; } if (gave_increment) { if (!well_ordered(valA, valB, inc)) inc = -inc; if (!gr_multiple(fabs(valB - valA), fabs(inc), fabs(0.001 * inc))) { err("\ `set image colorscale ... requires range/increment to be integral to 0.1%"); return false; } delta_image = 255.0 * fabs(inc / (valA - valB)); levels = (int) floor(1.0e-5 + fabs((valA - valB) / inc)); } // Calculate the transforms. NB: indexA and indexB are of the // indices of transform endpoints. Do RGB and HSB separately, each // interpolating linearly in its own space. (NB: a nonlinear transform // links RGB and HSB, so linear movement between equivalent endpoints in // these two spaces yields nonequivalent values.) // indexA = 255.0 * (valA - _image0) / (_image255 - _image0); indexB = 255.0 * (valB - _image0) / (_image255 - _image0); if (color_model == GriColor::rgb) { double delta_r = delta_image * fabs(rA - rB); double delta_g = delta_image * fabs(gA - gB); double delta_b = delta_image * fabs(bA - bB); // For each target imageTransform[], make a clipped, linear blend // from (rA,gA,bA) to (rB,gB,bB). Possibly pass this linear blend // to 'quantize', to make it into a staircase function. for (i = 0; i < 256; i++) { r = 255.0 * (rA + (rB - rA) * pin0_1((i - indexA) / (indexB - indexA))); g = 255.0 * (gA + (gB - gA) * pin0_1((i - indexA) / (indexB - indexA))); b = 255.0 * (bA + (bB - bA) * pin0_1((i - indexA) / (indexB - indexA))); if (gave_increment) { r = quantize(r, levels, delta_r); g = quantize(g, levels, delta_g); b = quantize(b, levels, delta_b); } _imageTransform[i] = (unsigned char) pin0_255(r); _imageTransform[i + 256] = (unsigned char) pin0_255(g); _imageTransform[i + 512] = (unsigned char) pin0_255(b); } // Ensure that endpoints match (rgb)A or (rgb)B, as appropriate. if (indexA < indexB) { _imageTransform[0] = (unsigned char) (255.0 * rA); _imageTransform[256] = (unsigned char) (255.0 * gA); _imageTransform[512] = (unsigned char) (255.0 * bA); _imageTransform[0 + 255] = (unsigned char) (255.0 * rB); _imageTransform[256 + 255] = (unsigned char) (255.0 * gB); _imageTransform[512 + 255] = (unsigned char) (255.0 * bB); } else { _imageTransform[0] = (unsigned char) (255.0 * rB); _imageTransform[256] = (unsigned char) (255.0 * gB); _imageTransform[512] = (unsigned char) (255.0 * bB); _imageTransform[0 + 255] = (unsigned char) (255.0 * rA); _imageTransform[256 + 255] = (unsigned char) (255.0 * gA); _imageTransform[512 + 255] = (unsigned char) (255.0 * bA); } } else if (color_model == GriColor::hsv) { double delta_h = delta_image * fabs(hA - hB); double delta_s = delta_image * fabs(sA - sB); double delta_br = delta_image * fabs(brA - brB); // For each target imageTransform[], make a clipped, linear blend // from (hA,sA,brA) to (hB,sB,brB). Possibly pass this linear blend // to 'quantize', to make it into a staircase function. for (i = 0; i < 256; i++) { h = (hA + (hB - hA) * pin0_1((i - indexA) / (indexB - indexA))); s = (sA + (sB - sA) * pin0_1((i - indexA) / (indexB - indexA))); br = (brA + (brB - brA) * pin0_1((i - indexA) / (indexB - indexA))); if (gave_increment) { // Quantize HSB *before* conversion to RGB h = quantize(255.0 * h, levels, delta_h) / 255.0; s = quantize(255.0 * s, levels, delta_s) / 255.0; br = quantize(255.0 * br, levels, delta_br) / 255.0; } gr_hsv2rgb(h, s, br, &r, &g, &b); _imageTransform[i] = (unsigned char) pin0_255(255.0 * r); _imageTransform[i + 256] = (unsigned char) pin0_255(255.0 * g); _imageTransform[i + 512] = (unsigned char) pin0_255(255.0 * b); } // Ensure that endpoints match (rgb)A or (rgb)B, as appropriate. gr_hsv2rgb(hA, sA, brA, &rA, &gA, &bA); gr_hsv2rgb(hB, sB, brB, &rB, &gB, &bB); if (indexA < indexB) { _imageTransform[0] = (unsigned char) (255.0 * rA); _imageTransform[256] = (unsigned char) (255.0 * gA); _imageTransform[512] = (unsigned char) (255.0 * bA); _imageTransform[0 + 255] = (unsigned char) (255.0 * rB); _imageTransform[256 + 255] = (unsigned char) (255.0 * gB); _imageTransform[512 + 255] = (unsigned char) (255.0 * bB); } else { _imageTransform[0] = (unsigned char) (255.0 * rB); _imageTransform[256] = (unsigned char) (255.0 * gB); _imageTransform[512] = (unsigned char) (255.0 * bB); _imageTransform[0 + 255] = (unsigned char) (255.0 * rA); _imageTransform[256 + 255] = (unsigned char) (255.0 * gA); _imageTransform[512 + 255] = (unsigned char) (255.0 * bA); } } else { err("Cannot handle this color model. Only `rgb' and `hsb' are known at this time"); return false; } // All done. Everything was OK. _imageTransform_exists = true; _image_color_model = rgb_model; return true; } bool set_image_grayscaleCmd() { int i; double indexA; if (_nword < 3) { err("`set image' what?"); return false; } // Do a (redundant?) check if (!word_is(2, "grayscale") && !word_is(2, "greyscale")) { err("`set image' what?"); return false; } if (!image_range_exists()) { err("First `set image range'"); return false; } // `set image grayscale' if (_nword == 3) { if (!_image.storage_exists) { err("First, you must read or create an image"); return false; } unsigned char valTmp; unsigned char valA = *(_image.image); unsigned char valB = valA; for (unsigned int ij = 1; ij < _image.ras_width * _image.ras_height; ij++) { valTmp = *(_image.image + ij); if (valTmp < valA) valA = valTmp; if (valTmp > valB) valB = valTmp; } indexA = pin0_255(255.0 * (valA - _image0) / (_image255 - _image0)); double scale = 255 / (valB - valA); for (i = 0; i < 256; i++) { _imageTransform[i] = (unsigned char) floor(double(pin0_255((int) floor(scale * (i - indexA))))); } _imageTransform[0] = (_imageTransform[0] <= 128) ? 0 : 255; _imageTransform[255] = (_imageTransform[255] <= 128) ? 0 : 255; _imageTransform_exists = true; _image_color_model = bw_model; //printf("_image0 %f _image255 %f valA %d valB %d scale %f indexA %f\n", _image0, _image255, valA, valB, scale, indexA); return true; } // `set image grayscale [black .bl. white .wh. [increment .inc.]]' if (_nword > 3 && (!strcmp(_word[3], "black") || !strcmp(_word[3], "white") || !strcmp(_word[3], "increment"))) { double inc = 0.0, valB, valA, scale; bool gave_increment = false; if (1 == get_cmd_values(_word, _nword, "black", 1, _dstack)) valA = _dstack[0]; else { err("Can't read .bl. in [white .wh. black .bl.]"); return false; } if (1 == get_cmd_values(_word, _nword, "white", 1, _dstack)) valB = _dstack[0]; else { err("Can't read .wh. in [white .wh. black .bl.]"); return false; } if (1 == get_cmd_values(_word, _nword, "increment", 1, _dstack)) { inc = _dstack[0]; gave_increment = true; } indexA = 255.0 * (valA - _image0) / (_image255 - _image0); scale = (_image255 - _image0) / (valB - valA); if (gave_increment) { // Set up quantized gray levels. For example, `set image // grayscale white -1 black 1 increment 0.5' will set up 4 gray // levels; thus, _imageTransform[] will be set up with 4 bands, // containing the distinct values (1/5, 2/5, 3/5, 4/5) * 255. // // BUG -- this quantized graylevel code has had lots of bugs double delta_image; // image change per level int levels; // number of levels if (!well_ordered(valA, valB, inc)) inc = -inc; if (!gr_multiple(valB - valA, inc, 0.001 * inc)) { err("\ `set image grayscale black .bl. white .wh. increment .inc.'\n\ has (.wh. - .bl.) not a multiple of .inc. to within 0.1%"); return false; } if (valA == valB) { err("\ `set image grayscale black .bl. white .wh. increment .inc.'\n\ has .wh. = .bl., which is not allowed."); return false; } delta_image = 255.0 * fabs(inc / (valB - valA)); levels = (int) floor(1.0e-5 + fabs((valB - valA) / inc)); for (i = 0; i < 256; i++) { // The .001 below is to prevent rounding problems. _imageTransform[i] = (unsigned char) floor(double(pin0_255((int) floor(double(0.001 + quantize(scale * (i - indexA), levels, delta_image)))))); } // BUG -- the following is a total kludge, because I could not // find an adequate rounding macro _imageTransform[0] = (_imageTransform[0] <= 128) ? 0 : 255; _imageTransform[255] = (_imageTransform[255] <= 128) ? 0 : 255; _imageTransform_exists = true; _image_color_model = bw_model; return true; } else { // Increment was not given. for (i = 0; i < 256; i++) { _imageTransform[i] = (unsigned char) floor(double(pin0_255((int) floor(scale * (i - indexA))))); } } _imageTransform_exists = true; _image_color_model = bw_model; return true; } demonstrate_command_usage(); err("Can't understand command."); return false; } bool set_image_grayscale_using_hist() { int i; double sum = 0.0, range; double wh, bl; if (!image_range_exists()) { err("First `set image range'"); return false; } // Since parser got to this point, must at least match `set image // grayscale using histogram' if (_nword == 5) { // `set image grayscale using histogram' calculate_image_histogram(); // The range is sum(255) - sum(0), but sum(255) is unity, because // _imageHist[] is defined that way, and sum(0) is _imageHist[0]. range = 1.0 - _imageHist[0]; if (range == 0.0) range = 1.0; for (i = 0; i < 256; i++) { _imageTransform[i] = (unsigned char) floor(pin0_255(255.0 * (1.0 - (sum - _imageHist[0]) / range))); sum += _imageHist[i]; } _imageTransform_exists = true; } else if (_nword == 9) { // `set image grayscale using histogram black .bl. white .wh.' int start, end; double sum_to_end = 0.0, sum_to_start = 0.0; if (1 == get_cmd_values(_word, _nword, "black", 1, _dstack)) { bl = _dstack[0]; } else { err("Can't read .bl. in [black .bl. white .wh.]"); return false; } if (1 == get_cmd_values(_word, _nword, "white", 1, _dstack)) { wh = _dstack[0]; } else { err("Can't read .wh. in [black .bl. white .wh.]"); return false; } calculate_image_histogram(); start = value_to_image(wh); // pixel end = value_to_image(bl); // pixel for (i = 0; i < start; i++) sum_to_start += _imageHist[i]; for (i = 0; i < end; i++) sum_to_end += _imageHist[i]; range = sum_to_end - sum_to_start; if (range == 0.0) range = 1.0; for (i = 0; i < 256; i++) { _imageTransform[i] = (unsigned char) floor(pin0_255(255.0 * (1.0 - (sum - sum_to_start) / range))); sum += _imageHist[i]; } _imageTransform_exists = true; } else { demonstrate_command_usage(); err("Can't understand command."); return false; } _image_color_model = bw_model; return true; } // `set image missing value color to white|black|{graylevel .brightness.}' bool set_image_missingCmd() { if (!image_range_exists()) { err("First `set image range'"); return false; } if (_nword == 7) { // `set image missing value color to white|black' if (word_is(6, "white")) { _image_missing_color_red = 1.0; _image_missing_color_green = 1.0; _image_missing_color_blue = 1.0; } else if (word_is(6, "black")) { _image_missing_color_red = 0.0; _image_missing_color_green = 0.0; _image_missing_color_blue = 0.0; } else { demonstrate_command_usage(); err("Unknown color specified for image missing-value."); return false; } } else if (_nword == 10) { // `set image missing value color to rgb .red. .green. .blue.' if (!strcmp(_word[6], "rgb")) { double red, green, blue; Require(getdnum(_word[7], &red), READ_WORD_ERROR(".red.")); Require(getdnum(_word[8], &green), READ_WORD_ERROR(".green.")); Require(getdnum(_word[9], &blue), READ_WORD_ERROR(".blue.")); // Clip if necessary CHECK_RGB_RANGE(red); CHECK_RGB_RANGE(green); CHECK_RGB_RANGE(blue); _image_missing_color_red = red; _image_missing_color_green = green; _image_missing_color_blue = blue; } } else { // `set image missing value color to {graylevel .brightness.}' if (1 == get_cmd_values(_word, _nword, "graylevel", 1, _dstack) || 1 ==get_cmd_values(_word, _nword, "greylevel", 1, _dstack)) { if (_dstack[0] < 0.0) { warning("`set image missing value color': clipping graylevel to 0.0"); _image_missing_color_red = 0.0; _image_missing_color_green = 0.0; _image_missing_color_blue = 0.0; } else if (_dstack[0] > 1.0) { warning("`set image missing value color': clipping graylevel to 0.0"); _image_missing_color_red = 1.0; _image_missing_color_green = 1.0; _image_missing_color_blue = 1.0; } else { _image_missing_color_red = _dstack[0]; _image_missing_color_green = _dstack[0]; _image_missing_color_blue = _dstack[0]; } } else { demonstrate_command_usage(); err("Can't understand color specification."); return false; } } return true; } bool set_image_rangeCmd() { double tmp1, tmp2; switch (_nword) { case 5: if (word_is(3, "from") && word_is(4, "grid")) { bool first = true; double min_val, max_val; for (int j = 0; j < _num_ymatrix_data; j++) { for (int i = 0; i < _num_xmatrix_data; i++) { double f = _f_xy(i, j); if (!gr_missing(f)) { if (first) { max_val = f; min_val = f; first = false; } else { if (f > max_val) max_val = f; if (f < min_val) min_val = f; } } } } if (first) { demonstrate_command_usage(); err("the grid has no non-missing data"); return false; } _image0 = min_val; _image255 = max_val; return true; } else { if (!getdnum(_word[3], &tmp1)) return false; if (!getdnum(_word[4], &tmp2)) return false; _image0 = tmp1; _image255 = tmp2; return true; } default: demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } } // `set grid missing inside|outside curve' // `set grid missing above|below .intercept. .slope' // 0 1 2 3 4 5 bool set_grid_missingCmd() { double intercept, slope; typedef enum { above, below, inside, outside, dont_know } WHERE; WHERE where = dont_know; switch(_nword) { case 5: if (word_is(3, "inside")) where = inside; else if (word_is(3, "outside")) where = outside; break; case 6: if (!getdnum(_word[4], &intercept)) return false; if (!getdnum(_word[5], &slope)) return false; if (word_is(3, "above")) where = above; else if (word_is(3, "below")) where = below; break; default: demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (!grid_exists()) return false; unsigned int i, j; switch (where) { case above: for (i = 0; i < _num_xmatrix_data; i++) for (j = 0; j < _num_ymatrix_data; j++) if (_ymatrix[j] > intercept + slope * _xmatrix[i]) _legit_xy(i, j) = false; return true; // ok case below: for (i = 0; i < _num_xmatrix_data; i++) for (j = 0; j < _num_ymatrix_data; j++) if (_ymatrix[j] < intercept + slope * _xmatrix[i]) _legit_xy(i, j) = false; return true; // ok case inside: return set_grid_missing_curve(true); case outside: return set_grid_missing_curve(false); default: demonstrate_command_usage(); err("Fourth word must be `above', `below', `inside' or `outside'"); return false; } } bool set_grid_missing_curve(bool inside) { if (!inside) { err("'set grid missing outside curve' not allowed"); return false; } unsigned int imax = 0, start = 0; for (unsigned int i = 0; i < _colX.size(); i++) { imax = i; if (gr_missingx(_colX[i]) || gr_missingy(_colY[i]) || i > _colX.size() - 1) { if (!mask_an_island(_colX.begin() + start, _colY.begin() + start, i - start)) return false; // problem while ((gr_missingx(_colX[i]) || gr_missingy(_colY[i])) && i < _colX.size()) i++; start = i; } } if (imax <= _colX.size()) { mask_an_island(_colX.begin() + start, _colY.begin() + start, imax - start); } return true; } bool mask_an_island(double *x, double *y, unsigned int n) { unsigned right_edge = 0; double xmax = x[0]; unsigned int i; for (i = 1; i < n; i++) { if (x[i] > xmax) { xmax = x[i]; right_edge = i; } } //DEBUG printf("\nIsland:\n"); //DEBUG for (i = 0; i < n; i++) { //DEBUG printf(" %f %f\n", x[i], y[i]); //DEBUG } //DEBUG printf("Rotates to:\n"); //DEBUG for (i = 0; i < n; i++) { //DEBUG int ii = (i + right_edge) % n; //DEBUG printf(" %f %f\n", x[ii], y[ii]); //DEBUG } for (i = 0; i < n; i++) { int ii = (i + right_edge) % n; for (unsigned int ixm = 0; ixm < _num_xmatrix_data; ixm++) { if (between(_xmatrix[ixm], x[(ii+1)%n], x[ii])) { //DEBUG printf("mask out ixm=%d at %f, bracketed by %f - %f\n", ixm, _xmatrix[ixm], x[(ii+1)%n],x[ii]); for (int iym = (int)_num_ymatrix_data - 1; iym > -1; iym--) { if (_ymatrix[iym] <= interpolate_linear(_xmatrix[ixm], x[ii], y[ii], x[(ii+1)%n], y[(ii+1)%n])) { // Reverse things below //DEBUG printf("reverse below y(%d)=%f\n", iym, _ymatrix[iym]); while (iym > -1) { _legit_xy(ixm, iym) = _legit_xy(ixm, iym) == true ? false : true; iym--; } //DEBUG printf("i=%d; grid=\n", i); show_grid_maskCmd(); break; // just in case } } } } } return true; } static bool width_rapidograph(char *s, double *w) { // Named pen sizes, following the notation of Rapidograph(TM) // technical drawing pens. #define NUM_RAPIDOGRAPH 16 typedef struct { const char *name; // allow both 'X' and 'x' in names float width; // in points } r; r r_table[NUM_RAPIDOGRAPH] = { {"6x0", 0.369}, {"6X0", 0.369}, {"4x0", 0.510}, {"4X0", 0.510}, {"3x0", 0.709}, {"3X0", 0.709}, {"00", 0.850}, {"0", 0.992}, {"1", 1.417}, {"2", 1.701}, {"2.5", 1.984}, {"3", 2.268}, {"3.5", 2.835}, {"4", 3.402}, {"6", 3.969}, {"7", 5.669} }; std::string ss(s); un_double_quote(ss); for (int i = 0; i < NUM_RAPIDOGRAPH; i++) if (!strcmp(ss.c_str(), r_table[i].name)) { *w = r_table[i].width; return true; } err("Unknown rapidograph pen size `\\", s, "' requested.\n Permitted sizes: 6x0, 4x0, 3x0, 00, 0, 1, 2, 2.5, 3, 3.5, 4, 6, 7", "\\"); return false; } bool set_line_capCmd() { if (_nword != 4) { err("`set line cap .type.' has wrong number of words on command line"); return false; } double tmp; if (!getdnum(_word[3], &tmp)) { READ_WORD_ERROR(".type."); return false; } int t = int(floor(0.5 + tmp)); if (t < 0 || t > 2) { err("`set line cap .type.' only permits types 0, 1 and 2"); return false; } _griState.set_line_cap(t); return true; } bool set_line_joinCmd() { if (_nword != 4) { err("`set line join .type.' has wrong number of words on command line"); return false; } double tmp; if (!getdnum(_word[3], &tmp)) { READ_WORD_ERROR(".type."); return false; } int t = int(floor(0.5 + tmp)); if (t < 0 || t > 2) { err("`set line join .type.' only permits types 0, 1 and 2"); return false; } _griState.set_line_join(t); return true; } bool set_line_widthCmd() { //show_words(); double w; // the width, in pt unsigned int skip = 0; int what = 0; // -1=curve/rapido 0=curve 1=axis 2=symbol 3=all if (word_is(3, "axis")) { skip = 1; what = 1; } else if (word_is(3, "symbol")) { skip = 1; what = 2; } else if (word_is(3, "all")) { skip = 1; what = 3; } else if (word_is(3, "rapidograph")) { what = -1; } else { if (_nword > 4) { err("`set line width' found unexpected word `\\", _word[3], "'.", "\\"); return false; } } // Check for 'set line width ...' with no width specification if (_nword <= (skip + 3)) { NUMBER_WORDS_ERROR; return false; } // Take care of 'default', simple, and 'rapidograph' styles if (word_is(3 + skip, "default")) { Require(_nword == (4 + skip), NUMBER_WORDS_ERROR); switch (what) { case 0: w = LINEWIDTH_DEFAULT; break; case 1: w = LINEWIDTHAXIS_DEFAULT; break; case 2: w = LINEWIDTHSYMBOL_DEFAULT; break; case 3: w = LINEWIDTH_DEFAULT; break; default: w = LINEWIDTHSYMBOL_DEFAULT; } } else if (_nword == (4 + skip) && !word_is(3, "rapidograph")) { // Simple case if (what == -1) { if (!width_rapidograph(_word[3 + skip], &w)) { err("`set line width' cannot understand rapidograph name"); return false; } } else { if (!getdnum(_word[3 + skip], &w)) return false; } } else if (_nword == (5 + skip)) { // Rapidograph style if (word_is(3 + skip, "rapidograph")) { if (!width_rapidograph(_word[4 + skip], &w)) { err("`set line width' cannot understand rapidograph name"); return false; } } else { err("`set line width' expecting word `rapidograph'"); return false; } } else { if (word_is(_nword - 1, "rapidograph")) { err("`set line width rapidograph' needs a pen-width name"); } else { err("`set line width' cannot understand the width"); } return false; } // check that w is not crazily small ... a common blunder. See if less // than 1 dot on a 600dpi printer. if (w != 0.0) { if (w / PT_PER_CM < 2.54 / 4800) { char msg[200]; sprintf(msg, "a line width of %g points is barely resolved on a 4800 dpi printer", w); warning(msg); } else if (w / PT_PER_CM < 2.54 / 2400) { char msg[200]; sprintf(msg, "a line width of %g points is barely resolved on a 2400 dpi printer", w); warning(msg); } else if (w / PT_PER_CM < 2.54 / 600) { char msg[200]; sprintf(msg, "a line width of %g points is barely resolved on a 600 dpi printer", w); warning(msg); } else if (w / PT_PER_CM < 2.54 / 400) { char msg[200]; sprintf(msg, "a line width of %g points is barely resolved on a 400 dpi printer", w); warning(msg); } } switch (what) { case -1: case 0: _griState.set_linewidth_line(w); PUT_VAR("..linewidth..", w); break; case 1: _griState.set_linewidth_axis(w); PUT_VAR("..linewidthaxis..", w); break; case 2: _griState.set_linewidth_symbol(w); PUT_VAR("..linewidthsymbol..", w); break; case 3: _griState.set_linewidth_line(w); PUT_VAR("..linewidth..", w); _griState.set_linewidth_axis(w); PUT_VAR("..linewidthaxis..", w); _griState.set_linewidth_symbol(w); PUT_VAR("..linewidthsymbol..", w); break; default: _griState.set_linewidth_line(w); PUT_VAR("..linewidthline..", w); } return true; } bool set_missing_valueCmd() { // `set missing value #|none' double tmp; if (_nword == 4) { if (!strcmp(_word[3], "none")) { gr_set_missing_value_none(); } else if (getdnum(_word[3], &tmp)) { gr_set_missing_value(tmp); PUT_VAR("..missingvalue..", gr_currentmissingvalue()); { char tmp[100]; sprintf(tmp, "%f", gr_currentmissingvalue()); put_syn("\\.missingvalue.", tmp, true); } } else { // Actually, can not reach this code, with current error checking // in getdnum(). demonstrate_command_usage(); READ_WORD_ERROR(".missing_value."); } } else { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } return true; } bool set_page_sizeCmd() { Require(_nword == 4, err("`set page size' requires 1 parameter")); const char *s = _word[3]; // save typing extern rectangle _page_size; if (!strcmp(s, "letter")) { _page_size.set(0.0, 0.0, 8.5, 11.0); _page_size.scale(CM_PER_IN); } else if (!strcmp(s, "legal")) { _page_size.set(0.0, 0.0, 8.5, 14.0); _page_size.scale(CM_PER_IN); } else if (!strcmp(s, "folio")) { _page_size.set(0.0, 0.0, 8.5, 13.0); _page_size.scale(CM_PER_IN); } else if (!strcmp(s, "tabloid")) { _page_size.set(0.0, 0.0, 11.0, 17.0); _page_size.scale(CM_PER_IN); } else if (!strcmp(s, "A5")) { _page_size.set(0.0, 0.0, 14.8, 21.0); } else if (!strcmp(s, "A4")) { _page_size.set(0.0, 0.0, 21.0, 29.7); } else if (!strcmp(s, "A3")) { _page_size.set(0.0, 0.0, 29.7, 42.0); } else if (!strcmp(s, "A2")) { _page_size.set(0.0, 0.0, 42.0, 59.4); } else if (!strcmp(s, "A1")) { _page_size.set(0.0, 0.0, 59.4, 84.1); } else if (!strcmp(s, "A0")) { _page_size.set(0.0, 0.0, 84.1, 118.9); } else { demonstrate_command_usage(); err("Unknown paper size `\\", s, "'.", "\\"); return false; } return true; } bool set_pageCmd() { extern rectangle _page_size; Require(_nword > 2, err("`set page' requires parameter(s)")); double mag, xcm, ycm; if (!strcmp(_word[2], "portrait")) { gr_setup_ps_portrait(); } else if (!strcmp(_word[2], "landscape")) { if (!already_landscape) { if (_page_size.get_urx() == 0.0) { warning("Defaulting to page size US-letter; you should really do `set page size' before `set page landscape'"); fprintf(gr_currentPSFILEpointer(), "%.2f 72 mul 0 translate 90 rotate %% Landscape\n", 8.5); } else { fprintf(gr_currentPSFILEpointer(), "%.2f 72 mul 0 translate 90 rotate %% Landscape\n", _page_size.get_urx() / CM_PER_IN); } check_psfile(); } already_landscape = true; PUT_VAR("..landscape..", 1.0); gr_setup_ps_landscape(); } else if (!strcmp(_word[2], "factor")) { if (_nword != 4) { err("Must specify .mag. in `set page factor .mag.'"); return false; } if (!getdnum(_word[3], &mag)) return false; if (mag <= 0.0) { err("Can't use negative enlargement factor"); return false; } gr_setscale(mag, mag); } else if (!strcmp(_word[2], "translate")) { if (_nword != 5) { err("Must specify .xcm. and .ycm. in `set page translate .xcm. .ycm.'"); return false; } if (!getdnum(_word[3], &xcm)) return false; if (!getdnum(_word[4], &ycm)) return false; gr_settranslate(xcm, ycm); } else { err("Unknown `set page' parameter"); return false; } return true; } //`set path to "\path"|default for data|commands' bool set_pathCmd() { if (_nword != 6) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (strNE(_word[4], "for")) { err("Fourth word must be `for', not `\\", _word[4], "' as given.", "\\"); return false; } char *which_path; if (strEQ(_word[5], "data")) which_path = (char *)"\\.path_data."; else if (strEQ(_word[5], "commands")) which_path = (char *)"\\.path_commands."; else { err("Sixth word must be `data' or `commands', not `\\", _word[5], "' as given.", "\\"); return false; } if (strEQ(_word[3], "default")) { if (!put_syn(which_path, ".", true)) { err("Internal error in setting path to default."); return false; } } else { std::string unquoted; int ok = ExtractQuote(_word[3], unquoted); if (ok) { if (!put_syn(which_path, unquoted.c_str(), true)) { err("`set path' cannot save `\\", _word[2], "' in synonym", which_path, "\\"); return false; } } else { err("`set path' cannot understand path `\\", _word[2], "'.", "\\"); return false; } } return true; } bool set_postscript_filenameCmd() { if (_nword != 4) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (!gr_reopen_postscript(_word[3])) { demonstrate_command_usage(); warning("Cannot open `\\", _word[3], "', so using old name.", "\\"); } return true; } bool set_symbol_sizeCmd() { if (_nword < 3) { err("`set symbol' what?"); return false; } if (!strcmp(_word[2], "size")) { if (!strcmp(_word[3], "default")) { tmp = SYMBOLSIZE_DEFAULT; PUT_VAR("..symbolsize..", tmp); gr_setsymbolsize_cm(SYMBOLSIZE_DEFAULT); return true; } if (!getdnum(_word[3], &tmp)) return false; if (tmp < 0.0 || tmp > 20.0) { err("Ignoring bad symbol size <0 or >20 cm"); return false; } PUT_VAR("..symbolsize..", tmp); gr_setsymbolsize_cm(tmp); } else { err("`set symbol' what?"); return false; } return true; } bool set_tic_sizeCmd() { if (_nword < 3) { err("`set tic' what?"); return false; } if (!strcmp(_word[2], "size")) { if (_nword < 4) { err("`set tic size' what?"); return false; } if (_nword > 4) { err("Extra words in `set tic size' command"); return false; } if (!strcmp(_word[3], "default")) { tmp = TICSIZE_DEFAULT; PUT_VAR("..tic_size..", tmp); return true; } if (!getdnum(_word[3], &tmp)) return false; if (tmp < 0.0 || tmp > 20.0) { err("Ignoring bad tic size <0 or >20 cm"); return false; } PUT_VAR("..tic_size..", tmp); } else { err("`set tic' what?"); return false; } return true; } bool set_ticsCmd() { if (_nword != 3) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (!strcmp(_word[2], "in")) { PUT_VAR("..tic_direction..", 1.0); } else if (!strcmp(_word[2], "out")) { PUT_VAR("..tic_direction..", 0.0); } else { demonstrate_command_usage(); err("Third word must be \"in\" or \"out\"."); return false; } return true; } bool set_transparencyCmd() { if (_nword != 3) { err("`set transpancy' to what value?"); return false; } double transparency; Require(getdnum(_word[2], &transparency), READ_WORD_ERROR(".transparency.")); if (transparency < 0.0) transparency = 0.0; if (transparency > 1.0) transparency = 1.0; PUT_VAR("..transparency..", transparency); _griState.set_transparency_line(transparency); _griState.set_transparency_text(transparency); return true; } bool set_u_scaleCmd() { double xsize; if (_nword < 3) { demonstrate_command_usage(); err("`set u' ?WHAT?"); return false; } if (strcmp(_word[2], "scale")) { demonstrate_command_usage(); err("`set u ?WHAT?' (try `set u scale ...'"); return false; } switch (_nword) { case 4: // `set u scale .cm_per_unit.' if (!getdnum(_word[3], &tmp)) return false; if (tmp != 0.0) { _cm_per_u = tmp; _uscale_exists = true; return true; } else { err("`set u scale 0' illegal"); return false; } case 5: // `set u scale as x' if (strcmp(_word[3], "as") || strcmp(_word[4], "x")) { err("Correct usage `set u scale as x'"); return false; } if (!_xscale_exists) { err("First `set x axis' or `read columns x ...'"); return false; } if (_xtype != gr_axis_LINEAR) { err("Can only `set u scale as x' if x is LINEAR"); return false; } if (!get_var("..xsize..", &xsize)) { err("Can't remember ..xsize.."); return false; } _cm_per_u = xsize / (_xright - _xleft); _uscale_exists = true; return true; default: err("`set u' what?"); return false; } } bool set_v_scaleCmd() { double ysize; if (_nword < 3) { err("`set v' ?WHAT?"); return false; } if (strcmp(_word[2], "scale")) { err("`set v ?WHAT?' (try `set v scale ...'"); return false; } switch (_nword) { case 4: // `set v scale .cm_per_unit.' if (!getdnum(_word[3], &tmp)) return false; if (tmp != 0.0) { _cm_per_v = tmp; _vscale_exists = true; return true; } else { err("`set v scale 0' illegal"); return false; } case 5: // `set v scale as y' if (strcmp(_word[3], "as") || strcmp(_word[4], "y")) { demonstrate_command_usage(); err("Correct usage `set v scale as y'"); return false; } if (!_yscale_exists) { demonstrate_command_usage(); err("First `set y axis' or `read columns y ...'"); return false; } if (_ytype != gr_axis_LINEAR) { demonstrate_command_usage(); err("Can only `set u scale as y' if y is LINEAR"); return false; } if (!get_var("..ysize..", &ysize)) { demonstrate_command_usage(); err("Can't remember ..ysize.."); return false; } _cm_per_v = ysize / (_ytop - _ybottom); _vscale_exists = true; return true; default: err("`set v' what?"); return false; } } bool set_traceCmd() { switch (_nword) { case 2: PUT_VAR("..trace..", 1.0); break; case 3: if (!strcmp(_word[2], "on")) { PUT_VAR("..trace..", 1.0); } else if (!strcmp(_word[2], "off")) { PUT_VAR("..trace..", 0.0); } break; default: break; } return true; } bool well_ordered(double min, double max, double inc) { if (min < max) return ((inc > 0.0) ? true : false); else return ((inc < 0.0) ? true : false); } bool inc_within_range(double min, double max, double inc) { if (min < max) return (min + inc < max); else return (min + inc > max); } bool set_x_axisCmd() { _xatbottom = true; #if 1 // 2.9.x if (word_is(3, "labels")) { if (word_is(4, "automatic")) { _x_labels.erase(_x_labels.begin(), _x_labels.end()); _x_label_positions.erase(_x_label_positions.begin(), _x_label_positions.end()); return true; } else { unsigned int start = 4; if (word_is(start, "add")) { start++; } else { _x_labels.erase(_x_labels.begin(), _x_labels.end()); _x_label_positions.erase(_x_label_positions.begin(), _x_label_positions.end()); } for (unsigned int i = start; i < _nword; i++) { double tmp; if (!getdnum(_word[i], &tmp)) { READ_WORD_ERROR(".pos."); demonstrate_command_usage(); return false; } _x_label_positions.push_back(tmp); if (i++ == _nword - 1) { err("Missing label to be applied at position \\", _word[i-1], "\\"); demonstrate_command_usage(); return false; } std::string l = _word[i]; un_double_quote(l); _x_labels.push_back(l); } return true; } } #endif // 2.9.x _x_gave_labelling = false; double labelling_value = 0.0; if (_nword > 6 && (!strcmp(_word[_nword - 2], "labelling") || !strcmp(_word[_nword - 2], "labeling"))) { if (_xtype == gr_axis_LOG) { err("cannot use a 'labelling' value with a logarithmic axis"); return false; } if (!getdnum(_word[_nword - 1], &labelling_value)) { READ_WORD_ERROR("labelling .labelling_value."); return false; } _x_gave_labelling = true; _nword -= 2; // gobble last two words } if (!strcmp(_word[_nword - 1], "bottom")) { _xatbottom = true; if (_nword == 4) { _need_x_axis = true; _need_y_axis = true; return true; } _nword--; } else if (!strcmp(_word[_nword - 1], "top")) { _xatbottom = false; if (_nword == 4) { _need_x_axis = true; _need_y_axis = true; return true; } _nword--; } else if (_nword == 4 && !strcmp(_word[_nword - 1], "increasing")) { _xincreasing = true; if (_xscale_exists && _xleft > _xright) { swap(_xleft, _xright); _xinc = -fabs(_xinc); _x_labelling = _x_gave_labelling ? labelling_value : _xleft; // FIXME PUT_VAR("..xleft..", _xleft); PUT_VAR("..xright..", _xright); PUT_VAR("..xinc..", _xinc); PUT_VAR("..xlabelling..", _x_labelling); } return true; } else if (_nword == 4 && !strcmp(_word[_nword - 1], "decreasing")) { _xincreasing = false; if (_xscale_exists && _xleft < _xright) { swap(_xleft, _xright); _xinc = fabs(_xinc); _x_labelling = _x_gave_labelling ? labelling_value : _xleft; PUT_VAR("..xleft..", _xleft); PUT_VAR("..xright..", _xright); PUT_VAR("..xinc..", _xinc); PUT_VAR("..xlabelling..", _x_labelling); } return true; } else if (_nword == 4 && !strcmp(_word[_nword - 1], "unknown")) { _xscale_exists = false; _need_x_axis = true; _user_set_x_axis = false; return true; } // ... specifying x axis // 'set x axis .left. .right.' if (_nword == 5) { if (!getdnum(_word[3], &xleft) || !getdnum(_word[4], &xright)) { READ_WORD_ERROR(".left. and .right."); return false; } if (_xtype == gr_axis_LOG) { Require(xleft > 0.0, err("`set x axis .left. .right.' cannot have non-positive .left. value for logarithmic axis")); Require(xright > 0.0, err("`set x axis .left. .right.' cannot have non-positive .right. value for logarithmic axis")); } _xleft = xleft; _xright = xright; if (_xtype == gr_axis_LOG) _xinc = 1.0; else _xinc = _xright - _xleft; _x_labelling = _x_gave_labelling ? labelling_value : _xleft; PUT_VAR("..xleft..", _xleft); PUT_VAR("..xright..", _xright); PUT_VAR("..xinc..", _xinc); PUT_VAR("..xlabelling..", _x_labelling); _xsubdiv = 1; _xscale_exists = true; _need_x_axis = true; _need_y_axis = true; _user_set_x_axis = true; return true; } else if (_nword == 6) { // 'set x axis .left. .right. .inc.' if (!getdnum(_word[3], &xleft) || !getdnum(_word[4], &xright) || !getdnum(_word[5], &xinc)) { // 'set x axis .left. .right. .incBig.' READ_WORD_ERROR(".left. .right. .incBig."); return false; } Require(well_ordered(xleft, xright, xinc), err("`set x axis .left. .right. .incBig.' has .incBig. of wrong sign")); SUGGEST(inc_within_range(xleft, xright, xinc), warning("`set x axis .left. .right. .incBig.' has .incBig. that goes outside range")); if (_xtype == gr_axis_LOG) { Require(xleft > 0.0, err("`set x axis .left. .right. .incBig.' cannot have non-positive .left. value for logarithmic axis")); Require(xright > 0.0, err("`set x axis .left. .right. .incBig.' cannot have non-positive .right. value for logarithmic axis")); Require(xinc > 0.0, err("`set x axis .left. .right. .incBig.' cannot have non-positive .incBig. value for logarithmic axis")); } _xleft = xleft; _xright = xright; if (_xtype == gr_axis_LOG) { _xinc = xinc; _xsubdiv = 1; } else { _xinc = xinc; _xsubdiv = 1; } _x_labelling = _x_gave_labelling ? labelling_value : _xleft; PUT_VAR("..xleft..", _xleft); PUT_VAR("..xright..", _xright); PUT_VAR("..xinc..", _xinc); PUT_VAR("..xlabelling..", _x_labelling); _xscale_exists = true; _need_x_axis = true; _need_y_axis = true; _user_set_x_axis = true; return true; } else if (_nword == 7) { // 'set x axis .left. .right. .incBig. .incSml.' if (!getdnum(_word[3], &xleft) || !getdnum(_word[4], &xright) || !getdnum(_word[5], &xinc) || !getdnum(_word[6], &tmp)) { READ_WORD_ERROR(".left. .right. .incBig. .incSml."); return false; } Require(well_ordered(xleft, xright, xinc), err("`set x axis .left. .right. .incBig. .incSml.' has .incBig. of wrong sign")); if (_xtype == gr_axis_LOG) { Require(xleft > 0.0, err("`set x axis .left. .right. .incBig. .incSml.' cannot have non-positive .left. value for logarithmic axis")); Require(xright > 0.0, err("`set x axis .left. .right. .incBig. .incSml.' cannot have non-positive .right. value for logarithmic axis")); Require(xinc > 0.0, err("`set x axis .left. .right. .incBig. .incSml.' cannot have non-positive .incBig. value for logarithmic axis")); } SUGGEST(inc_within_range(xleft, xright, xinc), warning("`set x axis .left. .right. .incBig.' has .incBig. that goes outside range")); _xleft = xleft; _xright = xright; if (_xtype == gr_axis_LOG) { _xinc = xinc; _xsubdiv = (tmp > 0) ? 1 : -1; } else { _xinc = xinc; _xsubdiv = int(floor(0.5 + fabs((double) (xinc / tmp)))); } _x_labelling = _x_gave_labelling ? labelling_value : _xleft; PUT_VAR("..xleft..", _xleft); PUT_VAR("..xright..", _xright); PUT_VAR("..xinc..", _xinc); PUT_VAR("..xlabelling..", _xleft); _xscale_exists = true; _need_x_axis = true; _need_y_axis = true; _user_set_x_axis = true; return true; } else if (_nword == 8) { // 'set x axis .left. .right. .inc. labelling .xlabelling.' printf("HERE have 8 words\n"); } else { err("`set x axis' may have only 2, 3 or 4 parameters"); return false; } _user_set_x_axis = true; return true; } bool set_x_formatCmd() { if (_nword < 4) { err("Must specify a format for `set x format'"); return false; } if (!strcmp(_word[3], "off")) { _xFmt.assign(""); } else if (!strcmp(_word[3], "default")){ _xFmt.assign(X_FMT_DEFAULT); } else { if (*_word[3] == '"') { int len = strlen(_word[3]); if (len <= 1) { _xFmt.assign(X_FMT_DEFAULT); } else { if (*(_word[3] + len - 1) == '"') _xFmt.assign(_word[3] + 1, len - 2); else _xFmt.assign(_word[3] + 1, len - 1); } } else { _xFmt.assign(_word[3]); } } return true; } bool set_x_gridCmd() { double x, xmin, xmax, xinc; int i, nx; // get numbers if (_nword != 6 && _nword != 7) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } Require(getdnum(_word[3], &xmin), READ_WORD_ERROR(".xmin.")); Require(getdnum(_word[4], &xmax), READ_WORD_ERROR(".xmax.")); if (*_word[5] == '/') { // kludge in case previous parsing didn't separate / from last number if (_nword == 6) { Require(getdnum(1 + _word[5], &xinc), err("Can't read /.numx.")); } else if (_nword == 7) { Require(getdnum(_word[6], &xinc), err("Can't read /.numx.")); } else { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } Require(xinc >= 1.9, err("Bad /.x.; need >1")); nx = (int) floor(0.5 + xinc); // redefined below, using xinc xinc = (xmax - xmin) / (nx - 1); } else { Require(getdnum(_word[5], &xinc), READ_WORD_ERROR(".xinc.")); } // check for stupidity Require(xinc != 0.0, err("Can't have .xinc.=0")); Require(xmin != xmax, err("Can't have .xmin. = .xmax.")); Require(well_ordered(xmin, xmax, xinc), err("`set x grid .xmin. .xmax. .xinc.' has .xinc. of wrong sign")); SUGGEST(inc_within_range(xmin, xmax, xinc), warning("`set x grid .xmin. .xmax. .xinc.' has .xinc. that goes outside range")); nx = int(floor(1.5 + fabs((double) ((xmax - xmin) / xinc)))); Require(nx > 0, err(".xinc. too big")); // check against existing matrix if (_grid_exists == true && nx != (int)_num_xmatrix_data) { sprintf(_errorMsg, "# intervals %d disagrees with existing grid size %d", nx, _num_xmatrix_data); err(_errorMsg); return false; } // get storage space Require(allocate_xmatrix_storage(nx), err("Insufficient space for grid x data")); // set up x grid for (i = 0, x = xmin; i < nx; i++, x += xinc) _xmatrix[i] = x; // Use grid for axis scale, if the latter does not exist yet if (!_xscale_exists) { _xleft = xmin; _xright = xmax; _xinc = xinc; _xscale_exists = true; //printf("creating x scale %f to %f by %f\n",_xleft, _xright, _xinc); } // Override any existing scale define_image_scales(_xmatrix[0], 0.0, _xmatrix[nx - 1], 0.0); _xgrid_exists = true; if (_xmatrix[1] > _xmatrix[0]) _xgrid_increasing = true; else _xgrid_increasing = false; return true; } // end set_x_gridCmd() bool set_y_gridCmd() { double y, ymin, ymax, yinc; int i, ny; if (_nword != 6 && _nword != 7) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (!getdnum(_word[3], &ymin)) { demonstrate_command_usage(); READ_WORD_ERROR(".ymin."); return false; } if (!getdnum(_word[4], &ymax)) { demonstrate_command_usage(); READ_WORD_ERROR(".ymax."); return false; } if (*_word[5] == '/') { // kludge in case previous parsing didn't separate / from last number if (_nword == 6) { Require(getdnum(1 + _word[5], &yinc), err("Can't read /.numy.")); } else if (_nword == 7) { Require(getdnum(_word[6], &yinc), err("Can't read /.numy.")); } else { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } Require(yinc >= 1.9, err("Bad /.y.; need >1")); ny = int(floor(0.5 + yinc)); yinc = (ymax - ymin) / (yinc - 1); } else { if (!getdnum(_word[5], &yinc)) { demonstrate_command_usage(); READ_WORD_ERROR(".yinc."); return false; } } // check for stupidity Require(yinc != 0.0, err("Can't have .yinc.=0")); Require(ymin != ymax, err("Can't have .ymin.=.ymax.")); Require(well_ordered(ymin, ymax, yinc), err("`set y grid .ymin. .ymax. .yinc.' has .yinc. of wrong sign")); SUGGEST(inc_within_range(ymin, ymax, yinc), warning("`set y grid .ymin. .ymax. .yinc.' has .yinc. that goes outside range")); ny = 1 + int(floor(0.5 + fabs((double) ((ymax - ymin) / yinc)))); Require(ny > 0, err(".yinc. too big")); // check against existing matrix if (_grid_exists == true && ny != int(_num_ymatrix_data)) { demonstrate_command_usage(); sprintf(_errorMsg, "# intervals %d disagrees with existing grid %d", ny, _num_ymatrix_data); err(_errorMsg); return false; } // get storage space Require(allocate_ymatrix_storage(ny), err("Insufficient space for grid y data.")); // set up y grid for (i = 0, y = ymin; i < ny; i++, y += yinc) _ymatrix[i] = y; // Use grid for axis scale, if the latter does not exist yet if (!_yscale_exists) { _ybottom = ymin; _ytop = ymax; _yinc = yinc; _yscale_exists = true; //printf("creating y scale %f to %f by %f\n",_ybottom, _ytop, _yinc); } // Override any existing scale define_image_scales(0.0, _ymatrix[0], 0.0, _ymatrix[ny - 1]); _ygrid_exists = true; if (_ymatrix[1] > _ymatrix[0]) _ygrid_increasing = true; else _ygrid_increasing = false; return true; } // end set_y_gridCmd() bool set_x_marginCmd() { if (_nword == 4) { if (!strcmp(_word[3], "default")) { tmp = XMARGIN_DEFAULT; PUT_VAR("..xmargin..", tmp); _need_x_axis = true; _need_y_axis = true; return true; } if (!getdnum(_word[3], &tmp)) { err("Can't understand `set x margin' parameter."); return false; } PUT_VAR("..xmargin..", tmp); _need_x_axis = true; _need_y_axis = true; return true; } else if (_nword == 5) { double old = 0.0; if (!strcmp(_word[3], "bigger")) { if (!getdnum(_word[4], &tmp)) { err("can't understand `set x margin bigger' parameter"); return false; } get_var("..xmargin..", &old); tmp = old + tmp; PUT_VAR("..xmargin..", tmp); _need_x_axis = true; _need_y_axis = true; return true; } else if (!strcmp(_word[3], "smaller")) { if (!getdnum(_word[4], &tmp)) { err("can't understand `set x margin smaller' parameter"); return false; } get_var("..xmargin..", &old); tmp = old - tmp; PUT_VAR("..xmargin..", tmp); _need_x_axis = true; _need_y_axis = true; return true; } else { err("bad `set x margin' parameter\nvalid list: bigger/smaller"); return false; } } else { err("Must specify margin in cm"); return false; } } bool set_x_nameCmd() { Require(_nword > 3, err("Must specify a name")); if (word_is(3, "default")) { _colX.setName("x"); } else { std::string unquoted; int status = ExtractQuote(_cmdLine, unquoted); if (status == 0) { err("`set x name' needs a double-quoted string"); return false; } if (status < 0) { err("`set x name' found starting double-quote but no ending double-quote"); return false; } _colX.setName(unquoted.c_str()); } return true; } // set_x_sizeCmd() -- set width of plot bool set_x_sizeCmd() { if (_nword != 4) { err("Must specify axis length in cm"); return false; } if (!strcmp(_word[3], "default")) { tmp = XSIZE_DEFAULT; PUT_VAR("..xsize..", tmp); _need_x_axis = true; _need_y_axis = true; return true; } Require(getdnum(_word[3], &tmp), READ_WORD_ERROR(".width_cm.")); Require(tmp >= 0.0, err("ignoring bad xsize <0")); PUT_VAR("..xsize..", tmp); _need_x_axis = true; _need_y_axis = true; return true; } bool set_y_axisCmd() { _yatleft = true; #if 1 // 2.9.x if (word_is(3, "labels")) { if (word_is(4, "automatic")) { _y_labels.erase(_y_labels.begin(), _y_labels.end()); _y_label_positions.erase(_y_label_positions.begin(), _y_label_positions.end()); return true; } else { unsigned int start = 4; if (word_is(start, "add")) { start++; } else { _y_labels.erase(_y_labels.begin(), _y_labels.end()); _y_label_positions.erase(_y_label_positions.begin(), _y_label_positions.end()); } for (unsigned int i = start; i < _nword; i++) { double tmp; if (!getdnum(_word[i], &tmp)) { READ_WORD_ERROR(".pos."); demonstrate_command_usage(); return false; } _y_label_positions.push_back(tmp); if (i++ == _nword - 1) { err("Missing label to be applied at position \\", _word[i-1], "\\"); demonstrate_command_usage(); return false; } std::string l = _word[i]; un_double_quote(l); _y_labels.push_back(l); } return true; } } #endif // 2.9.x _y_gave_labelling = false; double labelling_value = 0.0; if (_nword > 6 && (!strcmp(_word[_nword - 2], "labelling") || !strcmp(_word[_nword - 2], "labeling"))) { if (_ytype == gr_axis_LOG) { err("cannot use a 'labelling' value with a logarithmic axis"); return false; } if (!getdnum(_word[_nword - 1], &labelling_value)) { READ_WORD_ERROR("labelling .labelling_value."); return false; } _y_gave_labelling = true; _nword -= 2; // gobble last two words } if (!strcmp(_word[_nword - 1], "left")) { _yatleft = true; if (_nword == 4) { _need_x_axis = true; _need_y_axis = true; return true; } _nword--; } else if (!strcmp(_word[_nword - 1], "right")) { _yatleft = false; if (_nword == 4) { _need_x_axis = true; _need_y_axis = true; return true; } _nword--; } else if (_nword == 4 && !strcmp(_word[_nword - 1], "increasing")) { _yincreasing = true; if (_yscale_exists && _ybottom > _ytop) { double tmp = _ybottom; _ybottom = _ytop; _ytop = tmp; _yinc = -_yinc; _y_labelling = _y_gave_labelling ? labelling_value : _ybottom; PUT_VAR("..ybottom..", _ybottom); PUT_VAR("..ytop..", _ytop); PUT_VAR("..yinc..", _yinc); PUT_VAR("..ylabelling..", _y_labelling); } return true; } else if (_nword == 4 && !strcmp(_word[_nword - 1], "decreasing")) { _yincreasing = false; if (_yscale_exists && _ybottom < _ytop) { double tmp = _ybottom; _ybottom = _ytop; _ytop = tmp; _yinc = -_yinc; _y_labelling = _y_gave_labelling ? labelling_value : _ybottom; PUT_VAR("..ybottom..", _ybottom); PUT_VAR("..ytop..", _ytop); PUT_VAR("..yinc..", _yinc); PUT_VAR("..ylabelling..", _y_labelling); } return true; } else if (_nword == 4 && !strcmp(_word[_nword - 1], "unknown")) { _yscale_exists = false; _need_y_axis = true; _user_set_y_axis = false; return true; } // set y axis name ... if (_nword == 5 && word_is(3, "name")) { set_y_axis_nameCmd(); return true; } if (_nword == 5 && word_is(3, "label")) { //printf("YA YA YA %f %f %d\n",_version,_version_expected,gri_version_exceeds(2,8,99)); if (gri_version_exceeds(2, 8, 99)) { if (_version_expected != 0 && _version_expected < 2.0899) { warning("Using compatibility mode, interpreting `set y axis label'\n as if it were the newly-named command `set y axis name'."); set_y_axis_nameCmd(); return true; } else { err("The `set y axis label' command is no longer available.\n Please use `set y axis name' instead, or use the `expecting'\n command with a version number lower than 2.9.0, to get\n backwards compatability."); return false; } } else { set_y_axis_nameCmd(); return true; } } // ... specifying y axis if (_nword == 5) { // set y axis .bottom. .top. if (!getdnum(_word[3], &ybottom) || !getdnum(_word[4], &ytop)) { err("can't understand parameters"); return false; } if (_ytype == gr_axis_LOG) { Require(ybottom > 0.0, err("`set y axis .bottom. .top.' cannot have non-positive .bottom. value for logarithmic axis")); Require(ytop > 0.0, err("`set y axis .bottom. .top.' cannot have non-positive .top. value for logarithmic axis")); } _ybottom = ybottom; _ytop = ytop; if (_ytype == gr_axis_LOG) _yinc = 1.0; else _yinc = _ytop - _ybottom; _y_labelling = _y_gave_labelling ? labelling_value : _ybottom; PUT_VAR("..ybottom..", _ybottom); PUT_VAR("..ytop..", _ytop); PUT_VAR("..yinc..", _yinc); PUT_VAR("..ylabelling..", _y_labelling); _ysubdiv = 1; _yscale_exists = true; _need_x_axis = true; _need_y_axis = true; reset_top_of_plot(); _user_set_y_axis = true; return true; } else if (_nword == 6) { // set y axis .bottom. .top. .incBig. if (!getdnum(_word[3], &ybottom) || !getdnum(_word[4], &ytop) || !getdnum(_word[5], &yinc)) { err("can't understand parameters"); return false; } Require(well_ordered(ybottom, ytop, yinc), err("`set y axis .bottom. .top. .incBig.' has .incBig. of wrong sign")); if (_ytype == gr_axis_LOG) { Require(ybottom > 0.0, err("`set y axis .bottom. .top. .incBig.' cannot have non-positive .bottom. value for logarithmic axis")); Require(ytop > 0.0, err("`set y axis .bottom. .top. .incBig.' cannot have non-positive .top. value for logarithmic axis")); Require(yinc > 0.0, err("`set y axis .bottom. .top. .incBig.' cannot have non-positive .incBig. value for logarithmic axis")); } SUGGEST(inc_within_range(ybottom, ytop, yinc), warning("`set y axis .bottom. .top. .incBig.' has .incBig. that goes outside range")); _ybottom = ybottom; _ytop = ytop; if (_ytype == gr_axis_LOG) { _yinc = yinc; _ysubdiv = 1; } else { _yinc = yinc; _ysubdiv = 1; } _y_labelling = _y_gave_labelling ? labelling_value : _ybottom; PUT_VAR("..ybottom..", _ybottom); PUT_VAR("..ytop..", _ytop); PUT_VAR("..yinc..", _yinc); PUT_VAR("..ylabelling..", _y_labelling); _yscale_exists = true; _need_x_axis = true; _need_y_axis = true; reset_top_of_plot(); _user_set_y_axis = true; return true; } else if (_nword == 7) { // 'set y axis .bottom. .top. .incBig. .incSml.' if (!getdnum(_word[3], &ybottom) || !getdnum(_word[4], &ytop) || !getdnum(_word[5], &yinc) || !getdnum(_word[6], &tmp)) { err("can't understand parameters"); return false; } Require(well_ordered(ybottom, ytop, yinc), err("`set y axis .bottom. .top. .incBig. .incSml.' has .incBig. of wrong sign")); if (_ytype == gr_axis_LOG) { Require(ybottom > 0.0, err("`set y axis .bottom. .top. .incBig. .incSml.' cannot have non-positive .bottom. value for logarithmic axis")); Require(ytop > 0.0, err("`set y axis .bottom. .top. .incBig. .incSml.' cannot have non-positive .top. value for logarithmic axis")); Require(yinc > 0.0, err("`set y axis .bottom. .top. .incBig. .incSml.' cannot have non-positive .incBig. value for logarithmic axis")); } SUGGEST(inc_within_range(ybottom, ytop, yinc), warning("`set y axis .bottom. .top. .incBig.' has .incBig. that goes outside range")); _ybottom = ybottom; _ytop = ytop; if (_ytype == gr_axis_LOG) { _yinc = yinc; _ysubdiv = (tmp > 0) ? 1 : -1; } else { _yinc = yinc; _ysubdiv = int(floor(0.5 + fabs((double) (yinc / tmp)))); } _y_labelling = _y_gave_labelling ? labelling_value : _ybottom; PUT_VAR("..ybottom..", _ybottom); PUT_VAR("..ytop..", _ytop); PUT_VAR("..yinc..", _yinc); PUT_VAR("..ylaelled..", _y_labelling); _yscale_exists = true; _need_x_axis = true; _need_y_axis = true; reset_top_of_plot(); _user_set_y_axis = true; return true; } else { //printf("_nword=%d\n",_nword); dandandan err("`set y axis' may have only 2, 3 or 4 parameters"); return false; } _user_set_y_axis = true; return true; } bool set_y_axis_nameCmd() { if (_nword == 5 && !strcmp(_word[3], "label")) { // Syntax prior to version 2.9.0 if (!strcmp(_word[4], "horizontal")) gr_setyaxisstyle(1); else if (!strcmp(_word[4], "vertical")) gr_setyaxisstyle(0); else { err("`set y axis name' expecting 'horizontal' or 'vertical', but got `\\", _word[4], "'", "\\"); demonstrate_command_usage(); return false; } } else if (_nword == 5 && !strcmp(_word[3], "name")) { // From version 2.9.0 onwards if (!strcmp(_word[4], "horizontal")) gr_setyaxisstyle(1); else if (!strcmp(_word[4], "vertical")) gr_setyaxisstyle(0); else { err("`set y axis name' expecting 'horizontal' or 'vertical', but got `\\", _word[4], "'", "\\"); demonstrate_command_usage(); return false; } } return true; } bool set_y_formatCmd() { Require(_nword > 3, err("Must specify a format for `set y format'")); if (!strcmp(_word[3], "off")) { _yFmt.assign(""); } else if (!strcmp(_word[3], "default")){ _yFmt.assign(Y_FMT_DEFAULT); } else { if (*_word[3] == '"') { int len = strlen(_word[3]); if (len <= 1) { _yFmt.assign(Y_FMT_DEFAULT); } else { if (*(_word[3] + len - 1) == '"') _yFmt.assign(_word[3] + 1, len - 2); else _yFmt.assign(_word[3] + 1, len - 1); } } else { _yFmt.assign(_word[3]); } } return true; } bool set_y_marginCmd() { if (_nword == 4) { if (!strcmp(_word[3], "default")) { tmp = YMARGIN_DEFAULT; PUT_VAR("..ymargin..", tmp); _need_x_axis = true; _need_y_axis = true; reset_top_of_plot(); return true; } Require(getdnum(_word[3], &tmp), err("can't understand `set y margin' parameter")); PUT_VAR("..ymargin..", tmp); _need_x_axis = true; _need_y_axis = true; reset_top_of_plot(); return true; } else if (_nword == 5) { double old = 0.0; if (!strcmp(_word[3], "bigger")) { Require(getdnum(_word[4], &tmp), err("can't understand `set y margin bigger' parameter")); get_var("..ymargin..", &old); tmp = old + tmp; PUT_VAR("..ymargin..", tmp); _need_x_axis = true; _need_y_axis = true; reset_top_of_plot(); return true; } else if (!strcmp(_word[3], "smaller")) { Require(getdnum(_word[4], &tmp), err("can't understand `set y margin smaller' parameter")); get_var("..ymargin..", &old); tmp = old - tmp; PUT_VAR("..ymargin..", tmp); _need_x_axis = true; _need_y_axis = true; reset_top_of_plot(); return true; } else { err("bad `set y margin' parameter\nvalid list: bigger/smaller"); return false; } } else { err("Must specify margin in cm"); return false; } } bool set_y_nameCmd() { Require(_nword > 3, err("Must specify a name")); if (word_is(3, "default")) { _colY.setName("y"); } else { std::string unquoted; int status = ExtractQuote(_cmdLine, unquoted); if (status == 0) { err("`set y name' needs a double-quoted string"); return false; } if (status < 0) { err("`set y name' found starting double-quote but no ending double-quote"); return false; } _colY.setName(unquoted.c_str()); } return true; } // set_y_sizeCmd() -- store height of plot bool set_y_sizeCmd() { Require(_nword == 4, err("Must specify axis length in cm")); if (!strcmp(_word[3], "default")) { tmp = YSIZE_DEFAULT; PUT_VAR("..ysize..", tmp); reset_top_of_plot(); _need_x_axis = true; _need_y_axis = true; return true; } Require(getdnum(_word[3], &tmp), READ_WORD_ERROR(".height_cm.")); Require (tmp >= 0.0, err("ignoring bad ysize <0")); PUT_VAR("..ysize..", tmp); reset_top_of_plot(); _need_x_axis = true; _need_y_axis = true; return true; } // Possible calls are as follows; code below may // be in a different order though! // Type 1. \syn = word .n. of "string" // Type 2. \syn = system ... // Type 3. \syn = tmpname #if 0 // Type 4. \syn = &.a_var. // Type 5. \syn = &\a_syn #endif // Type 6. \syn = "string" bool assign_synonym() { #if 0 printf("DEBUG %s:%d in assign_synonym. words: ", __FILE__,__LINE__); for (unsigned int iw = 0; iw < _nword; iw++) printf("<%s> ", _word[iw]); printf("\n"); #endif Require (_nword > 2, err("Can't understand command.")); if (!strncmp(_word[0], "\\@", 2)) { err("The purported alias `\\", _word[0], "' doesn't name any known variable or synonym.", "\\"); return false; } // If assigning as e.g. // \.word1. = 10 // \.word1. = "hi" // then see if the calling-arg was a var/syn with an & to the left if (!strncmp(_word[0], "\\.word", 6) && *(_word[0] + strlen(_word[0]) - 1) == '.') { //printf("DEBUG %s:%d ASSIGNING to word[0] as '%s'\n",__FILE__,__LINE__,_word[0]); std::string value; if (!get_syn(_word[0], value, false)) { err("Cannot access \\.word0. synonym"); return false; } //printf("DEBUG %s:%d value of '%s' is '%s'\n",__FILE__,__LINE__,_word[0],value.c_str()); std::string coded_name; int coded_level = -1; if (is_coded_string(value, coded_name, &coded_level)) { //printf("DEBUG %s:%d '%s' was encoded `%s' at level %d\n",__FILE__,__LINE__, _word[0], coded_name.c_str(), coded_level); if (coded_name.c_str()[0] == '.') { int index = index_of_variable(coded_name.c_str(), coded_level); //printf("DEBUG %s:%d A VAR ... index %d. to assign '%s'\n",__FILE__,__LINE__,index,_word[2]); if (index < 0) { err("Cannot assign to non-existing variable `", coded_name.c_str(), "' as inferred from coded word `", value.c_str(), "'.", "\\"); return false; } double rhs; if (!getdnum(_word[2], &rhs)) { err("cannot assign `", _word[2], "' to variable `", coded_name.c_str(), "'.", "\\"); return false; } if (!strcmp(_word[1], "=")) { variableStack[index].set_value(rhs); } else { double oldValue = variableStack[index].get_value(); if (strEQ(_word[1], "*=")) variableStack[index].set_value(oldValue * rhs); else if (strEQ(_word[1], "/=")) variableStack[index].set_value(oldValue / rhs); else if (strEQ(_word[1], "+=")) variableStack[index].set_value(oldValue +rhs); else if (strEQ(_word[1], "-=")) variableStack[index].set_value(oldValue - rhs); else if (strEQ(_word[1], "^=")) variableStack[index].set_value(pow(oldValue, rhs)); else if (strEQ(_word[1], "_=")) { if (oldValue < 0.0) variableStack[index].set_value(gr_currentmissingvalue()); else variableStack[index].set_value(log(oldValue) / log(rhs)); } else { err("`\\", _word[1], "' is not a known operator for variables", "'\\"); return false; } } } else if (coded_name.c_str()[0] == '\\') { int index = index_of_synonym(coded_name.c_str(), coded_level); //printf("DEBUG %s:%d '%s' is syn index %d\n",__FILE__,__LINE__, coded_name.c_str(), index); std::string unquoted; int status = ExtractQuote(_word[2], unquoted); if (status == 0) { err("`\\synonym = \"value\" found no double-quoted string"); return false; } //printf("BEFORE trying to insert at position %d.\n",index); //show_syn_stack(); synonymStack[index].set_value(unquoted.c_str()); //printf("AFTER.\n"); //show_syn_stack(); } else { err("Internal error in decoding &\\.word?. for assignment"); return false; } return true; } } #if 0 // Check for e.g // \syn = &.a_var. // \syn = &\a_syn if (_nword == 3 && *_word[2] == '&') { const char *name = 1 + _word[2]; //printf("DEBUG %s:%d GOT A & and think name is <%s>\n",__FILE__,__LINE__,name); char coded_pointer[200]; // BUG: should be big enough. Jeeze! if (is_var(name)) { //printf("DEBUG: %s:%d & on a var named <%s>\n",__FILE__,__LINE__,name); int the_index = index_of_variable(name); sprintf(coded_pointer, "\\#v%d#", int(variablePointer.size())); //printf("DEBUG %s:%d pushing back %d into position %d of variablePointer list\n",__FILE__,__LINE__,the_index,int(variablePointer.size())); variablePointer.push_back(the_index); Require(put_syn(_word[0], coded_pointer, true), err("Cannot store synonym `\\", _word[0], "'", "\\")); } else if (is_syn(name)) { //printf("DEBUG: %s:%d & on a syn named <%s>\n",__FILE__,__LINE__,name); int the_index = index_of_synonym(name); //printf("DEBUG %s:%d pushing back %d into position %d of synonymPointer list\n",__FILE__,__LINE__,the_index,int(synonymPointer.size())); sprintf(coded_pointer, "\\#s%d#", int(synonymPointer.size())); synonymPointer.push_back(the_index); Require(put_syn(_word[0], coded_pointer, true), err("Cannot store synonym `\\", _word[0], "'", "\\")); return true; } else { err("Cannot do '&' unless item to right is name of variable or synonym"); return false; } return true; } #endif // Following check should never be needed, but keep for possible future // changes. Require(is_syn(_word[0]), err("`\\", _word[0], "' must begin with `\\'", "\\")); // `\synonym = word .n. of "string"' if (_nword == 6 && !strcmp(_word[1], "=") && !strcmp(_word[2], "word") && !strcmp(_word[4], "of")) { double tmp; if (!getdnum(_word[3], &tmp)) { READ_WORD_ERROR(".n. in e.g. `\\syn = word .n. of \"string\"'"); return false; } int iwhich = int(floor(0.5 + tmp)); if (iwhich < 0) { err("Cannot take a negatively-indexed word"); return false; } unsigned int which = (unsigned int)(iwhich); std::string to_chop(_word[_nword - 1]); if (to_chop[0] == '"') to_chop.STRINGERASE(0, 1); if (to_chop[to_chop.size() - 1] == '"') { to_chop.STRINGERASE(to_chop.size() - 1, 1); } else { err("`\\syn = word N of \"string\" requires closing double-quote (\") sign"); return false; } char *to_chop_in_C = strdup(to_chop.c_str()); if (to_chop_in_C == NULL) { err("Out of memory while trying to assign synonym as n-th word of string"); return false; } unsigned int max; chop_into_words(to_chop_in_C, _Words2, &max, MAX_nword); int i = strlen(_Words2[max - 1]); if (i > 2 && *(_Words2[max - 1] + i - 1) == '"') *(_Words2[max - 1] + i - 1) = '\0'; if (which > (max - 1)) { err("The string \n`\\", _word[_nword - 1], "'\ndoes not have that many words. NOTE: the first word is counted as 0.", "\\"); free(to_chop_in_C); return false; } Require(put_syn(_word[0], _Words2[which], true), err("Cannot store synonym `\\", _word[0], "'", "\\")); free(to_chop_in_C); return true; } else if (!strcmp(_word[1], "=") && !strcmp(_word[2], "tmpname")) { if (!put_syn(_word[0], tmp_file_name(), true)) gr_Error("Ran out of storage"); return true; } else if (!strcmp(_word[1], "=") && !strcmp(_word[2], "system")) { // `\synonym = system ...' #if !defined(HAVE_POPEN) err("\ This computer can't `\\synonym = system ...' since no popen() subroutine."); return false; #else FILE *pipefile; // Much of following code duplicated in sytemCmd(), so if any // problems crop up, check there too. char * s = _cmdLine; s += skip_space(s); // skip any initial space s += skip_nonspace(s); // skip first word "\syn" s += skip_space(s); // skip space s += skip_nonspace(s); // skip "=" s += skip_space(s); // skip space s += skip_nonspace(s); // skip "system" s += skip_space(s); // skip space if (*s == '\0' || *s == '\n') { err("`\\syn = system ...' needs a system command to do."); return false; } // See if last word starts with "<<"; if so, then the stuff to be done // appears on the lines following, ended by whatever word follows the // "<<". // ... compare doline.cc near line 510. int i = strlen(s) - 2; std::string read_until; bool using_read_until = false; while (--i) { if (!strncmp((s + i), "<<", 2)) { bool quoted_end_string = false; int spaces = 0; while (isspace(*(s + i + 2 + spaces))) { spaces++; } if (*(s + i + 2 + spaces) == '"') { spaces++; quoted_end_string = true; } read_until.assign(s + i + 2 + spaces); using_read_until = true; // trim junk from end of the 'read until' string std::string::size_type cut_at; if (quoted_end_string) cut_at = read_until.find("\""); else cut_at = read_until.find(" "); //printf("READING UNTIL '%s' ... i.e.\n", read_until.c_str()); if (cut_at != STRING_NPOS) read_until.STRINGERASE(cut_at, read_until.size() - cut_at); if (read_until.size() < 1) { err("`system ... < bsStack; if (bsStack.size() == 0) { if (((unsigned) superuser()) & FLAG_SYS)printf("DEBUG %s:%d GOBBLE from a file\n",__FILE__,__LINE__); while (get_command_line()) { if (((unsigned) superuser()) & FLAG_SYS)printf("DEBUG %s:%d cmd line is [%s]\n",__FILE__,__LINE__,_cmdLine); // Trim filename/fileline indicator unsigned int l = strlen(_cmdLine); for (unsigned int ii = 0; ii < l; ii++) { if (_cmdLine[ii] == PASTE_CHAR) { _cmdLine[ii] = '\0'; break; } } if (!strncmp(_cmdLine + skip_space(_cmdLine), read_until.c_str(), read_until.size())) { cmd.append(_cmdLine + skip_space(_cmdLine)); cmd.append("\n"); break; } cmd.append(_cmdLine); cmd.append("\n"); } std::string cmd_sub; substitute_synonyms_cmdline(cmd.c_str(), cmd_sub, false); cmd = cmd_sub; } else { extern unsigned int chars_read; extern unsigned int offset_for_read; extern bool get_line_in_block(const char *block, unsigned int *offset); unsigned int offset = offset_for_read + chars_read; if (((unsigned) superuser()) & FLAG_SYS)printf("DEBUG %s:%d GOBBLE from block source\n",__FILE__,__LINE__); while (get_line_in_block(bsStack.back().get_start(), &offset)) { if (((unsigned) superuser()) & FLAG_SYS)printf("DEBUG %s:%d cmd line is [%s]\n",__FILE__,__LINE__,_cmdLine); bsStack.back().move_offset(strlen(_cmdLine) + 1); chars_read += strlen(_cmdLine) + 1; if (!strncmp(_cmdLine + skip_space(_cmdLine), read_until.c_str(), read_until.size())) { cmd.append(_cmdLine + skip_space(_cmdLine)); cmd.append("\n"); break; } cmd.append(_cmdLine); cmd.append("\n"); } std::string cmd_sub; substitute_synonyms_cmdline(cmd.c_str(), cmd_sub, false); cmd = cmd_sub; } if (((unsigned) superuser()) & FLAG_SYS)printf("DEBUG %s:%d COMMAND START...\n%s\nDEBUG %s:%d ... COMMAND END\n",__FILE__,__LINE__,cmd.c_str(),__FILE__,__LINE__); #endif } else { // No, it is not of the < %d (%d=eof_after %d=eofbeforedata, %d=no_eof)\n",this_line.getValue(),s,eof_after_data,eof_before_data,no_eof); if (s == eof_before_data) break; result.append(this_line.getValue()); //printf("NOW <%s>\n",result.c_str()); } while (1); pclose(pipefile); while (result[result.size() - 1] == '\n') { //printf("ERASING newline at end ....\n"); result.STRINGERASE(result.size() - 1, 1); //printf("<%s>\n",result.c_str()); } //printf("final <%s>\n",result.c_str()); if (!put_syn(_word[0], result.c_str(), true)) OUT_OF_MEMORY; return true; } else { err("`\\", _word[0], " = system ...' can't access system", "\\"); return false; } #endif } else { // Type 6. \syn = "string" std::string unquoted; int status = ExtractQuote(_cmdLine, unquoted); if (status == 0) { err("`\\synonym = \"value\" found no double-quoted string"); return false; } if (status < 0) { err("`\\synonym = \"value\" found starting double-quote but no ending double-quote"); return false; } //printf("%s:%d raw <%s> became <%s>\n",__FILE__,__LINE__,_cmdLine,unquoted.c_str()); if (!put_syn(_word[0], unquoted.c_str(), true)) OUT_OF_MEMORY; } return true; } // `set "\\syn" to "STRING"' // `set ".var." to NUMBER' bool setCmd() { if (_nword != 4) { NUMBER_WORDS_ERROR; return false; } if (strNE(_word[2], "to")) { demonstrate_command_usage(); err("Third word must be `to', not `\\", _word[2], "' as given.", "\\"); return false; } std::string name(_word[1]); clean_blanks_quotes(name); //printf("<%s> ... <%s>>\n", _word[1], name.c_str()); if (is_var(name.c_str())) { double value; if (!getdnum(_word[3], &value)) { demonstrate_command_usage(); err("Cannot interpret `\\", _word[3], "' as a numerical value.", "\\"); return false; } PUT_VAR(name.c_str(), value); } else if (is_syn(name.c_str())) { std::string value(_word[3]); if (value.size() < 2 || (value[0] != '"' || value[-1 + value.size()] != '"')) { demonstrate_command_usage(); err("Need a double-quoted string to set the synonym to"); return false; } value.STRINGERASE(0, 1); value.STRINGERASE(-1 + value.size(), 1); put_syn(name.c_str(), value.c_str(), true); //printf("Assigned '%s' to synonym named '%s'\n", value.c_str(), name.c_str()); } else { demonstrate_command_usage(); err("Second word must be a variable name or a double-backslashed synonym name, in double quotes, not `\\", name.c_str(), "' as given.", "\\"); return false; } return true; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/ignore.cc�����������������������������������������������������������������������������������0000644�0001750�0001750�00000005020�13147557614�012376� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include "extern.hh" static bool reduce_columns(unsigned int n); bool ignoreCmd() { double tmp; if (_nword != 3) { err("Proper syntax 'ignore last n'"); return false; } if (!strcmp(_word[1], "last")) { if (!getdnum(_word[2], &tmp)) { err("Can't read n in 'ignore last n'"); return false; } if (tmp < 0) { err("Can't have n<0 in 'ignore last n'"); return false; } unsigned int n = unsigned(floor(0.5 + tmp)); return reduce_columns(n); } else { err("Proper syntax 'ignore last n'"); return false; } } static bool reduce_columns(unsigned int n) { if (!_columns_exist) { err("First 'read columns'"); return false; } if (n > 0) { if (_colX.size()) { if (_colX.size() >= n) { _colX.setDepth(_colX.size() - n); } else { err("Too few columns to do that"); return false; } } if (_colY.size()) { if (_colY.size() >= n) { _colY.setDepth(_colY.size() - n); } else { err("Too few columns to do that"); return false; } } if (_colZ.size()) { if (_colZ.size() >= n) { _colZ.setDepth(_colZ.size() - n); } else { err("Too few columns to do that"); return false; } } if (_colU.size()) { if (_colU.size() >= n) { _colU.setDepth(_colU.size() - n); } else { err("Too few columns to do that"); return false; } } if (_colV.size()) { if (_colV.size() >= n) { _colV.setDepth(_colV.size() - n); } else { err("Too few columns to do that"); return false; } } if (_colWEIGHT.size()) { if (_colWEIGHT.size() >= n) { _colWEIGHT.setDepth(_colWEIGHT.size() - n); } else { err("Too few columns to do that"); return false; } } } return true; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/main.cc�������������������������������������������������������������������������������������0000644�0001750�0001750�00000001641�13147557614�012044� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ extern int gri_main(int argc, char **argv); int main(int argc, char **argv) { return gri_main(argc, argv); } �����������������������������������������������������������������������������������������������gri/src/chopword.cc���������������������������������������������������������������������������������0000644�0001750�0001750�00000011153�13147557614�012744� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "gr.hh" // DESCRIPTION: Get words (stored in strings w[0], w[1], ...) // from string `s', finding at most 'max' words. Then // set 'nw' to number words read. // // IMPORTANT: input string `s' is destroyed in the process! // // RETURN VALUE: // 0 if everything is OK // 1 if a double-quoted item lacked a final double-quote // 2 if string has too many words for the w[] buffer. // // 1995-Feb-11: not using 'isspace' speeds by factor of 1.9, which // yields a 9% speedup in 'read grid data' with 55,000 elements. // 1999-Dec-15: permit TAB type separator // 2001-Feb-02: change to return error values int chop_into_words(char *s, char **w, unsigned int *nw, unsigned int max) { register char c, *cp; max--; cp = s; *nw = 0; if (*cp == '\0') return 0; // ok // Traverse s, getting pointers to words and terminating ends while (*nw < max) { // Skip space and tabs; break if done. while (*cp == ' ' || *cp == '\t' || *cp == '\n' || *cp == '\r') cp++; if (!*cp) break; // Now point to non-blank. Different actions depending on whether // it is a double-quoted string if (*cp == '"') { char last = *cp; w[*nw] = cp; // Collect until matching double-quote or end-of-string while (*++cp && !(*cp == '"' && last != '\\')) last = *cp; if (!*cp) { (*nw)++; return 1; } cp++; c = *cp; *cp++ = '\0'; (*nw)++; // increment number-of-words } else { // It's a word not beginning with `"' w[(*nw)++] = cp; while (*++cp && !(*cp == ' ' || *cp == '\t' || *cp == '\n' || *cp == '\r')) { ; // EMPTY } c = *cp; *cp++ = '\0'; } // Break if done if (!c) break; } #if 0 printf("chop_into_words set nw %d\n",*nw); for (int ii = 0; ii < *nw; ii++) printf("\tw[%d] is <%s>\n",ii,w[ii]); #endif if (*nw == max) return 2; // too many words for buffer return 0; // ok } // As above, but obey the separator from 'set input data separator' bool chop_into_data_words(char *s, char **w, unsigned int *nw, unsigned int max) { extern char _input_data_separator; if (_input_data_separator == ' ') { max--; char c; register char *cp = s; *nw = 0; if (*cp == '\0') return true; // Traverse s, getting pointers to words and terminating ends while (*nw < max) { // Skip space and tabs; break if done. while (*cp == ' ' || *cp == '\t' || *cp == '\n' || *cp == '\r') cp++; if (!*cp) break; // Now point to non-blank. Different actions depending on whether // it is a double-quoted string if (*cp == '"') { // It's a word beginning with `"'. Set word to point to first // character after the `"', and break the word at the last // character before the final `"'. Intermediate quotes may be // protected with a backslash; these are left in the word as \", // which must be removed later if needed. register char last = *cp; w[*nw] = cp; while (*++cp && !(*cp == '"' && last != '\\')) last = *cp; cp++; // save the quote c = *cp; *cp++ = '\0'; (*nw)++; // increment number-of-words } else { // It's a word not beginning with `"' w[(*nw)++] = cp; while (*++cp && !(*cp == ' ' || *cp == '\t' || *cp == '\n' || *cp == '\r')) { ; // EMPTY } c = *cp; *cp++ = '\0'; } // Break if done if (!c) break; } return true; } else if (_input_data_separator == '\t') { max--; // save <= below (is this faster or slower?) register char *cp = s; *nw = 0; if (*cp == '\0') return true; while (*nw < max) { w[(*nw)++] = cp; if (*cp == '\t') { *cp++ = '\0'; continue; } while (*++cp != '\0' && *cp != '\t') { ; // EMPTY } char c = *cp; *cp++ = '\0'; if (!c) break; } return true; } else { *nw = 0; return false; // huh?? } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/rgb.txt�������������������������������������������������������������������������������������0000644�0001750�0001750�00000044571�13147557614�012135� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # This file is not a part of Gri; it is from X11, and the # following copyright notice applies to this file: # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # X Window System is a trademark of X Consortium, Inc. # 255 250 250 snow 248 248 255 ghost white 248 248 255 GhostWhite 245 245 245 white smoke 245 245 245 WhiteSmoke 220 220 220 gainsboro 255 250 240 floral white 255 250 240 FloralWhite 253 245 230 old lace 253 245 230 OldLace 250 240 230 linen 250 235 215 antique white 250 235 215 AntiqueWhite 255 239 213 papaya whip 255 239 213 PapayaWhip 255 235 205 blanched almond 255 235 205 BlanchedAlmond 255 228 196 bisque 255 218 185 peach puff 255 218 185 PeachPuff 255 222 173 navajo white 255 222 173 NavajoWhite 255 228 181 moccasin 255 248 220 cornsilk 255 255 240 ivory 255 250 205 lemon chiffon 255 250 205 LemonChiffon 255 245 238 seashell 240 255 240 honeydew 245 255 250 mint cream 245 255 250 MintCream 240 255 255 azure 240 248 255 alice blue 240 248 255 AliceBlue 230 230 250 lavender 255 240 245 lavender blush 255 240 245 LavenderBlush 255 228 225 misty rose 255 228 225 MistyRose 255 255 255 white 0 0 0 black 47 79 79 dark slate gray 47 79 79 DarkSlateGray 47 79 79 dark slate grey 47 79 79 DarkSlateGrey 105 105 105 dim gray 105 105 105 DimGray 105 105 105 dim grey 105 105 105 DimGrey 112 128 144 slate gray 112 128 144 SlateGray 112 128 144 slate grey 112 128 144 SlateGrey 119 136 153 light slate gray 119 136 153 LightSlateGray 119 136 153 light slate grey 119 136 153 LightSlateGrey 190 190 190 gray 190 190 190 grey 211 211 211 light grey 211 211 211 LightGrey 211 211 211 light gray 211 211 211 LightGray 25 25 112 midnight blue 25 25 112 MidnightBlue 0 0 128 navy 0 0 128 navy blue 0 0 128 NavyBlue 100 149 237 cornflower blue 100 149 237 CornflowerBlue 72 61 139 dark slate blue 72 61 139 DarkSlateBlue 106 90 205 slate blue 106 90 205 SlateBlue 123 104 238 medium slate blue 123 104 238 MediumSlateBlue 132 112 255 light slate blue 132 112 255 LightSlateBlue 0 0 205 medium blue 0 0 205 MediumBlue 65 105 225 royal blue 65 105 225 RoyalBlue 0 0 255 blue 30 144 255 dodger blue 30 144 255 DodgerBlue 0 191 255 deep sky blue 0 191 255 DeepSkyBlue 135 206 235 sky blue 135 206 235 SkyBlue 135 206 250 light sky blue 135 206 250 LightSkyBlue 70 130 180 steel blue 70 130 180 SteelBlue 176 196 222 light steel blue 176 196 222 LightSteelBlue 173 216 230 light blue 173 216 230 LightBlue 176 224 230 powder blue 176 224 230 PowderBlue 175 238 238 pale turquoise 175 238 238 PaleTurquoise 0 206 209 dark turquoise 0 206 209 DarkTurquoise 72 209 204 medium turquoise 72 209 204 MediumTurquoise 64 224 208 turquoise 0 255 255 cyan 224 255 255 light cyan 224 255 255 LightCyan 95 158 160 cadet blue 95 158 160 CadetBlue 102 205 170 medium aquamarine 102 205 170 MediumAquamarine 127 255 212 aquamarine 0 100 0 dark green 0 100 0 DarkGreen 85 107 47 dark olive green 85 107 47 DarkOliveGreen 143 188 143 dark sea green 143 188 143 DarkSeaGreen 46 139 87 sea green 46 139 87 SeaGreen 60 179 113 medium sea green 60 179 113 MediumSeaGreen 32 178 170 light sea green 32 178 170 LightSeaGreen 152 251 152 pale green 152 251 152 PaleGreen 0 255 127 spring green 0 255 127 SpringGreen 124 252 0 lawn green 124 252 0 LawnGreen 0 255 0 green 127 255 0 chartreuse 0 250 154 medium spring green 0 250 154 MediumSpringGreen 173 255 47 green yellow 173 255 47 GreenYellow 50 205 50 lime green 50 205 50 LimeGreen 154 205 50 yellow green 154 205 50 YellowGreen 34 139 34 forest green 34 139 34 ForestGreen 107 142 35 olive drab 107 142 35 OliveDrab 189 183 107 dark khaki 189 183 107 DarkKhaki 240 230 140 khaki 238 232 170 pale goldenrod 238 232 170 PaleGoldenrod 250 250 210 light goldenrod yellow 250 250 210 LightGoldenrodYellow 255 255 224 light yellow 255 255 224 LightYellow 255 255 0 yellow 255 215 0 gold 238 221 130 light goldenrod 238 221 130 LightGoldenrod 218 165 32 goldenrod 184 134 11 dark goldenrod 184 134 11 DarkGoldenrod 188 143 143 rosy brown 188 143 143 RosyBrown 205 92 92 indian red 205 92 92 IndianRed 139 69 19 saddle brown 139 69 19 SaddleBrown 160 82 45 sienna 205 133 63 peru 222 184 135 burlywood 245 245 220 beige 245 222 179 wheat 244 164 96 sandy brown 244 164 96 SandyBrown 210 180 140 tan 210 105 30 chocolate 178 34 34 firebrick 165 42 42 brown 233 150 122 dark salmon 233 150 122 DarkSalmon 250 128 114 salmon 255 160 122 light salmon 255 160 122 LightSalmon 255 165 0 orange 255 140 0 dark orange 255 140 0 DarkOrange 255 127 80 coral 240 128 128 light coral 240 128 128 LightCoral 255 99 71 tomato 255 69 0 orange red 255 69 0 OrangeRed 255 0 0 red 255 105 180 hot pink 255 105 180 HotPink 255 20 147 deep pink 255 20 147 DeepPink 255 192 203 pink 255 182 193 light pink 255 182 193 LightPink 219 112 147 pale violet red 219 112 147 PaleVioletRed 176 48 96 maroon 199 21 133 medium violet red 199 21 133 MediumVioletRed 208 32 144 violet red 208 32 144 VioletRed 255 0 255 magenta 238 130 238 violet 221 160 221 plum 218 112 214 orchid 186 85 211 medium orchid 186 85 211 MediumOrchid 153 50 204 dark orchid 153 50 204 DarkOrchid 148 0 211 dark violet 148 0 211 DarkViolet 138 43 226 blue violet 138 43 226 BlueViolet 160 32 240 purple 147 112 219 medium purple 147 112 219 MediumPurple 216 191 216 thistle 255 250 250 snow1 238 233 233 snow2 205 201 201 snow3 139 137 137 snow4 255 245 238 seashell1 238 229 222 seashell2 205 197 191 seashell3 139 134 130 seashell4 255 239 219 AntiqueWhite1 238 223 204 AntiqueWhite2 205 192 176 AntiqueWhite3 139 131 120 AntiqueWhite4 255 228 196 bisque1 238 213 183 bisque2 205 183 158 bisque3 139 125 107 bisque4 255 218 185 PeachPuff1 238 203 173 PeachPuff2 205 175 149 PeachPuff3 139 119 101 PeachPuff4 255 222 173 NavajoWhite1 238 207 161 NavajoWhite2 205 179 139 NavajoWhite3 139 121 94 NavajoWhite4 255 250 205 LemonChiffon1 238 233 191 LemonChiffon2 205 201 165 LemonChiffon3 139 137 112 LemonChiffon4 255 248 220 cornsilk1 238 232 205 cornsilk2 205 200 177 cornsilk3 139 136 120 cornsilk4 255 255 240 ivory1 238 238 224 ivory2 205 205 193 ivory3 139 139 131 ivory4 240 255 240 honeydew1 224 238 224 honeydew2 193 205 193 honeydew3 131 139 131 honeydew4 255 240 245 LavenderBlush1 238 224 229 LavenderBlush2 205 193 197 LavenderBlush3 139 131 134 LavenderBlush4 255 228 225 MistyRose1 238 213 210 MistyRose2 205 183 181 MistyRose3 139 125 123 MistyRose4 240 255 255 azure1 224 238 238 azure2 193 205 205 azure3 131 139 139 azure4 131 111 255 SlateBlue1 122 103 238 SlateBlue2 105 89 205 SlateBlue3 71 60 139 SlateBlue4 72 118 255 RoyalBlue1 67 110 238 RoyalBlue2 58 95 205 RoyalBlue3 39 64 139 RoyalBlue4 0 0 255 blue1 0 0 238 blue2 0 0 205 blue3 0 0 139 blue4 30 144 255 DodgerBlue1 28 134 238 DodgerBlue2 24 116 205 DodgerBlue3 16 78 139 DodgerBlue4 99 184 255 SteelBlue1 92 172 238 SteelBlue2 79 148 205 SteelBlue3 54 100 139 SteelBlue4 0 191 255 DeepSkyBlue1 0 178 238 DeepSkyBlue2 0 154 205 DeepSkyBlue3 0 104 139 DeepSkyBlue4 135 206 255 SkyBlue1 126 192 238 SkyBlue2 108 166 205 SkyBlue3 74 112 139 SkyBlue4 176 226 255 LightSkyBlue1 164 211 238 LightSkyBlue2 141 182 205 LightSkyBlue3 96 123 139 LightSkyBlue4 198 226 255 SlateGray1 185 211 238 SlateGray2 159 182 205 SlateGray3 108 123 139 SlateGray4 202 225 255 LightSteelBlue1 188 210 238 LightSteelBlue2 162 181 205 LightSteelBlue3 110 123 139 LightSteelBlue4 191 239 255 LightBlue1 178 223 238 LightBlue2 154 192 205 LightBlue3 104 131 139 LightBlue4 224 255 255 LightCyan1 209 238 238 LightCyan2 180 205 205 LightCyan3 122 139 139 LightCyan4 187 255 255 PaleTurquoise1 174 238 238 PaleTurquoise2 150 205 205 PaleTurquoise3 102 139 139 PaleTurquoise4 152 245 255 CadetBlue1 142 229 238 CadetBlue2 122 197 205 CadetBlue3 83 134 139 CadetBlue4 0 245 255 turquoise1 0 229 238 turquoise2 0 197 205 turquoise3 0 134 139 turquoise4 0 255 255 cyan1 0 238 238 cyan2 0 205 205 cyan3 0 139 139 cyan4 151 255 255 DarkSlateGray1 141 238 238 DarkSlateGray2 121 205 205 DarkSlateGray3 82 139 139 DarkSlateGray4 127 255 212 aquamarine1 118 238 198 aquamarine2 102 205 170 aquamarine3 69 139 116 aquamarine4 193 255 193 DarkSeaGreen1 180 238 180 DarkSeaGreen2 155 205 155 DarkSeaGreen3 105 139 105 DarkSeaGreen4 84 255 159 SeaGreen1 78 238 148 SeaGreen2 67 205 128 SeaGreen3 46 139 87 SeaGreen4 154 255 154 PaleGreen1 144 238 144 PaleGreen2 124 205 124 PaleGreen3 84 139 84 PaleGreen4 0 255 127 SpringGreen1 0 238 118 SpringGreen2 0 205 102 SpringGreen3 0 139 69 SpringGreen4 0 255 0 green1 0 238 0 green2 0 205 0 green3 0 139 0 green4 127 255 0 chartreuse1 118 238 0 chartreuse2 102 205 0 chartreuse3 69 139 0 chartreuse4 192 255 62 OliveDrab1 179 238 58 OliveDrab2 154 205 50 OliveDrab3 105 139 34 OliveDrab4 202 255 112 DarkOliveGreen1 188 238 104 DarkOliveGreen2 162 205 90 DarkOliveGreen3 110 139 61 DarkOliveGreen4 255 246 143 khaki1 238 230 133 khaki2 205 198 115 khaki3 139 134 78 khaki4 255 236 139 LightGoldenrod1 238 220 130 LightGoldenrod2 205 190 112 LightGoldenrod3 139 129 76 LightGoldenrod4 255 255 224 LightYellow1 238 238 209 LightYellow2 205 205 180 LightYellow3 139 139 122 LightYellow4 255 255 0 yellow1 238 238 0 yellow2 205 205 0 yellow3 139 139 0 yellow4 255 215 0 gold1 238 201 0 gold2 205 173 0 gold3 139 117 0 gold4 255 193 37 goldenrod1 238 180 34 goldenrod2 205 155 29 goldenrod3 139 105 20 goldenrod4 255 185 15 DarkGoldenrod1 238 173 14 DarkGoldenrod2 205 149 12 DarkGoldenrod3 139 101 8 DarkGoldenrod4 255 193 193 RosyBrown1 238 180 180 RosyBrown2 205 155 155 RosyBrown3 139 105 105 RosyBrown4 255 106 106 IndianRed1 238 99 99 IndianRed2 205 85 85 IndianRed3 139 58 58 IndianRed4 255 130 71 sienna1 238 121 66 sienna2 205 104 57 sienna3 139 71 38 sienna4 255 211 155 burlywood1 238 197 145 burlywood2 205 170 125 burlywood3 139 115 85 burlywood4 255 231 186 wheat1 238 216 174 wheat2 205 186 150 wheat3 139 126 102 wheat4 255 165 79 tan1 238 154 73 tan2 205 133 63 tan3 139 90 43 tan4 255 127 36 chocolate1 238 118 33 chocolate2 205 102 29 chocolate3 139 69 19 chocolate4 255 48 48 firebrick1 238 44 44 firebrick2 205 38 38 firebrick3 139 26 26 firebrick4 255 64 64 brown1 238 59 59 brown2 205 51 51 brown3 139 35 35 brown4 255 140 105 salmon1 238 130 98 salmon2 205 112 84 salmon3 139 76 57 salmon4 255 160 122 LightSalmon1 238 149 114 LightSalmon2 205 129 98 LightSalmon3 139 87 66 LightSalmon4 255 165 0 orange1 238 154 0 orange2 205 133 0 orange3 139 90 0 orange4 255 127 0 DarkOrange1 238 118 0 DarkOrange2 205 102 0 DarkOrange3 139 69 0 DarkOrange4 255 114 86 coral1 238 106 80 coral2 205 91 69 coral3 139 62 47 coral4 255 99 71 tomato1 238 92 66 tomato2 205 79 57 tomato3 139 54 38 tomato4 255 69 0 OrangeRed1 238 64 0 OrangeRed2 205 55 0 OrangeRed3 139 37 0 OrangeRed4 255 0 0 red1 238 0 0 red2 205 0 0 red3 139 0 0 red4 255 20 147 DeepPink1 238 18 137 DeepPink2 205 16 118 DeepPink3 139 10 80 DeepPink4 255 110 180 HotPink1 238 106 167 HotPink2 205 96 144 HotPink3 139 58 98 HotPink4 255 181 197 pink1 238 169 184 pink2 205 145 158 pink3 139 99 108 pink4 255 174 185 LightPink1 238 162 173 LightPink2 205 140 149 LightPink3 139 95 101 LightPink4 255 130 171 PaleVioletRed1 238 121 159 PaleVioletRed2 205 104 137 PaleVioletRed3 139 71 93 PaleVioletRed4 255 52 179 maroon1 238 48 167 maroon2 205 41 144 maroon3 139 28 98 maroon4 255 62 150 VioletRed1 238 58 140 VioletRed2 205 50 120 VioletRed3 139 34 82 VioletRed4 255 0 255 magenta1 238 0 238 magenta2 205 0 205 magenta3 139 0 139 magenta4 255 131 250 orchid1 238 122 233 orchid2 205 105 201 orchid3 139 71 137 orchid4 255 187 255 plum1 238 174 238 plum2 205 150 205 plum3 139 102 139 plum4 224 102 255 MediumOrchid1 209 95 238 MediumOrchid2 180 82 205 MediumOrchid3 122 55 139 MediumOrchid4 191 62 255 DarkOrchid1 178 58 238 DarkOrchid2 154 50 205 DarkOrchid3 104 34 139 DarkOrchid4 155 48 255 purple1 145 44 238 purple2 125 38 205 purple3 85 26 139 purple4 171 130 255 MediumPurple1 159 121 238 MediumPurple2 137 104 205 MediumPurple3 93 71 139 MediumPurple4 255 225 255 thistle1 238 210 238 thistle2 205 181 205 thistle3 139 123 139 thistle4 0 0 0 gray0 0 0 0 grey0 3 3 3 gray1 3 3 3 grey1 5 5 5 gray2 5 5 5 grey2 8 8 8 gray3 8 8 8 grey3 10 10 10 gray4 10 10 10 grey4 13 13 13 gray5 13 13 13 grey5 15 15 15 gray6 15 15 15 grey6 18 18 18 gray7 18 18 18 grey7 20 20 20 gray8 20 20 20 grey8 23 23 23 gray9 23 23 23 grey9 26 26 26 gray10 26 26 26 grey10 28 28 28 gray11 28 28 28 grey11 31 31 31 gray12 31 31 31 grey12 33 33 33 gray13 33 33 33 grey13 36 36 36 gray14 36 36 36 grey14 38 38 38 gray15 38 38 38 grey15 41 41 41 gray16 41 41 41 grey16 43 43 43 gray17 43 43 43 grey17 46 46 46 gray18 46 46 46 grey18 48 48 48 gray19 48 48 48 grey19 51 51 51 gray20 51 51 51 grey20 54 54 54 gray21 54 54 54 grey21 56 56 56 gray22 56 56 56 grey22 59 59 59 gray23 59 59 59 grey23 61 61 61 gray24 61 61 61 grey24 64 64 64 gray25 64 64 64 grey25 66 66 66 gray26 66 66 66 grey26 69 69 69 gray27 69 69 69 grey27 71 71 71 gray28 71 71 71 grey28 74 74 74 gray29 74 74 74 grey29 77 77 77 gray30 77 77 77 grey30 79 79 79 gray31 79 79 79 grey31 82 82 82 gray32 82 82 82 grey32 84 84 84 gray33 84 84 84 grey33 87 87 87 gray34 87 87 87 grey34 89 89 89 gray35 89 89 89 grey35 92 92 92 gray36 92 92 92 grey36 94 94 94 gray37 94 94 94 grey37 97 97 97 gray38 97 97 97 grey38 99 99 99 gray39 99 99 99 grey39 102 102 102 gray40 102 102 102 grey40 105 105 105 gray41 105 105 105 grey41 107 107 107 gray42 107 107 107 grey42 110 110 110 gray43 110 110 110 grey43 112 112 112 gray44 112 112 112 grey44 115 115 115 gray45 115 115 115 grey45 117 117 117 gray46 117 117 117 grey46 120 120 120 gray47 120 120 120 grey47 122 122 122 gray48 122 122 122 grey48 125 125 125 gray49 125 125 125 grey49 127 127 127 gray50 127 127 127 grey50 130 130 130 gray51 130 130 130 grey51 133 133 133 gray52 133 133 133 grey52 135 135 135 gray53 135 135 135 grey53 138 138 138 gray54 138 138 138 grey54 140 140 140 gray55 140 140 140 grey55 143 143 143 gray56 143 143 143 grey56 145 145 145 gray57 145 145 145 grey57 148 148 148 gray58 148 148 148 grey58 150 150 150 gray59 150 150 150 grey59 153 153 153 gray60 153 153 153 grey60 156 156 156 gray61 156 156 156 grey61 158 158 158 gray62 158 158 158 grey62 161 161 161 gray63 161 161 161 grey63 163 163 163 gray64 163 163 163 grey64 166 166 166 gray65 166 166 166 grey65 168 168 168 gray66 168 168 168 grey66 171 171 171 gray67 171 171 171 grey67 173 173 173 gray68 173 173 173 grey68 176 176 176 gray69 176 176 176 grey69 179 179 179 gray70 179 179 179 grey70 181 181 181 gray71 181 181 181 grey71 184 184 184 gray72 184 184 184 grey72 186 186 186 gray73 186 186 186 grey73 189 189 189 gray74 189 189 189 grey74 191 191 191 gray75 191 191 191 grey75 194 194 194 gray76 194 194 194 grey76 196 196 196 gray77 196 196 196 grey77 199 199 199 gray78 199 199 199 grey78 201 201 201 gray79 201 201 201 grey79 204 204 204 gray80 204 204 204 grey80 207 207 207 gray81 207 207 207 grey81 209 209 209 gray82 209 209 209 grey82 212 212 212 gray83 212 212 212 grey83 214 214 214 gray84 214 214 214 grey84 217 217 217 gray85 217 217 217 grey85 219 219 219 gray86 219 219 219 grey86 222 222 222 gray87 222 222 222 grey87 224 224 224 gray88 224 224 224 grey88 227 227 227 gray89 227 227 227 grey89 229 229 229 gray90 229 229 229 grey90 232 232 232 gray91 232 232 232 grey91 235 235 235 gray92 235 235 235 grey92 237 237 237 gray93 237 237 237 grey93 240 240 240 gray94 240 240 240 grey94 242 242 242 gray95 242 242 242 grey95 245 245 245 gray96 245 245 245 grey96 247 247 247 gray97 247 247 247 grey97 250 250 250 gray98 250 250 250 grey98 252 252 252 gray99 252 252 252 grey99 255 255 255 gray100 255 255 255 grey100 169 169 169 dark grey 169 169 169 DarkGrey 169 169 169 dark gray 169 169 169 DarkGray 0 0 139 dark blue 0 0 139 DarkBlue 0 139 139 dark cyan 0 139 139 DarkCyan 139 0 139 dark magenta 139 0 139 DarkMagenta 139 0 0 dark red 139 0 0 DarkRed 144 238 144 light green 144 238 144 LightGreen ���������������������������������������������������������������������������������������������������������������������������������������gri/src/GriTimer.hh���������������������������������������������������������������������������������0000644�0001750�0001750�00000002017�13147557614�012652� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #if !defined(_GriTimer_hh) #define _GriTimer_hh #include class GriTimer { public: GriTimer(); ~GriTimer() {}; char *now_ascii(); double elapsed_time(); private: SECOND_TYPE start; }; #endif // _GriTimer_hh �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/grimage.cc����������������������������������������������������������������������������������0000644�0001750�0001750�00000051472�13147557614�012542� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// vim: noexpandtab tabstop=8 softtabstop=8 /* Gri - A language for scientific graphics programming Copyright (C) 2011 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include "gr.hh" #include "extern.hh" extern bool _grWritePS; extern FILE *_grPS; /* * gr_drawBWmaskedimage() -- draw a image of an unsigned char matrix * * DESCRIPTION: Draws an image using 'im', a matrix of rows*cols unsigned char * elements. You should assign elements to im as: * * for(i=0;i * gr_drawBWimage(im,NULL,...); If you would like to supply an alternate * mapping of values of im to grayscale, you can store it in imTransform. * Then gr_drawBWimage() uses not 'im', but rather imTransform[im]. Here's an * example which reverses the mapping, so that im==0 becomes white and * im==255 becomes black: * * unsigned char imTransform[256]; for (i = 0; i < 256; i++) imTransform[i] = * 255 - i; gr_drawBWmaskedimage_pt(...); * * * NOTE: To use the default mapping, imTransform must be supplied as NULL; to * arrange an alternate mapping, it must be an unsigned character vector of * length 256 (anything else will produce a spurious map). * * GEOMETRY: The image is drawn in the rectangle defined by (xl,yb) as * lower-left and (xr,yt) as upper-right, in user units. * * MISSING VALUES: if the mask image is equal to 2, the supplied "missing" value * is used. * */ void gr_drawBWmaskedimage_pt(unsigned char missing, unsigned char *mask, unsigned char *im, unsigned char *imTransform, int imax, int jmax, double xlpt, double ybpt, double xrpt, double ytpt) { extern output_file_type _output_file_type; if (_output_file_type == postscript) { register int i, j; extern FILE *_grPS; int perline = 0; int perlineMAX = 39; if (imax < perlineMAX) perlineMAX = imax; /* write postscript */ if (_grWritePS) { fprintf(_grPS, "%f %f %f %f %d %d im\n", xlpt, ybpt, xrpt, ytpt, jmax, imax); check_psfile(); if (imTransform == NULL) { for (j = jmax - 1; j > -1; j--) { for (i = 0; i < imax; i++) { if (mask != NULL && *(mask + i * jmax + j) == 2) fprintf(_grPS, "%02X", missing); else fprintf(_grPS, "%02X", *(im + i * jmax + j)); if ((++perline) == perlineMAX) { fprintf(_grPS, "\n"); perline = 0; } } } check_psfile(); } else { /* scale contained in imTransform[] */ for (j = jmax - 1; j > -1; j--) { for (i = 0; i < imax; i++) { if (mask != NULL && *(mask + i * jmax + j) == 2) fprintf(_grPS, "%02X", missing); else fprintf(_grPS, "%02X", imTransform[*(im + i * jmax + j)]); if ((++perline) == perlineMAX) { fprintf(_grPS, "\n"); perline = 0; } } } } if (perline != 0) fprintf(_grPS, "\n"); check_psfile(); } } else { err("INTERNAL ERROR: gr_drawBWmaskedimage() only works for postscript files."); } } void gr_drawimage_svg( // Draw image, possibly color, in rectangle given in cm coords. unsigned char *im, unsigned char *imTransform, gr_color_model color_model, unsigned char *mask, double mask_r, double mask_g, double mask_b, int imax, // image size int jmax, // image size double xl, // image lower-left-x, in cm double yb, // image lower-left-y, in cm double xr, // image upper-right-x, in cm double yt, // image upper-right-y, in cm bool insert_placer) { extern FILE *_grSVG; unsigned char cmask_r, cmask_g, cmask_b; bool have_mask; unsigned char value; register int i, j; double x, y, page_height_pt = gr_page_height_pt(); char hex[8]; // #000000 for example if (!_grWritePS) return; // Figure out about mask have_mask = (mask == NULL) ? false : true; xl *= PT_PER_CM; xr *= PT_PER_CM; yb *= PT_PER_CM; yt *= PT_PER_CM; double dx = (xr - xl) / imax; // FIXME: check to see the sign always works double dy = (yt - yb) / jmax; double xl_c = xl, xr_c = xr, yb_c = yb, yt_c = yt; int ilow = 0, ihigh = imax, jlow = 0, jhigh = jmax; if (_clipping_postscript && _clipping_is_postscript_rect) { ilow = int(floor(0.5 + (_clip_ps_xleft - xl)*imax/((xr-xl)))); ihigh = int(floor(0.5 + (_clip_ps_xright - xl)*imax/((xr-xl)))); jlow = int(floor(0.5 + (_clip_ps_ybottom - yb)*jmax/((yt-yb)))); jhigh = int(floor(0.5 + (_clip_ps_ytop - yb)*jmax/((yt-yb)))); if (ihigh < ilow) { int tmp = ihigh; ihigh = ilow; ilow = tmp; } if (jhigh < jlow) { int tmp = jhigh; jhigh = jlow; jlow = tmp; } ilow = LARGER_ONE(ilow, 0); ihigh = SMALLER_ONE(ihigh, imax); jlow = LARGER_ONE(jlow, 0); jhigh = SMALLER_ONE(jhigh, jmax); if (ilow > 0) xl_c = xl + ilow * (xr - xl) / imax; if (ihigh < imax) xr_c = xl + ihigh * (xr - xl) / imax; if (jlow > 0) yb_c = yb + jlow * (yt - yb) / jmax; if (jhigh < jmax) yt_c = yb + jhigh * (yt - yb) / jmax; if (_chatty > 2) { printf("image clipping debugging...\n"); printf("image xrange (%f %f) pt\n",xl,xr); printf("image yrange (%f %f) pt\n",yb,yt); printf("clip xrange (%f %f) pt\n",_clip_ps_xleft,_clip_ps_xright); printf("clip yrange (%f %f) pt\n",_clip_ps_ybottom,_clip_ps_ytop); printf("making i run from %d to %d instead of 0 to %d\n",ilow,ihigh,imax); printf("making j run from %d to %d instead of 0 to %d\n",jlow,jhigh,jmax); printf("clipped image xrange (%f %f) pt\n",xl_c,xr_c); printf("clipped image yrange (%f %f) pt\n",yb_c,yt_c); } } rectangle box(xl_c/PT_PER_CM, yb_c/PT_PER_CM, xr_c/PT_PER_CM, yt_c/PT_PER_CM); // CHECK: is it only updating if it's within clip region? bounding_box_update(box); // Make image overhang the region. if (imax > 1) { double dx = (xr_c - xl_c) / ((ihigh-ilow) - 1); // pixel width xl_c -= dx / 2.0; xr_c += dx / 2.0; } if (jmax > 1) { double dy = (yt_c - yb_c) / ((jhigh-jlow) - 1); // pixel height yb_c -= dy / 2.0; yt_c += dy / 2.0; } // Optimize a bit by using style sheet to define fixed quantities. (I had // hoped to set width= and height= here, but that does not work.) fprintf(_grSVG, "\n \n\n", 0.2, 1.0); // FIXME: remove opacity, if add image transparency on a pixel-by-pixel basis. // Handle BW and color differently, since PostScript handles differently. switch (color_model) { default: // taken as BW case bw_model: fprintf(_grSVG, " \n"); warning("Sorry, svg output of black/white images is not working yet"); return; #if 0 check_psfile(); // Write map to PostScript, creating a linear one if none exists fprintf(_grPS, "%% Push map onto stack, then image stuff.\n"); fprintf(_grPS, "[\n"); if (imTransform == NULL) { for (i = 0; i < 256; i++) { fprintf(_grPS, "%.4f ", i / 255.0); if (!((i + 1) % 10)) fprintf(_grPS, "\n"); } } else { for (i = 0; i < 256; i++) { fprintf(_grPS, "%.4f ", imTransform[i] / 255.0); if (!((i + 1) % 10)) fprintf(_grPS, "\n"); } } fprintf(_grPS, "\n]\n"); if (insert_placer) fprintf(_grPS, "%%BEGIN_IMAGE\n"); // for grepping in ps file // Now write image. fprintf(_grPS, "%f %f %f %f %d %d im\n", xl_c, yb_c, xr_c, yt_c, (jhigh-jlow), (ihigh-ilow)); // BUG or +1? if (have_mask == true) { int diff, min_diff = 256; unsigned char index = 0; // assign to calm compiler ???? unsigned char mask_value = (unsigned char)(255.0 * mask_r); // If there is a mapping, must (arduously) look up which image // value corresponds to this color. if (imTransform != NULL) { for (i = 0; i < 256; i++) { diff = (int) fabs(double(imTransform[i] - mask_value)); if (diff < min_diff) { min_diff = diff; index = i; } } mask_value = index; } } for (j = jhigh - 1; j >= jlow; j--) { for (i = ilow; i < ihigh; i++) { value = *(im + i * jmax + j); if (have_mask == true && *(mask + i * jmax + j) == 2) { fprintf(_grSVG, "\n", mask_value); } else { fprintf(_grSVG, "\n", value); } } } fprintf(_grSVG, " \n"); #endif break; case rgb_model: group_start("RGB image"); // printf("DEBUG: ilow, ihigh = %d %d jlow, jhigh = %d %d\n",ilow,ihigh,jlow,jhigh); cmask_r = (unsigned char)pin0_255(mask_r * 255.0); cmask_g = (unsigned char)pin0_255(mask_g * 255.0); cmask_b = (unsigned char)pin0_255(mask_b * 255.0); double adx = fabs(dx), ady = fabs(dy); char label[100]; if (imTransform == NULL) { err("cannot handle SVG images that lack an image-transform."); for (j = jhigh - 1; j >= jlow; j--) { y = page_height_pt - (yb + (jhigh - j) * dy); // offset for page_height_pt ?? for (i = ilow; i < ihigh; i++) { x = xl + i * dx; value = *(im + i * jmax + j); if (have_mask == true && *(mask + i * jmax + j) == 2) sprintf(hex, "#%02X%02X%02X", cmask_r, cmask_g, cmask_b); else sprintf(hex, "#%02X%02X%02X", value, value, value); fprintf(_grSVG, "\n", x, y, adx, ady, hex, hex); } } } else { for (j = jhigh - 1; j >= jlow; j--) { //y = page_height_pt - (yb + (jhigh - j) * dy); y = page_height_pt - (yb + j * dy); sprintf(label, "j=%d", j); group_start(label); for (i = ilow; i < ihigh; i++) { x = xl + i * dx; value = *(im + i * jmax + j); if (have_mask == true && *(mask + i * jmax + j) == 2) { sprintf(hex, "#%02X%02X%02X", cmask_r, cmask_g, cmask_b); fprintf(_grSVG, "\n", x, y, adx, ady, hex, hex); } else { sprintf(hex, "#%02X%02X%02X", imTransform[value], imTransform[value + 256], imTransform[value + 512]); fprintf(_grSVG, "\n", x, y, adx, ady, hex, hex); } } group_end(); } } group_end(); } // switch(color_model) } void gr_drawimage( // Draw image, possibly color, in rectangle given in cm coords. unsigned char *im, unsigned char *imTransform, gr_color_model color_model, unsigned char *mask, double mask_r, double mask_g, double mask_b, int imax, // image size int jmax, // image size double xl, // image lower-left-x, in cm double yb, // image lower-left-y, in cm double xr, // image upper-right-x, in cm double yt, // image upper-right-y, in cm bool insert_placer) { unsigned char cmask_r, cmask_g, cmask_b; bool have_mask; unsigned char value, mask_value = 0; // assign to calm compiler register int i, j; int perline = 0; int perlineMAX; if (!_grWritePS) return; //printf("DEBUG [gr_drawimage() %s:%d] xl=%lf xr=%lf yb=%lf yt=%lf\n",__FILE__,__LINE__,xl,xr,yb,yt); // Figure out about mask have_mask = (mask == NULL) ? false : true; xl *= PT_PER_CM; xr *= PT_PER_CM; yb *= PT_PER_CM; yt *= PT_PER_CM; double xl_c = xl, xr_c = xr, yb_c = yb, yt_c = yt; int ilow = 0, ihigh = imax, jlow = 0, jhigh = jmax; if (_clipping_postscript && _clipping_is_postscript_rect) { ilow = int(floor(0.5 + (_clip_ps_xleft - xl)*imax/((xr-xl)))); ihigh = int(floor(0.5 + (_clip_ps_xright - xl)*imax/((xr-xl)))); jlow = int(floor(0.5 + (_clip_ps_ybottom - yb)*jmax/((yt-yb)))); jhigh = int(floor(0.5 + (_clip_ps_ytop - yb)*jmax/((yt-yb)))); if (jhigh > jmax) jhigh = jmax; if (_chatty > 1) printf("clipping postscript to rect %f < x < %f and %f < y < %f\n", _clip_ps_xleft, _clip_ps_xright, _clip_ps_ybottom, _clip_ps_ytop); if (ihigh < ilow) { if (_chatty > 2) printf("Interchanging ihigh (orig. %d) and ilow (orig %d)\n", ihigh, ilow); int tmp = ihigh; ihigh = ilow; ilow = tmp; } if (jhigh < jlow) { if (_chatty > 2) printf("Interchanging jhigh (orig. %d) and jlow (orig %d)\n", jhigh, jlow); int tmp = jhigh; jhigh = jlow; jlow = tmp; } ilow = LARGER_ONE(ilow, 0); ihigh = SMALLER_ONE(ihigh, imax); jlow = LARGER_ONE(jlow, 0); jhigh = SMALLER_ONE(jhigh, jmax); if (ilow > 0) xl_c = xl + ilow * (xr - xl) / imax; if (ihigh < imax) xr_c = xl + ihigh * (xr - xl) / imax; if (jlow > 0) yb_c = yb + jlow * (yt - yb) / jmax; if (jhigh < jmax) yt_c = yb + jhigh * (yt - yb) / jmax; if (_chatty > 2) { printf("image clipping debugging...\n"); printf("image xrange (%f %f) pt\n",xl,xr); printf("image yrange (%f %f) pt\n",yb,yt); printf("clip xrange (%f %f) pt\n",_clip_ps_xleft,_clip_ps_xright); printf("clip yrange (%f %f) pt\n",_clip_ps_ybottom,_clip_ps_ytop); printf("making i run from %d to %d instead of 0 to %d\n",ilow,ihigh,imax); printf("making j run from %d to %d instead of 0 to %d\n",jlow,jhigh,jmax); printf("clipped image xrange (%f %f) pt\n",xl_c,xr_c); printf("clipped image yrange (%f %f) pt\n",yb_c,yt_c); } } rectangle box(xl_c/PT_PER_CM, yb_c/PT_PER_CM, xr_c/PT_PER_CM, yt_c/PT_PER_CM); // CHECK: is it only updating if it's within clip region? bounding_box_update(box); // Make image overhang the region. if (imax > 1) { double dx = (xr_c - xl_c) / ((ihigh-ilow) - 1); // pixel width xl_c -= dx / 2.0; xr_c += dx / 2.0; } if (jmax > 1) { double dy = (yt_c - yb_c) / ((jhigh-jlow) - 1); // pixel height yb_c -= dy / 2.0; yt_c += dy / 2.0; } // Handle BW and color differently, since PostScript handles differently. switch (color_model) { default: // taken as BW case bw_model: perlineMAX = 39; // use only 78 columns so more readible if (imax < perlineMAX) perlineMAX = imax; check_psfile(); // Write map to PostScript, creating a linear one if none exists fprintf(_grPS, "%% Push map onto stack, then image stuff.\n"); fprintf(_grPS, "[\n"); if (imTransform == NULL) { for (i = 0; i < 256; i++) { fprintf(_grPS, "%.4f ", i / 255.0); if (!((i + 1) % 10)) fprintf(_grPS, "\n"); } } else { for (i = 0; i < 256; i++) { fprintf(_grPS, "%.4f ", imTransform[i] / 255.0); if (!((i + 1) % 10)) fprintf(_grPS, "\n"); } } fprintf(_grPS, "\n]\n"); if (insert_placer) fprintf(_grPS, "%%BEGIN_IMAGE\n"); // for grepping in ps file // Now write image. fprintf(_grPS, "%f %f %f %f %d %d im\n", xl_c, yb_c, xr_c, yt_c, (jhigh-jlow), (ihigh-ilow)); // BUG check_psfile(); if (have_mask == true) { int diff, min_diff = 256; unsigned char index = 0; // assign to calm compiler ???? mask_value = (unsigned char)(255.0 * mask_r); // If there is a mapping, must (arduously) look up which image // value corresponds to this color. if (imTransform != NULL) { for (i = 0; i < 256; i++) { diff = (int) fabs(double(imTransform[i] - mask_value)); if (diff < min_diff) { min_diff = diff; index = i; } } mask_value = index; } } for (j = jhigh - 1; j >= jlow; j--) { for (i = ilow; i < ihigh; i++) { value = *(im + i * jmax + j); if (have_mask == true && *(mask + i * jmax + j) == 2) { fprintf(_grPS, "%02X", mask_value); } else { if (imTransform==NULL) { fprintf(_grPS, "%02X", value); } else { fprintf(_grPS, "%02X", imTransform[value]); } } if ((++perline) == perlineMAX) { fprintf(_grPS, "\n"); perline = 0; } } } check_psfile(); if (perline != 0) fprintf(_grPS, "\n"); check_psfile(); if (insert_placer) fprintf(_grPS, "%%END_IMAGE\n"); // for grepping in ps file break; case rgb_model: perlineMAX = 13; // use only 78 columns so more readible if (imax < perlineMAX) perlineMAX = imax; if (insert_placer) fprintf(_grPS, "%%BEGIN_IMAGE\n"); fprintf(_grPS, "%f %f %f %f %d %d cim\n", xl_c, yb_c, xr_c, yt_c, (jhigh-jlow), (ihigh-ilow)); // BUG check_psfile(); cmask_r = (unsigned char)pin0_255(mask_r * 255.0); cmask_g = (unsigned char)pin0_255(mask_g * 255.0); cmask_b = (unsigned char)pin0_255(mask_b * 255.0); if (imTransform == NULL) { for (j = jhigh - 1; j >= jlow; j--) { for (i = ilow; i < ihigh; i++) { value = *(im + i * jmax + j); if (have_mask == true && *(mask + i * jmax + j) == 2) { fprintf(_grPS, "%02X%02X%02X", cmask_r, cmask_g, cmask_b); } else { fprintf(_grPS, "%02X%02X%02X", value, value, value); } if ((++perline) == perlineMAX) { fprintf(_grPS, "\n"); perline = 0; } } } check_psfile(); } else { for (j = jhigh - 1; j >= jlow; j--) { // BUG: should these run on max, or on 'ihigh' etc??? for (i = ilow; i < ihigh; i++) { value = *(im + i * jmax + j); if (have_mask == true && *(mask + i * jmax + j) == 2) { fprintf(_grPS, "%02X%02X%02X", cmask_r, cmask_g, cmask_b); } else { fprintf(_grPS, "%02X%02X%02X", imTransform[value], imTransform[value + 256], imTransform[value + 512]); } if ((++perline) == perlineMAX) { fprintf(_grPS, "\n"); perline = 0; } } } } if (perline != 0) fprintf(_grPS, "\n"); if (insert_placer) fprintf(_grPS, "%%END_IMAGE\n"); // for grepping in ps file check_psfile(); } // switch(color_model) } // gr_drawimage() /* * gr_drawBWimage_pt() -- draw a image of an unsigned char matrix * * SYNOPSIS void gr_drawBWimage_pt(unsigned char *im, unsigned char * imTransform, imax, jmax, xl, yb, xr, yt); * * DESCRIPTION: As gr_drawBWimagept() except that xl, yb, xr and yt are * measured in points. * */ void gr_drawBWimage_pt(unsigned char *im, unsigned char *imTransform, int imax, int jmax, double xlpt, double ybpt, double xrpt, double ytpt) { register int i, j; int perline = 0; int perlineMAX = 39; if (imax < perlineMAX) perlineMAX = imax; /* write postscript */ if (_grWritePS) { fprintf(_grPS, "%f %f %f %f %d %d im\n", xlpt, ybpt, xrpt, ytpt, jmax, imax); check_psfile(); if (imTransform == NULL) { for (j = jmax - 1; j > -1; j--) { for (i = 0; i < imax; i++) { fprintf(_grPS, "%02X", *(im + i * jmax + j)); if ((++perline) == perlineMAX) { fprintf(_grPS, "\n"); perline = 0; } } } check_psfile(); } else { /* scale contained in imTransform[] */ for (j = jmax - 1; j > -1; j--) { for (i = 0; i < imax; i++) { fprintf(_grPS, "%02X", imTransform[*(im + i * jmax + j)]); if ((++perline) == perlineMAX) { fprintf(_grPS, "\n"); perline = 0; } } } } if (perline != 0) fprintf(_grPS, "\n"); check_psfile(); } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/tags.hh�������������������������������������������������������������������������������������0000644�0001750�0001750�00000032757�13147557614�012104� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #if !defined(_tags_hh_) #define _tags_hh_ #include "gr.hh" bool assertCmd(void), cdCmd(void), closeCmd(void), convert_col_fro_pol_to_recCmd(void), convert_col_fro_rec_to_polCmd(void), convert_col_to_gridCmd(void), convert_col_to_splineCmd(void), convert_grid_to_columnsCmd(void), convert_grid_to_imageCmd(void), convert_image_to_gridCmd(void), debugCmd(void), deleteCmd(void), differentiateCmd(void), draw_arcCmd(void), draw_arrow_from_toCmd(void), draw_arrowsCmd(void), draw_axes_if_needed(void), draw_axesCmd(void), draw_boxCmd(void), draw_box_filledCmd(void), draw_circleCmd(void), draw_contourCmd(void), draw_curveCmd(void), draw_gri_logoCmd(void), draw_gridCmd(void), draw_imageCmd(void), draw_image_histogramCmd(void), draw_image_paletteCmd(void), draw_isopycnalCmd(void), draw_labelCmd(void), draw_line_from_toCmd(void), draw_linesCmd(void), draw_patchesCmd(void), draw_polygonCmd(void), draw_symbolCmd(void), draw_titleCmd(void), draw_valuesCmd(void), draw_x_axisCmd(void), draw_x_box_plotCmd(void), draw_y_axisCmd(void), draw_y_box_plotCmd(void), draw_zero_lineCmd(void), end_groupCmd(void), expectingCmd(void), filter_columnCmd(void), filter_gridCmd(void), filter_imageCmd(void), flipCmd(void), get_envCmd(void), get_optionsCmd(void), groupCmd(void), healCmd(void), helpCmd(void), ignoreCmd(void), inputCmd(void), insertCmd(void), interpolateCmd(void), listCmd(void), lsCmd(void), maskCmd(void), newCmd(void), new_pageCmd(void), new_postscript_fileCmd(void), nullCmd(void), openCmd(void), postscriptCmd(void), pwdCmd(void), queryCmd(void), quitCmd(void), read_colornamesCmd(void), read_columnsCmd(void), read_from_filenameCmd(void), read_gridCmd(void), read_imageCmd(void), read_image_colorscaleCmd(void), read_image_grayscaleCmd(void), read_image_maskCmd(void), read_image_mask_rasterfileCmd(void), read_image_pgmCmd(void), read_image_rasterfileCmd(void), read_synonym_or_variableCmd(void), read_lineCmd(void), regressCmd(void), reorder_columnsCmd(void), rpnfunctionCmd(void), rescaleCmd(void), rewindCmd(void), set_axes_styleCmd(void), set_arrow_sizeCmd(void), set_arrow_typeCmd(void), set_beepCmd(void), set_bounding_boxCmd(void), set_clipCmd(void), set_colorCmd(void), set_colornameCmd(void), set_contour_formatCmd(void), set_contour_labelCmd(void), set_contour_labelsCmd(void), set_dashCmd(void), set_environment(void), set_error_actionCmd(void), set_flagCmd(void), set_font_colorCmd(void), set_font_encodingCmd(void), set_font_sizeCmd(void), set_font_toCmd(void), set_graylevelCmd(void), set_grid_missingCmd(void), set_image_colorscaleCmd(void), set_image_grayscale_using_hist(void), set_image_grayscaleCmd(void), set_image_missingCmd(void), set_image_rangeCmd(void), set_ignore_initial_newlineCmd(void), set_ignoreCmd(void), set_input_data_windowCmd(void), set_input_data_separatorCmd(void), set_line_capCmd(void), set_line_joinCmd(void), set_line_widthCmd(void), set_missing_valueCmd(void), set_pageCmd(void), set_page_sizeCmd(void), set_pathCmd(void), set_postscript_filenameCmd(void), set_symbol_sizeCmd(void), set_ticsCmd(void), set_tic_sizeCmd(void), set_transparencyCmd(void), set_u_scaleCmd(void), set_v_scaleCmd(void), set_traceCmd(void), set_x_axisCmd(void), set_x_formatCmd(void), set_x_gridCmd(void), set_x_marginCmd(void), set_x_nameCmd(void), set_x_sizeCmd(void), set_x_typeCmd(void), set_y_axisCmd(void), set_y_axis_nameCmd(void), set_y_axisCmd(void), set_y_formatCmd(void), set_y_gridCmd(void), set_y_marginCmd(void), set_y_nameCmd(void), set_y_sizeCmd(void), set_y_typeCmd(void), set_z_missingCmd(void), setCmd(void), show_allCmd(void), show_axesCmd(void), show_colorCmd(void), show_colornamesCmd(void), show_columnsCmd(void), show_expression_or_stringCmd(void), show_flagsCmd(void), show_gridCmd(void), show_imageCmd(void), show_licenseCmd(void), show_miscCmd(void), show_next_lineCmd(void), show_stopwatchCmd(void), show_synonymsCmd(void), show_timeCmd(void), show_tracebackCmd(void), show_variablesCmd(void), smoothCmd(void), sourceCmd(void), skipCmd(void), sleepCmd(void), sprintfCmd(void), stateCmd(void), systemCmd(void), superuserCmd(void), unlinkCmd(void), whileCmd(void), writeCmd(void); typedef struct { bool(*fcn) (); const char *name; unsigned int name_len; // speeds finding the command } C_FCN; C_FCN c_fcn[] = { {assertCmd, "assertCmd", 9}, {cdCmd, "cdCmd", 5}, {closeCmd, "closeCmd", 8}, {convert_col_to_gridCmd, "convert_columns_to_gridCmd", 26}, {convert_col_to_splineCmd, "convert_columns_to_splineCmd", 28}, {convert_grid_to_columnsCmd, "convert_grid_to_columnsCmd", 26}, {convert_grid_to_imageCmd, "convert_grid_to_imageCmd", 24}, {convert_image_to_gridCmd, "convert_image_to_gridCmd", 24}, {debugCmd, "debugCmd", 8}, {deleteCmd, "deleteCmd", 9}, {differentiateCmd, "differentiateCmd", 16}, {draw_arcCmd, "draw_arcCmd", 11}, {draw_arrow_from_toCmd, "draw_arrow_from_toCmd", 21}, {draw_arrowsCmd, "draw_arrowsCmd", 14}, {draw_axes_if_needed, "draw_axes_if_needed", 19}, {draw_axesCmd, "draw_axesCmd", 12}, {draw_boxCmd, "draw_boxCmd", 11}, {draw_box_filledCmd, "draw_box_filledCmd", 18}, {draw_circleCmd, "draw_circleCmd", 14}, {draw_contourCmd, "draw_contourCmd", 15}, {draw_curveCmd, "draw_curveCmd", 13}, {draw_gri_logoCmd, "draw_gri_logoCmd", 16}, {draw_gridCmd, "draw_gridCmd", 12}, {draw_imageCmd, "draw_imageCmd", 13}, {draw_image_histogramCmd, "draw_image_histogramCmd", 23}, {draw_image_paletteCmd, "draw_image_paletteCmd", 21}, {draw_isopycnalCmd, "draw_isopycnalCmd", 17}, {draw_labelCmd, "draw_labelCmd", 13}, {draw_line_from_toCmd, "draw_line_from_toCmd", 20}, {draw_linesCmd, "draw_linesCmd", 13}, {draw_patchesCmd, "draw_patchesCmd", 15}, {draw_polygonCmd, "draw_polygonCmd", 15}, {draw_symbolCmd, "draw_symbolCmd", 14}, {draw_titleCmd, "draw_titleCmd", 13}, {draw_valuesCmd, "draw_valuesCmd", 14}, {draw_x_axisCmd, "draw_x_axisCmd", 14}, {draw_x_box_plotCmd, "draw_x_box_plotCmd", 18}, {draw_y_axisCmd, "draw_y_axisCmd", 14}, {draw_y_box_plotCmd, "draw_y_box_plotCmd", 18}, {draw_zero_lineCmd, "draw_zero_lineCmd", 17}, {end_groupCmd, "end_groupCmd", 12}, {expectingCmd, "expectingCmd", 12}, {filter_columnCmd, "filter_columnCmd", 16}, {filter_gridCmd, "filter_gridCmd", 14}, {filter_imageCmd, "filter_imageCmd", 15}, {flipCmd, "flipCmd", 7}, {get_envCmd, "get_envCmd", 10}, {get_optionsCmd, "get_optionsCmd", 14}, {groupCmd, "groupCmd", 8}, {healCmd, "healCmd", 7}, {helpCmd, "helpCmd", 7}, {ignoreCmd, "ignoreCmd", 9}, {inputCmd, "inputCmd", 8}, {insertCmd, "insertCmd", 9}, {interpolateCmd, "interpolateCmd", 14}, {listCmd, "listCmd", 7}, {lsCmd, "lsCmd", 5}, {maskCmd, "maskCmd", 7}, {newCmd, "newCmd", 6}, {new_pageCmd, "new_pageCmd", 11}, {new_postscript_fileCmd, "new_postscript_fileCmd", 22}, {nullCmd, "nullCmd", 7}, {openCmd, "openCmd", 7}, {postscriptCmd, "postscriptCmd", 13}, {pwdCmd, "pwdCmd", 6}, {queryCmd, "queryCmd", 8}, {quitCmd, "quitCmd", 7}, {read_colornamesCmd, "read_colornamesCmd", 18}, {read_columnsCmd, "read_columnsCmd", 15}, {read_from_filenameCmd, "read_from_filenameCmd", 21}, {read_gridCmd, "read_gridCmd", 12}, {read_imageCmd, "read_imageCmd", 13}, {read_image_colorscaleCmd, "read_image_colorscaleCmd", 24}, {read_image_grayscaleCmd, "read_image_grayscaleCmd", 23}, {read_image_maskCmd, "read_image_maskCmd", 18}, {read_image_mask_rasterfileCmd, "read_image_mask_rasterfileCmd", 29}, {read_image_pgmCmd, "read_image_pgmCmd", 17}, {read_image_rasterfileCmd, "read_image_rasterfileCmd", 24}, {read_synonym_or_variableCmd, "read_synonym_or_variableCmd", 27}, {read_lineCmd, "read_lineCmd", 12}, {regressCmd, "regressCmd", 10}, {reorder_columnsCmd, "reorder_columnsCmd", 18}, {rpnfunctionCmd, "rpnfunctionCmd", 14}, {rescaleCmd, "rescaleCmd", 10}, // resizeCmd is written in Gri {rewindCmd, "rewindCmd", 9}, {set_axes_styleCmd, "set_axes_styleCmd", 17}, {set_arrow_sizeCmd, "set_arrow_sizeCmd", 17}, {set_arrow_typeCmd, "set_arrow_typeCmd", 17}, {set_beepCmd, "set_beepCmd", 11}, {set_bounding_boxCmd, "set_bounding_boxCmd", 19}, {set_clipCmd, "set_clipCmd", 11}, {set_colorCmd, "set_colorCmd", 12}, {set_colornameCmd, "set_colornameCmd", 16}, {set_contour_formatCmd, "set_contour_formatCmd", 21}, {set_contour_labelCmd, "set_contour_labelCmd", 20}, {set_contour_labelsCmd, "set_contour_labelsCmd", 21}, {set_dashCmd, "set_dashCmd", 11}, {set_environment, "set_environmentCmd", 18}, {set_error_actionCmd, "set_error_actionCmd", 19}, {set_flagCmd, "set_flagCmd", 11}, {set_font_colorCmd, "set_font_colorCmd", 17}, {set_font_encodingCmd, "set_font_encodingCmd", 20}, {set_font_sizeCmd, "set_font_sizeCmd", 16}, {set_font_toCmd, "set_font_toCmd", 14}, {set_graylevelCmd, "set_graylevelCmd", 16}, {set_grid_missingCmd, "set_grid_missingCmd", 19}, {set_image_colorscaleCmd, "set_image_colorscaleCmd", 23}, {set_image_grayscale_using_hist,"set_image_grayscale_using_histogram", 35}, {set_image_grayscaleCmd, "set_image_grayscaleCmd", 22}, {set_image_missingCmd, "set_image_missingCmd", 20}, {set_image_rangeCmd, "set_image_rangeCmd", 18}, {set_ignore_initial_newlineCmd, "set_ignore_initial_newlineCmd", 29}, {set_ignoreCmd, "set_ignoreCmd", 13}, {set_input_data_windowCmd, "set_input_data_windowCmd", 24}, {set_input_data_separatorCmd, "set_input_data_separatorCmd", 27}, {set_line_capCmd, "set_line_capCmd", 15}, {set_line_joinCmd, "set_line_joinCmd", 16}, {set_line_widthCmd, "set_line_widthCmd", 17}, {set_missing_valueCmd, "set_missing_valueCmd", 20}, {set_pageCmd, "set_pageCmd", 11}, {set_page_sizeCmd, "set_page_sizeCmd", 16}, {set_pathCmd, "set_pathCmd", 11}, {set_postscript_filenameCmd, "set_postscript_filenameCmd", 26}, {set_symbol_sizeCmd, "set_symbol_sizeCmd", 18}, {set_ticsCmd, "set_ticsCmd", 11}, {set_tic_sizeCmd, "set_tic_sizeCmd", 15}, {set_transparencyCmd, "set_transparencyCmd", 19}, {set_u_scaleCmd, "set_u_scaleCmd", 14}, {set_v_scaleCmd, "set_v_scaleCmd", 14}, {set_traceCmd, "set_traceCmd", 12}, {set_x_axisCmd, "set_x_axisCmd", 13}, {set_x_formatCmd, "set_x_formatCmd", 15}, {set_x_gridCmd, "set_x_gridCmd", 13}, {set_x_marginCmd, "set_x_marginCmd", 15}, {set_x_nameCmd, "set_x_nameCmd", 13}, {set_x_sizeCmd, "set_x_sizeCmd", 13}, {set_x_typeCmd, "set_x_typeCmd", 13}, {set_y_axisCmd, "set_y_axisCmd", 13}, {set_y_axis_nameCmd, "set_y_axis_nameCmd", 18}, {set_y_axisCmd, "set_y_axisCmd", 13}, {set_y_formatCmd, "set_y_formatCmd", 15}, {set_y_gridCmd, "set_y_gridCmd", 13}, {set_y_marginCmd, "set_y_marginCmd", 15}, {set_y_nameCmd, "set_y_nameCmd", 13}, {set_y_sizeCmd, "set_y_sizeCmd", 13}, {set_y_typeCmd, "set_y_typeCmd", 13}, {set_z_missingCmd, "set_z_missingCmd", 16}, {setCmd, "setCmd", 6}, {show_allCmd, "show_allCmd", 11}, {show_axesCmd, "show_axesCmd", 12}, {show_colorCmd, "show_colorCmd", 13}, {show_colornamesCmd, "show_colornamesCmd", 18}, {show_columnsCmd, "show_columnsCmd", 15}, {show_expression_or_stringCmd, "show_expression_or_stringCmd", 28}, {show_flagsCmd, "show_flagsCmd", 13}, {show_gridCmd, "show_gridCmd", 12}, {show_imageCmd, "show_imageCmd", 13}, {show_licenseCmd, "show_licenseCmd", 15}, {show_miscCmd, "show_miscCmd", 12}, {show_next_lineCmd, "show_next_lineCmd", 17}, {show_stopwatchCmd, "show_stopwatchCmd", 17}, {show_synonymsCmd, "show_synonymsCmd", 16}, {show_timeCmd, "show_timeCmd", 12}, {show_tracebackCmd, "show_tracebackCmd", 17}, {show_variablesCmd, "show_variablesCmd", 17}, {smoothCmd, "smoothCmd", 9}, {sourceCmd, "sourceCmd", 9}, {skipCmd, "skipCmd", 7}, {sleepCmd, "sleepCmd", 8}, {sprintfCmd, "sprintfCmd", 10}, {stateCmd, "stateCmd", 8}, {systemCmd, "systemCmd", 9}, {superuserCmd, "superuserCmd", 12}, {unlinkCmd, "unlinkCmd", 9}, {whileCmd, "whileCmd", 8}, {writeCmd, "writeCmd", 8}, {0, "", 0} }; #endif // _tags_hh �����������������gri/src/grstring.cc���������������������������������������������������������������������������������0000644�0001750�0001750�00000226514�13147557614�012767� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ //#define DEBUG 1 #include #include #include #include #include #include #include "gr.hh" #include "extern.hh" #include "GriPath.hh" #include "superus.hh" #include "defaults.hh" #define NCODES 100 // symbol_code (p 604 new PostScript book): (1) define name, (2) Postscript // code, (3) symbol-font crossref code (used for estimage of symbol // size, by index_for_math_symbol() ... a bad idea, really), and (4) // SVG code [broken; need to transcribe the codes from // http://www.w3.org/TR/html4/sgml/entities.html#h-24.3 one by one] static char *symbol_code[NCODES][4] = { // name, code in Table E.11, p604 new ps book, char-equivalent} // // Organization of list below is as in the tables in // Lamport's Latex book // // Table 3.3 Greek Letters // lowercase {(char *)"alpha", (char *)"\\141", (char *)"a", (char *)"α"}, {(char *)"beta", (char *)"\\142", (char *)"b", (char *)"β"}, {(char *)"gamma", (char *)"\\147", (char *)"g", (char *)"γ"}, {(char *)"delta", (char *)"\\144", (char *)"d", (char *)"δ"}, {(char *)"epsilon", (char *)"\\145", (char *)"e", (char *)"ε"}, // varepsilon {(char *)"zeta", (char *)"\\172", (char *)"z", (char *)"θ"}, {(char *)"eta", (char *)"\\150", (char *)"h", (char *)"η"}, {(char *)"theta", (char *)"\\161", (char *)"q", (char *)"θ"}, {(char *)"vartheta", (char *)"\\112", (char *)"q", (char *)"ϑ"}, {(char *)"iota", (char *)"\\151", (char *)"i", (char *)"┻"}, {(char *)"kappa", (char *)"\\153", (char *)"k", (char *)"κ"}, {(char *)"lambda", (char *)"\\154", (char *)"l", (char *)"λ"}, {(char *)"mu", (char *)"\\155", (char *)"m", (char *)"μ"}, {(char *)"nu", (char *)"\\156", (char *)"n", (char *)"ν"}, {(char *)"xi", (char *)"\\170", (char *)"x", (char *)"ξ"}, // o [not needed, really] {(char *)"pi", (char *)"\\160", (char *)"p", (char *)"π"}, {(char *)"varpi", (char *)"\\166", (char *)"p", (char *)"π"}, {(char *)"rho", (char *)"\\162", (char *)"r", (char *)"ρ"}, {(char *)"sigma", (char *)"\\163", (char *)"s", (char *)"σ"}, // or 962 {(char *)"varsigma", (char *)"\\126", (char *)"s", (char *)"ς"}, {(char *)"tau", (char *)"\\164", (char *)"t", (char *)"τ"}, {(char *)"upsilon", (char *)"\\165", (char *)"u", (char *)"υ"}, {(char *)"psi", (char *)"\\171", (char *)"y", (char *)"ψ"}, {(char *)"chi", (char *)"\\143", (char *)"c", (char *)"χ"}, {(char *)"phi", (char *)"\\146", (char *)"f", (char *)"φ"}, {(char *)"varphi", (char *)"\\152", (char *)"f", (char *)"φ"}, //? {(char *)"omega", (char *)"\\167", (char *)"w", (char *)"ω"}, // // Uppercase {(char *)"Gamma", (char *)"\\107", (char *)"G", (char *)"Γ"}, {(char *)"Delta", (char *)"\\104", (char *)"D", (char *)"Δ"}, {(char *)"Theta", (char *)"\\121", (char *)"Q", (char *)"Θ"}, {(char *)"Lambda", (char *)"\\114", (char *)"L", (char *)"Λ"}, {(char *)"Xi", (char *)"\\130", (char *)"X", (char *)"Ξ"}, {(char *)"Pi", (char *)"\\120", (char *)"P", (char *)"Π"}, {(char *)"Sigma", (char *)"\\123", (char *)"S", (char *)"Σ"}, {(char *)"Upsilon", (char *)"\\241", (char *)"Y", (char *)"Υ"}, {(char *)"Phi", (char *)"\\106", (char *)"F", (char *)"Φ"}, {(char *)"Psi", (char *)"\\131", (char *)"Y", (char *)"Ψ"}, {(char *)"Omega", (char *)"\\127", (char *)"W", (char *)"Ω"}, // Table 3.4: Binary Operation Symbols {(char *)"pm", (char *)"\\261", (char *)"+", (char *)"±"}, // guess that size is same as + // mp {(char *)"times", (char *)"\\264", (char *)"x", (char *)"×"}, // guess that size is same as x {(char *)"div", (char *)"\\270", (char *)"x", (char *)"÷"}, // guess that size is same as x {(char *)"ast", (char *)"\\052", (char *)"*", (char *)"∗"}, // star {(char *)"circ", (char *)"\\260", (char *)".", (char *)"°"}, {(char *)"bullet", (char *)"\\267", (char *)"*", (char *)"•"}, // guess that size is same as * {(char *)"cdot", (char *)"\\327", (char *)",", (char *)"·"}, // ? Georgian comma // cap // cup // uplus // sqcap // sqcup // vee {(char *)"wedge", (char *)"\\331", (char *)"M", (char *)"∧"}, // guess that size is same as M // setminus // wr // diamond // bigtriangleup // bigtriangledown // triangleleft // triangleright // lhd // rhd // unlhd // unrhd {(char *)"oplus", (char *)"\\305", (char *)"o", (char *)"⊕"}, // ominus {(char *)"otimes", (char *)"\\304", (char *)"o", (char *)"⊗"}, // oslash // odot // bigcirc // dagger // ddagger // amalg // // Table 3.5: Relation Symbols {(char *)"leq", (char *)"\\243", (char *)"<", (char *)"≤"}, // guess that size is same as < // prec // preceq // ll {(char *)"subset", (char *)"\\314", (char *)"<", (char *)"⊂"}, // guess that size is same as < {(char *)"subseteq", (char *)"\\315", (char *)"<", (char *)"⊆"}, // guess that size is same as < // sqsubset // sqsubseteq // MOVE 'in' to after 'infty' // vdash {(char *)"geq", (char *)"\\263", (char *)">", (char *)"≥"}, // succ // succeq // gg {(char *)"supset", (char *)"\\311", (char *)">", (char *)"⊃"}, {(char *)"supseteq", (char *)"\\312", (char *)">", (char *)"⊇"}, // sqsupset // sqsupseteq // ni // dashv {(char *)"equiv", (char *)"\\272", (char *)"=", (char *)"≡"}, {(char *)"sim", (char *)"\\176", (char *)"~", (char *)"∼"}, // simeq // asymp {(char *)"approx", (char *)"\\273", (char *)"~", (char *)"≆"}, // ? {(char *)"cong", (char *)"\\100", (char *)"=", (char *)"∼"}, // ? {(char *)"neq", (char *)"\\271", (char *)"=", (char *)"≠"}, // doteq {(char *)"propto", (char *)"\\265", (char *)"~", (char *)"∝"}, // models {(char *)"perp", (char *)"\\136", (char *)"M", (char *)"⊥"}, // mid // parallel // bowtie // join // smile // frown // // Table 3.6: Arrow Symbols {(char *)"leftarrow", (char *)"\\254", (char *)"M", (char *)"←"}, {(char *)"Leftarrow", (char *)"\\334", (char *)"M", (char *)"⇐"}, {(char *)"rightarrow", (char *)"\\256", (char *)"M", (char *)"→"}, {(char *)"Rightarrow", (char *)"\\336", (char *)"M", (char *)"⇒"}, {(char *)"leftrightarrow", (char *)"\\253", (char *)"M", (char *)"↔"}, {(char *)"Leftrightarrow", (char *)"\\333", (char *)"M", (char *)"⇔"}, // mapsto // hookleftarrow // leftharpoonup // leftharpoondown // rightleftharpoons // longleftarrow // Longleftarrow // longrightarrow // Longrightarrow // longleftrightarrow // Longleftrightarrow // longmapsto // hookrightarrow // rightharpoonup // rightharpoon down // leadsto {(char *)"uparrow", (char *)"\\255", (char *)"|", (char *)"↑"}, {(char *)"Uparrow", (char *)"\\335", (char *)"|", (char *)"⇑"}, {(char *)"downarrow", (char *)"\\257", (char *)"|", (char *)"↓"}, {(char *)"Downarrow", (char *)"\\337", (char *)"|", (char *)"⇓"}, // updownarrow // Updownarrow // neararrow // searrow // swarrow // nwarrow // // Table 3.7: Miscellaneous Symbols {(char *)"aleph", (char *)"\\300", (char *)"M", (char *)"ℵ"}, // ? // hbar // imath // jmath // ell {(char *)"wp", (char *)"\\303", (char *)"M", (char *)"&#;8476"}, // BUG: figure out what this is {(char *)"Re", (char *)"\\302", (char *)"R", (char *)"&#;8476"}, {(char *)"Im", (char *)"\\301", (char *)"M", (char *)"ℑ"}, // mho {(char *)"prime", (char *)"\\242", (char *)"'", (char *)"′"}, {(char *)"emptyset", (char *)"\\306", (char *)"M", (char *)"&#;8709"}, {(char *)"nabla", (char *)"\\321", (char *)"M", (char *)"∇"}, {(char *)"surd", (char *)"\\326", (char *)"M", (char *)"√"}, {(char *)"sqrt", (char *)"\\326", (char *)"M", (char *)"√"}, // top {(char *)"bot", (char *)"\\136", (char *)"M", (char *)"&#;8730"}, // BUG: no idea what this is // | {(char *)"angle", (char *)"\\320", (char *)"M", (char *)"∠"}, {(char *)"forall", (char *)"\\042", (char *)"M", (char *)"∀"}, {(char *)"exists", (char *)"\\044", (char *)"M", (char *)"∃"}, {(char *)"neg", (char *)"\\330", (char *)"M", (char *)"¬"}, // flat // natural // sharp // backslash {(char *)"partial", (char *)"\\266", (char *)"d", (char *)"∂"}, {(char *)"infty", (char *)"\\245", (char *)"M", (char *)"∞"}, // Interpose 'int' and 'in' here to avoid clashes with 'infty' {(char *)"int", (char *)"\\362", (char *)"M", (char *)"∫"}, {(char *)"in", (char *)"\\316", (char *)"<", (char *)"∈"}, // Box // Diamond // triangle {(char *)"clubsuit", (char *)"\\247", (char *)"M", (char *)"♣"}, {(char *)"diamondsuit", (char *)"\\340", (char *)"M", (char *)"♦"}, // heartsuit {(char *)"spadesuit", (char *)"\\252", (char *)"M", (char *)"♥"}, // // Table 3.8 Variable-sized symbols {(char *)"sum", (char *)"\\345", (char *)"M", (char *)"∑"}, {(char *)"prod", (char *)"\\325", (char *)"M", (char *)"∏"}, // int -- moved up to avoid name clashes // oint // bigcap // bigcup // bigsqcup // bigvee // bigwedge // bigodot // bigotimes // bigoplus // biguplus // // Table 3.10 {(char *)"lfloor", (char *)"\\353", (char *)"M", (char *)"⌊"}, {(char *)"lceil", (char *)"\\351", (char *)"M", (char *)"⌈"}, {(char *)"langle", (char *)"\\341", (char *)"<", (char *)"〈"}, {(char *)"rfloor", (char *)"\\373", (char *)"M", (char *)"⌋"}, {(char *)"rceil", (char *)"\\371", (char *)"M", (char *)"⌉"}, {(char *)"rangle", (char *)"\\361", (char *)">", (char *)"〉"} // backslash SEE ABOVE // \| // uparrow SEE ABOVE // downarrow SEE ABOVE // updownarrow SEE ABOVE // Uparrow SEE ABOVE // Downarrow SEE ABOVE // Updownarrow SEE ABOVE }; double gr_current_descender(void); std::vector part_string(const std::string &s) { using namespace std; string::size_type i, lasti = 0, len = s.size(); bool inmath = false; vector parts; for (i = 0; i < len; i++) { if (s[i] == '$') { // \$ escapes but not \\$ if (i > 0 && s[i-1] == '\\') { if (!(i > 1 && s[i-2] == '\\')) continue; } if (inmath) i++; // keep the $ at the end parts.push_back(s.substr(lasti, i-lasti)); inmath = !inmath; lasti = i; } } parts.push_back(s.substr(lasti, len-lasti)); #if 0 printf("\n\"%s\"\n", s.c_str()); for (unsigned int l = 0; l < parts.size(); l++) printf(" \"%s\"\n", parts[l].c_str()); #endif return parts; } const char* gr_fontname_from_id(int id); #define default_fontID gr_font_Helvetica #define default_encoding font_encoding_isolatin1 #define default_fontsize_pt 12.0 static gr_font CurrentFont = { default_fontID, default_encoding, default_fontsize_pt }; // Q: should this be done in Moveup() routine? [then what about $N$N though] #define START_NEW_TEXT {\ if (_output_file_type == postscript && _grWritePS) { \ fprintf(_grPS, "(");\ check_psfile();\ }\ } #define STOP_OLD_TEXT {\ if (_output_file_type == postscript && _grWritePS) {\ fprintf(_grPS, ") sh\n");\ check_psfile();\ }\ } enum position {Superscript, Subscript, Inline}; // Baseline indicator static std::stack pstack; // baseline position stack // Use spacing patterned on results of a TeX example (using Large font). All // quantities are multiples of Mspace. static const double SubSize = 0.75; // relative height of subscripts = 6/8 static const double SuperSize = 0.75; // relative height of superscripts = 6/8 static const double SuperMoveUp =0.625; // Move up for super = 5/8 static const double SubMoveDown =0.375; // Move down for sub = 3/8 #define PS_showpage "grestore\nshowpage\n" #define PS_stroke "s\n" extern FILE *_grPS; extern FILE *_grSVG; extern bool _grNeedBegin; extern bool _grPathExists; extern bool _grWritePS; static void gr_drawstring(const char *s); static void gr_drawchar_svg(char c, double xcm, double ycm, gr_fontID font_id); static void gr_drawsymbol_svg(int index, double xcm, double ycm, gr_fontID font_id); static void gr_drawstring_svg(const char *s, double xcm, double ycm, double angle); //static int index_for_math_symbol(const char *s); // base routine static double gr_charwidth_cm(int c, int font, double fontsize_pt); static void gr_DrawChar(const char *c); static void gr_setfont_fontsize(gr_fontID newID, bool force = false); static void pstack_erase(); static void MoveDown(void); static void MoveUp(void); static void MoveUp_svg(double *xcm, double *ycm); static void MoveDn_svg(double *xcm, double *ycm); static void MoveHorizontally(double em_distance); static int symbol_in_math(const char *sPtr, int *inc); gr_font_info font_list[] = { {gr_font_Courier, (char *)"Courier"}, {gr_font_CourierOblique, (char *)"Courier-Oblique"}, {gr_font_CourierBold, (char *)"Courier-Bold"}, {gr_font_CourierBoldOblique, (char *)"Courier-BoldOblique"}, {gr_font_Helvetica, (char *)"Helvetica"}, {gr_font_HelveticaBold, (char *)"Helvetica-Bold"}, {gr_font_HelveticaOblique, (char *)"Helvetica-Oblique"}, {gr_font_PalatinoRoman, (char *)"Palatino-Roman"}, {gr_font_PalatinoItalic, (char *)"Palatino-Italic"}, {gr_font_PalatinoBold, (char *)"Palatino-Bold"}, {gr_font_PalatinoBoldItalic, (char *)"Palatino-BoldItalic"}, {gr_font_Symbol, (char *)"Symbol"}, {gr_font_TimesRoman, (char *)"Times-Roman"}, {gr_font_TimesItalic, (char *)"Times-Italic"}, {gr_font_TimesBold, (char *)"Times-Bold"}, {gr_font_TimesBoldItalic, (char *)"Times-BoldItalic"}, {gr_font_Century, (char *)"Century"}, {gr_font_end_of_list, (char *)""} }; // Draw text at specified location. void gr_show_at(/*const*/ char *s, double xcm, double ycm, gr_textStyle style, double angle_deg) { #ifdef DEBUG printf("DEBUG %s:%d gr_show_at(\"%s\",xcm,ycm,style,%f)\n",__FILE__,__LINE__,s,angle_deg); #endif if (0.0 == gr_currentfontsize_pt() || !strlen(s)) { return; } double oldfontsize_pt = gr_currentfontsize_pt(); gr_fontID oldfontID = gr_currentfont(); double width_cm, ascent_cm, descent_cm; rectangle box; extern bool _warn_offpage; if (_warn_offpage && ( xcm < OFFPAGE_LEFT || xcm > OFFPAGE_RIGHT || ycm < OFFPAGE_BOTTOM || ycm > OFFPAGE_TOP)) { warning("Drawing text at a location that is offpage."); } const char *fn_svg = NULL; double r, g, b; _griState.color_text().getRGB(&r, &g, &b); switch (_output_file_type) { case postscript: break; case svg: switch (CurrentFont.id) { case gr_font_Courier: fn_svg = "Courier"; break; case gr_font_CourierOblique: fn_svg = "Courier-Italic"; break; case gr_font_CourierBold: fn_svg = "Courier-Bold"; break; case gr_font_CourierBoldOblique: fn_svg = "Courier-BoldItalic"; break; case gr_font_Helvetica: fn_svg = "Helvetica"; break; case gr_font_HelveticaOblique: fn_svg = "Helvetica-Italic"; break; case gr_font_HelveticaBold: fn_svg = "Helvetica-Bold"; break; case gr_font_PalatinoRoman: case gr_font_PalatinoItalic: case gr_font_PalatinoBold: case gr_font_PalatinoBoldItalic: fn_svg = "Times"; warning("SVG cannot handle Palatino font yet"); break; case gr_font_Symbol: fn_svg = "Symbol"; break; case gr_font_TimesRoman: fn_svg = "Times"; break; case gr_font_TimesItalic: fn_svg = "Times-Italic"; break; case gr_font_TimesBold: fn_svg = "Times-Bold"; break; case gr_font_TimesBoldItalic: fn_svg = "Times-BoldItalic"; break; case gr_font_Century: fn_svg = "Century"; break; default: fn_svg = "Times"; warning("SVG defaulting to Times font"); break; } break; case gif: fprintf(stderr, "INTERNAL error at %s:%d -- nothing known for GIF\n\n", __FILE__, __LINE__); exit(99); break; } // if (_output_file_type == svg) { // fprintf(stderr, "%s:%d approximating drawing of '%s' NOTE: subscripts, etc won't work\n", __FILE__, __LINE__, s); // } void set_ps_color(char what); set_ps_color('t'); gr_setfontsize_pt(oldfontsize_pt); gr_setfont(oldfontID); gr_stringwidth(s, &width_cm, &ascent_cm, &descent_cm); switch (style) { case TEXT_LJUST: gr_moveto_cm(xcm, ycm); if (_output_file_type == postscript) { if (_grWritePS) { if (fabs(angle_deg) > 0.1) fprintf(_grPS, "%.2f rotate ", angle_deg); gr_drawstring(s); } } else if (_output_file_type == svg) { gr_drawstring_svg(s, xcm, ycm, angle_deg); } else { fprintf(stderr, "%s:%d unknown file output type\n",__FILE__,__LINE__); } // This box not tested specifically box.set(0, -descent_cm, width_cm, ascent_cm); box.rotate(angle_deg); box.shift_x(xcm); box.shift_y(ycm); break; case TEXT_RJUST: if (_output_file_type == postscript) { if (_grWritePS) { fprintf(_grPS, "%.1f %.1f m ", PT_PER_CM * (xcm - width_cm * cos(angle_deg / DEG_PER_RAD)), PT_PER_CM * (ycm - width_cm * sin(angle_deg / DEG_PER_RAD))); if (fabs(angle_deg) > 0.1) fprintf(_grPS, "%.2f rotate ", angle_deg); gr_drawstring(s); } } else if (_output_file_type == svg) { if (_grWritePS) { gr_drawstring_svg(s, xcm - width_cm * cos(angle_deg / DEG_PER_RAD), ycm - width_cm * sin(angle_deg / DEG_PER_RAD), angle_deg); } } else { fprintf(stderr, "%s:%d unknown file output type\n",__FILE__,__LINE__); } // This box not tested specifically box.set(-width_cm, -descent_cm, 0.0, ascent_cm); box.rotate(angle_deg); box.shift_x(xcm); box.shift_y(ycm); break; case TEXT_CENTERED: if (_output_file_type == postscript) { if (_grWritePS) { #ifdef DEBUG fprintf(_grPS, "%% DEBUG %s:%d '%s' at angle %f\n",__FILE__,__LINE__,s,angle_deg); #endif fprintf(_grPS, "%.1f %.1f m ", PT_PER_CM * (xcm - 0.5 * width_cm * cos(angle_deg / DEG_PER_RAD)), PT_PER_CM * (ycm - 0.5 * width_cm * sin(angle_deg / DEG_PER_RAD))); if (fabs(angle_deg) > 0.1) fprintf(_grPS, "%.2f rotate ", angle_deg); gr_drawstring(s); } } else if (_output_file_type == svg) { if (_grWritePS) { gr_drawstring_svg(s, xcm - 0.5 * width_cm * cos(angle_deg / DEG_PER_RAD), ycm - 0.5 * width_cm * sin(angle_deg / DEG_PER_RAD), angle_deg); } } else { fprintf(stderr, "%s:%d unknown file output type\n",__FILE__,__LINE__); } box.set(-width_cm/2, -descent_cm, width_cm/2, ascent_cm); box.rotate(angle_deg); box.shift_x(xcm); box.shift_y(ycm); break; default: warning("gr_show_at type is UNKNOWN\n"); } switch (_output_file_type) { case postscript: if (_grWritePS) { if (fabs(angle_deg) > 0.1) fprintf(_grPS, "%.2f rotate ", -angle_deg); check_psfile(); //fprintf(_grPS, "%% gr_show_at() END\n"); } break; case svg: //fprintf(_grSVG, "\n"); break; case gif: fprintf(stderr, "INTERNAL error at %s:%d -- nothing known for GIF\n\n", __FILE__, __LINE__); exit(99); break; default: fprintf(stderr, "%s:%d unknown file output type\n",__FILE__,__LINE__); break; // BUG: should check filetype here } // Update bounding box bounding_box_update(box); _drawingstarted = true; } // gr_drawstring() -- draw string, including font changes &super/subscripts static void gr_drawstring(const char *s) { char slast = '\0'; int slen = strlen(s); bool inmath = false; gr_fontID original_font = gr_currentfont(); gr_fontID current_font = original_font; gr_fontID slant_font = original_font; // prevent compiler warning double original_fontsize = gr_currentfontsize_pt(); bool know_slant_font = false; #ifdef DEBUG printf("DEBUG %s:%d gr_drawstring(\"%s\")\n",__FILE__,__LINE__,s); #endif if (slen <= 0) return; if (0.0 == gr_currentfontsize_pt()) return; // Figure out slant font, if there is an appropriate one switch (original_font) { case gr_font_TimesRoman: slant_font = gr_font_TimesItalic; know_slant_font = true; break; case gr_font_TimesBold: slant_font = gr_font_TimesBoldItalic; know_slant_font = true; break; case gr_font_Helvetica: slant_font = gr_font_HelveticaOblique; know_slant_font = true; break; case gr_font_HelveticaBold: slant_font = gr_font_HelveticaBoldOblique; know_slant_font = true; break; case gr_font_Courier: slant_font = gr_font_CourierOblique; know_slant_font = true; break; case gr_font_CourierBold: slant_font = gr_font_CourierBoldOblique; know_slant_font = true; break; case gr_font_PalatinoRoman: slant_font = gr_font_PalatinoItalic; know_slant_font = true; break; case gr_font_PalatinoBold: slant_font = gr_font_PalatinoBoldItalic; know_slant_font = true; break; case gr_font_Century: slant_font = gr_font_TimesItalic; // BUG: should be Century Italic know_slant_font = true; break; default: know_slant_font = false; } // Scan through whole string. START_NEW_TEXT; while (*s != '\0') { #ifdef DEBUG // printf("DEBUG(%s:%d) *s= '%c'\n",__FILE__,__LINE__,*s); #endif if (*s == '-' && CurrentFont.encoding == font_encoding_isolatin1) { // Use a different character to avoid looking like underscore. if (_grWritePS) { STOP_OLD_TEXT; fprintf(_grPS, "(\\255) sh\n"); // endash check_psfile(); START_NEW_TEXT; } s++; continue; } // Figure out whether entering or leaving math mode; enter/leave if // find $ without preceeding \. Thus a$b$ has math but a\$b\$ does // not. if (*s == '$' && slast != '\\') { if (inmath) { #ifdef DEBUG printf("DEBUG(%s:%d) got $ so leave math mode\n",__FILE__,__LINE__); printf("DEBUG(%s:%d) pstack size is %d\n",__FILE__,__LINE__,int(pstack.size())); #endif // Were in math; now go back to original font. inmath = false; if (current_font != original_font) { current_font = original_font; STOP_OLD_TEXT; gr_setfont(current_font); START_NEW_TEXT; } if (!pstack.empty()) { warning("a text string ended without completing a mathematical grouping (superscript, subscript, or {block})"); pstack_erase(); } } else { #ifdef DEBUG printf("DEBUG(%s:%d) got $ so enter math mode\n",__FILE__,__LINE__); #endif // Go to Italic/Oblique font, as case may be. Unfortunately, // PostScript uses different names for this slanted font. inmath = true; if (know_slant_font) { current_font = slant_font; STOP_OLD_TEXT; gr_setfont(current_font); START_NEW_TEXT; } if (!pstack.empty()) { warning("a text string started without an empty mathematical grouping (superscript, subscript, or {block})"); pstack_erase(); } } slast = *s++; continue; } // Handle math mode. This code is a little kludgy, so be carefull. if (inmath) { if (*s == '^') { // Handle superscripts slast = *s++; if (*s == '\0') { // Odd -- nothing to superscript if (current_font != original_font) { STOP_OLD_TEXT; gr_setfontsize_pt(original_fontsize); gr_setfont(original_font); } return; } else if (*s == '{') { // Several characters to superscript pstack.push(Superscript); #ifdef DEBUG printf("DEBUG(%s:%d) pushed superscript=%d onto stack to make length %d\n",__FILE__,__LINE__,Superscript, int(pstack.size())); #endif MoveUp(); } else if (*s == '\\') { // Math character to superscript int inc; int symbol_index = symbol_in_math(s, &inc); if (inc) { gr_fontID oldfontID = gr_currentfont(); pstack.push(Superscript); #ifdef DEBUG printf("DEBUG(%s:%d) pushed subscript=%d onto stack to make length %d\n",__FILE__,__LINE__,Superscript, int(pstack.size())); #endif MoveUp(); STOP_OLD_TEXT; gr_setfont(gr_font_Symbol); if (_grWritePS) { fprintf(_grPS, "(%s) sh\n", symbol_code[symbol_index][1]); check_psfile(); } gr_setfont(oldfontID); START_NEW_TEXT; s += inc; #ifdef DEBUG printf("DEBUG(%s:%d) about to pop stack (was %d) to make length %d\n",__FILE__,__LINE__,pstack.top(), int(pstack.size())-1); #endif MoveDown(); pstack.pop(); } } else { // Single character to superscript pstack.push(Superscript); #ifdef DEBUG printf("DEBUG(%s:%d) pushed subscript=%d onto stack to make length %d\n",__FILE__,__LINE__,Subscript, int(pstack.size())); #endif MoveUp(); // Draw single character in math mode. If it's a digit, // do not do in italics! if (isdigit(*s) || ispunct(*s)) { if (*s == '/' && !isdigit(slast)) { gr_DrawChar(s); } else { STOP_OLD_TEXT; gr_setfont(original_font); START_NEW_TEXT; gr_DrawChar(s); STOP_OLD_TEXT; gr_setfont(slant_font); START_NEW_TEXT; } } else { gr_DrawChar(s); } MoveDown(); #ifdef DEBUG printf("DEBUG(%s:%d) about to pop stack (was %d) to make length %d\n",__FILE__,__LINE__,pstack.top(), int(pstack.size())-1); #endif pstack.pop(); } } else if (*s == '_') { // Handle subscript slast = *s++; if (*s == '\0') { // Odd -- nothing to subscript if (current_font != original_font) { STOP_OLD_TEXT; gr_setfontsize_pt(original_fontsize); gr_setfont(original_font); } return; } else if (*s == '{') { // Several characters to subscript pstack.push(Subscript); #ifdef DEBUG printf("DEBUG(%s:%d) pushed subscript=%d onto stack to make length %d\n",__FILE__,__LINE__,Subscript, int(pstack.size())); #endif MoveDown(); } else if (*s == '\\') { // Math character to subscript int inc; int symbol_index = symbol_in_math(s, &inc); if (symbol_index > -1) { gr_fontID oldfontID = gr_currentfont(); pstack.push(Subscript); #ifdef DEBUG printf("DEBUG(%s:%d) pushed subscript=%d onto stack to make length %d\n",__FILE__,__LINE__,Subscript, int(pstack.size())); #endif MoveDown(); STOP_OLD_TEXT; gr_setfont(gr_font_Symbol); if (_grWritePS) { fprintf(_grPS, "(%s) sh\n", symbol_code[symbol_index][1]); check_psfile(); } gr_setfont(oldfontID); START_NEW_TEXT; s += inc; MoveUp(); #ifdef DEBUG printf("DEBUG(%s:%d) about to pop stack (was %d) to make length %d\n",__FILE__,__LINE__,pstack.top(), int(pstack.size())-1); #endif pstack.pop(); } } else { // Single character to subscript pstack.push(Subscript); #ifdef DEBUG printf("DEBUG(%s:%d) pushed subscript=%d onto stack to make length %d\n",__FILE__,__LINE__,Subscript, int(pstack.size())); #endif MoveDown(); // Draw single character in math mode. If it's a digit, // do not do in italics! if (isdigit(*s) || ispunct(*s)) { if (*s == '/' && !isdigit(slast)) { gr_DrawChar(s); } else { STOP_OLD_TEXT; gr_setfont(original_font); START_NEW_TEXT; gr_DrawChar(s); STOP_OLD_TEXT; gr_setfont(slant_font); START_NEW_TEXT; } } else { gr_DrawChar(s); } MoveUp(); #ifdef DEBUG printf("DEBUG(%s:%d) about to pop stack (was %d) to make length %d\n",__FILE__,__LINE__,pstack.top(), int(pstack.size())-1); #endif pstack.pop(); } } else if (*s == '{') { // just a grouping, not a baseline shift pstack.push(Inline); #ifdef DEBUG printf("DEBUG(%s:%d) pushed Inline=%d onto stack to make length %d\n",__FILE__,__LINE__,Inline,int(pstack.size())); #endif } else if (*s == '}') { // finished with Superscript/Subscript/Inline if (pstack.size() > 0) { position p = pstack.top(); if (p == Superscript) { MoveDown(); } else if (p == Subscript) { MoveUp(); } // ignore inline #ifdef DEBUG printf("DEBUG(%s:%d) about to pop stack (was %d) to make length %d\n",__FILE__,__LINE__,pstack.top(), int(pstack.size())-1); #endif pstack.pop(); } else { warning("unmatched \"}\" in a mathematicsal string"); } } else if (*s == '\\') { // Substitute math symbol, unless it's // an escaped string if (*(s + 1) == '$') { slast = *s++; } else if (*(s + 1) == ',') { slast = *s++; MoveHorizontally(0.1666666); // thinspace } else if (*(s + 1) == '!') { slast = *s++; MoveHorizontally(-0.1666666); // neg thinspace } else if (*(s + 1) == '"') { slast = *s++; } else if (*(s + 1) == '\\') { slast = *s++; } else if (*(s + 1) == '{' || *(s + 1) == '}') { STOP_OLD_TEXT; gr_setfont(original_font); START_NEW_TEXT; gr_DrawChar(s + 1); STOP_OLD_TEXT; gr_setfont(slant_font); START_NEW_TEXT; slast = *s++; } else { int inc; int symbol_index = symbol_in_math(s, &inc); if (inc) { // math symbol in symbol font gr_fontID oldfontID = gr_currentfont(); STOP_OLD_TEXT; gr_setfont(gr_font_Symbol); if (_grWritePS) { fprintf(_grPS, "(%s) sh\n", symbol_code[symbol_index][1]); check_psfile(); } gr_setfont(oldfontID); START_NEW_TEXT; s += inc; } else { // Not a known math-mode symbol, so just // draw it. Is this the right thing to do? gr_DrawChar(s + 1); } } } else { // Draw single character in math mode. // If it's a digit, do not use italics. if (isdigit(*s) || ispunct(*s)) { if (*s == '/' && !isdigit(slast)) { gr_DrawChar(s); } else { STOP_OLD_TEXT; gr_setfont(original_font); START_NEW_TEXT; gr_DrawChar(s); STOP_OLD_TEXT; gr_setfont(slant_font); START_NEW_TEXT; } } else { gr_DrawChar(s); } } } else { // draw simple character outside math mode if (*s == '\\') { if (*(s + 1) == '$') { slast = *s++; } else if (*(s + 1) == '"') { slast = *s++; } else if (*(s + 1) == '\\') { slast = *s++; } } gr_DrawChar(s); } slast = *s++; } STOP_OLD_TEXT; gr_setfontsize_pt(original_fontsize); gr_setfont(original_font); _drawingstarted = true; if (!pstack.empty()) { warning("a text string ended without completing a mathematical grouping (superscript, subscript, or {block})"); pstack_erase(); } return; } const char* gr_fontname_from_id(int id) { switch (id) { case gr_font_Courier: return("Courier"); case gr_font_CourierOblique: return("Courier-Italic"); case gr_font_CourierBold: return("Courier-Bold"); case gr_font_CourierBoldOblique: return("Courier-BoldItalic"); case gr_font_Helvetica: return("Helvetica"); case gr_font_HelveticaOblique: return("Helvetica-Italic"); case gr_font_HelveticaBold: return("Helvetica-Bold"); case gr_font_PalatinoRoman: case gr_font_PalatinoItalic: case gr_font_PalatinoBold: case gr_font_PalatinoBoldItalic: warning("SVG cannot handle Palatino font yet"); return("Times"); case gr_font_Symbol: return("Symbol"); case gr_font_TimesRoman: return("Times"); case gr_font_TimesItalic: return("Times-Italic"); case gr_font_TimesBold: return("Times-Bold"); case gr_font_TimesBoldItalic: return("Times-BoldItalic"); case gr_font_Century: return("Century"); } warning("SVG defaulting to Times font"); return("Times"); } static void gr_drawchar_svg(char c, double xcm, double ycm, gr_fontID font_id) { double size = gr_currentfontsize_pt(); const char *font_style; //printf("%s:%d | gr_drawchar_svg('%c', ...) decodes to '%c' font_id=.s\n", __FILE__, __LINE__, c, symbol_code[int(c)][1]);//, gr_fontID); if (pstack.size() > 0) size *= SuperSize; if (isdigit(c) || font_id == gr_font_Symbol) font_style = "normal"; else font_style = "italic"; const char *fill = _griState.color_text().get_hexcolor().c_str(); double transparency = _griState.color_text().getT(); fprintf(_grSVG, "%c\n", xcm * PT_PER_CM, /*gr_page_height_pt() -*/ -ycm * PT_PER_CM, gr_fontname_from_id(font_id), size, font_style, fill, 1.0 - transparency, fill, c); gr_setfont(font_id); char st[2]; st[0] = c; st[1] = '\0'; double w, a, d; double oldfontsize = gr_currentfontsize_pt(); gr_setfontsize_pt(size); gr_stringwidth(st, &w, &a, &d); // BUG: NEED TO SET FONT FIRST gr_setfontsize_pt(oldfontsize); //*xcm += w; } static void gr_drawsymbol_svg(int index, double xcm, double ycm, gr_fontID font_id) { double size = gr_currentfontsize_pt(); const char *font_style; //printf("%s:%d | gr_drawchar_svg('%c', ...) decodes to '%c' font_id=.s\n", __FILE__, __LINE__, c, symbol_code[int(c)][1]);//, gr_fontID); if (pstack.size() > 0) size *= SuperSize; if (font_id == gr_font_Symbol) font_style = "normal"; else font_style = "italic"; const char *fill = _griState.color_text().get_hexcolor().c_str(); double transparency = _griState.color_text().getT(); if (font_id == gr_font_Symbol) { fprintf(_grSVG, "%s\n", xcm * PT_PER_CM, /*gr_page_height_pt() -*/ -ycm * PT_PER_CM, gr_fontname_from_id(font_id), size, font_style, fill, 1.0 - transparency, fill, symbol_code[index][3]); } else { fprintf(_grSVG, "%s\n", xcm * PT_PER_CM, /*gr_page_height_pt() -*/ -ycm * PT_PER_CM, gr_fontname_from_id(font_id), size, font_style, fill, 1.0 - transparency, fill, "?"); } gr_setfont(font_id); char st[2]; st[0] = 'm'; // guess at width st[1] = '\0'; double w, a, d; double oldfontsize = gr_currentfontsize_pt(); gr_setfontsize_pt(size); gr_stringwidth(st, &w, &a, &d); // BUG: NEED TO SET FONT FIRST gr_setfontsize_pt(oldfontsize); //*xcm += w; // BUG } static void gr_drawstring_svg(const char *s, double xcm, double ycm, double angle) { #ifdef DEBUG printf("DEBUG %s:%d gr_drawstring_svg(s=\"%s\", xcm=%f, ycm=%f, angle=%f)\n", __FILE__,__LINE__, s, xcm, ycm, angle); #endif int slen = strlen(s); gr_fontID original_font = gr_currentfont(); gr_fontID slant_font = original_font; // prevent compiler warning double original_fontsize = gr_currentfontsize_pt(); bool know_slant_font = false; if (slen <= 0) return; if (0.0 == gr_currentfontsize_pt()) return; // Figure out slant font, if there is an appropriate one switch (original_font) { case gr_font_TimesRoman: slant_font = gr_font_TimesItalic; know_slant_font = true; break; case gr_font_TimesBold: slant_font = gr_font_TimesBoldItalic; know_slant_font = true; break; case gr_font_Helvetica: slant_font = gr_font_HelveticaOblique; know_slant_font = true; break; case gr_font_HelveticaBold: slant_font = gr_font_HelveticaBoldOblique; know_slant_font = true; break; case gr_font_Courier: slant_font = gr_font_CourierOblique; know_slant_font = true; break; case gr_font_CourierBold: slant_font = gr_font_CourierBoldOblique; know_slant_font = true; break; case gr_font_PalatinoRoman: slant_font = gr_font_PalatinoItalic; know_slant_font = true; break; case gr_font_PalatinoBold: slant_font = gr_font_PalatinoBoldItalic; know_slant_font = true; break; case gr_font_Century: slant_font = gr_font_TimesItalic; // BUG: should be Century Italic know_slant_font = true; break; default: know_slant_font = false; } std::vector parts; parts = part_string(s); int nparts = parts.size(); double xxcm = xcm, yycm = ycm; fprintf(_grSVG, "\n", xxcm*PT_PER_CM, gr_page_height_pt() - yycm*PT_PER_CM); xxcm = yycm = 0.0; fprintf(_grSVG, "\n", -angle); angle = 0.0; // BUG: not sure if this is the best method //printf("DEBUG (%s)\n", _griState.color_text().get_hexcolor().c_str()); for (int i = 0; i < nparts; i++) { double w, a, d; std::string p = parts[i]; gr_stringwidth(p.c_str(), &w, &a, &d); //printf(" \"%s\" w=%f a=%f d=%f\n", parts[i].c_str(),w,a,d); if (p[0] != '$') { // Normal text fprintf(_grSVG, "%s\n", xxcm * PT_PER_CM, /*gr_page_height_pt() -*/ -yycm * PT_PER_CM, gr_fontname_from_id(original_font), original_fontsize, _griState.color_text().get_hexcolor().c_str(), 1.0 - _griState.color_text().getT(), _griState.color_text().get_hexcolor().c_str(), p.c_str()); xxcm += w; //FIXME: should s/\$/$/ first } else { // Math text unsigned int ic, nc = p.size(); // w = gr_thinspace_cm() / 1.0; // put a bit of space before math // xxcm += w; if (p[nc-1] == '$') nc--; fprintf(_grSVG, "\n\n"); for (ic = 1; ic < nc; ic++) { #ifdef DEBUG printf(" -- %d [%c] --\n", ic, p[ic]); #endif if (p[ic] == '\\') { // HEREHEREHERE if (p[ic+1] == '\\') { gr_drawsymbol_svg(-1, xxcm, yycm, original_font); ic += 1; continue; } int inc; int symbol_index = symbol_in_math(p.c_str() + ic, &inc); if (inc) { gr_drawsymbol_svg(symbol_index, xxcm, yycm, gr_font_Symbol); ic += inc; } else { gr_drawstring_svg("?", xxcm, yycm, gr_font_Symbol); } } else if (p[ic] == '{') { // ignore pstack.push(Inline); ic++; continue; } else if (p[ic] == '}') { if (pstack.size() > 0) { position p = pstack.top(); if (p == Superscript) { MoveDn_svg(&xxcm, &yycm); } else if (p == Subscript) { MoveUp_svg(&xxcm, &yycm); } #ifdef DEBUG printf("DEBUG(%s:%d) about to pop stack (was %d) to make length %d\n",__FILE__,__LINE__,pstack.top(), int(pstack.size())-1); #endif pstack.pop(); } else { warning("unmatched \"}\" in a mathematical string"); } } else if (p[ic] == '_') { pstack.push(Subscript); MoveDn_svg(&xxcm, &yycm); if (p[ic+1] != '{') { // BUG: should check for symbol gr_drawchar_svg(p[ic+1], xxcm, yycm, original_font); MoveUp_svg(&xxcm, &yycm); pstack.pop(); } ic++; continue; } else if (p[ic] == '^') { pstack.push(Superscript); MoveUp_svg(&xxcm, &yycm); if (p[ic+1] != '{') { // BUG: should check for symbol gr_drawchar_svg(p[ic+1], xxcm, yycm, original_font); MoveDn_svg(&xxcm, &yycm); pstack.pop(); } ic++; continue; } else { gr_drawchar_svg(p[ic], xxcm, yycm, original_font); } } fprintf(_grSVG, "\n"); } } fprintf(_grSVG, "\n"); // rotate fprintf(_grSVG, "\n"); // translate return; } // set fontsize in points void gr_setfontsize_pt(double fontsize_pt) { if (fontsize_pt < 0.0) CurrentFont.size_pt = default_fontsize_pt; else CurrentFont.size_pt = fontsize_pt; gr_setfont_fontsize(CurrentFont.id); } // Set font encoding void gr_set_font_encoding(gr_font_encoding encoding) { CurrentFont.encoding = encoding; } // Get font encoding gr_font_encoding gr_current_font_encoding() { return CurrentFont.encoding; } /* * gr_currentfont() -- find current font synopsis int gr_currentfont() * description: gets the current font,as set by gr_setfont(). return value: * current font number. */ gr_fontID gr_currentfont() { return CurrentFont.id; } /* * gr_currentfontsize_pt() -- return current fontsize in points */ double gr_currentfontsize_pt() { return CurrentFont.size_pt; } /* * gr_setfont() -- set new font. SYNOPSIS void gr_setfont(int new_font) * DESCRIPTION: Sets the font for future string drawing to 'new_font'. These * fonts are predefined: TimesRoman Helvetica Courier Symbol Palatino-Roman * Palatino-Italic. * */ void gr_setfont(gr_fontID newID, bool force /* default false */) { gr_setfont_fontsize(newID, force); } static void gr_setfont_fontsize(gr_fontID newID, bool force) { int i = 0; static bool have_set_font = false; static gr_font last_font; /* Search the font list */ while (font_list[i].id != gr_font_end_of_list) { if (newID == font_list[i].id) { /* Found the font, but ignore request if no change */ if (force || (!have_set_font || newID != last_font.id || CurrentFont.encoding != last_font.encoding || CurrentFont.size_pt != last_font.size_pt)) { CurrentFont.id = newID; if (!_grNeedBegin) { /* * Don't try to write if haven't done gr_begin() yet, * since then will ruin things like * gr_setup_ps_filename(); */ if (_grWritePS) { switch (CurrentFont.encoding) { case font_encoding_standard: fprintf(_grPS, "/%s findfont ", font_list[i].name); break; case font_encoding_isolatin1: if (CurrentFont.id == gr_font_Symbol) fprintf(_grPS, "/%s findfont ", font_list[i].name); else fprintf(_grPS, "/%s-ISOLatin1 findfont ", font_list[i].name); break; } fprintf(_grPS, "%.2f sc sf\n", CurrentFont.size_pt); } have_set_font = true; last_font.id = newID; last_font.encoding = CurrentFont.encoding; last_font.size_pt = CurrentFont.size_pt; } } return; } i++; } warning("Ignoring request for unknown font."); } static int symbol_in_math(const char *sPtr, int *inc) // handle greek letter or symbol in math mode { sPtr++; *inc = 0; for (int i = 0; i < NCODES; i++) { int len = strlen(symbol_code[i][0]); if (!strncmp(sPtr, symbol_code[i][0], len)) { *inc = len; return i; } } return -1; } // Clear the position stack (doesn't STL do this??) static void pstack_erase() { while (!pstack.empty()) { position p = pstack.top(); if (p == Superscript) { MoveDown(); } else if (p == Subscript) { MoveUp(); } // ignore inline #ifdef DEBUG if (p == Superscript) printf("\tcleared Superscript from position stack\n"); else if (p == Subscript) printf("\tcleared Subscript from position stack\n"); #endif pstack.pop(); } } // Move left/right by indicated number of M spaces static void MoveHorizontally(double em_distance) { double w, a, d; gr_stringwidth("M", &w, &a, &d); STOP_OLD_TEXT; gr_rmoveto_cm(em_distance * w, 0.0); START_NEW_TEXT; } // MoveUp() -- move up, shifting to smaller/larger size if necessary static void MoveUp_svg(double *xcm, double *ycm) { #ifdef DEBUG printf("DEBUG(%s:%d) moving text position up one level. Stack size on entry = %d\n", __FILE__,__LINE__,(int)pstack.size()); #endif if (!pstack.size()) return; double dy; // See if already in subscript. position p = pstack.top(); if (p == Subscript) { // Moving up from subscript, so enlarge font, then undo last move // down. gr_setfontsize_pt(gr_currentfontsize_pt() / SubSize); dy = SubMoveDown * gr_currentCapHeight_cm(); } else { // Moving up from inline or superscript, so move up, then reduce font. dy = SuperMoveUp * gr_currentCapHeight_cm(); gr_setfontsize_pt(gr_currentfontsize_pt() * SuperSize); } // ignore Inline *ycm += dy; } // MoveDown() -- move down, shifting to smaller/larger size if necessary static void MoveDn_svg(double *xcm, double *ycm) { #ifdef DEBUG printf("DEBUG(%s:%d) moving text position down one level\n", __FILE__,__LINE__); #endif if (!pstack.size()) return; double dy; position p = pstack.top(); // See if already in superscript. if (p == Superscript) { // Moving down from superscript, so enlarge font, then undo last move up. gr_setfontsize_pt(gr_currentfontsize_pt() / SuperSize); dy = -SuperMoveUp * gr_currentCapHeight_cm(); } else { // Moving down from inline or subscript, so move down, then reduce font. dy = -SubMoveDown * gr_currentCapHeight_cm(); gr_setfontsize_pt(gr_currentfontsize_pt() * SubSize); } *ycm += dy; } static void MoveUp() { #ifdef DEBUG printf("DEBUG(%s:%d) moving text position up one level\n", __FILE__,__LINE__); #endif STOP_OLD_TEXT; // See if already in subscript. position p = pstack.top(); if (p == Subscript) { // Moving up from subscript, so enlarge font, then undo last move // down. gr_setfontsize_pt(gr_currentfontsize_pt() / SubSize); gr_rmoveto_pt(0.0, SubMoveDown * gr_currentCapHeight_cm() * PT_PER_CM); } else { // Moving up from inline or superscript, so move up, then reduce font. gr_rmoveto_pt(0.0, SuperMoveUp * gr_currentCapHeight_cm() * PT_PER_CM); gr_setfontsize_pt(gr_currentfontsize_pt() * SuperSize); } // ignore Inline START_NEW_TEXT; } // MoveDown() -- move down, shifting to smaller/larger size if necessary static void MoveDown() { #ifdef DEBUG printf("DEBUG(%s:%d) moving text position down one level\n", __FILE__,__LINE__); #endif STOP_OLD_TEXT; position p = pstack.top(); // See if already in superscript. if (p == Superscript) { // Moving down from superscript, so enlarge font, then undo last move up. gr_setfontsize_pt(gr_currentfontsize_pt() / SuperSize); gr_rmoveto_pt(0.0, -SuperMoveUp * gr_currentCapHeight_cm() * PT_PER_CM); } else { // Moving down from inline or subscript, so move down, then reduce font. gr_rmoveto_pt(0.0, -SubMoveDown * gr_currentCapHeight_cm() * PT_PER_CM); gr_setfontsize_pt(gr_currentfontsize_pt() * SubSize); } START_NEW_TEXT; } static void gr_DrawChar(const char *c) { extern bool _grWritePS; if (_grWritePS) { extern FILE *_grPS; switch (*c) { case '\\': fprintf(_grPS, "\\\\"); break; case '(': fprintf(_grPS, "\\("); break; case ')': fprintf(_grPS, "\\)"); break; default: fprintf(_grPS, "%c", *c); break; } check_psfile(); } _drawingstarted = true; } // Draw indicated text in a "whiteout" box of indicated color, left-right // centered at the indicated (x,y) locn specified in user-units. The text // and box will be rotated by gr_currenttextangle_deg() degrees, measured // counterclockwise from the horizontal. void gr_show_in_box(/*const*/GriString &s, const GriColor& text_color, const GriColor& box_color, double x, // cm units double y, double angle_deg) { GriColor old_text_color = _griState.color_text(); GriColor old_line_color = _griState.color_line(); double width, ascent, descent; double x0, y0, dx, dy, dx_rot, dy_rot; double thin_space = gr_thinspace_cm(); if (0.0 == gr_currentfontsize_pt()) return; gr_stringwidth(s.getValue(), &width, &ascent, &descent); x0 = x; // save y0 = y; // White out below text. dx = -0.5 * width - thin_space; dy = -thin_space; gr_rotate_xy(dx, dy, angle_deg, &dx_rot, &dy_rot); static GriPath p(5); p.clear(); p.push_back(x0 + dx_rot, y0 + dy_rot, 'm'); dx = -dx; gr_rotate_xy(dx, dy, angle_deg, &dx_rot, &dy_rot); p.push_back(x0 + dx_rot, y0 + dy_rot, 'l'); dx = 0.5 * width + thin_space; dy = ascent + thin_space; gr_rotate_xy(dx, dy, angle_deg, &dx_rot, &dy_rot); p.push_back(x0 + dx_rot, y0 + dy_rot, 'l'); dx = -dx; gr_rotate_xy(dx, dy, angle_deg, &dx_rot, &dy_rot); p.push_back(x0 + dx_rot, y0 + dy_rot, 'l'); p.push_back(x0 + dx_rot, y0 + dy_rot, 'l'); _griState.set_color_line(box_color); p.fill(units_cm); bounding_box_update(p.bounding_box(units_cm)); // Draw text _griState.set_color_text(text_color); dx = -0.5 * width; dy = 0.0; gr_rotate_xy(dx, dy, angle_deg, &dx_rot, &dy_rot); gr_show_at(s.getValue(), x0 + dx_rot, y0 + dy_rot, TEXT_LJUST, angle_deg); _griState.set_color_line(old_line_color); _griState.set_color_text(old_text_color); _drawingstarted = true; } // Rotate (x,y) into (xx,yy), through `angle' degrees counterclockwise. void gr_rotate_xy(double x, double y, double angle, double *xx, double *yy) { angle /= DEG_PER_RAD; // convert to radians double c = cos(angle); double s = sin(angle); *xx = c * x - s * y; *yy = s * x + c * y; } // Get the width, ascent and descent of string s, in current font. // BUG: Ascent and descent are inaccurate. // BUG: Smaller size of super/subscripts not accounted for. void gr_stringwidth(const char *s, double *w, double *a, double *d) { *w = *a = *d = 0.0; if (strlen(s) == 0) return; bool used_supers = false; bool used_subs = false; bool inmath = false; bool oldWritePS = _grWritePS; double oldfontsize_pt = gr_currentfontsize_pt(); _grWritePS = false; while (*s != '\0') { // figure out whether entering or leaving math mode if (*s == '$' && *(s - 1) != '\\') { #ifdef DEBUG printf("DEBUG %s:%d toggling inmath; rest of string is \"%s\"\n",__FILE__,__LINE__,s); #endif inmath = (inmath ? false : true); s++; continue; } // handle math mode differently // ?? BUG Superscripts and subscripts are printed smaller, but // ?? BUG their size is assumed to be the same as normal chars. if (inmath) { if (*s == '^') // handle superscript used_supers = true; else if (*s == '_') // handle subscript used_subs = true; else if (*s == '{') // ignore groups while computing string length ; // EMPTY else if (*s == '}') // ignore groups ; // EMPTY else if (*s == '\\') { // handle synonym // First catch thinspace commands if (*(s + 1) == ',') { // Thinspace = Mwidth/6 *w += gr_charwidth_cm((int)'M', CurrentFont.id, CurrentFont.size_pt) / 6.0; s += 1; } else if (*(s + 1) == '!') { // Negative thinspace = -Mwidth/6 *w -= gr_charwidth_cm((int)'M', CurrentFont.id, CurrentFont.size_pt) / 6.0; s += 1; } else { int inc; int symbol_index = symbol_in_math(s, &inc); if (symbol_index > -1) { gr_fontID oldfontID = CurrentFont.id; s += inc; // *w += gr_charwidth_cm("m" symbol_code[symbol_index][1], gr_font_Symbol, CurrentFont.size_pt); *w += gr_charwidth_cm('m', gr_font_Symbol, CurrentFont.size_pt); // BUG CurrentFont.id = oldfontID; } else { // it's not a known math symbol *w += gr_charwidth_cm('\\', CurrentFont.id, CurrentFont.size_pt); } } } else { // We are in math-mode, but it's not a special character. Add // appropriate amount for either super/subscript or normal // character. *w += gr_charwidth_cm((int) *s, CurrentFont.id, CurrentFont.size_pt); } } else { // not inmath *w += gr_charwidth_cm((int) *s, CurrentFont.id, CurrentFont.size_pt); } s++; } // Calculate ascent/descent. BUG: doesn't take math chars into acct *a = gr_currentCapHeight_cm() * (1 + (used_supers ? 1 : 0) * (SuperSize + SuperMoveUp - 1)); #if 0 // before 2.054 *d = gr_currentCapHeight_cm() * (1.0 + 0.5 * (int) used_subs); #endif *d = gr_current_descender() * (1 + (used_subs ? 1.0 : 0.0) * (SubSize + SubMoveDown - 1)); #ifdef DEBUG printf("DEBUG %s:%d gr_stringwidth(s=\"%s\",...) RETURNING w=%f, a=%f d=%f\n", __FILE__,__LINE__,s,*w,*a,*d); #endif // reset fontsize ... can't do with gr_setfontsize_pt() // because that would call this function in infinite recursion. CurrentFont.size_pt = oldfontsize_pt; _grWritePS = oldWritePS; } #if 0 // return index (for size-table) for a character (given as integer) static int index_for_math_symbol(const char *s) { //printf("index_for_math_symbol(%s)\n",s); if (!s) return (int)'?'; for (int i = 0; i < NCODES; i++) { //printf(" %3d (%s) (%s)\n", i, symbol_code[i][1],symbol_code[i][2]); if (!strncmp(s, symbol_code[i][1], strlen(symbol_code[i][1]))) { //printf(" match\n"); return (int) *symbol_code[i][2]; } //printf(" no match\n"); } //printf("index_for_math_symbol(%s) cannot find a match\n", s); return (int) 'M'; // a guess, since we have no clue } #endif // Return thinspace (=1/6 of width of "M" in current font), in cm double gr_thinspace_cm() { return (gr_charwidth_cm(int('M'), CurrentFont.id, CurrentFont.size_pt) / 6.0); } // Return width of quad (= width of "M" in current font), in cm double gr_quad_cm() { return (gr_charwidth_cm((int) 'M', CurrentFont.id, CurrentFont.size_pt)); } // Following page should substituted as output from // ~kelley/src/gri/src/get_font_metrics struct font_metric { float XHeight; float CapHeight; float Ascender; float Descender; float width[128]; }; // // Following font metric generated by `get_font_metrics' // perlscript from Font Metric file `/usr/openwin/lib/X11/fonts/F3/afm/Courier.afm'. // All measurement in centimetres, given a pointsize of 1.0 // // Created by Perl script get_font_metrics.pl struct font_metric CenturyRoman = { 0.016369, // XHeight 0.025471, // CapHeight 0.026000, // Ascender -0.007232, // Descender { // Widths of first 128 characters 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0098072, 0.0104422, 0.0137231, 0.0196144, 0.0196144, 0.0293864, 0.0287514, 0.0071967, 0.0117475, 0.0117475, 0.0176389, 0.0213783, 0.0098072, 0.0117475, 0.0098072, 0.0098072, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0098072, 0.0098072, 0.0213783, 0.0213783, 0.0213783, 0.0156633, 0.0259997, 0.0254706, 0.0254706, 0.0254706, 0.0274461, 0.0254706, 0.0235303, 0.0274461, 0.0293864, 0.0143581, 0.0196144, 0.0274461, 0.0235303, 0.0333022, 0.0287514, 0.0274461, 0.0235303, 0.0274461, 0.0254706, 0.0222250, 0.0235303, 0.0287514, 0.0254706, 0.0346075, 0.0248356, 0.0248356, 0.0215547, 0.0117475, 0.0213783, 0.0117475, 0.0213783, 0.0176389, 0.0071967, 0.0196144, 0.0196144, 0.0156633, 0.0202494, 0.0176389, 0.0117475, 0.0189442, 0.0215547, 0.0111125, 0.0104422, 0.0209197, 0.0111125, 0.0313619, 0.0215547, 0.0176389, 0.0202494, 0.0196144, 0.0156633, 0.0163336, 0.0137231, 0.0215547, 0.0189442, 0.0274461, 0.0189442, 0.0189442, 0.0169686, 0.0117475, 0.0213783, 0.0117475, 0.0213783, 0.0000000 } }; struct font_metric Courier = { 0.015028, // XHeight 0.019826, // CapHeight 0.022190, // Ascender -0.005539, // Descender { // Widths of first 128 characters 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0211667, 0.0000000 } }; // // Following font metric generated by `get_font_metrics' // perlscript from Font Metric file `/usr/openwin/lib/X11/fonts/F3/afm/Helvetica.afm'. // All measurement in centimetres, given a pointsize of 1.0 // struct font_metric Helvetica = { 0.018450, // XHeight 0.025329, // CapHeight 0.025329, // Ascender -0.007302, // Descender { // Widths of first 128 characters 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0098072, 0.0098072, 0.0125236, 0.0196144, 0.0196144, 0.0313619, 0.0235303, 0.0078317, 0.0117475, 0.0117475, 0.0137231, 0.0206022, 0.0098072, 0.0117475, 0.0098072, 0.0098072, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0098072, 0.0098072, 0.0206022, 0.0206022, 0.0206022, 0.0196144, 0.0358069, 0.0235303, 0.0235303, 0.0254706, 0.0254706, 0.0235303, 0.0215547, 0.0274461, 0.0254706, 0.0098072, 0.0176389, 0.0235303, 0.0196144, 0.0293864, 0.0254706, 0.0274461, 0.0235303, 0.0274461, 0.0254706, 0.0235303, 0.0215547, 0.0254706, 0.0235303, 0.0333022, 0.0235303, 0.0235303, 0.0215547, 0.0098072, 0.0098072, 0.0098072, 0.0165453, 0.0196144, 0.0078317, 0.0196144, 0.0196144, 0.0176389, 0.0196144, 0.0196144, 0.0098072, 0.0196144, 0.0196144, 0.0078317, 0.0078317, 0.0176389, 0.0078317, 0.0293864, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0117475, 0.0176389, 0.0098072, 0.0196144, 0.0176389, 0.0254706, 0.0176389, 0.0176389, 0.0176389, 0.0117828, 0.0091722, 0.0117828, 0.0206022, 0.0000000 } }; // // Following font metric generated by `get_font_metrics' // perlscript from Font Metric file `/usr/openwin/lib/X11/fonts/F3/afm/Helvetica-Oblique.afm'. // All measurement in centimetres, given a pointsize of 1.0 // struct font_metric Helvetica_Oblique = { 0.018450, // XHeight 0.025329, // CapHeight 0.025329, // Ascender -0.007302, // Descender { // Widths of first 128 characters 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0098072, 0.0098072, 0.0125236, 0.0196144, 0.0196144, 0.0313619, 0.0235303, 0.0078317, 0.0117475, 0.0117475, 0.0137231, 0.0206022, 0.0098072, 0.0117475, 0.0098072, 0.0098072, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0098072, 0.0098072, 0.0206022, 0.0206022, 0.0206022, 0.0196144, 0.0358069, 0.0235303, 0.0235303, 0.0254706, 0.0254706, 0.0235303, 0.0215547, 0.0274461, 0.0254706, 0.0098072, 0.0176389, 0.0235303, 0.0196144, 0.0293864, 0.0254706, 0.0274461, 0.0235303, 0.0274461, 0.0254706, 0.0235303, 0.0215547, 0.0254706, 0.0235303, 0.0333022, 0.0235303, 0.0235303, 0.0215547, 0.0098072, 0.0098072, 0.0098072, 0.0165453, 0.0196144, 0.0078317, 0.0196144, 0.0196144, 0.0176389, 0.0196144, 0.0196144, 0.0098072, 0.0196144, 0.0196144, 0.0078317, 0.0078317, 0.0176389, 0.0078317, 0.0293864, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0117475, 0.0176389, 0.0098072, 0.0196144, 0.0176389, 0.0254706, 0.0176389, 0.0176389, 0.0176389, 0.0117828, 0.0091722, 0.0117828, 0.0206022, 0.0000000 } }; // // Following font metric generated by `get_font_metrics' // perlscript from Font Metric file `/usr/openwin/lib/X11/fonts/F3/afm/Helvetica-Bold.afm'. // All measurement in centimetres, given a pointsize of 1.0 // struct font_metric Helvetica_Bold = { 0.018768, // XHeight 0.025329, // CapHeight 0.025329, // Ascender -0.007302, // Descender { // Widths of first 128 characters 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0098072, 0.0117475, 0.0167217, 0.0196144, 0.0196144, 0.0313619, 0.0254706, 0.0098072, 0.0117475, 0.0117475, 0.0137231, 0.0206022, 0.0098072, 0.0117475, 0.0098072, 0.0098072, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0196144, 0.0117475, 0.0117475, 0.0206022, 0.0206022, 0.0206022, 0.0215547, 0.0343958, 0.0254706, 0.0254706, 0.0254706, 0.0254706, 0.0235303, 0.0215547, 0.0274461, 0.0254706, 0.0098072, 0.0196144, 0.0254706, 0.0215547, 0.0293864, 0.0254706, 0.0274461, 0.0235303, 0.0274461, 0.0254706, 0.0235303, 0.0215547, 0.0254706, 0.0235303, 0.0333022, 0.0235303, 0.0235303, 0.0215547, 0.0117475, 0.0098072, 0.0117475, 0.0206022, 0.0196144, 0.0098072, 0.0196144, 0.0215547, 0.0196144, 0.0215547, 0.0196144, 0.0117475, 0.0215547, 0.0215547, 0.0098072, 0.0098072, 0.0196144, 0.0098072, 0.0313619, 0.0215547, 0.0215547, 0.0215547, 0.0215547, 0.0137231, 0.0196144, 0.0117475, 0.0215547, 0.0196144, 0.0274461, 0.0196144, 0.0196144, 0.0176389, 0.0137231, 0.0098778, 0.0137231, 0.0206022, 0.0000000 } }; // // Following font metric generated by `get_font_metrics' // perlscript from Font Metric file `/usr/openwin/lib/X11/fonts/F3/afm/Palatino-Roman.afm'. // All measurement in centimetres, given a pointsize of 1.0 // struct font_metric PalatinoRoman = { 0.016545, // XHeight 0.024412, // CapHeight 0.025612, // Ascender -0.009913, // Descender { // Widths of first 128 characters 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0088194, 0.0098072, 0.0130881, 0.0176389, 0.0176389, 0.0296333, 0.0274461, 0.0098072, 0.0117475, 0.0117475, 0.0137231, 0.0213783, 0.0088194, 0.0117475, 0.0088194, 0.0213783, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0088194, 0.0088194, 0.0213783, 0.0213783, 0.0213783, 0.0156633, 0.0263525, 0.0274461, 0.0215547, 0.0250119, 0.0273050, 0.0215547, 0.0196144, 0.0269169, 0.0293511, 0.0118886, 0.0117475, 0.0256117, 0.0215547, 0.0333728, 0.0293158, 0.0277283, 0.0213078, 0.0277283, 0.0235656, 0.0185208, 0.0216253, 0.0274461, 0.0254706, 0.0352778, 0.0235303, 0.0235303, 0.0235303, 0.0117475, 0.0213783, 0.0117475, 0.0213783, 0.0176389, 0.0098072, 0.0176389, 0.0195086, 0.0156633, 0.0215547, 0.0168981, 0.0117475, 0.0196144, 0.0205317, 0.0102658, 0.0082550, 0.0196144, 0.0102658, 0.0311503, 0.0205317, 0.0192617, 0.0212019, 0.0197556, 0.0139347, 0.0149578, 0.0115006, 0.0212725, 0.0199319, 0.0294217, 0.0182033, 0.0196144, 0.0176389, 0.0117475, 0.0213783, 0.0117475, 0.0213783, 0.0000000 } }; // Created by Perl script get_font_metrics.pl struct font_metric PalatinoItalic = { 0.017004, // XHeight 0.024412, // CapHeight 0.025859, // Ascender -0.009737, // Descender { // Widths of first 128 characters 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0088194, 0.0117475, 0.0176389, 0.0176389, 0.0176389, 0.0313619, 0.0274461, 0.0098072, 0.0117475, 0.0117475, 0.0137231, 0.0213783, 0.0088194, 0.0117475, 0.0088194, 0.0104422, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0088194, 0.0088194, 0.0213783, 0.0213783, 0.0213783, 0.0176389, 0.0263525, 0.0254706, 0.0215547, 0.0235303, 0.0274461, 0.0215547, 0.0196144, 0.0254706, 0.0274461, 0.0117475, 0.0117475, 0.0235303, 0.0196144, 0.0333022, 0.0274461, 0.0274461, 0.0215547, 0.0274461, 0.0235303, 0.0196144, 0.0215547, 0.0274461, 0.0254706, 0.0333022, 0.0254706, 0.0235303, 0.0235303, 0.0117475, 0.0213783, 0.0117475, 0.0213783, 0.0176389, 0.0098072, 0.0156633, 0.0163336, 0.0143581, 0.0176389, 0.0137231, 0.0098072, 0.0176389, 0.0176389, 0.0098072, 0.0098072, 0.0156633, 0.0098072, 0.0274461, 0.0196144, 0.0156633, 0.0176389, 0.0163336, 0.0137231, 0.0137231, 0.0117475, 0.0196144, 0.0176389, 0.0254706, 0.0176389, 0.0176389, 0.0156633, 0.0117475, 0.0213783, 0.0117475, 0.0213783, 0.0000000 } }; // Created by Perl script get_font_metrics.pl struct font_metric PalatinoBold = { 0.016616, // XHeight 0.024024, // CapHeight 0.025400, // Ascender -0.009102, // Descender { // Widths of first 128 characters 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0088194, 0.0098072, 0.0141817, 0.0176389, 0.0176389, 0.0313619, 0.0293864, 0.0098072, 0.0117475, 0.0117475, 0.0156633, 0.0213783, 0.0088194, 0.0117475, 0.0088194, 0.0104422, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0088194, 0.0088194, 0.0213783, 0.0213783, 0.0213783, 0.0156633, 0.0263525, 0.0274461, 0.0235303, 0.0254706, 0.0293864, 0.0215547, 0.0196144, 0.0293864, 0.0293864, 0.0137231, 0.0137231, 0.0274461, 0.0215547, 0.0352778, 0.0293864, 0.0293864, 0.0215547, 0.0293864, 0.0254706, 0.0215547, 0.0235303, 0.0274461, 0.0274461, 0.0352778, 0.0235303, 0.0235303, 0.0235303, 0.0117475, 0.0213783, 0.0117475, 0.0213783, 0.0176389, 0.0098072, 0.0176389, 0.0215547, 0.0156633, 0.0215547, 0.0176389, 0.0137231, 0.0196144, 0.0215547, 0.0117475, 0.0117475, 0.0215547, 0.0117475, 0.0313619, 0.0215547, 0.0196144, 0.0215547, 0.0215547, 0.0137231, 0.0156633, 0.0117475, 0.0215547, 0.0196144, 0.0293864, 0.0176389, 0.0196144, 0.0176389, 0.0109361, 0.0213783, 0.0109361, 0.0213783, 0.0000000 } }; // // Following font metric generated by `get_font_metrics' // perlscript from Font Metric file `/usr/openwin/lib/X11/fonts/F3/afm/Symbol.afm'. // All measurement in centimetres, given a pointsize of 1.0 // struct font_metric Symbol = { 0.000000, // XHeight 0.000000, // CapHeight 0.000000, // Ascender 0.000000, // Descender { // Widths of first 128 characters 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0088194, 0.0117475, 0.0251531, 0.0176389, 0.0193675, 0.0293864, 0.0274461, 0.0154869, 0.0117475, 0.0117475, 0.0176389, 0.0193675, 0.0088194, 0.0193675, 0.0088194, 0.0098072, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0098072, 0.0098072, 0.0193675, 0.0193675, 0.0193675, 0.0156633, 0.0193675, 0.0254706, 0.0235303, 0.0254706, 0.0215900, 0.0215547, 0.0269169, 0.0212725, 0.0254706, 0.0117475, 0.0222603, 0.0254706, 0.0242006, 0.0313619, 0.0254706, 0.0254706, 0.0270933, 0.0261408, 0.0196144, 0.0208844, 0.0215547, 0.0243417, 0.0154869, 0.0270933, 0.0227542, 0.0280458, 0.0215547, 0.0117475, 0.0304447, 0.0117475, 0.0232128, 0.0176389, 0.0176389, 0.0222603, 0.0193675, 0.0193675, 0.0174272, 0.0154869, 0.0183797, 0.0144992, 0.0212725, 0.0116064, 0.0212725, 0.0193675, 0.0193675, 0.0203200, 0.0183797, 0.0193675, 0.0193675, 0.0183797, 0.0193675, 0.0212725, 0.0154869, 0.0203200, 0.0251531, 0.0242006, 0.0173919, 0.0242006, 0.0174272, 0.0169333, 0.0070556, 0.0169333, 0.0193675, 0.0000000 } }; // // Following font metric generated by `get_font_metrics' // perlscript from Font Metric file `/usr/openwin/lib/X11/fonts/F3/afm/Times-Roman.afm'. // All measurement in centimetres, given a pointsize of 1.0 // struct font_metric TimesRoman = { 0.015875, // XHeight 0.023354, // CapHeight 0.024095, // Ascender -0.007655, // Descender { // Widths of first 128 characters 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0088194, 0.0117475, 0.0143933, 0.0176389, 0.0176389, 0.0293864, 0.0274461, 0.0117475, 0.0117475, 0.0117475, 0.0176389, 0.0198967, 0.0088194, 0.0117475, 0.0088194, 0.0098072, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0098072, 0.0098072, 0.0198967, 0.0198967, 0.0198967, 0.0156633, 0.0324908, 0.0254706, 0.0235303, 0.0235303, 0.0254706, 0.0215547, 0.0196144, 0.0254706, 0.0254706, 0.0117475, 0.0137231, 0.0254706, 0.0215547, 0.0313619, 0.0254706, 0.0254706, 0.0196144, 0.0254706, 0.0235303, 0.0196144, 0.0215547, 0.0254706, 0.0254706, 0.0333022, 0.0254706, 0.0254706, 0.0215547, 0.0117475, 0.0098072, 0.0117475, 0.0165453, 0.0176389, 0.0117475, 0.0156633, 0.0176389, 0.0156633, 0.0176389, 0.0156633, 0.0117475, 0.0176389, 0.0176389, 0.0098072, 0.0098072, 0.0176389, 0.0098072, 0.0274461, 0.0176389, 0.0176389, 0.0176389, 0.0176389, 0.0117475, 0.0137231, 0.0098072, 0.0176389, 0.0176389, 0.0254706, 0.0176389, 0.0176389, 0.0156633, 0.0169333, 0.0070556, 0.0169333, 0.0190853, 0.0000000 } }; /* * gr_charwidth_cm(char c, int font, double fontsize_pt) * * RETURN VALUE the width of the character, in centimetres * * Font info created by the `get_font_metrics' perlscript, in the Gri src * directory. This looks in the OpenWindows font metrics files to figure the * pertintent stuff out. (You might have to edit this for different * machines). */ static double gr_charwidth_cm(int c, int font, double fontsize_pt) { unsigned char i = (int) c; if (i > 127) return fontsize_pt * 0.0211663; /* error, but guess Courier size * anyway */ switch (font) { case gr_font_TimesRoman: return fontsize_pt * TimesRoman.width[i]; case gr_font_Courier: return fontsize_pt * 0.0211663; /* Courier has fixed width */ case gr_font_Symbol: return fontsize_pt * Symbol.width[i]; case gr_font_Helvetica: return fontsize_pt * Helvetica.width[i]; case gr_font_HelveticaBold: return fontsize_pt * Helvetica_Bold.width[i]; case gr_font_PalatinoRoman: return fontsize_pt * PalatinoRoman.width[i]; case gr_font_Century: return fontsize_pt * CenturyRoman.width[i]; default: break; /* Guess similar size to Helvetica */ } return (fontsize_pt * Helvetica.width[i]); } double gr_current_descender() // descender, in positive cm { switch (CurrentFont.id) { case gr_font_Courier: return (-CurrentFont.size_pt * Courier.Descender); case gr_font_Helvetica: return(-CurrentFont.size_pt * Helvetica.Descender); case gr_font_Symbol: return(-CurrentFont.size_pt * Symbol.Descender); case gr_font_TimesRoman: return(-CurrentFont.size_pt * TimesRoman.Descender); case gr_font_Century: return(-CurrentFont.size_pt * CenturyRoman.Descender); case gr_font_PalatinoRoman: return(-CurrentFont.size_pt * PalatinoRoman.Descender); case gr_font_PalatinoItalic: return(-CurrentFont.size_pt * PalatinoItalic.Descender); case gr_font_PalatinoBold: return(-CurrentFont.size_pt * PalatinoBold.Descender); default: break; } return CurrentFont.size_pt * 0.025329; // Guess similar to Helvetica } // gr_currentCapHeight_cm() -- find height of capital characters double gr_currentCapHeight_cm() { double height_cm = 0.0; switch (CurrentFont.id) { case gr_font_Courier: height_cm = (CurrentFont.size_pt * Courier.CapHeight); break; case gr_font_Helvetica: height_cm = (CurrentFont.size_pt * Helvetica.CapHeight); break; case gr_font_Symbol: height_cm = (CurrentFont.size_pt * Symbol.CapHeight); break; case gr_font_TimesRoman: height_cm = (CurrentFont.size_pt * TimesRoman.CapHeight); break; case gr_font_Century: height_cm = (CurrentFont.size_pt * CenturyRoman.CapHeight); break; case gr_font_PalatinoRoman: height_cm = (CurrentFont.size_pt * PalatinoRoman.CapHeight); break; case gr_font_PalatinoItalic: height_cm = (CurrentFont.size_pt * PalatinoItalic.CapHeight); break; case gr_font_PalatinoBold: height_cm = (CurrentFont.size_pt * PalatinoBold.CapHeight); break; default: /* * Don't know this font. */ break; } if (height_cm > 0.0) return height_cm; else return CurrentFont.size_pt * 0.025329; /* Guess Helvetica */ } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/Makefile.am���������������������������������������������������������������������������������0000644�0001750�0001750�00000023362�13147557614�012651� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Process this file with automake to produce Makefile.in # gri: src/Makefile.am srcdir = @srcdir@ VPATH = @srcdir@ SUBDIRS = popt DIST_SUBDIRS = popt bin_PROGRAMS = gri gri_LDADD = @LIBS@ popt/libgripopt.a gridir = $(datadir)/gri #gri_DATA = gri.cmd nodist_gri_SOURCES = startup.debian startup.redhat gri_SOURCES = main.cc G_string.cc GriColor.cc GriPath.cc GriState.cc assert.cc\ chopword.cc close.cc command.cc convert.cc debug.cc delete.cc differ.cc\ doline.cc draw.cc endup.cc expect.cc file.cc filter.cc flip.cc\ gr.cc gr_coll.cc graxes.cc grcntour.cc gri.cc grimage.cc grinterp.cc\ grsmooth.cc grstring.cc group.cc heal.cc help.cc if.cc ignore.cc\ image.cc input.cc insert.cc interp.cc mask.cc math.cc new.cc open.cc\ popen.cc query.cc quit.cc read.cc regress.cc reorder.cc rescale.cc\ rewind.cc rpn.cc rpncalc.cc scales.cc set.cc show.cc skip.cc sleep.cc\ smooth.cc source.cc startup.cc state.cc stats.cc storage.cc\ synonyms.cc template.cc timer.cc unlink.cc utility.cc variable.cc\ version.cc while.cc write.cc\ CmdFile.hh command.hh DataFile.hh debug.hh defaults.hh errors.hh\ extern.hh files.hh GCounter.hh GMatrix.hh gr_coll.hh gr.hh\ GriColor.hh GriPath.hh GriState.hh GriTimer.hh G_string.hh image_ex.hh\ install-sh macro.hh postscpt.hh private.hh superus.hh Synonym.hh\ tags.hh types.hh Variable.hh EXTRA_DIST = Makefile.dj2 \ gri.cmd-skel logo.dat rgb.txt\ gri-mode.el gri_merge gri_unpage\ startup.msg startup.debian startup.redhat PACKAGE_VERSION = @PACKAGE_VERSION@ #if OS_IS_LINUX_DEBIAN #DEFS = -DDEFAULT_GRI_DIR=\"$(prefix)/share/gri/$(PACKAGE_VERSION)/\" @DEFS@ #else #DEFS = -DDEFAULT_GRI_DIR=\"$(prefix)/share/gri/\" @DEFS@ #endif if OS_IS_APPLE_OSX DGD = /Applications/Gri else if OS_IS_LINUX_DEBIAN DGD = $(prefix)/share/gri/$(PACKAGE_VERSION)/ else if OS_IS_FINK DGD = /sw/share/gri/ else if OS_IS_OSX_BUNDLE OSX_BUNDLE = -DOSX_BUNDLE else DGD = ${prefix}/share/gri/ endif endif endif endif DEFS = -DDEFAULT_GRI_DIR=\"$(DGD)\" $(OSX_BUNDLE) @DEFS@ EXTRA_CFLAGS_TEMPLATE = @EXTRA_CFLAGS_TEMPLATE@ $(LINUX_EXTRA_CFLAGS) #### End of system configuration section. #### # Special rule for templates, so as not to use # -fno-implicit-templates (g++ weirdness). This special # case depends on whether -frepo exists ... and whether the installer # has temerity to try it! template.o: template.cc $(CXX) -c $(CXXFLAGS) $(EXTRA_CFLAGS_TEMPLATE) $(DEFS) -I$(srcdir) $< #.cc.o: # $(CXX) -c $(CXXFLAGS) $(EXTRA_CFLAGS) $(AM_CXXFLAGS) $(DEFS) -I$(srcdir) $< debian_lib = $(debian)/usr/share/gri/$(PACKAGE_VERSION) install_linux_debian: gri @echo "Installing into '$(debian)' directory" install -d $(debian_lib) if test -f startup.debian; then sed -e s,VERSION,${PACKAGE_VERSION}, startup.debian > $(debian_lib)/startup.msg; else echo "WARNING: no startup.debian file!"; fi; install -d $(debian)/usr/bin install -m 755 gri $(debian)/usr/bin/gri-$(PACKAGE_VERSION) (cd $(debian)/usr/bin; ln -fs gri-$(PACKAGE_VERSION) gri) install -m 644 gri.cmd $(debian_lib)/gri.cmd install -m 644 rgb.txt $(debian_lib)/rgb.txt install -m 644 logo.dat $(debian_lib)/logo.dat if test -f gri_merge; then install -m 755 gri_merge $(debian)/usr/bin; else echo "WARNING: no gri_merge file!"; fi; if test -f gri_unpage; then install -m 755 gri_unpage $(debian)/usr/bin; else echo "WARNING: no gri_unpage file!";fi; # install -d $(debian)/usr/share/emacs/site-lisp # install -m 644 gri-mode.el $(debian)/usr/share/emacs/site-lisp/ install_linux_debian_grionly: gri @echo "Installing into '$(debian)' directory" install -d $(debian_lib) install -m 644 gri.cmd $(debian_lib)/gri.cmd install -m 644 rgb.txt $(debian_lib)/rgb.txt install -m 644 logo.dat $(debian_lib)/logo.dat if test -f startup.debian; then sed -e s,VERSION,${PACKAGE_VERSION}, startup.debian > $(debian_lib)/startup.msg; else echo "WARNING: no startup.debian file!"; fi; install -d $(debian)/usr/bin install -m 755 gri $(debian)/usr/bin/gri-$(PACKAGE_VERSION) author_check: @perl $(srcdir)/check.pl check: @./gri -directory . -c 0 $(srcdir)/../doc/tst_suite/tst_var_syn.gri @./gri -directory . -c 0 $(srcdir)/../doc/tst_suite/tst_control.gri @./gri -directory . -c 0 $(srcdir)/../doc/tst_suite/tst_rpn.gri # The next few lines are a kludge since I got bored with trying # to figure out how to redirect things for automake. @cp $(srcdir)/../doc/tst_suite/tst_IO.gri . @cp $(srcdir)/../doc/tst_suite/tst_IO_1.dat . @cp $(srcdir)/../doc/tst_suite/tst_IO_2.dat . @./gri -directory . -c 0 tst_IO.gri @rm -f tst_IO.gri tst_IO_1.dat tst_IO_2.dat @cat $(srcdir)/../gri.spec | perl -ane 'if(/griversion (.*)/) {$$v=$$1; if ("$$v" ne "$(PACKAGE_VERSION)") {print "** Version in gri.spec ($$v) disagrees with $(PACKAGE_VERSION) in Makefile.\n"} else { print "Version number in gri.spec ... is OK\n";}}' @cat $(srcdir)/../debian/changelog | perl -ne 'if (($$. == 1)&&(/\(([^-]+)-/)) {if ("$$1" ne "$(PACKAGE_VERSION)") {print "** Version in debian/changelog ($$1) disagrees with $(PACKAGE_VERSION) in Makefile.\n"} else { print "Version number in debian/changelog ... is OK\n";}}' # @echo "" # @echo " /-----------------------------------------------------\\" # @echo " | NOTE: Developers should do 'make author_check' next |" # @echo " \\----------------------------------------------------/" # @echo "" # Sun microsystems, sunOS 5.x # NOTE: this target doesn't depend on 'gri' or 'doc', etc; this # is to be done manually, the first step perhaps on an # entirely different computer!! SUNOS5_NAME = gri-$(PACKAGE_VERSION)-SunOS5 package-SunOS5: -rm -rf $(SUNOS5_NAME) -mkdir -m 755 -p $(SUNOS5_NAME) -mkdir -m 755 -p $(SUNOS5_NAME)/bin -mkdir -m 755 -p $(SUNOS5_NAME)/lib -mkdir -m 755 -p $(SUNOS5_NAME)/doc -mkdir -m 755 -p $(SUNOS5_NAME)/doc/html -mkdir -m 755 -p $(SUNOS5_NAME)/doc/html/resources -mkdir -m 755 -p $(SUNOS5_NAME)/doc/html/screenshots -mkdir -m 755 -p $(SUNOS5_NAME)/doc/html/tst_suite -mkdir -m 755 -p $(SUNOS5_NAME)/doc/html/examples -cp -p gri $(SUNOS5_NAME)/bin -cp gri.cmd rgb.txt logo.dat copyright.txt license.txt gri-mode.el $(SUNOS5_NAME)/lib -cat startup.msg | sed -e s,VERSION,${PACKAGE_VERSION}, | sed -e "s/DATE/`date`/" > tmp -cp tmp $(SUNOS5_NAME)/lib/startup.msg -cat install-SunOS5 | sed -e s,VERSION,${PACKAGE_VERSION}, > tmp -cp tmp $(SUNOS5_NAME)/install -chmod a+rx $(SUNOS5_NAME)/install -cp README-SunOS5 $(SUNOS5_NAME)/README -cat ../doc/gri-manpage-SunOS5.1 | sed -e s,VERSION,${PACKAGE_VERSION}, >tmp -cp tmp $(SUNOS5_NAME)/doc/gri.1 -rm -f tmp # Next should really be done by "cd doc; make something" etc. -cp ../doc/*html $(SUNOS5_NAME)/doc/html -cp ../doc/*png $(SUNOS5_NAME)/doc/html -cp ../doc/resources/*gif $(SUNOS5_NAME)/doc/html/resources -cp ../doc/screenshots/*png $(SUNOS5_NAME)/doc/html/screenshots -cp ../doc/tst_suite/*dat ../doc/tst_suite/*gri ../doc/tst_suite/*html $(SUNOS5_NAME)/doc/html/tst_suite -cp ../doc/examples/*dat ../doc/examples/*gri ../doc/examples/*html $(SUNOS5_NAME)/doc/html/examples -tar chof $(SUNOS5_NAME).tar $(SUNOS5_NAME) -rm -rf $(SUNOS5_NAME) -gzip $(SUNOS5_NAME).tar # The '-local' part means that these are appended after the automake-created # targets of names 'all', etc. if OS_IS_LINUX_REDHAT the_startup_file = $(srcdir)/startup.redhat else the_startup_file = $(srcdir)/startup.msg endif gri.cmd: gri.cmd-skel cat $(srcdir)/gri.cmd-skel | sed -e s,VERSION,${PACKAGE_VERSION}, > gri.cmd startup.msg-tmp: $(the_startup_file) cat $(the_startup_file) | sed -e s,VERSION,${PACKAGE_VERSION}, -e s,PREFIX,$(prefix), > startup.msg-tmp all-local: gri.cmd startup.msg-tmp install-exec-local: mkdir -m 755 -p $(DESTDIR)$(prefix)/bin $(INSTALL_SCRIPT) $(srcdir)/gri_unpage $(DESTDIR)$(prefix)/bin/gri_unpage $(INSTALL_SCRIPT) $(srcdir)/gri_merge $(DESTDIR)$(prefix)/bin/gri_merge install-data-local: if OS_IS_FINK mkdir -m 755 -p $(DESTDIR)$(prefix)/share/emacs/site-lisp $(INSTALL_DATA) $(srcdir)/gri-mode.el $(DESTDIR)$(prefix)/share/emacs/site-lisp/gri-mode.el else if OS_IS_LINUX_DEBIAN mkdir -m 755 -p $(DESTDIR)$(prefix)/share/emacs/site-lisp/gri $(INSTALL_DATA) $(srcdir)/gri-mode.el $(DESTDIR)$(prefix)/share/emacs/site-lisp/gri/gri-mode.el else mkdir -m 755 -p $(DESTDIR)$(prefix)/share/emacs/site-lisp $(INSTALL_DATA) $(srcdir)/gri-mode.el $(DESTDIR)$(prefix)/share/emacs/site-lisp/gri-mode.el endif endif mkdir -m 755 -p $(DESTDIR)$(prefix)/share/gri $(INSTALL_DATA) startup.msg-tmp $(DESTDIR)$(prefix)/share/gri/startup.msg $(INSTALL_DATA) gri.cmd $(DESTDIR)$(prefix)/share/gri/gri.cmd $(INSTALL_DATA) rgb.txt $(DESTDIR)$(prefix)/share/gri/rgb.txt $(INSTALL_DATA) logo.dat $(DESTDIR)$(prefix)/share/gri/logo.dat uninstall-local: rm -f $(DESTDIR)$(prefix)/bin/gri_unpage rm -f $(DESTDIR)$(prefix)/bin/gri_merge rm -f $(DESTDIR)$(prefix)/share/emacs/site-lisp/gri-mode.el rm -f $(DESTDIR)$(prefix)/share/gri/startup.msg rm -f $(DESTDIR)$(prefix)/share/gri/gri.cmd rm -f $(DESTDIR)$(prefix)/share/gri/rgb.txt rm -f $(DESTDIR)$(prefix)/share/gri/logo.dat rm -f startup.msg-tmp rm -f gri.cmd ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/if.cc���������������������������������������������������������������������������������������0000644�0001750�0001750�00000011603�13147557614�011515� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include "extern.hh" #define TOP 20000 /* max number nested if-s */ static int top = 0; /* nesting level minus 1 */ static bool got_an_else[TOP]; /* keeps track of duplicate `else' */ static bool skipping[TOP]; /* flag telling that skipping code */ static bool skip_to_end[TOP]; /* set to 1 if part of block done */ static bool inside_if_statement[TOP]; static bool need_to_initialize = true; void initialize_if_necessary(void); void initialize_if_necessary() { if (need_to_initialize) { for (int i = 0; i < TOP; i++) { got_an_else[i] = false; skipping[i] = false; skip_to_end[i] = false; inside_if_statement[i] = false; } need_to_initialize = false; } } void push_if(int flag) { initialize_if_necessary(); if (++top >= TOP) fatal_err("Fatal error: too many nested if-statements (max is 20000)."); got_an_else[top] = false; skipping[top] = ((!flag) || skipping[top - 1]) ? true : false; skip_to_end[top] = flag != 0 ? true : false; inside_if_statement[top] = true; } void pop_if() { initialize_if_necessary(); if (--top < 0) { warning("Warning - ignoring extra `end if'"); top = 0; } } bool skipping_through_if() { initialize_if_necessary(); return skipping[top]; } /* * handle_if_block - handle `else if' and `else' by setting skip-flags. * RETURN VALUE 1 if the commands `if', `else if' or `else' were detected. */ bool handle_if_block() { if (((unsigned) superuser()) & FLAG_FLOW) printf("DEBUG: %s:%d handle_if_block()\n",__FILE__,__LINE__); initialize_if_necessary(); if (!_nword) return false; /* * Handle `end if' */ if (_nword == 2 && !strcmp(_word[0], "end") && !strcmp(_word[1], "if")) { pop_if(); return true; } /* * Handle `if' */ if (!strcmp(_word[0], "if")) { if (_nword < 2) { err("if what?"); return true; } double flag; if (((unsigned) superuser()) & FLAG_FLOW) printf("DEBUG %s:%d DEBUG '%s' ... inside_if= %d skipping= %d\n",__FILE__,__LINE__,_word[1], inside_if_statement[top], skipping[top]); if (skipping[top]) { push_if(false); // does the value matter?????? } else { if (!strcmp(_word[1], "!")) { if (!getdnum(_word[2], &flag)) { err("if what?"); return true; } flag = !flag; } else if (!getdnum(_word[1], &flag)) { err("`if' what?"); return true; } push_if(floor(0.5 + flag) ? true : false); } return true; } /* * Handle `else' and `else if ...' */ if (!strcmp(_word[0], "else")) { if (!inside_if_statement[top]) { err("This `else' doesn't match an `if'"); return true; } /* `else [...]' */ if (_nword == 1) { /* `else' */ if (got_an_else[top] && !skipping[top]) { err("Ignoring duplicate else"); return true; } got_an_else[top] = true; skipping[top] = (skip_to_end[top] || skipping[top - 1]) ? true : false; return true; } else if (_nword > 2 && !strcmp(_word[1], "if")) { if (!inside_if_statement[top]) { err("This `else if' doesn't match an `if'"); return true; } //printf("NOTE: In else if. skipping[%d]=%d\n",top,skipping[top]); // Only consider the value if presently skipping if (skipping[top] == 0) { skipping[top] = 1; //printf("ELSE IF Set skipping[%d] to 1\n",top); return true; } // Must figure out rpn expressions (if any) since they // are ignored for the 'false' part of if blocks, and // that's what we are in at the moment. while (substitute_rpn_expressions(_cmdLine, _cmdLineCOPY)) strcpy(_cmdLine, _cmdLineCOPY); chop_into_words(_cmdLine, _word, &_nword, MAX_nword); /* `else if #' */ double tmp; if (!getdnum(_word[2], &tmp)) { err("else if ?what?"); return true; } if (tmp) { if (skip_to_end[top]) { err("skipping second TRUE part of IF"); skipping[top] = true; return true; } skipping[top] = skipping[top - 1]; skip_to_end[top] = true; } else { skipping[top] = true; } return true; } else { err("else ?what?"); return true; } } /* cmd = something to do */ return false; } �����������������������������������������������������������������������������������������������������������������������������gri/src/grsmooth.cc���������������������������������������������������������������������������������0000644�0001750�0001750�00000014705�13147557614�012767� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include "gr.hh" #include "GMatrix.hh" // gr_smootharray() -- smooth z(x,y) data // // DESCRIPTION Smooths data z[i][j] defined on a rectangular grid x[i] and y[j] // (where 0<=i &z, GriMatrix &zS, GriMatrix &legit, GriMatrix &legitS, int nx, int ny, int method) { register int i, j; double sum; int good; // number data used per gridpoint int nx_1, ny_1; // Test for errors if (nx <= 0 || ny <= 0) return false; nx_1 = nx - 1; ny_1 = ny - 1; dx = dy = dt = 0.0; // Kill warning on non-use switch (method) { case 0: for (i = 0; i < nx; i++) { for (j = 0; j < ny; j++) { good = 0; sum = 0.0; // Datum at centre if (legit(i, j) == true) { sum += 0.5 * z(i, j); good++; } // Datum to left if (i == 0) { // Left edge: interpolate if (legit(i + 1, j) == true && legit(i, j) == true) { sum += 0.125 * (2.0 * z(i, j) - z(i + 1, j)); good++; } } else { // Interior if (legit(i - 1, j) == true) { sum += 0.125 * z(i - 1, j); good++; } } // Datum to right if (i == nx_1) { // Right edge: interpolate if (legit(i - 1, j) == true && legit(i, j) == true) { sum += 0.125 * (2.0 * z(i, j) - z(i - 1, j)); good++; } } else { // Interior if (legit(i + 1, j) == true) { sum += 0.125 * z(i + 1, j); good++; } } // Datum below if (j == 0) { // Bottom: interpolate if (legit(i, j + 1) == true && legit(i, j) == true) { sum += 0.125 * (2.0 * z(i, j) - z(i, j + 1)); good++; } } else { if (legit(i, j - 1) == true) { sum += 0.125 * z(i, j - 1); good++; } } // Datum above if (j == ny_1) { // Top: interpolate if (legit(i, j - 1) == true && legit(i, j) == true) { sum += 0.125 * (2.0 * z(i, j) - z(i, j - 1)); good++; } } else { if (legit(i, j + 1) == true) { sum += 0.125 * z(i, j + 1); good++; } } if (good == 5) { zS(i, j) = sum; legitS(i, j) = true; } else { zS(i, j) = z(i, j); // won't be used anyway legitS(i, j) = false; } } } break; case 1: // smooth across x for (i = 0; i < nx; i++) { for (j = 0; j < ny; j++) { sum = 0.0; good = 0; // Datum at centre if (legit(i, j) == true) { sum += 0.5 * z(i, j); good++; } // Datum to left if (i == 0) { // Left edge: interpolate if (legit(i + 1, j) == true && legit(i, j) == true) { sum += 0.25 * (2.0 * z(i, j) - z(i + 1, j)); good++; } } else { // Interior if (legit(i - 1, j) == true) { sum += 0.25 * z(i - 1, j); good++; } } // Datum to right if (i == nx_1) { // Right edge: interpolate if (legit(i - 1, j) == true && legit(i, j) == true) { sum += 0.25 * (2.0 * z(i, j) - z(i - 1, j)); good++; } } else { // Interior if (legit(i + 1, j) == true) { sum += 0.25 * z(i + 1, j); good++; } } if (good == 5) { zS(i, j) = sum; legitS(i, j) = true; } else { zS(i, j) = z(i, j); // won't be used anyway legitS(i, j) = false; } } } break; case 2: // smooth across y for (i = 0; i < nx; i++) { for (j = 0; j < ny; j++) { sum = 0.0; good = 0; // Datum at centre if (legit(i, j) == true) { sum += 0.5 * z(i, j); good++; } // Datum below if (j == 0) { // Bottom: interpolate if (legit(i, j + 1) == true && legit(i, j) == true) { sum += 0.25 * (2.0 * z(i, j) - z(i, j + 1)); good++; } } else { if (legit(i, j - 1) == true) { sum += 0.25 * z(i, j - 1); good++; } } // Datum above if (j == ny_1) { // Top: interpolate if (legit(i, j - 1) == true && legit(i, j) == true) { sum += 0.25 * (2.0 * z(i, j) - z(i, j - 1)); good++; } } else { if (legit(i, j + 1) == true) { sum += 0.25 * z(i, j + 1); good++; } } if (good == 5) { zS(i, j) = sum; legitS(i, j) = true; } else { zS(i, j) = z(i, j); // won't be used anyway legitS(i, j) = false; } } } break; default: return false; // unknown } return true; } �����������������������������������������������������������gri/src/defaults.hh���������������������������������������������������������������������������������0000644�0001750�0001750�00000004344�13147557614�012744� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* set up default geometry of plots */ #if !defined(_defaults_) #define _defaults_ #define GRIINPUTS ".:/usr/local/lib/gri" /* where to search */ #define ARROWSIZE_DEFAULT 0.2 /* cm */ #define COLUMN_LEN_DEFAULT 256 /* data column length */ #define CONTOUR_FMT_DEFAULT "%lg" /* format for contour labels */ #define FONT_DEFAULT gr_font_Helvetica #define FONTSIZE_PT_DEFAULT 12. /* pt */ #define IMAGE_SIZE_WHEN_CONVERTING 128 /* `convert grid to image' */ /* before 1.043, following numbers were 0.25, 0.5, and 0.25 */ #define LINEWIDTHAXIS_DEFAULT 0.369 /* pt (=rapidograph 6x0) */ #define LINEWIDTH_DEFAULT 0.709 /* pt (=rapidograph 3x0) */ #define LINEWIDTHSYMBOL_DEFAULT 0.369 /* pt (=rapidograph 6x0) */ #define MISSING_VALUE 1.0e22 /* missing value */ #define SYMBOLSIZE_DEFAULT 0.1 /* radius in cm */ #define TICSIZE_DEFAULT 0.2 /* cm */ #define X_FMT_DEFAULT "%lg" #define XMARGIN_DEFAULT 6.0 /* cm */ #define XSIZE_DEFAULT 10. /* cm */ #define Y_FMT_DEFAULT "%lg" #define YMARGIN_DEFAULT 6.0 /* cm */ #define YSIZE_DEFAULT 10. /* cm */ // Page limits #define OFFPAGE_LEFT -21.6 #define OFFPAGE_RIGHT 43.2 #define OFFPAGE_BOTTOM -27.9 #define OFFPAGE_TOP 55.9 #endif /* _defaults_ */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/expect.cc�����������������������������������������������������������������������������������0000644�0001750�0001750�00000011413�13147557614�012406� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #if !defined(IS_MINGW32) #include #else #define index strrchr #endif #include #include "gr.hh" #include "extern.hh" #if defined(__DECCXX) || defined(OS_IS_BEOS) extern "C" char *index(const char *s, int c); #endif extern char _grTempString[]; bool expectingCmd() { double version_expected, this_version; if (_nword != 3) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } char *dot1 = index(_word[2], int('.')); if (dot1 == NULL) { err("Version number must have a decimal point"); return false; } char *dot2 = index(dot1 + 1, int('.')); bool only_one_dot = false; if (dot2 == NULL) { only_one_dot = true; if (!getdnum(_word[2], &version_expected)) { demonstrate_command_usage(); READ_WORD_ERROR(".version."); return false; } version_expected = atof(_word[2]); } else { char *dot3 = index(dot2 + 1, int('.')); if (dot3 != NULL) { err("Version number must not have more than two decimal points"); return false; } int major, minor, minorminor; if (3 != sscanf(_word[2], "%d.%d.%d", &major, &minor, &minorminor)) { err("Cannot decode version number"); return false; } version_expected = major + float(minor) / 100.0 + float(minorminor) / 10000.0; } _version_expected = version_expected; this_version = _version; //printf("DEBUG: this_version %f version_expected %f only_one_dot=%d\n",this_version,_version_expected, only_one_dot); if (this_version < version_expected) { sprintf(_grTempString, "\ WARNING: You are expecting a gri version (%.4f) more recent than\n\ the present version (%.4f); this might cause problems.\n\n", double(version_expected), double(this_version)); ShowStr(_grTempString); } ShowStr("\ Following is a list of things changed in Gri since the version you\n\ are expecting. Note that this list includes *all* commands, even\n\ if you are not using them in your Gri program.\n\n"); if (this_version > 2.0899) { ShowStr("\ Incompatibilities introduced in version 2.9.0:\n\ * `set y axis label horizontal' changed to `set y axis name horizontal'\n\ * `set y axis label vertical' changed to `set y axis name vertical'\n"); } if (version_expected < 1.064) { ShowStr("\n\ Incompatibilities introduced in version 1.064:\n\ * `{rpn x column_min}' RENAMED `{rpn x min}'; same for\n\ the column_max and column_mean operators.\n\ * Disallow multiple statements on one line, separated by semicolons\n"); } if (version_expected < 1.050) { ShowStr("\n\ Incompatibilities introduced in version 1.050:\n\ * The `function' command has been removed, and all builtin functions\n\ replaced with RPN functions\n"); } if (version_expected < 1.037) { ShowStr("\n\ Incompatibilities introduced in version 1.037:\n\ * `draw image grayscale' RENAMED `draw image palette'\n"); } if (version_expected < 1.036) { ShowStr("\n\ Incompatibilities introduced in version 1.036:\n\ * ALL image commands now require `set image range' to have been first.\n\ In a related change, `convert grid to image' now does not permit the\n\ `white' and `black' options, and `read image' now does not permit the\n\ `scale' option. Although these changes are obnoxious, they should\n\ make images much more reliable and easy to use.\n"); } if (version_expected < 1.034) { ShowStr("\n\ Incompatibilities introduced in version 1.034:\n\ * Within math - mode, normal letters appear in italics, as in TeX.\n"); } if (version_expected < 1.033) { ShowStr("\n\ Incompatibilities introduced in version 1.033:\n\ * The commandline option ` -extract ' is renamed `-creator'.\n\ * `convert columns to grid neighborhood ' is removed since it was\n\ pretty useless. (It' s easy enough to do in awk.\n\ * `convert columns to grid planar ' is removed; use the `boxcar'\n\ method instead.\n\ * The commandline option ` -quiet ' is removed; use `-chatty' instead.\n"); } return true; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/gr_coll.cc����������������������������������������������������������������������������������0000644�0001750�0001750�00000040711�13147557614�012542� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // Classes for Gri. See gr_coll.hh for docs //#define DEBUG_GR_COLL 1 // uncomment to debug #include #include #include #include #include #include "gr.hh" #include "extern.hh" #include "gr_coll.hh" static const unsigned int CAPACITY_DEFAULT = 32; GriString::GriString(const char *s) { capacity = 1 + strlen(s); value = new char[capacity]; if (!value) OUT_OF_MEMORY; strcpy(value, s); } GriString::GriString(const GriString& n) { char *cp = n.getValue(); capacity = 1 + strlen(cp); value = new char[capacity]; if (!value) OUT_OF_MEMORY; strcpy(value, cp); } GriString::GriString(unsigned int len) { capacity = 1 + len; value = new char[capacity]; if (!value) OUT_OF_MEMORY; value[0] = '\0'; } void GriString::convert_slash_to_MSDOS() { unsigned int l = strlen(value); for (unsigned int i = 0; i < l; i++) if (value[i] == '/') value[i] = '\\'; } // Read line from file, enlarging space if needed. Leave newline // at end; if file ends before newline, tack one on anyhow. // // RETURN true if file at EOF before reading any data eof_status GriString::line_from_FILE(FILE *fp) { //printf("DEBUG %s:%d line_from_FILE fp at %x\n",__FILE__,__LINE__,int(fp)); unsigned int i = 0; bool got_eof = false; if (feof(fp)) { value[0] = '\0'; return eof_before_data; } do { value[i] = getc(fp); if ((got_eof = feof(fp))) break; if (i >= capacity - 1) { // Get more space if required capacity += capacity; char *more_space = new char[capacity]; if (!more_space) OUT_OF_MEMORY; for (unsigned int j = 0; j <= i; j++) more_space[j] = value[j]; delete [] value; value = more_space; } if (value[i++] == '\n') break; } while (!got_eof); if (got_eof) { //printf("got eof i= %d\n",i); value[i++] = '\n'; // tack newline on value[i] = '\0'; //printf("%s:%d {{{{{{%s}}}}}}}}}}}\n",__FILE__,__LINE__,value); return eof_after_data; } value[i] = '\0'; return no_eof; } // Read word from file, enlarging if neccessary. Leave newline if // found, but if hit eof do not insert extra newline. // RETURN true if hit EOF // CHANGE 28AUG95: DO // NOT KEEP NEWLINE; PUT IT BACK INTO FILE SO 'READ WORD' CAN FLUSH COMMENTS // AND EXTRA JUNK AT EOL ... PROVISIONAL CHANGE. bool GriString::word_from_DataFile(DataFile& f) { bool status; unsigned int eol; status = GriString::word_from_FILE(f.get_fp(), &eol); for (unsigned int e = 0; e < eol; e++) { //printf("dd %s:%d got eol\n", __FILE__,__LINE__); f.increment_line(); } return status; } bool GriString::word_from_FILE(FILE *fp, unsigned int *eol) { *eol = 0; //printf("dd eol at start is %d\n", *eol); if (feof(fp)) { value[0] = '\0'; return true; } // The default (single or multiple whitespace) is VERY // different from TAB, since the latter requires precisely // one TAB. Also, in the default case, whitespace is skipped, // but not in the TAB case. extern char _input_data_separator; if (_input_data_separator == ' ') { unsigned int i = 0; value[i] = getc(fp); if (feof(fp)) { value[0] = '\0'; return true; } // Flush any existing whitespace while (isspace(value[i])) { //printf(" flushing whitespace [%c] at i=%d\n",value[i],i); value[i] = getc(fp); if (value[i] == '\n') *eol++; if (feof(fp)) { value[i] = '\0'; return true; } } i++; do { value[i] = getc(fp); if (i >= capacity - 1) { // Get more space if required capacity += capacity; char *more_space = new char[capacity]; if (!more_space) OUT_OF_MEMORY; for (unsigned int j = 0; j <= i; j++) more_space[j] = value[j]; delete [] value; value = more_space; } if (value[i] == '\n') { *eol = *eol + 1; //printf("dd * POSITION 1 newline. eol is now %d\n", *eol); ungetc(value[i], fp); break; } if (isspace(value[i])) break; i++; } while (!feof(fp)); if (feof(fp)) i--; value[i] = '\0'; return false; } else if (_input_data_separator == '\t') { // For 'set input data separator TAB' case, require // just one tab. Two tabs implies missing data. unsigned int i = 0; value[i] = getc(fp); if (feof(fp)) { value[0] = '\0'; return true; } if (value[i] == '\t') { value[0] = '\0'; return false; } i++; do { value[i] = getc(fp); if (i >= capacity - 1) { // Get more space if required capacity += capacity; char *more_space = new char[capacity]; if (!more_space) OUT_OF_MEMORY; for (unsigned int j = 0; j <= i; j++) more_space[j] = value[j]; delete [] value; value = more_space; } if (value[i] == '\n') { *eol = *eol + 1; //printf("dd ** POSITION 2 newline. eol is now %d\n", *eol); ungetc(value[i], fp); break; } if (value[i] == '\t') { break; } i++; } while (!feof(fp)); if (feof(fp)) i--; value[i] = '\0'; return false; } else { gr_Error("Internal error _input_data_separator value is not understood."); return false; } } void GriString::fromSTR(const char *s) { unsigned int len = strlen(s); if (capacity < len + 1) { delete [] value; capacity = len + 1; value = new char[capacity]; if (!value) OUT_OF_MEMORY; } strcpy(value, s); } void GriString::catSTR(const char *s) { unsigned int len = strlen(s); unsigned int oldlen = strlen(value); if ((1 + len + oldlen) > capacity) { capacity += len + 1; char *tmp = new char[capacity]; if (!tmp) OUT_OF_MEMORY; strcpy(tmp, value); strcat(tmp, s); delete [] value; value = tmp; } else { strcat(value, s); } } #if 0 void GriString::sed(const char *cmd) // Assume, *WITHOUT CHECKING*, that cmd is of one of the forms // s/A/B/ where 'A' and 'B' are strings // s:A:B: or any other 'stop-char', as in sed unix command // Also, require B to be a shorter string than A. (easily fixed) { switch (cmd[0]) { case 's': { int len_cmd = strlen(cmd); int len_value = strlen(value); char *copy = new char[1 + strlen(value)]; char stop = cmd[1]; char *A = new char [1 + len_cmd]; char *B = new char [1 + len_cmd]; int lenA = 0; int iA; for (iA = 2; iA < len_cmd; iA++) { if (cmd[iA] == stop) break; A[lenA++] = cmd[iA]; } A[lenA] = '\0'; int lenB = 0; int iB; for (iB = iA + 1; iB < len_cmd; iB++) { if (cmd[iB] == stop) break; B[lenB++] = cmd[iB]; } B[lenB] = '\0'; Require2(lenB <= lenA, gr_Error("sed requires lenB <= lenA\n")); int iCOPY = 0; for (int iVALUE = 0; iVALUE < len_value; iVALUE++) { for (iA = 0; iA < lenA; iA++) { if (iVALUE + iA > len_value - 1) { break; } if (value[iVALUE + iA] != A[iA]) { break; } } if (iA == lenA) { for (iB = 0; iB < lenB; iB++) { copy[iCOPY++] = B[iB++]; } iVALUE += lenA - 1; } else { copy[iCOPY++] = value[iVALUE]; } } copy[iCOPY] = '\0'; delete [] A; delete [] B; strcpy(value, copy); delete [] copy; break; } default: gr_Error("GriString's sed() command can only do 's' commands"); } } #endif // Return reference to indicated item, getting new space if exceeds // capacity. char& GriString::operator[](unsigned int offset) { if (offset < capacity) return value[offset]; // Must get more space char *cp = new char[capacity = offset + 1]; if (!cp) OUT_OF_MEMORY; strcpy(cp, value); delete [] value; value = cp; // Set to null characters, to prevent returning junk for (unsigned int i = strlen(value); i < capacity; i++) value[i] = '\0'; return value[offset]; } void GriString::draw(double xcm, double ycm, gr_textStyle s, double angle) const { if (strlen(value) == 0) return; gr_show_at(value, xcm, ycm, s, angle); // Figure bounding box double width, ascent, descent; gr_stringwidth(value, &width, &ascent, &descent); #if 0 printf("DEBUG: %s:%d GriString::Draw with value `%s' xcm=%.1f ycm=%.1f width=%.1f ascent=%.1f descent=%.1f angle=%.1f\n",__FILE__,__LINE__,value, xcm,ycm,width,ascent, descent, angle); #endif double tmpx[4], tmpy[4]; // 0123 from lower-left anticlockwise switch (s) { case TEXT_LJUST: gr_rotate_xy( 0.0, -descent, angle, tmpx + 0, tmpy + 0); gr_rotate_xy( width, -descent, angle, tmpx + 1, tmpy + 1); gr_rotate_xy( width, ascent, angle, tmpx + 2, tmpy + 2); gr_rotate_xy( 0.0, ascent, angle, tmpx + 3, tmpy + 3); break; case TEXT_RJUST: gr_rotate_xy( -width, -descent, angle, tmpx + 0, tmpy + 0); gr_rotate_xy( 0.0, -descent, angle, tmpx + 1, tmpy + 1); gr_rotate_xy( 0.0, ascent, angle, tmpx + 2, tmpy + 2); gr_rotate_xy( -width, ascent, angle, tmpx + 3, tmpy + 3); break; case TEXT_CENTERED: gr_rotate_xy(-width/2, -descent, angle, tmpx + 0, tmpy + 0); gr_rotate_xy( width/2, -descent, angle, tmpx + 1, tmpy + 1); gr_rotate_xy( width/2, ascent, angle, tmpx + 2, tmpy + 2); gr_rotate_xy(-width/2, ascent, angle, tmpx + 3, tmpy + 3); break; } tmpx[0] += xcm, tmpy[0] += ycm; tmpx[1] += xcm, tmpy[1] += ycm; tmpx[2] += xcm, tmpy[2] += ycm; tmpx[3] += xcm, tmpy[3] += ycm; rectangle box(vector_min(tmpx, 4), vector_min(tmpy, 4), vector_max(tmpx, 4), vector_max(tmpy, 4)); bounding_box_update(box); } GriDvector::GriDvector() { the_depth = 0; the_capacity = CAPACITY_DEFAULT; contents = new double [the_capacity]; if (!contents) OUT_OF_MEMORY; } GriDvector::GriDvector(unsigned int length) { the_depth = 0; the_capacity = length; contents = new double [the_capacity]; if (!contents) OUT_OF_MEMORY; } GriDvector::~GriDvector() { delete [] contents; } // Get more storage void GriDvector::expand() { if (!the_capacity) the_capacity = CAPACITY_DEFAULT; the_capacity *= 2; double *tmp; tmp = new double[the_capacity]; if (!tmp) OUT_OF_MEMORY; for (unsigned i = 0; i < the_depth; i++) tmp[i] = contents[i]; delete [] contents; contents = tmp; } // Get more storage, to specified level void GriDvector::expand(unsigned int capacity) { if (capacity == the_capacity) return; if (capacity < the_capacity) return; // Ignore the_capacity = capacity == 0 ? CAPACITY_DEFAULT : capacity; double *tmp; tmp = new double[the_capacity]; if (!tmp) OUT_OF_MEMORY; for (unsigned int i = 0; i < the_depth; i++) tmp[i] = contents[i]; delete [] contents; contents = tmp; } // Compact down to 'the_depth' or CAPACITY_DEFAULT, whichever is smaller void GriDvector::compact() { unsigned int old_capacity = the_capacity; the_capacity = the_depth > CAPACITY_DEFAULT ? the_depth : CAPACITY_DEFAULT; if (the_capacity != old_capacity) { double *tmp; tmp = new double[the_capacity]; if (!tmp) OUT_OF_MEMORY; for (unsigned int i = 0; i < the_depth; i++) tmp[i] = contents[i]; delete [] contents; contents = tmp; } } void GriDvector::push_back(double value) { while (the_depth > the_capacity - 1) expand(); contents[the_depth++] = value; } void GriDvector::pop_back() // retains storage { if (the_depth) the_depth--; } double GriDvector::topElement() { return contents[the_depth - 1]; } void GriDvector::erase(/* iterator */ double *pos_ /*unsigned int offset*/) { unsigned offset = pos_ - contents; for (unsigned i = offset; i < the_depth - 1; i++) contents[i] = contents[i + 1]; the_depth--; } double& GriDvector::operator[](unsigned int offset) { if (offset <= the_depth - 1) return contents[offset]; else { gr_Error("Trying to access GriDvector out of bounds."); return contents[0]; // never done, prevent compiler warning } } double GriDvector::min() { //printf("%s:%d\n",__FILE__,__LINE__); bool first = true; double the_min = gr_currentmissingvalue(); for (unsigned int i = 0; i < the_depth; i++) { double tmp = contents[i]; //printf("%s:%d contents[%d] = %lf ... ",__FILE__,__LINE__,i,tmp); if (!gr_missing(tmp)) { //printf("NOT MISSING\n"); if (first) { the_min = tmp; } else { if (tmp < the_min) { the_min = tmp; } } first = false; }// else { // printf("MISSING\n"); //} } //printf("%s:%d the_min = %lf\n",__FILE__,__LINE__,the_min); return the_min; } double GriDvector::max() { bool first = true; double the_max = gr_currentmissingvalue(); for (unsigned int i = 0; i < the_depth; i++) { double tmp = contents[i]; //printf("tmp= %lf ",tmp); if (!gr_missing(tmp)) { //printf("NOT MISSING.\n"); if (first) { the_max = tmp; } else { if (tmp > the_max) { the_max = tmp; } } first = false; }// else { //printf("MISSING\n"); //} } //printf("%s:%d the_max = %lf\n",__FILE__,__LINE__,the_max); return the_max; } double GriDvector::median() { double q1, q2, q3; histogram_stats(contents, the_depth, &q1, &q2, &q3) ; return q2; } double GriDvector::mean() { double sum = 0.0; long good = 0; for (unsigned int i = 0; i < the_depth; i++) if (!gr_missing(contents[i])) { sum += contents[i]; good++; } if (good) return double(sum / good); else return gr_currentmissingvalue(); } double GriDvector::stddev() { double the_mean = mean(); double sum = 0.0; long good = 0; for (unsigned int i = 0; i < the_depth; i++) if (!gr_missing(contents[i])) { double tmp = (contents[i] - the_mean); sum += tmp * tmp; good++; } if (good > 1) return double(sqrt(sum / (good - 1))); else return gr_currentmissingvalue(); } double GriDvector::skewness() { double the_mean = mean(); double sum = 0.0; long good = 0; for (unsigned int i = 0; i < the_depth; i++) if (!gr_missing(contents[i])) { double tmp = (contents[i] - the_mean); sum += tmp * tmp * tmp; good++; } double s = stddev(); if (good > 0 && s > 0) return double((sum / good) / s / s / s); else return gr_currentmissingvalue(); } double GriDvector::kurtosis() { double the_mean = mean(); double sum = 0.0; long good = 0; for (unsigned int i = 0; i < the_depth; i++) if (!gr_missing(contents[i])) { double tmp = (contents[i] - the_mean); sum += tmp * tmp * tmp * tmp; good++; } double s = stddev(); // BUG: which kurtosis definition to use??? // some subtract 3 from the below if (good > 1) return double(sum / good / s / s / s / s); else return gr_currentmissingvalue(); } double * GriDvector::begin() { return contents; } void GriDvector::setDepth(unsigned int depth) { if (depth < the_depth) { the_depth = depth; compact(); } else { expand(depth); the_depth = depth; } } size_t GriDvector::size() { return the_depth; } unsigned int GriDvector::size_legit() { unsigned int num = 0; for (unsigned int i = 0; i < the_depth; i++) if (!gr_missing(contents[i])) num++; return num; } unsigned int GriDvector::capacity() { return the_capacity; } GriColumn::GriColumn() { name = new char[2]; if (!name) OUT_OF_MEMORY; name[0] = '\0'; } GriColumn::~GriColumn() { delete [] name; } void GriColumn::setName(const char *theName) { delete [] name; name = new char[1 + strlen(theName)]; if (!name) OUT_OF_MEMORY; strcpy(name, theName); } char *GriColumn::getName() { return name; } RpnItem::RpnItem() { name = new char[1]; if (!name) OUT_OF_MEMORY; name[0] = '\0'; value = 0.0; valid = true; type = UNKNOWN; } RpnItem::RpnItem(const RpnItem& n) { name = new char[1 + strlen(n.getName())]; if (!name) OUT_OF_MEMORY; strcpy(name, n.getName()); value = n.getValue(); valid = n.getValid(); type = n.getType(); } void RpnItem::set(const char *the_name, double the_value, operand_type the_type, bool the_valid) { if (strlen(the_name) > strlen(name)) { delete [] name; name = new char[1 + strlen(the_name)]; if (!name) OUT_OF_MEMORY; } strcpy(name, the_name); value = the_value; valid = the_valid; type = the_type; } RpnItem& RpnItem::operator=(const RpnItem& n) { char *cp = n.getName(); if (strlen(cp) > strlen(name)) { delete [] name; name = new char[1 + strlen(cp)]; if (!name) OUT_OF_MEMORY; } strcpy(name, cp); value = n.getValue(); valid = n.getValid(); type = n.getType(); return *this; } �������������������������������������������������������gri/src/sleep.cc������������������������������������������������������������������������������������0000644�0001750�0001750�00000002475�13147557614�012236� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "gr.hh" #include "extern.hh" #include "GMatrix.hh" #if defined(IS_MINGW32) #include #endif bool sleepCmd() { if (_nword != 2) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } double sec_f; if (!getdnum(_word[1], &sec_f)) { err("`sleep' can't read .sec. in `\\", _word[1], "'.", "\\"); return false; } if (sec_f <= 0.0) return true; int sec = int(floor(0.5 + sec_f)); #if !defined(IS_MINGW32) sleep(sec); #else Sleep(sec*1000); #endif return true; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/logo.dat������������������������������������������������������������������������������������0000644�0001750�0001750�00000005637�13147557614�012254� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������0.40 0.2 0.40 0.448982 0.751148 0.448982 0.751148 0.285716 0.73935 0.226531 0.71772 0.17551 0.682326 0.128571 0.641032 0.089796 0.597773 0.0612242 0.556479 0.0408161 0.511253 0.0244899 0.466027 0.0122444 0.432599 0.00816254 0.395238 0.00816254 0.355911 0.0142853 0.316584 0.0285706 0.263492 0.0510207 0.212367 0.0836732 0.180905 0.104081 0.147477 0.132653 0.112083 0.167348 0.0806206 0.210203 0.0412936 0.277552 0.0235966 0.334693 0.0078656 0.400001 0 0.457142 0 0.518367 0.0019664 0.571427 0.0117986 0.632652 0.0314616 0.700001 0.0511256 0.751021 0.0766876 0.791837 0.116015 0.844898 0.159275 0.883674 0.228098 0.932655 0.281189 0.955103 0.326415 0.973471 0.375574 0.985716 0.420801 0.99388 0.47262 1 1.13459 1 1.21128 0.99796 1.26044 0.99388 1.30566 0.985716 1.36269 0.963268 1.39415 0.946939 1.41774 0.932655 1.45314 0.904082 1.47477 0.87755 1.49247 0.842858 1.5023 0.806122 1.51016 0.748982 1.5023 0.700001 1.48657 0.667348 1.46297 0.624492 1.42954 0.581632 1.39808 0.548979 1.34892 0.506122 1.30173 0.467346 1.25847 0.438778 1.20538 0.397961 1.13852 0.35102 1.08936 0.318369 1.03824 0.285716 0.941889 0.230613 0.926159 0.253059 0.996939 0.300001 1.0756 0.355101 1.18178 0.434693 1.24077 0.483674 1.2919 0.530611 1.33909 0.579591 1.36859 0.618367 1.38825 0.653061 1.40005 0.689796 1.40201 0.730613 1.40005 0.779593 1.38628 0.82245 1.36072 0.86939 1.32729 0.904082 1.26437 0.940819 1.21914 0.955103 1.16408 0.967348 1.10116 0.972000 0.57221 0.972000 0.534849 0.968 0.483724 0.961224 0.428666 0.946939 0.377541 0.930611 0.338214 0.912247 0.300853 0.889798 0.267425 0.865306 0.23203 0.834695 0.212367 0.808166 0.178939 0.763266 0.161241 0.718369 0.139612 0.661224 0.125847 0.59388 0.119948 0.534695 0.121914 0.47143 0.127814 0.402041 0.137645 0.334693 0.155342 0.273467 0.180905 0.206123 0.212367 0.142858 0.249728 0.0938778 0.292987 0.0612242 0.342146 0.0408161 0.409002 0.0306115 0.467993 0.0367343 0.521085 0.0571424 0.574176 0.0918369 0.61547 0.130612 0.654797 0.177551 0.674461 0.22449 0.68036 0.261224 0.678393 0.306124 0.660696 0.353061 0.631201 0.383673 0.595806 0.40 0.564344 0.40 0.54 0.395 0.52 0.385 0.50 0.375 0.48 0.36 0.46 0.340 0.44 0.31 0.42 0.260 0.40 0.2 -999 -999 0.888793 0.891839 0.888793 0.0122444 0.827836 0.0122444 0.827836 0.657145 0.826803 0.693877 0.823903 0.724489 0.814072 0.763266 0.798341 0.797961 0.768845 0.836734 0.73935 0.861226 0.703956 0.875511 0.650864 0.889798 0.625302 0.893879 0.886827 0.893879 -999 -999 1.23094 0.377553 1.2742 0.334693 1.33516 0.281632 1.40005 0.228572 1.46297 0.179592 1.54162 0.124489 1.61635 0.0755095 1.70483 0.0163262 1.69107 0 1.64584 0.022449 1.57309 0.0530605 1.49247 0.10204 1.42168 0.142858 1.35875 0.183674 1.3037 0.220408 1.26437 0.25102 1.21521 0.287756 1.16408 0.328572 1.23094 0.375509 -999 -999 1.81291 0.995919 1.81291 0.0122444 1.75000 0.0122444 1.75000 0.77551 1.74809 0.830614 1.74219 0.86939 1.72646 0.912247 1.695 0.938776 1.65174 0.963268 1.61241 0.981632 1.56522 0.995919 1.81101 0.995919 �������������������������������������������������������������������������������������������������gri/src/Variable.hh���������������������������������������������������������������������������������0000644�0001750�0001750�00000006267�13147557614�012670� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // Store variable name/value #if !defined(_grivariable_h_) #define _grivariable_h_ #include "GCounter.hh" #if 1 class GriVariable : public GriCounter { public: GriVariable() { value = 0.0; } GriVariable(const char *the_name, double the_value) { name.assign(the_name); value = the_value; }; GriVariable(const GriVariable& c) { name.assign(c.get_name()); value = c.get_value_quietly(); }; ~GriVariable() { #if 0 // BUG 2001-feb-17 -- not sure on next 2 lines name.string::~string(); // not executed #endif }; void set_name_value(const char *the_name, double the_value) { name.assign(the_name); value = the_value; }; void set_value(double the_value) {value = the_value;}; const char *get_name(void) const {return name.c_str();}; double get_value(void) {incrementCount(); return value;}; double get_value_quietly(void) const {return value;}; GriVariable& operator=(const GriVariable& n) { name.assign(n.get_name()); value = n.get_value_quietly(); return *this; } private: std::string name; double value; }; #else class GriVariable : public GriCounter { public: GriVariable() { name = new char [1]; if (!name) OUT_OF_MEMORY; name[0] = '\0'; value = 0.0; } GriVariable(const char *the_name, double the_value) { name = new char [1 + strlen(the_name)]; if (!name) OUT_OF_MEMORY; strcpy(name, the_name); value = the_value; }; GriVariable(const GriVariable& c) { name = new char [1 + strlen(c.get_name())]; if (!name) OUT_OF_MEMORY; strcpy(name, c.get_name()); value = c.get_value_quietly(); }; ~GriVariable() {delete [] name;}; void set_name_value(const char *the_name, double the_value) { if (strlen(the_name) > strlen(name)) { delete [] name; name = new char [1 + strlen(the_name)]; if (!name) OUT_OF_MEMORY; } strcpy(name, the_name); value = the_value; }; void set_value(double the_value) {value = the_value;}; char *get_name(void) const {return name;}; double get_value(void) {incrementCount(); return value;}; double get_value_quietly(void) const {return value;}; GriVariable& operator=(const GriVariable& n) { char *cp = n.get_name(); if (strlen(cp) > strlen(name)) { delete [] name; name = new char [1 + strlen(cp)]; if (!name) OUT_OF_MEMORY; } strcpy(name, cp); value = n.get_value_quietly(); return *this; } private: char *name; double value; }; #endif #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/debug.hh������������������������������������������������������������������������������������0000644�0001750�0001750�00000001676�13147557614�012230� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #if !defined(_debug_) #define _debug_ #define DEBUG_CLIPPED 0x0001 /* `debug clipped values in draw commands' */ #endif /* _debug_ */ ������������������������������������������������������������������gri/src/startup.redhat������������������������������������������������������������������������������0000644�0001750�0001750�00000000527�13147557614�013506� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� gri - scientific graphic program (version VERSION) Copyright 2017 by Dan E. Kelley; GPLv2+ licensing. Type `help' for an overview of Gri commands, or see the full manual at PREFIX/share/doc/gri-VERSION/html/index.html and its text-only version in the 'gri' INFO node. Visit http://gri.sourceforge.net for updates and resources. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/version.cc����������������������������������������������������������������������������������0000644�0001750�0001750�00000002525�13147557614�012607� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2011 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // NB: _gri_number will be checked against line 1 of gri.cmd #ifdef OSX_BUNDLE char _gri_number[] = PACKAGE_VERSION; #else // Don't ask me why, but I used to do // #define stringify(x) # x // char _gri_number[] = stringify(VERSION); // here. I think I was messing with the OSX bundle release, // but whatever I was doing, it sems not to be needed. I'll // just leave it here for a while, though. // DEK 2005-12-18 // char _gri_number[] = PACKAGE_VERSION; #endif char _gri_release_time[] = "2017-01-31"; char _gri_date[] = "2017"; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/utility.cc����������������������������������������������������������������������������������0000644�0001750�0001750�00000173071�13147557614�012632� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ //#define DEBUG_RESOLVE_PATH //#define DEBUG_RE //#define DEBUG_UNDERSCORE #include #include #include #include #include #include #if !defined(IS_MINGW32) #include #include #endif #include #if defined(MSDOS) // need all these? #include #include #include #include #include #include #endif #include "extern.hh" #include "debug.hh" #include "defaults.hh" #include "gr.hh" #include "superus.hh" #include "GriTimer.hh" #ifdef DEBUG_RE static void show_pattern(const char *target, int tlen, int star, int plus); #endif extern double strtod(const char *, char **); bool get_normal_number(const char *s, double *d) { char *ptr = NULL; *d = strtod(s, &ptr); if (*ptr == '\0') { // Normal number; check for infinity/not-a-number #if defined(HAVE_ISNAN) && defined(HAVE_ISINF) #if !defined(__MACHTEN__) extern double _grMissingValue; if (isinf(*d) || isnan(*d)) { extern bool _grMissingValueUsed; if (!_grMissingValueUsed) // turn on missing-value, if it's off gr_set_missing_value(1.0e22); *d = (double) _grMissingValue; } #endif #endif return true; } else { return false; } } // This warning business is too hard. Just ignore it for now. #if 1 bool get_number_with_underscores(const char *s, double *value) { const char *si = s; static std::string ss; // keep in storage ss.assign(""); unsigned int slen = strlen(s); if (!isdigit(*si) && *si != '.' && *si != '+' && *si != '-') return false; if (*si == '.' && !isdigit(*(si + 1))) return false; for (unsigned int i = 0; i < slen; i++) { if (isdigit(*si) || *si == '.' || *si == '-' || *si == '+' || *si == 'e' || *si == 'E' || *si == 'd' || *si == 'D') { ss += *si; } else if (*si == '_') { ; } else { return false; } si++; } if (get_normal_number(ss.c_str(), value)) return true; else return false; } #else bool get_number_with_underscores(const char *s, double *value) { const char *si = s; static std::string ss; // keep in storage ss.assign(""); unsigned int slen = strlen(s); unsigned int last_underline = 0; bool have_underline = false; bool have_decimal = false; if (!isdigit(*si) && *si != '.' && *si != '+' && *si != '-') return false; if (*si == '.' && !isdigit(*(si + 1))) return false; for (unsigned int i = 0; i < slen; i++) { if (isdigit(*si) || *si == '-' || *si == '+') { ss += *si; } else if (*si == '.') { ss += *si; if (have_underline && ((i - 1 - last_underline) != 3)) warning("misplaced _ before decimal place in `\\", s, "'", "\\"); last_underline = i; // pretend have_underline = false; have_decimal = true; } else if (*si == 'e' || *si == 'E' || *si == 'd' || *si == 'D') { ss += *si; if (have_underline && ((i - 1 - last_underline) != 3)) warning("misplaced _ before exponent indicator in `\\", s, "'", "\\"); last_underline = i; have_underline = false; // reset } else if (*si == '_') { if (have_underline && ((i -1 - last_underline) != 3)) warning("misplaced _ in numerical constant `\\", s, "'", "\\"); last_underline = i; have_underline = true; } else { #ifdef DEBUG_UNDERSCORE printf("%s:%d NOT A NUMBER '%s'\n", __FILE__,__LINE__,s); #endif return false; } si++; } #ifdef DEBUG_UNDERSCORE printf("%s:%d last_underscore %d end at %d\n", __FILE__,__LINE__,last_underline, slen); #endif if (have_underline && (slen - 1 - last_underline != 3)) { warning("misplaced _ in constant `\\", s, "'", "\\"); } #ifdef DEBUG_UNDERSCORE printf("%s:%d OK, translated '%s' -> '%s'\n", __FILE__,__LINE__,s,ss.c_str()); #endif if (get_normal_number(ss.c_str(), value)) { #ifdef DEBUG_UNDERSCORE printf("%s:%d Right this is a number '%s' -> '%s' -> %e\n", __FILE__,__LINE__,s,ss.c_str(), *value); #endif return true; } #ifdef DEBUG_UNDERSCORE printf("%s:%d Not a number '%s' -> '%s'\n", __FILE__,__LINE__,s,ss.c_str()); #endif return false; } #endif bool get_coded_value(const std::string& name, int level, std::string& result) { //printf("DEBUG %s:%d get_coded_value(<%s>,%d)\n",__FILE__,__LINE__,name.c_str(),level); int mark_above = level + 1; if (name[0] == '.') { int index = index_of_variable(name.c_str(), level); //printf("DEBUG %s:%d index %d\n",__FILE__,__LINE__,index); if (index < 0) { // No such variable known return false; } char buf[100]; // BUG: could be too short sprintf(buf, "%g", variableStack[index].get_value()); result.assign(buf); return true; } else if (name[0] == '\\'){ int mark = 0; int index; for (index = 0; index < int(synonymStack.size()); index++) { const char *n = synonymStack[index].get_name(); if (*n == '\0') if (++mark == mark_above) break; } if (mark != mark_above) { //printf("DEBUG %s:%d no match for <%s>\n",__FILE__,__LINE__,name.c_str()); return false; } //printf("DEBUG %s:%d index %d\n",__FILE__,__LINE__,index); for (int i = index - 1; i >= 0; i--) { if (synonymStack[i].get_name() == name) { //printf("DEBUG %s:%d match at i= %d\n",__FILE__,__LINE__,i); result.assign(synonymStack[i].get_value()); return true; } } } else { err("Internal error in synonyms.cc; cannot decode `\\", name.c_str(), "'", "\\"); return false; } return true; } bool is_coded_string(const std::string&s, std::string& name, int* mark_level) { //printf("DEBUG %s:%d is_coded_string <%s>\n",__FILE__,__LINE__,s.c_str()); //for (unsigned int i = 0; i < s.size(); i++) printf("\ts[%d] = '%c'\n",i,s[i]); if (s.size() < 33) { // this long even if var and level each have only 1 character return false; } char cname[100]; // BUG: may be too short int ml = 0; if (2 != sscanf(s.c_str(), AMPERSAND_CODING, cname, &ml)) { //printf("DEBUG: %s:%d problem ... cname [%s] level %d\n",cname, ml); return false; } name.assign(cname); *mark_level = ml; //printf("DEBUG %s:%d decoded name <%s> level %d\n",__FILE__,__LINE__,name.c_str(),*mark_level); return true; } bool marker_draw() // put a marker on top { GriVariable markVar("", 0.0); variableStack.push_back(markVar); GriSynonym markSyn("", ""); synonymStack.push_back(markSyn); return true; } int marker_count() // -1 if error { int nv = 0; int vlen = variableStack.size(); for (int i = vlen - 1; i >= 0; i--) if (*variableStack[i].get_name() == '\0') nv++; int ns = 0; int slen = synonymStack.size(); for (int ii = slen - 1; ii >= 0; ii--) if (*synonymStack[ii].get_name() == '\0') ns++; if (ns == nv) return ns; return -1; // error } bool marker_erase() // erase top marker; return false if there is none { bool ok = false; int vlen = variableStack.size(); for (int i = vlen - 1; i >= 0; i--) { if (*variableStack[i].get_name() == '\0') { variableStack.erase(variableStack.begin() + i); ok = true; break; } } if (ok) { ok = false; int slen = synonymStack.size(); for (int i = slen - 1; i >= 0; i--) { if (*synonymStack[i].get_name() == '\0') { synonymStack.erase(synonymStack.begin() + i); ok = true; break; } } } return ok; } // Keep this in static area, so as not to waste time with // multiple allocation/deallocation for scratch strings static std::string tmp_string; bool get_nth_word(const std::string& s, unsigned int which, std::string& result) { char *w[MAX_nword]; // BUG: wasteful unsigned int nw; char *cpy = strdup(s.c_str()); chop_into_words(cpy, w, &nw, MAX_nword); if (nw <= which) return false; result.assign(w[which]); free(cpy); return true; } unsigned int get_number_of_words(const std::string& s) { if (s.size() == 0) return 0; char *w[MAX_nword]; // BUG: wasteful unsigned int nw; char *cpy = strdup(s.c_str()); chop_into_words(cpy, w, &nw, MAX_nword); free(cpy); return nw; } bool is_assignment_op(const char *s) { if (!strcmp(s, "=")) return true; if (!strcmp(s, "+=")) return true; if (!strcmp(s, "*=")) return true; if (!strcmp(s, "-=")) return true; if (!strcmp(s, "/=")) return true; if (!strcmp(s, "^=")) return true; if (!strcmp(s, "_=")) return true; return false; } // Return true if string is all space/tab chars bool string_is_blank(const char *s) { int len = strlen(s); for (int i = 0; i < len; i++) if (!isspace(s[i])) return false; return true; } // Returns number column data that are missing in *any* variable unsigned int number_missing_cols() { // Only examine other columns if they have same length unsigned int length = _colX.size(); bool do_y = _colY.size() == length; bool do_z = _colZ.size() == length; bool do_U = _colU.size() == length; bool do_V = _colV.size() == length; bool do_WEIGHT = _colWEIGHT.size() == length; unsigned int missing = 0; for (unsigned int i = 0; i < length; i++) { if ( gr_missing(_colX[i])) { missing++; continue; } if (do_y && gr_missing(_colY[i])) { missing++; continue; } if (do_z && gr_missing(_colZ[i])) { missing++; continue; } if (do_U && gr_missing(_colU[i])) { missing++; continue; } if (do_V && gr_missing(_colV[i])) { missing++; continue; } if (do_WEIGHT && gr_missing(_colWEIGHT[i])) { missing++; continue; } } return missing; } /* Return true if string starts and ends with character `"' */ bool quoted(const char *s) { int len = strlen(s); if (len < 2) return false; return (*s == '"' && *(s + len - 1) == '"') ? true : false; } /* Return transformed -- see code that calls it. */ double quantize(double x, int levels, double dx) { if (dx < 0.0) dx = -dx; if (dx) return (dx * levels / (1.0 + levels) * (floor(1.0 + x / dx))); else return x; } /* Change escaped quotes in word to quotes. Strlen changed! */ void remove_esc_quotes(char *w) { int i, max = strlen(w); char last; last = ' '; for (i = 0; i < max; i++) { if (w[i] == '\\' && w[i + 1] == '"' && last != '\\') { /* gobble rest up */ int j; for (j = i; j < max; j++) { w[j] = w[j + 1]; } } else { last = w[i]; } } } void show_words() { if (_nword > 0) { printf("DEBUG: "); for (unsigned int i = 0; i < _nword; i++) { printf("%d\"%s\" ", i, _word[i]); } printf("\n"); } else { printf("DEBUG: commandline is blank\n"); } } // Is the i-th word of _word[] equal to given word? (return 0 if too few // words) bool word_is(int i, const char *word) { return ((-1 < i && i < int(_nword) && !strcmp(word, _word[i])) ? true : false); } void check_psfile() { extern output_file_type _output_file_type; if (_output_file_type == postscript) { extern FILE *_grPS; if (ferror(_grPS)) { /* never returns */ fatal_err(" IO error on PostScript output file\n"); } } } bool delete_file(const char *filename) { #if defined(HAVE_UNISTD_H) return !(unlink(filename)); #else // will have to delete it 'manually' char sys_cmd[200]; #if defined(VMS) sprintf(sys_cmd, "DEL %s;*", filename); call_the_OS(sys_cmd, __FILE__, __LINE__); #elif defined(MSDOS) sprintf(sys_cmd, "DEL %s", filename); call_the_OS(sys_cmd, __FILE__, __LINE__); #else sprintf(sys_cmd, "rm %s", filename); call_the_OS(sys_cmd, __FILE__, __LINE__); #endif #endif // whether have unlink return true; } /* * skip_space () -- return number of spaces at start of string. (A space may * be SPC, TAB, etc.) */ int skip_space(const char *s) { int i = 0; while (isspace(*(s + i)) && *(s + i) != '\0') i++; return i; } // skip_nonspace () -- return number of non-spaces at start of string. (A // space may be SPC, TAB, etc.) int skip_nonspace(const char *s) { int i = 0; while (!isspace(*(s + i)) && *(s + i) != '\0') i++; return i; } // 'get env \a SHELL' bool get_envCmd() { if (_nword != 4) { NUMBER_WORDS_ERROR; demonstrate_command_usage(); return false; } std::string the_syn(_word[2]); un_double_quote(the_syn); un_double_slash(the_syn); de_reference(the_syn); if (!is_syn(the_syn)) { err("No synonym name given"); demonstrate_command_usage(); return false; } std::string the_env_var(_word[3]); un_double_quote(the_env_var); de_reference(the_env_var); char *result = egetenv(the_env_var.c_str()); if (result == NULL) { if (!put_syn(the_syn.c_str(), "", true)) { gr_Error("Ran out of storage"); return false; } warning("No environment variable called `\\", the_env_var.c_str(), "' exits.", "\\"); } else { if (!put_syn(the_syn.c_str(), result, true)) { gr_Error("Ran out of storage"); return false; } } return true; } /* Paste a single character onto the end of a string. */ void strcat_c(char *s, int c) { int slen = strlen(s); s[slen] = c; s[++slen] = '\0'; } bool is_punctuation(int c) { return ((c == ' ' || c == '\t' || c == '!' || c == '@' || c == '#' || c == '$' || c == '%' || c == '^' || c == '&' || c == '*' || c == '(' || c == ')' || c == '-' || c == '+' || c == '=' || c == '~' || c == '`' || c == '{' || c == '[' || c == '}' || c == ']' || c == '\\' || c == ':' || c == ';' || c == ',' || c == '<' || c == '"' || c == '<' || c == '.' || c == '>' || c == '/' || c == '?' ) ? true : false); } bool full_path_name(std::string& f) { if (f[0] == '~') { if (f[1] == '/') { f.STRINGERASE(0, 1); f.insert(0, egetenv("HOME")); return true; } else { #if !defined(IS_MINGW32) size_t name_end = f.find("/"); if (name_end == STRING_NPOS) name_end = f.size(); std::string username = f.substr(1, name_end - 1); struct passwd *pw_entry; pw_entry = getpwnam(username.c_str()); f.STRINGERASE(0, username.size() + 1); f.insert(0, pw_entry->pw_dir); return true; #else return false; #endif } } else if (f[0] == '.') { char wd[1024], *ptr = wd; // BUG: may not be long enough ptr = getcwd(ptr, 1023); if (ptr) { f.STRINGERASE(0, 1); f.insert(0, wd); //printf("GOT DIR %s\n", wd); } else { ; //printf("CANNOT get cwd\n"); } } return true; } bool resolve_filename(std::string& f, bool trace_path, char c_or_d) { unsigned int len; if (f[0] == '"') { f.STRINGERASE(0,1); len = f.size(); if (len < 2) return false; if (f[len - 1] != '"') return false; f.STRINGERASE(len-1, 1); } // Change any escaped quotes to quotes (not sure why // anybody would do this, but what the heck). unsigned int i; len = f.size(); for (i = 1; i < len; i++) { if (f[i] == '"' && f[i-1] == '\\') { f.STRINGERASE(i - 1, 1); if (--len == 0) return false; } } if (f[0] == '~') { if (f[1] == '/') { f.STRINGERASE(0, 1); f.insert(0, egetenv("HOME")); return true; } else { #if !defined(IS_MINGW32) size_t name_end = f.find("/"); if (name_end == STRING_NPOS) name_end = f.size(); std::string username = f.substr(1, name_end - 1); struct passwd *pw_entry; pw_entry = getpwnam(username.c_str()); f.STRINGERASE(0, username.size() + 1); f.insert(0, pw_entry->pw_dir); return true; #else return false; #endif } } // BUG: probably should substitute any env-vars here, e.g. $HOME // Done, unless we have to trace the path ... if (!trace_path) return true; // ... but can even skip that, if the pathname is complete already ... if (f[0] == '.' || f[0] == '/') return true; // ... ok, now we know we should trace! std::string path; if (c_or_d == 'c') { if (!get_syn("\\.path_commands.", path)) { err("Internal error in utility.cc:resolve_filename() -- cannot determine value of \\.path_commands\n"); return false; } } else if (c_or_d == 'd') { if (!get_syn("\\.path_data.", path)) { err("Internal error in utility.cc:resolve_filename() -- cannot determine value of \\.path_data\n"); return false; } } else { err("Internal error in utility.cc:resolve_filename() -- c_or_d has unacceptable value\n"); return false; } if (path.size() < 1) return true; // BUG: is this what I want for empty path? // HAD: path.assign(GRIINPUTS); // in defaults.hh ".:/usr/local/lib/gri" std::string::size_type start = 0; std::string::size_type colon; #ifdef DEBUG_RESOLVE_PATH printf("DEBUG(%s:%d) resolve_filename has path '%s'\n",__FILE__,__LINE__,path.c_str()); #endif do { colon = path.find(":", start); #ifdef DEBUG_RESOLVE_PATH printf("DEBUG(%s:%d) resolve_filename top of loop colon=%d start=%d string='%s'\n",__FILE__,__LINE__,int(colon),int(start),path.c_str()+start); #endif std::string test_file = path.substr(start, colon - start); #ifdef DEBUG_RESOLVE_PATH printf("DEBUG(%s:%d) resolve_filename isolated colon=%d start=%d string='%s'\n",__FILE__,__LINE__,int(colon),int(start),test_file.c_str()); #endif test_file.append("/"); test_file.append(f); #ifdef DEBUG_RESOLVE_PATH printf("DEBUG(%s:%d) resolve_filename trying file named '%s'\n", __FILE__,__LINE__,test_file.c_str()); #endif FILE *fp = fopen(test_file.c_str(), "r"); if (fp != NULL) { fclose(fp); f = test_file; return true; } start = colon + 1; // skip the ':' } while (colon != STRING_NPOS); // Well, we just can't find this file. Too bad. return false; } char * pwd() { #if HAVE_GETCWD static char msg[1024]; if (NULL == getcwd(msg, 1024)) return (char *)""; else return msg; #elif defined(VMS) /* vms version braindead */ return ""; #elif defined(MSDOS) /* msdos version braindead */ return ""; #elif !defined(HAVE_POPEN) //err("Cannot do `pwd' because computer lacks popen() subroutine"); return ""; #else char msg[1024]; FILE *pipefile = (FILE *) popen("pwd", "r"); if (pipefile) { char *result; if (1 == fscanf(pipefile, "%s", msg)) { pclose(pipefile); result = new char[1 + strlen(msg)]; if (!result) OUT_OF_MEMORY; strcpy(result, msg); return result; } else { pclose(pipefile); warning("Can't determine name of working directory; using `.' instead."); result = new char[2]; if (!result) OUT_OF_MEMORY; strcpy(result, "."); return result; } } else { return "."; } #endif } char* egetenv(const char *s) { #if defined(HAVE_GETENV) char *rval = (char *)""; #endif if (!strcmp(s, "PWD")) { return (char *) pwd(); } else if (!strcmp(s, "USER")) { #if defined(HAVE_GETENV) rval = (char *)getenv(s); if (rval == NULL) return (char *)""; else return rval; #else return (char *)"unknown"; #endif } else if (!strcmp(s, "SYSTEM")) { #if defined(VMS) return (char *)"vax"; #elif defined(MSDOS) return (char *)"msdos"; #else return (char *)"unix"; #endif } else if (!strcmp(s, "HOST")) { #if defined(HAVE_GETENV) rval = (char *)getenv(s); if (rval == NULL) return (char *)""; else return rval; #else return (char *)"unknown"; #endif } else if (!strcmp(s, "HOME")) { #if defined(HAVE_GETENV) rval = (char *)getenv(s); if (rval == NULL) return (char *)""; else return rval; #else return (char *)"unknown"; #endif } else if (!strcmp(s, "PAGER")) { #if defined(HAVE_GETENV) rval = (char *)getenv(s); if (rval == NULL) return (char *)""; else return rval; #else return (char *)"unknown"; #endif } else if (!strcmp(s, "GRIINPUTS")) { #if defined(HAVE_GETENV) rval = (char *)getenv(s); if (rval == NULL) return (char *)""; else return rval; #else return ""; #endif } else { #if defined(HAVE_GETENV) rval = (char *)getenv(s); if (rval == NULL) return (char*)""; else return rval; #else return "unknown"; #endif } } /* sprintfCmd() -- print things into a string */ #define N 20 bool sprintfCmd() { char *fmt; char msg[1024]; double x[N]; if (_nword < 4) { err("`sprintf \\synonym \"format\"' requires variable list to process"); return false; } *(_word[2] + strlen(_word[2]) - 1) = '\0'; fmt = _word[2] + 1; for (unsigned int i = 3; i < _nword; i++) { getdnum(_word[i], &x[i - 3]); } switch (_nword) { case 4: sprintf(msg, fmt, x[0]); break; case 5: sprintf(msg, fmt, x[0], x[1]); break; case 6: sprintf(msg, fmt, x[0], x[1], x[2]); break; case 7: sprintf(msg, fmt, x[0], x[1], x[2], x[3]); break; case 8: sprintf(msg, fmt, x[0], x[1], x[2], x[3], x[4]); break; case 9: sprintf(msg, fmt, x[0], x[1], x[2], x[3], x[4], x[5]); break; case 10: sprintf(msg, fmt, x[0], x[1], x[2], x[3], x[4], x[5], x[6]); break; case 11: sprintf(msg, fmt, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7]); break; case 12: sprintf(msg, fmt, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8]); break; case 13: sprintf(msg, fmt, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9]); break; case 14: sprintf(msg, fmt, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10]); break; case 15: sprintf(msg, fmt, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11]); break; case 16: sprintf(msg, fmt, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12]); break; case 17: sprintf(msg, fmt, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13]); break; case 18: sprintf(msg, fmt, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13], x[14]); break; case 19: sprintf(msg, fmt, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15]); break; case 20: sprintf(msg, fmt, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15], x[16]); break; case 21: sprintf(msg, fmt, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15], x[16], x[17]); break; case 22: sprintf(msg, fmt, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15], x[16], x[17], x[18]); break; case 23: sprintf(msg, fmt, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15], x[16], x[17], x[18], x[19]); break; default: err("Can only do `sprintf' for 1-20 variables"); return false; } std::string w1(_word[1]); de_reference(w1); if (!is_syn(w1)) { demonstrate_command_usage(); err("Second word of command must be a synonym-name'"); return false; } if (!put_syn(w1.c_str(), msg, true)) { gr_Error("Ran out of storage"); return false; } return true; } #undef N /* * get (double) values from a list of words (typically the words in the cmd * line). Typically this is used in getting optional parameters from * commands, and _dstack[] is used for objects. RETURN number of objects * actually found */ int get_cmd_values(char ** w, int nw, const char *key, int nobjects, double *objects) { int istart = -1, i, found = 0, iobject; if (nobjects > _num_dstackMAX) return 0; for (i = 0; i < nw; i++) if (!strcmp(w[i], key)) { istart = i + 1; break; } if (istart == -1) return 0; /* 'key' not present */ if (istart + nobjects > nw) return -1; /* too few */ for (i = istart, iobject = 0; iobject < nobjects; i++, iobject++) { if (true != getdnum(w[i], &objects[iobject])) return found; found++; } return found; } char last_character(const char *s) { return s[strlen(s) - 1]; } // getinum -- return 0 if can't get number bool getinum(const char *s, int *i) { if (*s == '\0') return 0; extern double _grMissingValue; double d; char *ptr = NULL; d = _grMissingValue; *i = (int) strtod(s, &ptr); if (*ptr == '\0') { // It was a normal number with no problems in reading. return true; } // Cannot read as a normal number. Check to see if it's a variable or // NaN/Inf. if (is_var(s)) { if (get_var(s, &d)) { *i = (int) d; return true; } else { if (!skipping_through_if()) { err("variable `\\", s, "' is not defined yet", "\\"); return false; } else { *i = (int) _grMissingValue; return true; } } } else if (is_syn(s)) { std::string syn_value; bool exists = get_syn(s, syn_value); //printf("DEBUG %s:%d '%s' exists= %d value [%s]\n",__FILE__,__LINE__,s,exists,syn_value.c_str()); if (exists) { const char* vptr = syn_value.c_str(); ptr = NULL; // reset this *i = int(strtod(vptr, &ptr)); if (*ptr == '\0') { return true; } else { return false; } } else { return false; } } else if (!strcmp(s, "-NaN") || !strcmp(s, "NaN") || !strcmp(s, "Inf") || !strcmp(s, "Infinity") || !strcmp(s, "-Inf") || !strcmp(s, "-Infinity") ) { *i = (int) (_grMissingValue); return true; } else { // Maybe it's a fortran 'D' exponential tmp_string.assign(s); int loc; loc=tmp_string.find('d'); if (-1!=loc) tmp_string.replace(loc,1,"e"); loc=tmp_string.find('D'); if (-1!=loc) tmp_string.replace(loc,1,"e"); *i = (int)strtod(tmp_string.c_str(), &ptr); if (*ptr == '\0') return true; } // It's a mystery. report error, fatal or nonfatal depending on // whether the user is interested in errors. *i = (int) _grMissingValue; if (!_ignore_error) { if (isalpha(s[1])) { err("Cannot interpret `\\", s, "' as a number.\n Did you forget the final \".\" in a variable name?", "\\"); } else { err("Cannot interpret `\\", s, "' as a number.", "\\"); } } return false; } // getdnum -- return 0 if can't get number bool getdnum(const char *s, double *d) { if (*s == '\0') return false; if (get_normal_number(s, d)) { #ifdef DEBUG_UNDERSCORE printf("%s:%d normal number '%s' = %e\n", __FILE__,__LINE__,s, *d); #endif return true; } if (get_number_with_underscores(s, d)) { #ifdef DEBUG_UNDERSCORE printf("%s:%d decoded underline '%s' to be %e\n", __FILE__,__LINE__,s, *d); #endif return true; } #ifdef DEBUG_UNDERSCORE printf("%s:%d OK, not any kinda number '%s'\n", __FILE__,__LINE__,s); #endif // Cannot read as a normal number. Check to see if it's a variable or // NaN/Inf. extern double _grMissingValue; if (is_var(s)) { if (get_var(s, d)) { return true; } else { if (!skipping_through_if()) { err("variable `\\", s, "' is not defined yet", "\\"); return false; } else { *d = _grMissingValue; return true; } } #if 1 // vsn 2.6.0 [2001-feb-18] } else if (is_syn(s)) { std::string syn_value; bool exists = get_syn(s, syn_value); //printf("DEBUG %s:%d '%s' exists= %d value [%s]\n",__FILE__,__LINE__,s,exists,syn_value.c_str()); if (exists) { const char* vptr = syn_value.c_str(); char *ptr; ptr = NULL; // reset this *d = strtod(vptr, &ptr); if (*ptr == '\0') { return true; } else { return false; } } else { return false; } #endif } else if (!strcmp(s, "-NaN") || !strcmp(s, "NaN") || !strcmp(s, "-Inf") || !strcmp(s, "Inf")) { *d = _grMissingValue; return true; } else { // Maybe it's a fortran 'D' exponential tmp_string.assign(s); int loc; loc=tmp_string.find('d'); if (-1!=loc) tmp_string.replace(loc,1,"e"); loc=tmp_string.find('D'); if (-1!=loc) tmp_string.replace(loc,1,"e"); char *ptr; *d = (double)strtod(tmp_string.c_str(), &ptr); if (*ptr == '\0') return true; } // It's a mystery. report error, fatal or nonfatal depending on // whether the user is interested in errors. *d = (double) _grMissingValue; if (!_ignore_error) { if (isalpha(s[1])) { err("Cannot interpret `\\", s, "' as a number.\n Did you forget the final \".\" in a variable name?", "\\"); } else { err("Cannot interpret `\\", s, "' as a number.", "\\"); } } return false; } /* * fatal_err () -- print error message. If the first (string) argument ends * in '\\', then several strings follow, ended by a string consisting only of * "\\". */ void fatal_err(const char *str,...) { char msg[1024]; bool several = false; int len; char * p; va_list ap; if (!_error_in_cmd && _gri_beep) gr_textput("\007"); if (str != NULL) { va_start(ap, str); strcpy(msg, str); len = strlen(msg); if (msg[len - 1] == '\\') { msg[len - 1] = '\0'; several = true; } gr_textput("FATAL ERROR: "); do { gr_textput(msg); if (several) { p = va_arg(ap, char *); strcpy(msg, p); } } while (several && strcmp(msg, "\\")); gr_textput("\n"); _error_in_cmd = true; va_end(ap); } // // Print file:line so emacs mode can locate error // if (superuser() & FLAG_AUT1) { // Remove quotes around source indicator extern char source_indicator[]; sprintf(msg, " Error at %s\n", source_indicator); } else { if (block_level() > 0) { if (block_source_file() != NULL) { if (superuser() & FLAG_AUT1)printf("DEBUG utility.cc:fatal_err(): block_source_line()=%d\n",block_source_line()); sprintf(msg, " Error at %s:%d\n", block_source_file(), block_source_line() - 1); gr_textput(msg); } } else { if (what_file() != NULL) { sprintf(msg, " Error at %s:%d\n", what_file(), what_line()); gr_textput(msg); } } } if (_error_action == 1) gri_abort(); else gri_exit(1); } const char * what_file() { if (_cmdFILE.size() == 0) return NULL; if (block_level() > 0) { if (_cmd_being_done < 1) { return NULL; } else { return _command[_cmd_being_done_code[_cmd_being_done - 1]].filename; } } else { return _cmdFILE.back().get_name(); } } int what_line() { if (block_level() > 0) { if (_cmd_being_done < 1) { return -1; /* note: what_file() will give NULL */ } else { return _command[_cmd_being_done_code[_cmd_being_done - 1]].fileline + block_offset_line() - 1; } } else { return _cmdFILE.back().get_line(); } } /* * err () -- print error message. If the first (string) argument ends in * '\\', then several strings follow, ended by a string consisting only of * "\\". */ void err(const char *str,...) { char msg[1024]; bool several = false; int len; char * p; va_list ap; if (!_error_in_cmd && _gri_beep) gr_textput("\007"); if (str != NULL) { va_start(ap, str); strcpy(msg, str); len = strlen(msg); if (msg[len - 1] == '\\') { msg[len - 1] = '\0'; several = true; } gr_textput("ERROR: "); do { gr_textput(msg); if (several) { p = va_arg(ap, char *); strcpy(msg, p); } } while (several && strcmp(msg, "\\")); gr_textput("\n"); } _error_in_cmd = true; va_end(ap); } // warning () -- print warning message. All arguments must be char*. // If the first argument ends in '\\', then several strings follow, // ended by a string consisting only of "\\". If only string is '\\', // then this is a request to notify of number of repeats of last msg. void warning(const char *s,...) { static unsigned int msg_last_copies = 0; static std::string msg_last; // must be static static std::string msg; // static only for efficiency if called a lot bool several = false; int len; char *p = NULL; va_list ap; if (!_error_in_cmd && _gri_beep) gr_textput("\007"); // Check for final wrap-up command if (!strcmp(s, "\\\\")) { if (msg_last_copies > 0) { char buffer[100]; sprintf(buffer, " ... this warning was repeated %d times.\n", ++msg_last_copies); gr_textput(buffer); } return; } if (s != NULL) { va_start(ap, s); len = strlen(s); msg = s; if (msg[len - 1] == '\\') { msg.STRINGERASE(len - 1, 1); several = true; } do { if (several) { p = va_arg(ap, char *); if (strcmp(p, "\\")) msg += p; } } while (several && strcmp(p, "\\")); if (msg == msg_last) { // Same as last msg. Collect till a new one. msg_last_copies++; } else { // Not same as last msg. if (msg_last_copies > 0) { // This msg repeated char buffer[100]; sprintf(buffer, "Warning: (The last warning was repeated %d times.)\n", msg_last_copies + 1); gr_textput(buffer); // Now show current msg gr_textput("Warning: "); gr_textput(msg.c_str()); gr_textput("\n"); } else { // First time for this msg gr_textput("Warning: "); gr_textput(msg.c_str()); gr_textput("\n"); } msg_last_copies = 0; } msg_last = msg; } va_end(ap); } /* * ExtractQuote() -- extract quote `sout' from string `s'. NOTE: You must * ensure sout is as long as s. RETURN VALUE: character position at end of * extracted quote, if all was OK. Otherwise 0. * * Accepts both quoted strings '... "hi" ...' and unquoted strings '... \"hi\" ...' * but not combinations. */ // RETURN VALUE: // 0 if no quoted thing found // -1 if missing final-quote // >0 OK; value 'i' is such that s[i] is just after the final quote int ExtractQuote(const char *s, std::string& sout) { //printf("DEBUG %s:%d input string is '%s'\n",__FILE__,__LINE__,s); int i = 0; bool slash_quoted = false; // Skip along to first quote ... while (s[i] != '"') { if (s[i] == '\0') return 0; // never found any quoted items i++; } if (i > 0 && s[i - 1] == '\\') slash_quoted = true; i++; // skip the quote // ... then copy along until find first un-escaped quote ... while (s[i] != '\0') { if (s[i] == '"') { if (i > 0 && s[i - 1] == '\\') { if (!slash_quoted) { sout += '"'; } else { sout.STRINGERASE(sout.size() - 1, 1); // trim it //printf("DEBUG %s:%d RETURNING-A %d. Extracted quote length %d as \n<%s>\n", __FILE__,__LINE__,i+1,sout.size(),sout.c_str()); return i + 1; } } else { //printf("DEBUG %s:%d RETURNING-B %d\n<%s>\n\n",__FILE__,__LINE__,i+1,sout.c_str()); return i + 1; } } else { sout += s[i]; } i++; } if (s[i] == '\0') { //printf("DEBUG %s:%d RETURNING-C -1. Extracted quote length %d as \n<%s>\n", __FILE__,__LINE__,sout.size(),sout.c_str()); return -1; } // ... and return an index so the parser can do more // work on 's' past the quote //printf("DEBUG %s:%d RETURNING %d. Extracted quote length %d as \n<%s>\n", __FILE__,__LINE__,i,sout.size(),sout.c_str()); return i; } // Make all trailing blanks, tabs, etc, into null chars void remove_trailing_blanks(char *s) { int i = strlen(s); while (--i > -1) if (isspace(s[i])) s[i] = '\0'; else break; } // Make all trailing blanks, tabs, etc, into null chars void remove_trailing_blanks(std::string& s) { int i = s.length(); while (--i > -1) if (!isspace(s[i])) break; //printf("BEFORE removing trailing blanks '%s' ... ", s.c_str()); s.STRINGERASE(i + 1); //printf("AFTER '%s' ... ", s.c_str()); } void beep_terminal() { if (_gri_beep) fprintf(stderr, "\007"); } /* matrix_limits() - find min/max of matrix */ void matrix_limits(double *min, double *max) { bool first = true; double f; *min = *max = 0.0; for (unsigned int c = 0; c < _num_xmatrix_data; c++) { for (unsigned int r = 0; r < _num_ymatrix_data; r++) { if (_legit_xy(c, r) == true) { f = _f_xy(c, r); if (first == true) { *min = *max = f; first = false; } if (f < *min) *min = f; if (*max < f) *max = f; } } } if (first == true) { *min = gr_currentmissingvalue(); *max = gr_currentmissingvalue(); } } /* * inside_box - see if data point inside clip box DESCRIPTION Returns 1 if * either: (1) clipping turned off or (2) clipping on and inside axes or * (3) clipping on and inside (xl,xr)(yb,yt) box */ bool inside_box(double x, double y) { extern char _grTempString[]; extern gr_axis_properties _grTransform_x, _grTransform_y; /* If logarithmic, ensure that positive value */ if (_grTransform_x == gr_axis_LOG && x <= 0.0) return false; if (_grTransform_y == gr_axis_LOG && y <= 0.0) return false; if (_clipData == 0) { /* user did `set clip off' */ return true; } else if (_clipData == 1) {/* user did `set clip on xl xr yb yt' */ if (!BETWEEN(_clipxleft, _clipxright, x)) { if (_debugFlag & DEBUG_CLIPPED) { sprintf(_grTempString, "Clipping (%g, %g)\n", x, y); gr_textput(_grTempString); } return false; } if (!BETWEEN(_clipybottom, _clipytop, y)) { if (_debugFlag & 0x01) { sprintf(_grTempString, "Clipping (%g, %g)\n", x, y); gr_textput(_grTempString); } return false; } return true; } else { /* user did `set clip on' */ if (!BETWEEN(_xleft, _xright, x)) { if (_debugFlag & 0x01) { sprintf(_grTempString, "Clipping (%g, %g)\n", x, y); gr_textput(_grTempString); } return false; } if (!BETWEEN(_ybottom, _ytop, y)) { if (_debugFlag & 0x01) { sprintf(_grTempString, "Clipping (%g, %g)\n", x, y); gr_textput(_grTempString); } return false; } return true; } } bool grid_exists() { Require(_xgrid_exists, err("First `set x grid' or `read grid x'")); Require(_ygrid_exists, err("First `set y grid' or `read grid y'")); Require(_grid_exists, err("First `read grid data' or `convert columns to grid'")); return true; } bool scales_defined() { return ((_xscale_exists && _yscale_exists) ? true : false); } // Set environment for line drawing. bool set_environment() { // Update some things possibly ruined by other routines. BUG: I don't // think most of this is required; Macintosh remants gr_fontID old_font = gr_currentfont(); double fontsize = FONTSIZE_PT_DEFAULT; double linewidth = LINEWIDTH_DEFAULT; double symbolsize = SYMBOLSIZE_DEFAULT; double tic_direction = 0.0; // out double tic_size = 0.2; double xmargin = XMARGIN_DEFAULT; double ymargin = YMARGIN_DEFAULT; double xsize = XSIZE_DEFAULT; double ysize = YSIZE_DEFAULT; if (!get_var("..fontsize..", &fontsize)) warning("(set_environment), ..fontsize.. undefined so using 12"); gr_setfontsize_pt(fontsize); gr_setfont(old_font); // weird, since already set if (!get_var("..linewidth..", &linewidth)) warning("(set_environment), ..linewidth.. undefined so using default"); _griState.set_linewidth_line(linewidth); if (!get_var("..linewidthsymbol..", &linewidth)) warning("(set_environment), ..linewidthsymbol.. undefined so using default"); _griState.set_linewidth_symbol(linewidth); if (!get_var("..symbolsize..", &symbolsize)) warning("(set_environment) ..symbolsize.. undefined so using 5.0"); gr_setsymbolsize_cm(symbolsize); if (!get_var("..tic_direction..", &tic_direction)) warning("(set_environment) ..tic_direction.. undefined so using OUT"); gr_setticdirection(int(floor(0.5 + tic_direction)) ? true : false); if (!get_var("..tic_size..", &tic_size)) { warning("(set_environment) ..tic_size.. undefined so using default (0.2cm)"); gr_setticsize_cm((double) TICSIZE_DEFAULT); } else gr_setticsize_cm(tic_size); if (!get_var("..xmargin..", &xmargin)) warning("(set_environment) ..xmargin.. undefined so using default"); if (!get_var("..ymargin..", &ymargin)) warning("(set_environment) ..ymargin.. undefined so using default"); if (!get_var("..xsize..", &xsize)) warning("(set_environment) ..xsize.. undefined so using default"); if (!get_var("..ysize..", &ysize)) warning("(set_environment) ..ysize.. undefined so using default"); gr_setxtransform(_xtype); gr_setxscale(xmargin, xmargin + xsize, _xleft, _xright); gr_setytransform(_ytype); gr_setyscale(ymargin, ymargin + ysize, _ybottom, _ytop); gr_record_scale(); return true; } bool draw_axes_if_needed() { if (_need_x_axis && _need_y_axis) draw_axes(_axesStyle, 0.0, (gr_axis_properties) gr_axis_LEFT, true); return true; } bool batch() { double batch; get_var("..batch..", &batch); if (batch) return true; else return false; } unsigned int superuser() { return _griState.superuser(); } // display file on terminal void more_file_to_terminal(const char *filename) { char sys_cmd[100]; #if defined(VMS) // vax-vms machine sprintf(sys_cmd, "TYPE %s/PAGE", filename); #elif defined(MSDOS) // ibm-style msdos machine GriString fn(filename); fn.convert_slash_to_MSDOS(); sprintf(sys_cmd, "COMMAND.COM MORE < %s", fn.getValue()); #else // a neutral machine char *egetenv(const char *); char *pager = egetenv("PAGER"); if (*pager != '\0') sprintf(sys_cmd, "%s %s", pager, filename); else sprintf(sys_cmd, "more %s", filename); #endif if (((unsigned) superuser()) & FLAG_SYS) { ShowStr("\nSending the following command to the operating system:\n"); ShowStr(sys_cmd); ShowStr("\n"); } call_the_OS(sys_cmd, __FILE__, __LINE__); } bool demonstrate_command_usage() { ShowStr("PROPER USAGE: `"); if (cmd_being_done() > -1) { ShowStr(_command[cmd_being_done()].syntax); ShowStr("'\n"); } else { ShowStr(" unknown.\n"); } return true; } // Regular expression search. This is limited; presently can match: // (1) characters; (2) alternative characters given in square brackets; (3) // multiple characters followed by '*' or by '+'; (4) the '\s' metacharacter // (for whitespace, either SPACE, TAB or NEWLINE). // Notes: (1) notation is standard for regular expressions, in the 'perl' style; // (2) '^' is not supported (implied anyway); (3) '+' not supported, but easy // if I ever need it; (4) () not supported. bool re_compare(const char *s, const char *pattern) { bool find_target(const char *pattern, int *pindex, int plen, std::string& target, int *star, int *plus); int slen = strlen(s); int plen = strlen(pattern); int sindex = 0; int pindex = 0; int star; // is subpattern followed by '*'? int plus; // is subpattern followed by '+'? bool need_new_target = true; int matches = 0; // Search through pattern std::string target(""); while (sindex < slen) { bool this_matches = false; if (need_new_target) { if (!find_target(pattern, &pindex, plen, target, &star, &plus)) { #ifdef DEBUG_RE printf("ran out of pattern\n"); #endif return false; } matches = 0; } // Now see if source string matches #ifdef DEBUG_RE printf("source[%d] = `%c' ", sindex, s[sindex]); show_pattern(target.c_str(), target.size(), star, plus); #endif for (unsigned int tindex = 0; tindex < target.size(); tindex++) { if (s[sindex] == target[tindex] || target[tindex] == '.') { this_matches = true; matches++; break; } } // See if match if (this_matches) { if (star || plus) { need_new_target = false; } } else { // Not match. See if it was a repeat pattern ('*' or '+') if (star) { need_new_target = true; sindex--; // try again on this one } else if (plus) { if (matches < 1) { return false; } need_new_target = true; sindex--; // try again on this one } else { return false; // Failed match } } sindex++; } // while (sindex < slen) // Have matched all the way through the source string. So we have a // complete match if and only if the pattern string is now exhausted. if (pindex == plen) { return true; } // Some pattern left. See if all remaining targets are '*' types; then // have a match. while (find_target(pattern, &pindex, plen, target, &star, &plus)) { if (!star) { #ifdef DEBUG_RE printf(" ... still some non-* target left: `%s'\n", target.c_str()); #endif return false; } } // All remaining patterns (if any) were * type, so don't need to match return true; } bool find_target(const char *pattern, int *pindex, int plen, std::string& target, int *star, int *plus) { target = ""; /* * Determine present target, leaving *pindex pointing at next part of * pattern. */ *star = *plus = 0; if (*pindex >= plen) return false; switch (pattern[*pindex]) { case '\\': /* * Check against list of known escapes */ switch (pattern[*pindex + 1]) { case '\\': target += '\\'; (*pindex)++; /* the backslash */ (*pindex)++; /* the '\\' */ break; case 's': /* whitespace as in perl */ target += ' '; target += '\t'; //target += '\r'; target += '\n'; (*pindex)++; /* the backslash */ (*pindex)++; /* the 's' */ break; default: printf("unknown escape pattern in search string"); return false; } break; case '[': /* * List of alternatives. */ (*pindex)++; /* skip the '[' */ while (pattern[*pindex] != ']' && pattern[*pindex] != '\0') target += pattern[(*pindex)++]; (*pindex)++; /* skip the ']' */ break; default: /* * A single character. */ target += pattern[(*pindex)++]; } if (pattern[*pindex] == '*') { *star = 1; (*pindex)++; /* skip the '*' */ } else if (pattern[*pindex] == '+') { *plus = 1; (*pindex)++; /* skip the '+' */ } return true; } #ifdef DEBUG_RE static void show_pattern(const char *target, int tlen, int star, int plus) { int i; printf("target: "); for (i = 0; i < tlen; i++) { printf(" `%c'", target[i]); } if (star) printf("*"); else if (plus) printf("+"); printf("\n"); } #endif void swap(double& a, double& b) { double tmp = a; a = b; b = tmp; } // Indicate if this command will take a long time. Usage example: // GriTimer t; // for (i = 0; i < n; i++) { // if (!warned) // double frac = double(i) / double(n - 1); // warned = warn_if_slow(&t, frac, "draw something"); // ... possibly slow code // } bool warn_if_slow(GriTimer *t, double fraction_done, const char *cmd) { const double calibrate = 10.0; // wait this long to calibrate speed double dt = t->elapsed_time(); extern char _grTempString[]; if (_chatty < 1) return true; // user does not want this if (fraction_done == 0.0) return false; if (dt > calibrate) { dt = dt / fraction_done; if (dt > 3600.0) { sprintf(_grTempString, "\n`%s':\n This operation will take %.1g h; it is now %s", cmd, dt / 3600.0, t->now_ascii()); ShowStr(_grTempString); } else if (dt > 60.0) { sprintf(_grTempString, "\n`%s':\n This operation will take %.1g min; it is now %s", cmd, dt / 60.0, t->now_ascii()); ShowStr(_grTempString); } else if (dt > 15.0) { sprintf(_grTempString, "\n`%s':\n This operation will take %.0g sec; it is now %s", cmd, dt, t->now_ascii()); ShowStr(_grTempString); } return true; } return false; } // Returns portion of filename after last '/' character, if // there is one, otherwise returns full filename. const char *filename_sans_dir(const char *fullfilename) { int i, len = strlen(fullfilename); for (i = len - 1; i > -1; i--) { if (fullfilename[i] == '/') { return fullfilename + i + 1; } } return fullfilename; } void bounding_box_display(const char *msg) { printf("%s\n", msg); printf("bbox: (%f %f) (%f %f) cm\n", _bounding_box.llx(),_bounding_box.lly(), _bounding_box.urx(),_bounding_box.ury()); } // Update bounding box (stored in cm on page) void bounding_box_update(const rectangle& box) { // Only process if supplied bbox is nonzero in size #if 0 printf("updating bounding box %f < x < %f %f < y < %f\n", box.llx(), box.urx(), box.lly(), box.ury()); #endif if (box.llx() != box.urx() || box.lly() != box.ury()) { // If have existing bbox, see if this lies outside ... if (_bounding_box.llx() != _bounding_box.urx() || _bounding_box.lly() != _bounding_box.ury()) { if (box.llx() < _bounding_box.llx()) _bounding_box.set_llx(box.llx()); if (box.lly() < _bounding_box.lly()) _bounding_box.set_lly(box.lly()); if (_bounding_box.urx() < box.urx()) _bounding_box.set_urx(box.urx()); if (_bounding_box.ury() < box.ury()) _bounding_box.set_ury(box.ury()); } else { // ... else just copy it _bounding_box.set_llx(box.llx()); _bounding_box.set_lly(box.lly()); _bounding_box.set_urx(box.urx()); _bounding_box.set_ury(box.ury()); } } } double vector_min(double *v, unsigned n) { double return_value = v[0]; for (unsigned i = 1; i < n; i++) if (v[i] < return_value) return_value = v[i]; return return_value; } double vector_max(double *v, unsigned n) { double return_value = v[0]; for (unsigned i = 1; i < n; i++) if (return_value < v[i]) return_value = v[i]; return return_value; } void set_ps_color(char what) // what='p' for path or 't' for text { extern output_file_type _output_file_type; if (_output_file_type == postscript) { extern FILE *_grPS; extern bool _grWritePS; if (!_grWritePS) return; double r, g, b; if (what == 'p') _griState.color_line().getRGB(&r, &g, &b); else _griState.color_text().getRGB(&r, &g, &b); if (r == g && g == b) { fprintf(_grPS, "%.3g g\n", r); fprintf(_grPS, "%.3g G\n", r); } else { fprintf(_grPS, "%.3g %.3g %.3g rg\n", r, g, b); fprintf(_grPS, "%.3g %.3g %.3g RG\n", r, g, b); } } } void gri_abort() { close_data_files(); abort(); } void gri_exit(int code) { close_data_files(); exit(code); } // Determine a 1-2-5 scaling for interval xl xl) { *xlr = delta125 * (floor(xl / delta125)); *xrr = delta125 * (ceil(xr / delta125)); *nr = (int) floor(0.5 + (*xrr - *xlr) / delta125); } else { *xlr = delta125 * (ceil(xl / delta125)); *xrr = delta125 * (floor(xr / delta125)); *nr = (int) floor(0.5 - (*xrr - *xlr) / delta125); } n = int(0.8 * n); if (n < 1) n = 1; // need at least 1 segment } while ((*nr > int(1.75 * n_orig)) && ++tries < max_tries); } double rho(double S /* PSU */, double T /* in-situ degC */, double p /* dbar */) { double rho_w, Kw, Aw, Bw, p1, S12, ro, xkst; rho_w = 999.842594 + T * (6.793952e-2 + T * (-9.095290e-3 + T * (1.001685e-4 + T * (-1.120083e-6 + T * 6.536332e-9)))); Kw = 19652.21 + T * (148.4206 + T * (-2.327105 + T * (1.360477e-2 - T * 5.155288e-5))); Aw = 3.239908 + T * (1.43713e-3 + T * (1.16092e-4 - T * 5.77905e-7)); Bw = 8.50935e-5 + T * (-6.12293e-6 + T * 5.2787e-8); p1 = 0.1 * p; S12 = sqrt(S); ro = rho_w + S * (8.24493e-1 + T * (-4.0899e-3 + T * (7.6438e-5 + T * (-8.2467e-7 + T * 5.3875e-9))) + S12 * (-5.72466e-3 + T * (1.0227e-4 - T * 1.6546e-6) + S12 * 4.8314e-4)); xkst = Kw + S * (54.6746 + T * (-0.603459 + T * (1.09987e-2 - T * 6.1670e-5)) + S12 * (7.944e-2 + T * (1.6483e-2 + T * (-5.3009e-4)))) + p1 * (Aw + S * (2.2838e-3 + T * (-1.0981e-5 + T * (-1.6078e-6)) + S12 * (1.91075e-4)) + p1 * (Bw + S * (-9.9348e-7 + T * (2.0816e-8 + T * (9.1697e-10))))); return (ro / (1.0 - p1 / xkst)); } double pot_temp(double S, double t, double p, double pref) { double dp, sq2; double dt1, t1, q1; double dt2, t2, q2; double dt3, t3, q3; double dt4, t4; dp = pref - p; sq2 = sqrt(2.); dt1 = dp * lapse_rate(S, t, p); q1 = dt1; t1 = t + 0.5 * dt1; dt2 = dp * lapse_rate(S, t1, p + 0.5 * dp); q2 = (2. - sq2) * dt2 + (-2. + 3. / sq2) * q1; t2 = t1 + (1. - 1. / sq2) * (dt2 - q1); dt3 = dp * lapse_rate(S, t2, p + 0.5*dp); q3 = (2 + sq2) * dt3 + (-2. - 3. / sq2) * q2; t3 = t2 + (1. + 1. / sq2) * (dt3 - q2); dt4 = dp * lapse_rate(S, t3, p + dp); t4 = t3 + 1. / 6. * (dt4 - 2. * q3); return t4; } /* From Unesco technical papers in marine science, number 44 (1983). * * SYNTAX double lapse_rate(double S, double t, double p) * * UNITS S in psu; t in degC; p in dbar; * * RETURN VALUE adiabatic lapse rate in degC/dbar * * Note: used to compute potential temperature. */ double lapse_rate(double S, double t, double p) { const double a0 = 3.5803e-5; const double a1 = 8.5258e-6; const double a2 = -6.8360e-8; const double a3 = 6.6228e-10; const double b0 = 1.8932e-6; const double b1 = -4.2393e-8; const double c0 = 1.8741e-8; const double c1 = -6.7795e-10; const double c2 = 8.7330e-12; const double c3 = -5.4481e-14; const double d0 = -1.1351e-10; const double d1 = 2.7759e-12; const double e0 = -4.6206e-13; const double e1 = 1.8676e-14; const double e2 = -2.1687e-16; double Gamma; Gamma = a0 + t * (a1 + t * (a2 + t * a3)) + (S - 35.) * (b0 + t * b1) + p * (c0 + t * (c1 + t * (c2 + t * c3)) + (S - 35.) * (d0 + t * d1) + p * (e0 + t * (e1 + t * e2))); return Gamma; } // Get name for temporary file (hide details of libraries here) char* tmp_file_name() { #if defined(HAVE_MKSTEMP) #ifndef PATH_MAX #define PATH_MAX 8192 #endif static char rval[PATH_MAX]; int fd; /* * Create the file safely and let caller scribble on it. Not * perfect but better than the alternative. (One could also * change the function to return a fd or FILE * instead of a * path, but that's quite invasive.) */ strcpy(rval, _PATH_TMP "griXXXXXX"); fd = mkstemp(rval); if (fd < 0) { return NULL; } close(fd); return rval; #else #if defined(HAVE_TEMPNAM) // rval = tempnam("/usr/tmp", "gri"); char *rval = tempnam(NULL, "gri"); if (rval == NULL) return NULL; return rval; #else #if defined(HAVE_TMPNAM) char *rval = tmpnam(NULL); if (rval == NULL) return NULL; return rval; #else return GRI_TMP_FILE; #endif #endif #endif } int call_the_OS(const char* cmd, const char* calling_filename, int calling_line) { std::string c(cmd); clean_blanks_quotes(c); c.append("\n"); if (((unsigned) superuser()) & FLAG_SYS) { printf("Sending the following command to the operating system [ref: %s:%d]:\n%s\n", calling_filename, calling_line, c.c_str()); } int status = system(c.c_str()); PUT_VAR("..exit_status..", double(status)); return status; } void clean_blanks_quotes(std::string& c) { // Trim any blanks at the start and end ... while (isspace(c[0])) c.STRINGERASE(0,1); while (c.size() > 0 && isspace(c[-1 + c.size()])) c.STRINGERASE(-1 + c.size(), 1); // ... and, if the first nonblank symbol is a quote, // then remove both it and a matching trailing quote. if (c[0] == '"') { c.STRINGERASE(0,1); if (c.size() > 0 && c[-1 + c.size()] == '"') c.STRINGERASE(-1 + c.size(), 1); } } bool is_even_integer(double v) { int iv = int(v); if (double(iv) != v) return false; // not even an integer int iiv = 2 * (iv / 2); if (iv == iiv) return true; return false; } bool is_odd_integer(double v) { int iv = int(v); if (double(iv) != v) return false; // not even an integer int iiv = 2 * (iv / 2); if (iv != iiv) return true; return false; } void de_reference(std::string& syn) { //printf("%s:%d 1. de_reference (%s)...\n",__FILE__,__LINE__,syn.c_str()); if (syn[0] == '\\' && syn[1] == '@') { std::string deref("\\"); deref.append(syn.substr(2, syn.size())); //printf("2. deref= <%s>\n", deref.c_str()); std::string buf; if (get_syn(deref.c_str(), buf)) { syn.assign(buf); //printf("3. syn= <%s>\n", syn.c_str()); if (syn[0] == '\\' && syn[1] == '\\') syn.STRINGERASE(0, 1); //printf("4. syn= <%s>\n", syn.c_str()); } } //printf("%s:%d de_reference returning MODIFIED TO <%s>\n",__FILE__,__LINE__,syn.c_str()); } void un_double_slash(std::string& word) // change leading double-backslash to single-backslash { if (word[0] == '\\' && word[1] == '\\') word.STRINGERASE(0, 1); } void un_double_quote(std::string& word) { if (word[0] == '"') if (word[word.size() - 1] == '"') { word.STRINGERASE(word.size() - 1, 1); word.STRINGERASE(0, 1); } } void fix_negative_zero(std::string& number) // change e.g. "-0" to "0", for axes { //#define DEBUG_FIX_NEGATIVE_ZERO #ifdef DEBUG_FIX_NEGATIVE_ZERO number = "-" + number; printf("called fix_negative_zero(%s) [%s]\n", number.c_str(), number.c_str()); #endif unsigned int i; unsigned size = number.size(); // find first non-blank character unsigned start = 0; for (i = 0; i < size; i++) { if (number[i] != ' ') { start = i; break; } } if (i == size || number[i] != '-') return; #ifdef DEBUG_FIX_NEGATIVE_ZERO printf(" first character is a minus. start=%d\n ", start); #endif // find last digit unsigned end = size - 1; for (i = end; i > start; i--) { #ifdef DEBUG_FIX_NEGATIVE_ZERO printf("c[%2d]='%c' ", i, number[i]); #endif if (isdigit(number[i]) || number[i] == '.') { end = i; #ifdef DEBUG_FIX_NEGATIVE_ZERO printf("\n"); #endif break; } } #ifdef DEBUG_FIX_NEGATIVE_ZERO printf(" end=%d\n", end); #endif std::string portion = number.substr(start + 1, end - start); // just digits or decimals #ifdef DEBUG_FIX_NEGATIVE_ZERO printf(" portion='%s'\n", portion.c_str()); #endif // The 'portion' is now a middle portion consisting of digits and decimals bool is_zero = true; for (i = 0; i < portion.size(); i++) { if (!(portion[i] == '0' || portion[i] == '.')) { is_zero = false; break; } } //printf(" is_zero=%d\n", is_zero); if (is_zero) { #ifdef DEBUG_FIX_NEGATIVE_ZERO printf(" ERASING at start=%d\n", start); #endif number[start] = ' '; } #ifdef DEBUG_FIX_NEGATIVE_ZERO printf(" returning '%s'\n", number.c_str()); #endif #undef DEBUG_FIX_NEGATIVE_ZERO } bool get_optionsCmd() { DEBUG_FUNCTION_ENTRY; DEBUG_MESSAGE("This command does NOTHING yet.\n"); DEBUG_MESSAGE("This command is NOT documented yet.\n"); if (_nword < 3 || _nword > 5) { NUMBER_WORDS_ERROR; demonstrate_command_usage(); return false; } bool keep = false; // keep the unused options? if (_nword == 4) { if (word_is(3, "keep")) { keep = true; } else { demonstrate_command_usage(); err("Cannot understand word `\\", _word[3], "'. Expecting `keep' here, if anything", "\\"); DEBUG_FUNCTION_EXIT; return false; } } if (keep) DEBUG_MESSAGE("Will keep unused options.\n") else DEBUG_MESSAGE("Will NOT keep unused options.\n") std::string options(_word[2]); // Remove containing quotes, if present if (options[0] == '"') options.STRINGERASE(0, 1); if (options[options.size() - 1] == '"') options.STRINGERASE(options.size() - 1, 1); DEBUG_MESSAGE("Option-specification string was"); printf(" \"%s\"\n", options.c_str()); DEBUG_FUNCTION_EXIT; return true; } // Byte swapping, from /usr/include/bits/byteswap.h on a linux box #define gri_bswap_constant_32(x) \ ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) unsigned int endian_swap_uint(unsigned int v) { return gri_bswap_constant_32(v); } #undef gri_bswap_constant_32 bool gri_version_exceeds(unsigned int n1, unsigned int n2, unsigned int n3) { double v = n1 + n2 / 100.0 + n3 / 100000.0; return _version > v; } bool xy_to_pt(double xin, double yin, units u, double *xout, double *yout) { if (u == units_user) { gr_usertopt(xin, yin, xout, yout); } else if (u == units_cm) { *xout = xin * PT_PER_CM; *yout = yin * PT_PER_CM; } else if (u == units_pt) { *xout = xin; *yout = yin; } else { // impossible???? *xout = xin; *yout = yin; } return true; } bool xy_to_cm(double xin, double yin, units u, double *xout, double *yout) { if (u == units_user) { gr_usertocm(xin, yin, xout, yout); } else if (u == units_pt) { *xout = xin / PT_PER_CM; *yout = yin / PT_PER_CM; } else if (u == units_cm) { *xout = xin; *yout = yin; } else { // impossible?? *xout = xin; *yout = yin; } return true; } void fix_line_ending(char *line) { unsigned int len = strlen(line); if (len > 2 && line[len - 2] == '\r') { line[len - 2] = '\n'; line[len - 1] = '\0'; } } bool is_column_name(const char* n) { //printf("is_column_name(%s)\n", n); if (strEQ(n, "u") || strEQ(n, "v") || strEQ(n, "weight") || strEQ(n, "x") || strEQ(n, "y") || strEQ(n, "z") || strEQ(n, "z") ) return true; else return false; } #define ASSIGN_TO_COLUMN(i,v,c) \ { \ if ((i) >= int((c).size())) { \ for (int ii = int((c).size()); ii <= (i); ii++) {\ (c).push_back(0.0); \ } \ PUT_VAR("..num_col_data..", double(i));\ } \ (c)[(i)] = (v); \ _columns_exist = true;\ } bool assign_to_column(int index, double value, const char* c) { if (index < 0) return false; //printf("assigning %f to %s[%d]\n", value, c, index); if (strEQ(c, "x")) ASSIGN_TO_COLUMN(index, value, _colX); if (strEQ(c, "y")) ASSIGN_TO_COLUMN(index, value, _colY); if (strEQ(c, "z")) ASSIGN_TO_COLUMN(index, value, _colZ); if (strEQ(c, "u")) ASSIGN_TO_COLUMN(index, value, _colU); if (strEQ(c, "v")) ASSIGN_TO_COLUMN(index, value, _colV); return true; if (strEQ(c, "weight")) ASSIGN_TO_COLUMN(index, value, _colWEIGHT); return true; } double gr_page_height_pt() { extern rectangle _page_size; return (_page_size.ury() * PT_PER_CM); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/filter.cc�����������������������������������������������������������������������������������0000644�0001750�0001750�00000016756�13147557614�012422� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include // for reverse #include #include #include "gr.hh" #include "extern.hh" #include "image_ex.hh" static bool filter_butterworth(double *x, double *xout, int nx, const std::vector& a, const std::vector& b); static bool filter_image(int horl); void highpass_image(); void lowpass_image(); #define ODD(n) (2 * ((n) / 2) != (n)) // filter grid rows|columns recursively a[0] a[1] ... b[0] b[1] ... // 0 1 2 3 4 bool filter_gridCmd() { if (_nword <= 3) { NUMBER_WORDS_ERROR; return false; } if (!word_is(3, "recursively")) { err("Fourth word must be `recursively'"); return false; } bool do_rows = true; if (word_is(2, "rows")) { do_rows = true; } else if (word_is(2, "columns")) { do_rows = false; } else { err("Third word must be `rows' or `columns'"); return false; } // Get the coefficients int nab = _nword - 4; // number (a,b) coefficients if (nab < 1) { err("No filter coefficients given."); return false; } if (ODD(nab)) { err("Must give even number of filter coefficients."); return false; } nab = nab / 2; std::vector a((size_t)nab, 0.0); std::vector b((size_t)nab, 0.0); unsigned row, col; for (unsigned int i = 0; i < (unsigned int) nab; i++) { a[i] = atof(_word[4 + i]); b[i] = atof(_word[4 + i + nab]); } // Do the filtering double *orig = NULL, *copy = NULL; if (do_rows) { GET_STORAGE(orig, double, (size_t)_num_ymatrix_data); GET_STORAGE(copy, double, (size_t)_num_ymatrix_data); for (col = 0; col < _num_xmatrix_data; col++) { for (row = 0; row < _num_ymatrix_data; row++) orig[row] = _f_xy(col, row); filter_butterworth(orig, copy, _num_ymatrix_data, a, b); for (row = 0; row < _num_ymatrix_data; row++) _f_xy(col, row) = copy[row]; } } else { GET_STORAGE(orig, double, (size_t)_num_xmatrix_data); GET_STORAGE(copy, double, (size_t)_num_xmatrix_data); for (row = 0; row < _num_ymatrix_data; row++) { for (col = 0; col < _num_xmatrix_data; col++) orig[col] = _f_xy(col, row); filter_butterworth(orig, copy, _num_xmatrix_data, a, b); for (col = 0; col < _num_xmatrix_data; col++) _f_xy(col, row) = copy[col]; } } if (orig != NULL) free(orig); if (copy != NULL) free(copy); return true; } // filter column x|y|z|u|v|weight recursively a[0] a[1] ... b[0] b[1] ... bool filter_columnCmd() { unsigned int nab; // number of a, b coefficients unsigned int num = 0; // length of column Require(_nword > 3, NUMBER_WORDS_ERROR); Require(word_is(3, "recursively"), err("Fourth word must be `recursively'")); double *orig; if (word_is(2, "x")) { num = _colX.size(); orig = _colX.begin(); } else if (word_is(2, "y")) { num = _colY.size(); orig = _colY.begin(); } else if (word_is(2, "z")) { num = _colZ.size(); orig = _colZ.begin(); } else if (word_is(2, "u")) { num = _colU.size(); orig = _colU.begin(); } else if (word_is(2, "v")) { num = _colV.size(); orig = _colV.begin(); } else if (word_is(2, "weight")) { num = _colWEIGHT.size(); orig = _colWEIGHT.begin(); } else { orig = 0; // prevent compiler warning err("Unknown item."); } Require (num > 0, err("No data in column named '", _word[2], "'", "\\")); nab = _nword - 4; Require(nab > 0, err("No filter coefficients given.")); Require(!ODD(nab), err("Must give even number of filter coefficients.")); nab = nab / 2; std::vector a((size_t)nab, 0.0); std::vector b((size_t)nab, 0.0); for (unsigned int i = 0; i < nab; i++) { a[i] = atof(_word[4 + i]); b[i] = atof(_word[4 + i + nab]); } double *copy = (double*)NULL; GET_STORAGE(copy, double, (size_t)num); filter_butterworth(orig, copy, num, a, b); for (unsigned int i = 0; i < num; i++) orig[i] = copy[i]; free(copy); return true; } // filter_butterworth() -- do butterworth filtering, forward+back // Input is x[] (unaltered), output is xout[]; recursive-style coefficients are // a[]; moving average-style coefficients are b[]. static bool filter_butterworth(double* x, double* xout, int nx, const std::vector& a, const std::vector& b) { int nab = a.size(); if (nab >= nx) return false; double *z = (double*)NULL; GET_STORAGE(z, double, (size_t)nx); register int ix, iab; // pass 1 -- forward for (ix = 0; ix < nab; ix++) { // beginning part -- just copy z[ix] = x[ix]; } for (ix = nab; ix < nx; ix++) { z[ix] = b[0] * x[ix]; for (iab = 1; iab < nab; iab++) z[ix] += b[iab] * x[ix - iab] - a[iab] * z[ix - iab]; } // pass 2 -- backward std::reverse(z, z + nx); for (ix = 0; ix < nab; ix++) xout[ix] = z[ix]; for (ix = nab; ix < nx; ix++) { xout[ix] = b[0] * z[ix]; for (iab = 1; iab < nab; iab++) xout[ix] += b[iab] * z[ix - iab] - a[iab] * xout[ix - iab]; } std::reverse(xout, xout + nx); free(z); return true; } bool filter_imageCmd() { if (_nword != 3) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; } else if (!strcmp(_word[2], "highpass")) filter_image(1); else if (!strcmp(_word[2], "lowpass")) filter_image(0); else { demonstrate_command_usage(); err("Can only do `highpass' or `lowpass' filter"); return false; } return true; } static bool filter_image(int horl) { unsigned char *imPtr; register int i, j; int nx, ny, nx1, ny1, newval, change; Require(_image.storage_exists, err("no image exists")); nx = _image.ras_width; nx1 = nx - 1; ny = _image.ras_height; ny1 = ny - 1; std::vector imagenew((size_t)(nx * ny), (unsigned char)0); for (j = ny - 1; j > -1; j--) { imagenew[j] = _image.image[j]; imagenew[nx1 * ny + j] = _image.image[nx1 * ny + j]; } for (i = 0; i < nx; i++) { imagenew[i * ny] = _image.image[i * ny]; imagenew[i * ny + ny1] = _image.image[i * ny + ny1]; } for (j = 1; j < ny1; j++) { for (i = 1; i < nx1; i++) { imPtr = _image.image + i * ny + j; change = *(imPtr + 1); // i,j+1 change += *(imPtr - 1); // i,j-1 change += *(imPtr - ny); // i-1,j change += *(imPtr + ny); // i-1,j change -= *imPtr * 4; change = (int) (0.125 * (double) change); switch (horl) { case 0: // low pass newval = *imPtr + change; break; case 1: // high pass default: newval = *imPtr - change; break; } if (newval < 0) imagenew[i * ny + j] = (unsigned char) 0; else if (newval > 255) imagenew[i * ny + j] = (unsigned char) 255; else imagenew[i * ny + j] = (unsigned char) newval; } } nx *= ny; for (i = 0; i < nx; i++) _image.image[i] = imagenew[i]; return true; } void highpass_image() { filter_image(1); } void lowpass_image() { filter_image(0); } ������������������gri/src/postscpt.hh���������������������������������������������������������������������������������0000644�0001750�0001750�00000035765�13147557614�013027� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // BUG: change the "n" and "S" in symbol drawing later. gr.cc:gr_drawsymbol #if !defined(_postscpt_) #define _postscpt_ #define PS_break_path "stroke newpath\n%.1f %.1f m\n" #define PS_closepath "h\n" #define PS_comment "%%%s\n" #define PS_fill "F\n" #define PS_fillrect "%.1f %.1f %.1f %.1f fr\n" #define PS_lineto "%.1f %.1f l\n" #define PS_rlineto "%.1f %.1f rl\n" #define PS_moveto "%.1f %.1f m\n" #define PS_rmoveto "%.1f %.1f rm\n" #define PS_weak_newpath "n\n" #define PS_newpath "newpath\n" #define PS_setgray "%.3f g\n" #define PS_setlinewidth "%.3f w\n" #define PS_showc "(%c) sh\n" #define PS_showpage "showpage\n" #define PS_stroke "S\n" // Commands to retire, when get a chance to recode next: // rl rm ALL TEXT COMMANDS const static char *PS_dict[] = { "% NOTE: The Gri postscript dictionary is being converted to the Adobe", "% Illustrator 3.0 dialect of PostScript, as described in the Adobe", "% documents stored at URL", "% http://www.adobe.com/Support/TechNotes.html", "% (as of Jan 1996, this doc is number 5007). When the conversion", "% is complete, the Adobe Illustrator drawing program -- and any", "% program compatible with AI -- will be able to edit Gri output.", "%", "% The IslandDraw (TM) program is able to read Gri output", "% at this time; remarkably, it can read/edit arbitrary PostScript.", "%", "% The definitions below are presented in the same order as the Adobe", "% manual. The stack configuration before and after is shown in curly", "% brackets. All the operators are listed, but only some are defined", "% here. Most things are faithful, except that no distinction is made", "% between colors for stroking and filling paths. The string 'WRONGLY'", "% appears with commands that are approximations.", "%", "% PDF-style abbreviations:", "/rg {setrgbcolor} def % {red green blue} {-} set RGB color", "/RG {setrgbcolor} def % {red green blue} {-} set RGB color", "/q {gsave} def", "/Q {grestore} def", "/W {clip} def", "/W* {eoclip} def", "%", "% Gri-specific abbreviations:", "/hsb {sethsbcolor} def % {hue saturation brightness} {-} set HSB color", "%", "% Following all try to mimic Adobe Illustrator", "%", "% Mimicking section 5.1 of Adobe manual:", "%A % {flag A} {-} Determine whether", " % following object can", " % be selected. Flag=1", " % prevents selection;", " % flag=0 allows it.", "", "% Mimicking section 5.2 of Adobe manual:", "%u % {u} {-} start group", "%U % end group", "%q % as 'u' but first item is a clip path", "%Q % as 'U' but first item is a clip path", "", "% Mimicking section 5.3 of Adobe manual:", "/g {setgray} def % {gray g} {-} Set gray for fill", " % path, WRONGLY used", " % for stroking also. ", "/G {setgray} def % As 'g', but for filling path.", "%k % Set cmyk color for filling path.", "%K % As 'k', but for stroking path.", "%x % Set cmyk custom color for filling path.", "%X % As 'x' but for stroking path.", "%p % Define pattern for filling path.", "%P % As 'p' but for stroking path.", "%O % Specify whether overprinting for fill paths", "%R % As 'O' but for stroking path.", "", "% Mimicking section 5.4 of Adobe manual:", "/d {setdash} def % {[array] phase d} {-} Set dash.", "/i {setflat} def % {flatness i} {-} Set flatness.", "/j {setlinejoin} def % {linejoin j} {-} Set line join.", "/J {setlinecap} def % {linecap J} {-} Set line cap.", "/M {setmiterlimit} def % {miterlimit M} {-} Set miter limit.", "/w {setlinewidth} def % {linewidth w} {-} Set line width.", "", "% Mimicking section 5.5 of Adobe manual:", "/m {moveto} def % {x y m} {-} Move to locn", "/l {lineto} def % {x y l} {-} Draw line to locn", " % not a smooth point.", " % WRONGLY, no", " % distinction is made", " % between smooth and", " % corner. ", "%L % {x y L} {-} As 'l' but a corner", "%c % Bezier curve to smooth point.", "%C % As 'c' but to corner point.", "%v % Something else to do with Bezier.", "%V % ", "%y % ", "%Y % ", "", "% Mimicking section 5.6 of Adobe manual:", "%N % {N} {-} As 'n' for nondrawn stuff", "/n {newpath} def % {n} {-} WRONGLY interpreted", " % as path constructor", "/F {fill} def % {F} {-} Fill current path.", "%f % {f} {-} 'F' but close first", "/S {stroke} def % {S} {-} Stroke current path.", "%s % {s} {-} 'S' but close first", "%B % {B} {-} As 's' but don't empty path.", "%b % {b} {-} As 'f' but don't empty path.", "%H % no-op (weird huh?)", "/h {closepath} def % {h} {-} Close current path", "%W % Used to create masks.", "", "% Mimicking section 5.7 of Adobe manual:", "%a % Begin text block ...", "%e % Similar to 'a' but ...", "%I % Similar to 'a' but ...", "%o % Similar to 'a' but ...", "%r % Similar to 'a' but ...", "%t % {len (string) t} {-} Render string.", "%T % End block of text", "", "% That's the end of the Illustrator stuff. Following are some Gri", "% definitions which provide a temporary way of handling fonts. ", "/sf {setfont} def % {fontname sf} {-} Set font name.", "/sh {show} def % {(text) sh} {-} Show text.", "/sc {scalefont} def % {size sc} {-} Scale font.", "% Gri items which should be translated to Illustrator format:", "/rl {rlineto} def", "/rm {rmoveto} def", "% Procedures", "/cimdict 7 dict def", "/cim {", " cimdict begin", " /cl exch def", " /rw exch def", " /yur exch def", " /xur exch def", " /yll exch def", " /xll exch def", " q", " xll yll translate", " xur xll sub yur yll sub scale", " /do cl 3 mul string def", " cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop} false 3 colorimage", " Q", " end", "} def", #if 1 // suggested 2001-mar-01 as workaround for ps2pdf bug "/imdict 14 dict def", "/im {", " imdict begin", " /cl exch def", " /rw exch def", " /yur exch def", " /xur exch def", " /yll exch def", " /xll exch def", " /imagemap exch def", " q", " % Until version 2.6.0 used a 'settransfer' here, but that", " % triggers a bug in ps2pdf", " xll yll translate", " xur xll sub yur yll sub scale", " /do cl string def", " cl rw 8 [cl 0 0 rw neg 0 rw]", " {currentfile do readhexstring pop", " dup length 1 sub 0 1 3 -1 roll", " { 1 index exch", " 2 copy get imagemap exch get 255 mul cvi put", " }", " for", " }image", " Q", " end", "} bind def", #else "/imdict 14 dict def", "/im {", " imdict begin", " /cl exch def", " /rw exch def", " /yur exch def", " /xur exch def", " /yll exch def", " /xll exch def", " /imagemap exch def", " q", " % Add the mapping to the transfer function (ref: white book, p 743.", " [{255 mul cvi imagemap exch get} /exec load currenttransfer /exec load]", " cvx settransfer", " xll yll translate", " xur xll sub yur yll sub scale", " /do cl string def", " cl rw 8 [cl 0 0 rw neg 0 rw] {currentfile do readhexstring pop}image", " Q", " end", "} def", #endif "/frdict 5 dict def", "/fr {", " frdict begin", " /yt exch def", " /xr exch def", " /yb exch def", " /xl exch def", " n", " xl yb m", " xl yt l", " xr yt l", " xr yb l", " h", " F", " n", " end", "} def", "/plusdict 3 dict def", "/_plus {", " plusdict begin", " dup 0.5 mul /t0 exch def", " /t1 exch def", " 0 t0 rm", " 0 t1 neg rl", " t0 neg t0 rm", " t1 0 rl", " t0 neg 0 rm", " end", "} def", "/timesdict 3 dict def", "/_times {", " timesdict begin", " dup 0.353553 mul /t0 exch def", " 0.707106 mul /t1 exch def", " t0 neg t0 rm", // upper left " t1 dup neg rl", // lower right " t1 neg 0 rm", // lower left " t1 dup rl", // upper right " t0 neg dup rm", // centre " end", "} def", "/boxdict 3 dict def", "/_box {", " boxdict begin", " dup 0.5 mul /t0 exch def", " 1 mul /t1 exch def", " t0 neg t0 rm", // top left " t1 0 rl", // top right " 0 t1 neg rl", // bottom right " t1 neg 0 rl", // bottom left " h", // back to top left " t0 dup neg rm", // end at centre " end", "} def", "/filledboxdict 3 dict def", "/_filledbox {", " filledboxdict begin", " dup 0.5 mul /t0 exch def", " 1 mul /t1 exch def", " t0 neg t0 rm", // top left " t1 0 rl", // top right " 0 t1 neg rl", // bottom right " t1 neg 0 rl", // bottom left " h", // back to top left " t0 dup neg rm", // end at centre " F end", "} def", "/diamonddict 2 dict def", "/_diamond {", " diamonddict begin", " 0.5 mul /t0 exch def", " t0 neg 0 rm", // left " t0 dup rl", // top " t0 dup neg rl", // right " t0 neg dup rl", // bottom " h", // back to left " t0 0 rm", // end at centre " end", "} def", "/filleddiamonddict 2 dict def", "/_filleddiamond {", " filleddiamonddict begin", " 0.5 mul /t0 exch def", " t0 neg 0 rm", // left " t0 dup rl", // top " t0 dup neg rl", // right " t0 neg dup rl", // bottom " h", // back to left " t0 0 rm", // end at centre " F end", "} def", "/triangleupdict 5 dict def", "/_triangleup {", " triangleupdict begin", " dup 0.25 mul /t0 exch def", " dup 0.433013 mul /t1 exch def", " dup 0.75 mul /t2 exch def", " 0.866026 mul /t3 exch def", " t1 neg t0 neg rm", // bottom left " t1 t2 rl", // top " t1 t2 neg rl", // bottom right " h", // back to bottom left " t1 t0 rm", // end at centre " end", "} def", "/filledtriangleupdict 5 dict def", "/_filledtriangleup {", " filledtriangleupdict begin", " dup 0.25 mul /t0 exch def", " dup 0.433013 mul /t1 exch def", " dup 0.75 mul /t2 exch def", " 0.866026 mul /t3 exch def", " t1 neg t0 neg rm", // bottom left " t1 t2 rl", // top " t1 t2 neg rl", // bottom right " h", // back to bottom left " t1 t0 rm", // end at centre " F end", "} def", "/trianglerightdict 5 dict def", "/_triangleright {", " trianglerightdict begin", " dup 0.25 mul /t0 exch def", " dup 0.433013 mul /t1 exch def", " dup 0.75 mul /t2 exch def", " 0.866026 mul /t3 exch def", " t0 neg t1 rm", // top " t2 t1 neg rl", // right " t2 neg t1 neg rl", // bottom " h", // back to top " t0 t1 neg rm", // end at centre " end", "} def", "/filledtrianglerightdict 5 dict def", "/_filledtriangleright {", " filledtrianglerightdict begin", " dup 0.25 mul /t0 exch def", " dup 0.433013 mul /t1 exch def", " dup 0.75 mul /t2 exch def", " 0.866026 mul /t3 exch def", " t0 neg t1 rm", // top " t2 t1 neg rl", // right " t2 neg t1 neg rl", // bottom " h", // back to top " t0 t1 neg rm", // end at centre " F end", "} def", "/triangledowndict 5 dict def", "/_triangledown {", " triangledowndict begin", " dup 0.25 mul /t0 exch def", " dup 0.433013 mul /t1 exch def", " dup 0.75 mul /t2 exch def", " 0.866026 mul /t3 exch def", " t1 neg t0 rm", // top left " t3 0 rl", // top right " t1 neg t2 neg rl", // bottom " h", // back to top left " t1 t0 neg rm", // end at centre " end", "} def", "/filledtriangledowndict 5 dict def", "/_filledtriangledown {", " filledtriangledowndict begin", " dup 0.25 mul /t0 exch def", " dup 0.433013 mul /t1 exch def", " dup 0.75 mul /t2 exch def", " 0.866026 mul /t3 exch def", " t1 neg t0 rm", // top left " t3 0 rl", // top right " t1 neg t2 neg rl", // bottom " h", // back to top left " t1 t0 neg rm", // end at centre " F end", "} def", "/triangleleftdict 5 dict def", "/_triangleleft {", " triangleleftdict begin", " dup 0.25 mul /t0 exch def", " dup 0.433013 mul /t1 exch def", " dup 0.75 mul /t2 exch def", " 0.866026 mul /t3 exch def", " t0 t1 rm", // top " 0 t3 neg rl", // bottom " t2 neg t1 rl", // left " h", // back to top " t0 neg t1 neg rm", // end at centre " end", "} def", "/filledtriangleleftdict 5 dict def", "/_filledtriangleleft {", " filledtriangleleftdict begin", " dup 0.25 mul /t0 exch def", " dup 0.433013 mul /t1 exch def", " dup 0.75 mul /t2 exch def", " 0.866026 mul /t3 exch def", " t0 t1 rm", // top " 0 t3 neg rl", // bottom " t2 neg t1 rl", // left " h", // back to top " t0 neg t1 neg rm", // end at centre " F end", "} def", "/circdict 5 dict def", "/_circ {", " circdict begin", " 0.5 mul /t0 exch def", " currentpoint", " /t2 exch def", " /t1 exch def", " S n t1 t2 t0 0 360 arc", " t1 t2 m", " end", "} def", "/bulldict 3 dict def", // stack: diameter "/_bull {", " bulldict begin", " 0.5 mul /r exch def", " currentpoint /y exch def /x exch def", " S n x y r 0 360 arc h F S", " end", "} def", "/filledhalfmoonupdict 3 dict def", // stack: diameter "/_filledhalfmoonup {", " bulldict begin", " 0.5 mul /r exch def", " currentpoint /y exch def /x exch def", " S n x y r 0 180 arc h F S", " end", "} def", "/filledhalfmoondowndict 3 dict def", // stack: diameter "/_filledhalfmoondown {", " bulldict begin", " 0.5 mul /r exch def", " currentpoint /y exch def /x exch def", " S n x y r 180 360 arc h F S", " end", "} def", NULL }; #endif // _postscpt_ �����������gri/src/quit.cc�������������������������������������������������������������������������������������0000644�0001750�0001750�00000002346�13147557614�012105� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include "gr.hh" #include "extern.hh" bool quitCmd() { double tmp; switch (_nword) { case 1: _done = 1; return true; case 2: if (!getdnum(_word[1], &tmp)) { fatal_err("Cannot interpret `quit' exit value `\\", _word[1], "'", "\\"); } _exit_value = (int) floor(0.5 + tmp); _done = 1; return true; default: demonstrate_command_usage(); fatal_err("Extra word in command"); return false; } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/flip.cc�������������������������������������������������������������������������������������0000644�0001750�0001750�00000007725�13147557614�012063� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include "gr.hh" #include "extern.hh" #include "image_ex.hh" bool flipCmd(); bool flip_gridCmd(void); bool flip_imageCmd(void); bool flipCmd() { if (_nword != 3) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (!strcmp(_word[1], "grid")) return flip_gridCmd(); else if (!strcmp(_word[1], "image")) return flip_imageCmd(); else return false; } bool flip_gridCmd() { register int i, j; int width, width_half, height, height_half; double swap; bool do_x = true; if (_nword != 3) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (!strcmp(_word[2], "x")) do_x = true; else if (!strcmp(_word[2], "y")) do_x = false; else { demonstrate_command_usage(); err("Can only flip with respect to `x' or `y'"); return false; } if (!_grid_exists) { err("No grid exists yet\n"); return false; } // Flip the grid. width = _num_xmatrix_data; width_half = width / 2; height = _num_ymatrix_data; height_half = height / 2; if (do_x) { for (i = 0; i < width_half; i++) for (j = 0; j < height; j++) { int i_swap = width - i - 1; swap = _f_xy(i, j); _f_xy(i, j) = _f_xy(i_swap, j); _f_xy(i_swap, j) = swap; bool swap_legit = _legit_xy(i, j); _legit_xy(i, j) = _legit_xy(i_swap, j); _legit_xy(i_swap, j) = swap_legit; } } else { for (i = 0; i < width; i++) for (j = 0; j < height_half; j++) { int j_swap = height - j - 1; swap = _f_xy(i, j); _f_xy(i, j) = _f_xy(i, j_swap); _f_xy(i, j_swap) = swap; bool swap_legit = _legit_xy(i, j); _legit_xy(i, j) = _legit_xy(i, j_swap); _legit_xy(i, j_swap) = swap_legit; } } return true; } bool flip_imageCmd() { register int i, j, width, width_half, height, height_half; register unsigned char swap; bool do_x = true; if (_nword != 3) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (!strcmp(_word[2], "x")) do_x = true; else if (!strcmp(_word[2], "y")) do_x = false; else { demonstrate_command_usage(); err("Can only flip with respect to `x' or `y'"); return false; } if (!_image.storage_exists) { err("No image exists yet\n"); return false; } /* * Flip the image. */ width = _image.ras_width; width_half = width / 2; height = _image.ras_height; height_half = height / 2; if (do_x) { //printf("flipping in x an image %d wide and %d tall\n",width,height); for (i = 0; i < width_half; i++) for (j = 0; j < height; j++) { int ii = width - i - 1; swap = *(_image.image + i * height + j); *(_image.image + i * height + j) = *(_image.image + ii * height + j); *(_image.image + ii * height + j) = swap; } } else { //printf("flipping in y an image %d wide and %d tall\n",width,height); for (i = 0; i < width; i++) for (j = 0; j < height_half; j++) { int jj = height - j - 1; swap = *(_image.image + i * height + j); *(_image.image + i * height + j) = *(_image.image + i * height + jj); *(_image.image + i* height + jj) = swap; } } return true; } �������������������������������������������gri/src/types.hh������������������������������������������������������������������������������������0000644�0001750�0001750�00000006054�13147557614�012301� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // Define some useful types #ifndef _gri_types_hh_ #include #include #define _gri_types_hh_ enum gr_textStyle { // Text writing options TEXT_LJUST, TEXT_RJUST, TEXT_CENTERED }; enum units { // Units for GriPath units_cm, units_pt, units_user }; static inline double min4(double a, double b, double c, double d) { double rval = a; if (b < a) rval = b; if (c < a) rval = c; if (d < a) rval = d; return rval; } static inline double max4(double a, double b, double c, double d) { double rval = a; if (b > a) rval = b; if (c > a) rval = c; if (d > a) rval = d; return rval; } class rectangle { // a rectangle oriented parallel to axis public: rectangle(double llx, double lly, double urx, double ury) { ll_x = llx; ll_y = lly; ur_x = urx; ur_y = ury; } rectangle(void) { ll_x = ll_y = ur_x = ur_y = 0.0; } ~rectangle() {} void set(double llx, double lly, double urx, double ury) { ll_x = llx; ll_y = lly; ur_x = urx; ur_y = ury; } void scale(double f) { ll_x *= f; ll_y *= f; ur_x *= f; ur_y *= f;} double llx(void) const { return ll_x; } double lly(void) const { return ll_y; } double urx(void) const { return ur_x; } double ury(void) const { return ur_y; } void set_llx(double llx) { ll_x = llx;} void set_lly(double lly) { ll_y = lly;} void set_urx(double urx) { ur_x = urx;} void set_ury(double ury) { ur_y = ury;} void shift_x(double dx) { ll_x += dx; ur_x += dx;} void shift_y(double dy) { ll_y += dy; ur_y += dy;} void rotate(double degrees_ccw) { double rad_ccw = degrees_ccw / 57.29577951; double c = cos(rad_ccw); double s = sin(rad_ccw); double x1 = c * ll_x - s * ll_y; double y1 = s * ll_x + c * ll_y; double x2 = c * ur_x - s * ll_y; double y2 = s * ur_x + c * ll_y; double x3 = c * ur_x - s * ur_y; double y3 = s * ur_x + c * ur_y; double x4 = c * ll_x - s * ur_y; double y4 = s * ll_x + c * ur_y; ll_x = min4(x1, x2, x3, x4); ur_x = max4(x1, x2, x3, x4); ll_y = min4(y1, y2, y3, y4); ur_y = max4(y1, y2, y3, y4); } double get_llx() { return ll_x; } double get_lly() { return ll_y; } double get_urx() { return ur_x; } double get_ury() { return ur_y; } private: double ll_x; // lower-left double ll_y; double ur_x; // upper-right double ur_y; }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/input.cc������������������������������������������������������������������������������������0000644�0001750�0001750�00000005315�13147557614�012261� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include "gr.hh" #include "extern.hh" #include "private.hh" extern char _grTempString[]; /* `input \ps_filename [.xcm. .ycm. [.xmag. .ymag. [.rot_deg.]]]' */ bool inputCmd() { double xcm = 0.0, ycm = 0.0, xmag = 1.0, ymag = 1.0, angle = 0.0; std::string fname(_word[1]); un_double_quote(fname); std::string completefilename(fname); resolve_filename(completefilename, true, 'c'); // BUG do I want 'c' or 'd' here?? switch (_nword) { case 7: getdnum(_word[6], &angle); getdnum(_word[5], &ymag); getdnum(_word[4], &xmag); getdnum(_word[3], &ycm); getdnum(_word[2], &xcm); break; case 6: getdnum(_word[5], &ymag); getdnum(_word[4], &xmag); getdnum(_word[3], &ycm); getdnum(_word[2], &xcm); break; case 4: getdnum(_word[3], &ycm); getdnum(_word[2], &xcm); break; default: demonstrate_command_usage(); NUMBER_WORDS_ERROR; break; } /* Search directory only if not specified as local/fullpath */ std::string longfilename(completefilename); //OLD if (completefilename[0] != '/' && completefilename[0] != '.') //OLD longfilename.assign(file_in_list(completefilename.c_str(), false, false)); FILE *fp; if (NULL == (fp = fopen(longfilename.c_str(), "r"))) { fatal_err("Cannot open `input' file named `\\", longfilename.c_str(), "'", "\\"); return false; } /* * Scan through the file, doing lines. */ extern FILE *_grPS; fprintf(_grPS, "q %% Beginning of `input' file named `%s'\n", longfilename.c_str()); fprintf(_grPS, "%f %f translate %f %f scale %f rotate\n", xcm * PT_PER_CM, ycm * PT_PER_CM, xmag, ymag, angle); while (!feof(fp)) { /* * See if hit EOF on a line with no text. */ if (NULL == fgets(_grTempString, LineLength, fp)) break; fprintf(_grPS, "%s", _grTempString); } fprintf(_grPS, "Q %% End of `input' file named `%s'\n", longfilename.c_str()); fclose(fp); return true; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/Synonym.hh����������������������������������������������������������������������������������0000644�0001750�0001750�00000007656�13147557614�012622� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // Store synonym name/value #if !defined(_grisynonym_h_) #define _grisynonym_h_ #include "GCounter.hh" #if 1 class GriSynonym : public GriCounter { public: GriSynonym() { ; } GriSynonym(const char *the_name, const char *the_value) { name.assign(the_name); value.assign(the_value); } GriSynonym(const GriSynonym& c) { name.assign(c.get_name()); value.assign(c.get_value_quietly()); } ~GriSynonym() { #if 0 // BUG 2001-feb-17 -- not sure on next 2 lines name.string::~string(); // not executed value.string::~string(); // not executed #endif } void setNameValue(const char *the_name, const char *the_value) { name.assign(the_name); value.assign(the_value); } void set_value(const char *the_value) {value.assign(the_value); } const char *get_name(void) const {return name.c_str();}; const char *get_value(void) {incrementCount(); return value.c_str();}; const char *get_value_quietly(void) const {return value.c_str();}; GriSynonym& operator=(const GriSynonym& n) { name.assign(n.get_name()); value.assign(n.get_value_quietly()); return *this; } private: std::string name; std::string value; }; #else class GriSynonym : public GriCounter { public: GriSynonym() { name = new char [1]; if (!name) OUT_OF_MEMORY; name[0] = '\0'; value = new char [1]; if (!value) OUT_OF_MEMORY; value[0] = '\0'; } GriSynonym(const char *the_name, const char *the_value) { name = new char [1 + strlen(the_name)]; if (!name) OUT_OF_MEMORY; strcpy(name, the_name); value = new char [1 + strlen(the_value)]; if (!value) OUT_OF_MEMORY; strcpy(value, the_value); } GriSynonym(const GriSynonym& c) { name = new char [1 + strlen(c.getName())]; if (!name) OUT_OF_MEMORY; strcpy(name, c.getName()); value = new char [1 + strlen(c.get_value_quietly())]; if (!value) OUT_OF_MEMORY; strcpy(value, c.get_value_quietly()); } ~GriSynonym() { #if 0 delete [] name; delete [] value; #endif } void setNameValue(const char *the_name, const char *the_value) { if (strlen(the_name) > strlen(name)) { delete [] name; name = new char [1 + strlen(the_name)]; if (!name) OUT_OF_MEMORY; } strcpy(name, the_name); if (strlen(the_value) > strlen(value)) { delete [] value; value = new char [1 + strlen(the_value)]; if (!value) OUT_OF_MEMORY; } strcpy(value, the_value); } void set_value(const char *the_value) { if (strlen(the_value) > strlen(value)) { delete [] value; value = new char[1 + strlen(the_value)]; if (!value) OUT_OF_MEMORY; } strcpy(value, the_value); } char *getName(void) const {return name;}; char *getValue(void) {incrementCount(); return value;}; char *get_value_quietly(void) const {return value;}; GriSynonym& operator=(const GriSynonym& n) { char *cp = n.getName(); if (strlen(cp) > strlen(name)) { delete [] name; name = new char [1 + strlen(cp)]; if (!name) OUT_OF_MEMORY; } strcpy(name, cp); cp = n.get_value_quietly(); if (strlen(cp) > strlen(value)) { delete [] value; value = new char [1 + strlen(cp)]; if (!value) OUT_OF_MEMORY; } strcpy(value, cp); return *this; } private: char *name; char *value; }; #endif #endif ����������������������������������������������������������������������������������gri/src/regress.cc����������������������������������������������������������������������������������0000644�0001750�0001750�00000017651�13147557614�012602� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include "gr.hh" #include "extern.hh" extern char _grTempString[]; bool regressCmd(void); bool regress_linearCmd(void); static int fit(double x[], double y[], unsigned int ndata, std::vector::iterator, double *a, double *b, double *siga, double *sigb, double *chi2, double *q); double R_linear(double x[], double y[], unsigned int n); double rms_deviation(double x[], double y[], unsigned int n, double a, double b); static double student_t_025(unsigned int nu); // regressCmd() - handle 'regress' command bool regressCmd() { if (!_columns_exist) { err("first 'read columns'\n"); return false; } switch (_nword) { case 4: // regress y vs x regress_linearCmd(); break; case 5: // regress y vs x linear if (!strcmp(_word[4], "linear")) regress_linearCmd(); else { err("only linear regression permitted now"); return false; } break; default: err("proper: regress y vs x [linear]"); return false; } return true; } bool regress_linearCmd() { double a, b, siga, sigb, chi2, q; double r2; if (_colX.size() < 2 || _colY.size() < 2) { err("need more than 2 data points\n"); return false; } if (strcmp(_word[2], "vs")) { err("keyword 'vs' required. proper: regress y vs x"); return false; } std::vector sigma(_colX.size(), 0.0); if (_colWEIGHT.size() == _colX.size()) { for (unsigned int i = 0; i < _colWEIGHT.size(); i++) { if (_colWEIGHT[i]) sigma[i] = 1.0 / sqrt(_colWEIGHT[i]); else { sigma[i] = 1.0e10; // something big } } } else { for (unsigned int i = 0; i < _colX.size(); i++) if (!gr_missing(_colX[i]) && !gr_missing(_colY[i])) sigma[i] = 1.0; else sigma[i] = 1.0e10; } if (!strcmp(_word[1], "y") && !strcmp(_word[3], "x")) { // regress y vs x int good = fit(_colX.begin(), _colY.begin(), _colX.size(), sigma.begin(), &a, &b, &siga, &sigb, &chi2, &q); r2 = R_linear(_colX.begin(), _colY.begin(), _colX.size()); r2 = r2 * r2; double deviation = rms_deviation (_colX.begin(), _colY.begin(), _colX.size(), a, b); if (good > 2) { sprintf(_grTempString, "\ y = [%g +/- %g] + [%g +/- %g]x (95%% CI); chi2=%g; q=%5g; R^2=%g; rms deviation=%g (%d good data)\n", a, student_t_025(good-2)*siga, b, student_t_025(good-2)*sigb, chi2, q, r2, deviation, good); } else { sprintf(_grTempString, "\ y = %g + %g x; chi2=%g; R^2=%g (%d good data)\n", a, b, chi2, r2, good); } PUT_VAR("..coeff0..", a); PUT_VAR("..coeff1..", b); PUT_VAR("..coeff0_sig..", student_t_025(good-2)*siga); PUT_VAR("..coeff1_sig..", student_t_025(good-2)*sigb); PUT_VAR("..R2..", r2); PUT_VAR("..regression_deviation..", deviation); gr_textput(_grTempString); return true; } else if (!strcmp(_word[1], "x") && !strcmp(_word[3], "y")) { // regress x vs y int good; good = fit(_colY.begin(), _colX.begin(), _colX.size(), sigma.begin(), &a, &b, &siga, &sigb, &chi2, &q); r2 = R_linear(_colY.begin(), _colX.begin(), _colX.size()); r2 = r2 * r2; double deviation = rms_deviation (_colY.begin(), _colX.begin(), _colY.size(), a, b); if (good > 2) { sprintf(_grTempString, "\ x = [%g +/- %g] + [%g +/- %g]y (95%% CI); chi2=%g; q=%5g; R^2=%g; rms deviation=%g (%d good data)\n", a, student_t_025(good-2)*siga, b, student_t_025(good-2)*sigb, chi2, q, r2, deviation, good); } else { sprintf(_grTempString, "\ x = %g + %g y; chi2=%g; R^2=%g (%d good data)\n", a, b, chi2, r2, good); } PUT_VAR("..coeff0..", a); PUT_VAR("..coeff1..", b); PUT_VAR("..coeff0_sig..", student_t_025(good-2)*siga); PUT_VAR("..coeff1_sig..", student_t_025(good-2)*sigb); PUT_VAR("..R2..", r2); PUT_VAR("..regression_deviation..", deviation); gr_textput(_grTempString); return true; } else { err("proper: regress y vs x [linear] or regress x vs y [linear]"); return false; } return true; // bug: is it actually ok to be here??? } // Compute Pearson correlation coefficient, R. double R_linear(double x[], double y[], unsigned int n) { // Use formulae in terms of demeaned variables, // for numerical accuracy. unsigned int non_missing = 0; double xmean = 0.0, ymean = 0.0; for (unsigned i = 0; i < n; i++) { if (!gr_missing(x[i]) && !gr_missing(y[i])) { xmean += x[i]; ymean += y[i]; non_missing++; } } if (non_missing == 0) return 0.0; xmean /= non_missing; ymean /= non_missing; double syy = 0.0, sxy = 0.0, sxx = 0.0; double xtmp, ytmp; for (unsigned int i = 0; i < n; i++) { if (!gr_missing(x[i]) && !gr_missing(y[i])) { xtmp = x[i] - xmean; ytmp = y[i] - ymean; sxx += xtmp * xtmp; syy += ytmp * ytmp; sxy += xtmp * ytmp; } } return (sxy / sqrt(sxx * syy)); } // RMS deviation to model y=a+bx double rms_deviation(double x[], double y[], unsigned int n, double a, double b) { unsigned int non_missing = 0; double sum = 0.0, dev; for (unsigned int i = 0; i < n; i++) { if (!gr_missing(x[i]) && !gr_missing(y[i])) { dev = y[i] - a - b * x[i]; sum += dev * dev; non_missing++; } } if (non_missing == 0) return gr_currentmissingvalue(); return sqrt(sum / non_missing); } // Returns number good data static double sqrarg; #define SQR(a) (sqrarg=(a),sqrarg*sqrarg) static int fit(double x[], double y[], unsigned int ndata, std::vector::iterator sig, // std-deviation in y double *a, double *b, double *siga, double *sigb, double *chi2, double *q) { unsigned int good = 0; double wt, t, sxoss, sx = 0.0, sy = 0.0, st2 = 0.0, ss, sigdat; *b = 0.0; ss = 0.0; for (unsigned i = 0; i < ndata; i++) { if (!gr_missing(x[i]) && !gr_missing(y[i]) && !gr_missing(sig[i])) { wt = 1.0 / SQR(sig[i]); sx += x[i] * wt; sy += y[i] * wt; ss += wt; good++; } } sxoss = sx / ss; for (unsigned int i = 0; i < ndata; i++) { if (!gr_missing(x[i]) && !gr_missing(y[i]) && !gr_missing(sig[i])) { t = (x[i] - sxoss) / sig[i]; st2 += t * t; *b += t * y[i] / sig[i]; } } *b /= st2; *a = (sy - sx * (*b)) / ss; *siga = sqrt((1.0 + sx * sx / (ss * st2)) / ss); *sigb = sqrt(1.0 / st2); *chi2 = 0.0; for (unsigned int i = 0; i < ndata; i++) if (!gr_missing(x[i]) && !gr_missing(y[i])) *chi2 += SQR(y[i] - (*a) - (*b) * x[i]); *q = 1.0; if (good > 2) { sigdat = sqrt((*chi2) / (good - 2)); *siga *= sigdat; *sigb *= sigdat; } else { *siga = -1.0; *sigb = -1.0; } return good; } #undef SQR // From table in a book. double student_t_025(unsigned int nu) { static double t_025[30] = { 12.706, // for nu=1 4.303, // for nu=2 3.182, 2.776, 2.571, 2.447, 2.365, 2.306, 2.262, 2.228, 2.201, 2.179, 2.160, 2.145, 2.131, 2.120, 2.110, 2.101, 2.093, 2.086, 2.080, 2.074, 2.069, 2.064, 2.060, 2.056, 2.052, 2.048, 2.045, 2.042 // for nu=30 }; if (nu < 1) return t_025[0]; // dunno what to do else if (nu <= 30) return t_025[nu - 1]; else if (nu <= 40) return 2.021; else if (nu <= 60) return 2.000; else if (nu <= 120) return 1.98; else return 1.96; } ���������������������������������������������������������������������������������������gri/src/graxes.cc�����������������������������������������������������������������������������������0000644�0001750�0001750�00000103435�13147557614�012415� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2010 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ //#define DEBUG_LABELLING 1 //#define DEBUG_LABELS 1 #include #include #if !defined(IS_MINGW32) #include #else #define index strrchr #endif #include #include #include "gr.hh" #include "GriPath.hh" #include "extern.hh" #if defined(__DECCXX) || defined(OS_IS_BEOS) extern "C" char *index(const char *s, int c); #endif #define TIC_RATIO 0.5 /* (Length small tic) / (large tic) */ extern char _grXAxisLabel[]; extern char _grYAxisLabel[]; extern char _grNumFormat_x[]; extern char _grNumFormat_y[]; extern char _grTempString[]; extern int _grAxisStyle_x; extern int _grAxisStyle_y; extern gr_axis_properties _grTransform_x; extern gr_axis_properties _grTransform_y; extern int _grNeedBegin; extern int _grNumSubDiv_x; extern int _grNumSubDiv_y; extern double _grCmPerUser_x; extern double _grCmPerUser_y; extern double _grTicSize_cm; #define round_down_to_10(x) (pow (10.0, floor (log10 ( (x) )))) #define round_to_1(x) (floor (0.5 + (x) )) /* Some twiddles */ #define AXIS_TWIDDLE 0.005 /* .05mm overhang on axis */ #define SMALLNUM (1.0e-3) /* twiddle axis range */ #define SMALLERNUM (1.0e-4) /* twiddle axis range */ #define SMALLFONTSIZE (1.0e-3) /* too small to draw */ /* * local functions */ static bool next_tic(double *next, double labelling, bool gave_labelling, double present, double final, double inc, gr_axis_properties axis_type, bool increasing); #if 0 static int num_decimals(char *s); static int create_labels(double y, double yb, double yinc, double yt, double smallinc, char *label[], int *num_label); #endif // Calculate next tic location on axis. Note that if the axis starts off // ragged, this will assign to *next the first multiple of "inc". Returns // true if more axis to do static bool next_tic(double *next, double labelling, bool gave_labelling, double present, double final, double inc, gr_axis_properties axis_type, bool increasing) { #if defined(DEBUG_LABELLING) printf("%s:%d next_tic(...,labelling=%f gave_labelling=%s present=%f final=%f inc=%f increasing=%s _x_gave_labelling=%s _y_gave_labelling=%s\n", __FILE__,__LINE__,labelling,gave_labelling?"true":"false",present,final,inc,increasing?"true":"false", _x_gave_labelling?"true":"false", _y_gave_labelling?"true":"false"); #endif double order_of_mag, mantissa; // Check to see if already ran out of axis. if (present >= final && increasing == true) return false; if (present <= final && increasing == false) return false; // Determine next tic to draw to, treating linear/log separately. switch (axis_type) { case gr_axis_LINEAR: //*next = inc * (1.0 + floor((SMALLERNUM * inc + (present - labelling)) / inc)); if (gave_labelling) { *next = labelling + inc * (1 + floor(SMALLERNUM + (present - labelling) / inc)); #if defined(DEBUG_LABELLING) printf("%s:%d next=%f present=%f inc=%f\n %f %f %f %f\n", __FILE__, __LINE__, *next, present, inc, inc * (1.001 + floor((present - labelling) / inc)), (1 + floor((present - labelling) / inc)), (floor((present - labelling) / inc)), (present - labelling) / inc); #endif } else { *next = inc * (1.0 + floor((SMALLERNUM * inc + present) / inc)); } break; case gr_axis_LOG: if (present <= 0.0) { err("zero or negative on log axis (internal error)."); return false; } order_of_mag = round_down_to_10(present); mantissa = present / order_of_mag; if (increasing) mantissa = ceil(mantissa + SMALLNUM); else { if (mantissa <= 1.0) mantissa = 0.9; else mantissa = floor(mantissa - SMALLNUM); } *next = order_of_mag * mantissa; break; default: gr_Error("unknown axis type (internal error)"); } // Set flag if this will overrun axis. if (increasing == true) return (*next <= final) ? true : false; else return (*next >= final) ? true : false; } /* * gr_drawxyaxes DESCRIPTION: Draws an x-y axis frame */ void gr_drawxyaxes(double xl, double xinc, double xr, double yb, double yinc, double yt) { double old_fontsize_pt = gr_currentfontsize_pt(); gr_drawxaxis(yb, xl, xinc, xr, xl, gr_axis_BOTTOM); gr_drawyaxis(xl, yb, yinc, yt, yb, gr_axis_LEFT); gr_setfontsize_pt(0.0); gr_drawxaxis(yt, xl, xinc, xr, xl, gr_axis_TOP); gr_drawyaxis(xr, yb, yinc, yt, yb, gr_axis_RIGHT); gr_setfontsize_pt(old_fontsize_pt); } // DESCRIPTION: The axis extends from 'xl' to 'xr',with numbers placed at // intervals of 'xinc'. // If 'side'==BOTTOM/TOP this is an axis designed to appear at the // bottom/top of a plotting region (ie, the numbers are below/above). void gr_drawxaxis(double y, double xl, double xinc, double xr, double xlabelling, gr_axis_properties side) { //printf("gr_drawxaxis(..., xl=%f xlabelling=%f same=%d\n", xl, xlabelling, xl==xlabelling); bool user_gave_labels = (_x_labels.size() != 0); #ifdef DEBUG_LABELS if (user_gave_labels) { printf("DEBUG: %s:%d x axis should have labels [", __FILE__,__LINE__); for (unsigned int i = 0; i < _x_labels.size(); i++) printf("'%s' ", _x_labels[i].c_str()); printf("] at positions ["); for (unsigned int i = 0; i < _x_label_positions.size(); i++) printf("%f ", _x_label_positions[i]); printf("]\n"); } #endif GriString label; std::string slabel; extern char _xtype_map; double CapHeight = gr_currentCapHeight_cm(); double angle = 0.0; // angle of axis tics, labels, etc #ifdef DEBUG_LABELS printf("DEBUG: %s:%d at top of gr_drawxaxis(), angle is %f\n", __FILE__, __LINE__, angle); #endif bool increasing = ((xr > xl) ? true : false); double tic, tic_sml; // length of tic marks double xcm, ycm; // tmp double offset; // for numbers double present, next, final = xr, smallinc = 0.0; int decade_between_labels; // for log axes double tmp1, tmp2; GriPath axis_path; // XREF -- axis transform // Calculate size of large and small tic marks. extern bool _grTicsPointIn; tic = ((side == gr_axis_LEFT && _grTicsPointIn == false) || (side == gr_axis_RIGHT && _grTicsPointIn == true)) ? -_grTicSize_cm : _grTicSize_cm; if (_grTransform_x == gr_axis_LOG && _xsubdiv < 0) tic_sml = 0.0; else tic_sml = TIC_RATIO * tic; // Calculate offset = space for numbers. offset = 0.0; int old_linecap = _griState.line_cap(); int old_linejoin = _griState.line_join(); _griState.set_line_cap(0); _griState.set_line_join(0); switch (_grTransform_x) { case gr_axis_LINEAR: case gr_axis_LOG: if (side == gr_axis_BOTTOM) { if (strlen(_grNumFormat_x)) offset -= 1.75 * CapHeight; offset -= ((_grTicsPointIn == false) ? _grTicSize_cm : 0.0); } else { if (strlen(_grNumFormat_x)) offset += 0.75 * CapHeight; offset += ((_grTicsPointIn == false) ? _grTicSize_cm : 0.0); } break; default: gr_Error("unknown axis type (internal error)"); } // Draw axis, moving from tic to tic. Tics are advanced by smallinc for // linear axes and by something appropriate for log axes. Whenever the // current location should be a big tic, such a tic is drawn along with a // label. double xl_cm, y_cm; int this_pass=0, pass_max=5000; switch (_grTransform_x) { case gr_axis_LINEAR: smallinc = xinc / _grNumSubDiv_x; // Twiddle axes to extend a bit beyond the requested // region, to prevent rounding problems. present = xl - xinc / 1.0e3; final = xr + xinc / 1.0e3; // Draw x-axis, moving from tic to tic. Tics are advanced by // smallinc for linear axes and by something appropriate for log // axes. Whenever the current location should be a big tic, such a // tic is drawn along with a label. gr_usertocm(xl, y, &xl_cm, &y_cm); axis_path.push_back(xl_cm, y_cm, 'm'); #if defined(DEBUG_LABELLING) printf("%s:%d _x_gave_labelling=%d xlabelling=%f present=%f\n", __FILE__, __LINE__, _x_gave_labelling, xlabelling, present); #endif while (next_tic(&next, xlabelling, _x_gave_labelling, present, final, smallinc, _grTransform_x, increasing)) { if (this_pass++ > pass_max) { extern bool _x_gave_labelling; if (_x_gave_labelling) { gr_Error("cannot draw x axis (internal error: problem dealing with 'labelling' keyword)"); } else { gr_Error("cannot draw x axis (internal error)"); } return; } // Determine angle of x-axis tics, for non-rectangular axes switch (_grTransform_x) { case gr_axis_LINEAR: case gr_axis_LOG: angle = atan2(1.0, 0.0); // angle for tics break; default: gr_Error("unknown axis type (internal error)"); break; } gr_usertocm(next, y, &xcm, &ycm); axis_path.push_back(xcm, ycm, 'l'); // Detect large tics on x axis if ((_x_gave_labelling && gr_multiple(next - xlabelling, xinc, 0.01 * smallinc)) || (!_x_gave_labelling && gr_multiple(next, xinc, 0.01 * smallinc))) { #if defined(DEBUG_LABELLING) printf("%s:%d next=%f\n", __FILE__, __LINE__, next); #endif // draw large tic axis_path.push_back(xcm + tic * cos(angle), ycm + tic * sin(angle), 'l'); if (gr_currentfontsize_pt() > SMALLFONTSIZE) { if (_xtype_map != ' ') { // It's a map, so figure the deg/min/seconds; // over-ride any existing format int hour, min, sec; if (gr_multiple(next, 1.0, 1.0e-6)) { hour = (int)floor(1.0e-4 + fabs(next)); if (next >= 0.0) sprintf(_grTempString,"%d$\\circ$%c",hour,_xtype_map); else sprintf(_grTempString,"-%d$\\circ$%c",hour,_xtype_map); } else if (gr_multiple(next, 1.0 / 60.0, 1.0e-7)) { hour = (int)floor(1.0e-4 + fabs(next)); min = (int)floor(1e-5 + 60.0 * (fabs(next) - hour)); if (next >= 0.0) sprintf(_grTempString,"%d$\\circ$%d'%c",hour,min,_xtype_map); else sprintf(_grTempString,"-%d$\\circ$%d'%c",hour,min,_xtype_map); } else if (gr_multiple(next, 1.0 / 3600.0, 1.0e-8)) { hour = (int)floor(1.0e-4 + fabs(next)); min = (int)floor(1e-5 + 60.0 * (fabs(next) - hour)); sec = (int)floor(1e-5 + 3600.0 * (fabs(next) - hour - min / 60.0)); if (next >= 0.0) sprintf(_grTempString, "%d$\\circ$%d'%d\"%c",hour,min,sec,_xtype_map); else sprintf(_grTempString, "-%d$\\circ$%d'%d\"%c",hour,min,sec,_xtype_map); } else { sprintf(_grTempString,"%f$\\circ$%c",next,_xtype_map); } } else if (strlen(_grNumFormat_x)) { sprintf(_grTempString, _grNumFormat_x, next); if (get_flag("emulate_gre")) { char *e = index(_grTempString, int('E')); if (e != NULL) { std::string gs(_grTempString); size_t chop; if (STRING_NPOS != (chop = gs.find("E+0"))) { gs.replace(chop, 3, "$\\times10^{"); gs.append("}$"); } else if (STRING_NPOS != (chop = gs.find("E-0"))) { gs.replace(chop, 3, "$\\times10^{-"); gs.append("}$"); } else if (STRING_NPOS != (chop = gs.find("E+"))) { gs.replace(chop, 2, "$\\times10^{"); gs.append("}$"); } else if (STRING_NPOS != (chop = gs.find("E-"))) { gs.replace(chop, 2, "$\\times10^{-"); gs.append("}$"); } else if (STRING_NPOS != (chop = gs.find("E"))) { gs.replace(chop, 1, "$\\times10^{"); gs.append("}$"); } strcpy(_grTempString, gs.c_str()); } } } else { *_grTempString = '\0'; } angle = 0; #ifdef DEBUG_LABELS printf("DEBUG: %s:%d after the loop, angle is %f\n", __FILE__, __LINE__, angle); #endif if (!user_gave_labels) { slabel.assign(_grTempString); fix_negative_zero(slabel); label.fromSTR(slabel.c_str()); label.draw(xcm - offset * sin(angle), ycm + offset * cos(angle), TEXT_CENTERED, DEG_PER_RAD * angle); } } } else { // Small tic axis_path.push_back(xcm + tic_sml * cos(angle), ycm + tic_sml * sin(angle), 'l'); } axis_path.push_back(gr_usertocm_x(next, y), gr_usertocm_y(next, y), 'l'); present = next; #if defined(DEBUG_LABELLING) printf("%s:%d bottom of loop; present=%f\n", __FILE__, __LINE__, present); #endif } if (user_gave_labels) { angle = 0; for (unsigned int i = 0; i < _x_labels.size(); i++) { if (BETWEEN(xl, xr, _x_label_positions[i])) { label.fromSTR(_x_labels[i].c_str()); // BUG: should interpolate into this string gr_usertocm(_x_label_positions[i], y, &xcm, &ycm); #ifdef DEBUG_LABELS printf("DEBUG: %s:%d drawing %d-th label '%s' at x=%f angle=%f\n",__FILE__,__LINE__,i,_x_labels[i].c_str(),_x_label_positions[i],angle); #endif label.draw(xcm - offset * sin(angle), ycm + offset * cos(angle), TEXT_CENTERED, DEG_PER_RAD * angle); } else { #ifdef DEBUG_LABELS printf("DEBUG: %s:%d SKIPPING %d-th label '%s' since x=%f\n",__FILE__,__LINE__,i,_x_labels[i].c_str(),_x_label_positions[i]); #endif } } } // Finish by drawing to end of axis (in case there was no tic there). axis_path.push_back(gr_usertocm_x(final, y), gr_usertocm_y(final, y), 'l'); axis_path.stroke(units_cm, _griState.linewidth_axis()); break; case gr_axis_LOG: decade_between_labels = (int) floor(0.5 + xinc); gr_usertocm(xl, y, &xcm, &ycm); gr_cmtouser(xcm - AXIS_TWIDDLE, ycm, &tmp1, &tmp2); present = tmp1; axis_path.push_back(present, y, 'm'); #if defined(DEBUG_LABELLING) printf("%s:%d _x_gave_labelling=%d xlabelling=%f present=%f\n", __FILE__, __LINE__, _x_gave_labelling, xlabelling, present); #endif while (next_tic(&next, xl, _x_gave_labelling, present, final, smallinc, _grTransform_x, increasing)) { double tmp, next_log; double xuser, yuser; axis_path.push_back(next, y, 'l'); next_log = log10(next); tmp = next_log - floor(next_log); gr_usertocm(next, y, &xcm, &ycm); if (-0.01 < tmp && tmp < 0.01) { // large tic & number gr_cmtouser(xcm, ycm+tic, &xuser, &yuser); axis_path.push_back(xuser, yuser, 'l'); gr_cmtouser(xcm, ycm+offset, &xuser, &yuser); tmp = next_log - decade_between_labels * floor(next_log / decade_between_labels); if (!user_gave_labels && gr_currentfontsize_pt() > SMALLFONTSIZE && -0.01 < tmp / xinc && tmp / xinc < 0.01 && strlen(_grNumFormat_x)) { // Draw "1" as a special case if (0.99 < next && next < 1.01) sprintf(_grTempString, "1"); else sprintf(_grTempString, "$10^{%.0f}$", log10(next)); slabel.assign(_grTempString); fix_negative_zero(slabel); label.fromSTR(slabel.c_str()); label.draw(xcm, ycm + offset, TEXT_CENTERED, 0.0); } } else { // small tic gr_cmtouser(xcm, ycm+tic_sml,&xuser, &yuser); axis_path.push_back(xuser, yuser, 'l'); } axis_path.push_back(next, y, 'm'); present = next; } if (user_gave_labels) { angle = 0; for (unsigned int i = 0; i < _x_labels.size(); i++) { if (BETWEEN(xl, xr, _x_label_positions[i])) { label.fromSTR(_x_labels[i].c_str()); // BUG: should interpolate into this string gr_usertocm(_x_label_positions[i], y, &xcm, &ycm); #ifdef DEBUG_LABELS printf("DEBUG: %s:%d drawing %d-th label '%s' at x=%f angle=%f\n",__FILE__,__LINE__,i,_x_labels[i].c_str(),_x_label_positions[i],angle); #endif label.draw(xcm - offset * sin(angle), ycm + offset * cos(angle), TEXT_CENTERED, DEG_PER_RAD * angle); } else { #ifdef DEBUG_LABELS //printf("DEBUG: %s:%d SKIPPING %d-th label '%s' since x=%f\n",__FILE__,__LINE__,i,_x_labels[i].c_str(),_x_label_positions[i]); #endif } } } // Finish by drawing to end of axis (in case there was no tic there). axis_path.push_back(final, y, 'l'); axis_path.stroke(units_user, _griState.linewidth_axis()); break; default: gr_Error("unknown axis type (internal error)"); } // Draw axis title. if (gr_currentfontsize_pt() > SMALLFONTSIZE) { label.fromSTR(_grXAxisLabel); switch (_grTransform_x) { case gr_axis_LINEAR: if (side == gr_axis_TOP) { double xcm, ycm; gr_usertocm(0.5 * (xl + final), y, &xcm, &ycm); label.draw(xcm, ycm + offset + 1.75 * CapHeight, TEXT_CENTERED, 0.0); } else { double xcm, ycm; gr_usertocm(0.5 * (xl + final), y, &xcm, &ycm); label.draw(xcm, ycm + offset - 1.75 * CapHeight, TEXT_CENTERED, 0.0); } break; case gr_axis_LOG: if (side == gr_axis_TOP) { double xcm, ycm; gr_usertocm(sqrt(xl * final), y, &xcm, &ycm); label.draw(xcm, ycm + offset + (1.75 + 0.75) * CapHeight, TEXT_CENTERED, 0.0); } else { double xcm, ycm; gr_usertocm(sqrt(xl * final), y, &xcm, &ycm); label.draw(xcm, ycm + offset - 1.75 * CapHeight, TEXT_CENTERED, 0.0); } break; default: gr_Error("unknown axis type (internal error)"); } } _griState.set_line_cap(old_linecap); _griState.set_line_join(old_linejoin); } #define FACTOR 1.35 // Kludge to scale fonts up // Draw a y axis void gr_drawyaxis(double x, double yb, double yinc, double yt, double ylabelling, gr_axis_properties side) { #if 1 // 2.9.x bool user_gave_labels = (_y_labels.size() != 0); #endif // 2.9.x GriString label; std::string slabel; extern char _ytype_map; double CapHeight = gr_currentCapHeight_cm(); double angle = 0.0; // angle of axis tics, labels, etc bool increasing = ((yt > yb) ? true : false); double tic, tic_sml; // length of tic marks double xcm, ycm; // used to step along axis double xcm2, ycm2; // tmp, allowed to mess with double labelx_cm, labely_cm; // where tic label will go double offset; // for numbers double present, next, final = yt, smallinc = 0.0; int decade_between_labels; // for log axes double max_num_width_cm = 0.0; // use for positioning label double tmp0, tmp1, tmp2; GriPath axis_path; // Calculate size of large and small tic marks. extern bool _grTicsPointIn; tic = ((side == gr_axis_LEFT && _grTicsPointIn == true) || (side == gr_axis_RIGHT && _grTicsPointIn == false)) ? _grTicSize_cm : -_grTicSize_cm; if (_grTransform_y == gr_axis_LOG && _ysubdiv < 0) tic_sml = 0.0; else tic_sml = TIC_RATIO * tic; // Calculate offset = space for numbers. if (side == gr_axis_LEFT) { if (_grTicsPointIn == true) { offset = -0.5 * FACTOR * CapHeight; } else { offset = -0.5 * FACTOR * CapHeight - _grTicSize_cm; } } else { if (_grTicsPointIn == true) { offset = 0.5 * FACTOR * CapHeight; } else { offset = 0.5 * FACTOR * CapHeight + _grTicSize_cm; } } int old_linecap = _griState.line_cap(); int old_linejoin = _griState.line_join(); _griState.set_line_cap(0); _griState.set_line_join(0); // Draw y-axis, moving from tic to tic. Tics are advanced by smallinc // for linear axes and by something appropriate for log axes. Whenever // the current location should be a big tic, such a tic is drawn along // with a label. int this_pass=0, pass_max=5000; switch (_grTransform_y) { case gr_axis_LINEAR: smallinc = yinc / _grNumSubDiv_y; present = yb - yinc / 1.0e3; final = yt + yinc / 1.0e3; axis_path.push_back(gr_usertocm_x(x, yb), gr_usertocm_y(x, yb), 'm'); #if defined(DEBUG_LABELLING) printf("%s:%d _y_gave_labelling=%d ylabelling=%f present=%f\n", __FILE__, __LINE__, _y_gave_labelling, ylabelling, present); #endif while (next_tic(&next, ylabelling, _y_gave_labelling, present, final, smallinc, _grTransform_y, increasing)) { axis_path.push_back(gr_usertocm_x(x, next), gr_usertocm_y(x, next), 'l'); gr_usertocm(x, next, &xcm, &ycm); angle = 0.0; // Detect large tics on y axis if ((_y_gave_labelling && gr_multiple(next - ylabelling, yinc, 0.01 * smallinc)) || (!_y_gave_labelling && gr_multiple(next, yinc, 0.01 * smallinc))) { double tmpx, tmpy; gr_cmtouser(xcm + tic * cos(angle), ycm + tic * sin(angle), &tmpx, &tmpy); axis_path.push_back(xcm + tic * cos(angle), ycm + tic * sin(angle), 'l'); labelx_cm = xcm + offset * cos(angle); labely_cm = ycm + offset * sin(angle) - 0.5 * CapHeight; if (gr_currentfontsize_pt() > SMALLFONTSIZE) { if (_ytype_map != ' ') { // It's a map, so figure the deg/min/seconds; // over-ride any existing format int hour, min, sec; if (gr_multiple(next, 1.0, 1.0e-6)) { hour = (int)floor(1.0e-4 + fabs(next)); if (next >= 0.0) sprintf(_grTempString,"%d$\\circ$%c",hour,_ytype_map); else sprintf(_grTempString,"-%d$\\circ$%c",hour,_ytype_map); } else if (gr_multiple(next, 1.0 / 60.0, 1.0e-7)) { hour = (int)floor(1.0e-4 + fabs(next)); min = (int)floor(1e-5 + 60.0 * (fabs(next) - hour)); if (next >= 0.0) sprintf(_grTempString,"%d$\\circ$%d'%c",hour,min,_ytype_map); else sprintf(_grTempString,"-%d$\\circ$%d'%c",hour,min,_ytype_map); } else if (gr_multiple(next, 1.0 / 3600.0, 1.0e-8)) { hour = (int)floor(1.0e-4 + fabs(next)); min = (int)floor(1e-5 + 60.0 * (fabs(next) - hour)); sec = (int)floor(1e-5 + 3600.0 * (fabs(next) - hour - min / 60.0)); if (next >= 0.0) sprintf(_grTempString, "%d$\\circ$%d'%d\"%c",hour,min,sec,_ytype_map); else sprintf(_grTempString, "-%d$\\circ$%d'%d\"%c",hour,min,sec,_ytype_map); } else { sprintf(_grTempString,"%f$\\circ$%c",next,_ytype_map); } } else if (strlen(_grNumFormat_y)) { if (get_flag("emulate_gre")) { sprintf(_grTempString, _grNumFormat_y, next); char *e = index(_grTempString, int('E')); if (e != NULL) { std::string gs(_grTempString); size_t chop; if (STRING_NPOS != (chop = gs.find("E+0"))) { gs.replace(chop, 3, "$\\times10^{"); gs.append("}$"); } else if (STRING_NPOS != (chop = gs.find("E-0"))) { gs.replace(chop, 3, "$\\times10^{-"); gs.append("}$"); } else if (STRING_NPOS != (chop = gs.find("E+"))) { gs.replace(chop, 2, "$\\times10^{"); gs.append("}$"); } else if (STRING_NPOS != (chop = gs.find("E-"))) { gs.replace(chop, 2, "$\\times10^{-"); gs.append("}$"); } else if (STRING_NPOS != (chop = gs.find("E"))) { gs.replace(chop, 1, "$\\times10^{"); gs.append("}$"); } strcpy(_grTempString, gs.c_str()); } } else { sprintf(_grTempString, _grNumFormat_y, next); } } else { *_grTempString = '\0'; } if (!user_gave_labels) { // 2.9.x slabel.assign(_grTempString); fix_negative_zero(slabel); label.fromSTR(slabel.c_str()); if (side == gr_axis_LEFT) label.draw(labelx_cm, labely_cm, TEXT_RJUST, angle * DEG_PER_RAD); else label.draw(labelx_cm, labely_cm, TEXT_LJUST, angle * DEG_PER_RAD); } // Keep track of maximum width of axis numbers, so that // axis label can be offset right amount. gr_stringwidth(_grTempString, &tmp0, &tmp1, &tmp2); if (tmp0 > max_num_width_cm) max_num_width_cm = tmp0; } } else { // Small tic axis_path.push_back(xcm + tic_sml * cos(angle), ycm + tic_sml * sin(angle), 'l'); } axis_path.push_back(gr_usertocm_x(x, next), gr_usertocm_y(x, next), 'l'); present = next; } #if 1 // 2.9.x if (user_gave_labels) { //printf("labels...\n"); for (unsigned int i = 0; i < _y_labels.size(); i++) { label.fromSTR(_y_labels[i].c_str()); // BUG: should interpolate into this string gr_usertocm(x, _y_label_positions[i], &xcm, &ycm); labelx_cm = xcm + offset * cos(angle); labely_cm = ycm + offset * sin(angle) - 0.5 * CapHeight; //printf("%f %f %f %f\n", ycm, offset*sin(angle),CapHeight, labely_cm); if (side == gr_axis_LEFT) label.draw(labelx_cm, labely_cm, TEXT_RJUST, DEG_PER_RAD * angle); else label.draw(labelx_cm, labely_cm, TEXT_LJUST, DEG_PER_RAD * angle); gr_stringwidth(_y_labels[i].c_str(), &tmp0, &tmp1, &tmp2); if (tmp0 > max_num_width_cm) max_num_width_cm = tmp0; } } #endif // Finish by drawing to end of axis (in case there was no tic there). axis_path.push_back(gr_usertocm_x(x, yt), gr_usertocm_y(x, yt), 'l'); axis_path.stroke(units_cm, _griState.linewidth_axis()); break; case gr_axis_LOG: decade_between_labels = (int) floor(0.5 + yinc); gr_usertocm(x, yb, &xcm, &ycm); gr_cmtouser(xcm, ycm - AXIS_TWIDDLE, &tmp1, &tmp2); present = tmp2; axis_path.push_back(x, present, 'm'); if (_y_gave_labelling) { err("cannot use 'labelling' parameter for logarithmic axis"); return; } #if defined(DEBUG_LABELLING) printf("%s:%d _y_gave_labelling=%d ylabelling=%f present=%f\n", __FILE__, __LINE__, _y_gave_labelling, ylabelling, present); #endif while (next_tic(&next, yb, _y_gave_labelling, present, final, smallinc, _grTransform_y, increasing)) { if (this_pass++ > pass_max) { extern bool _y_gave_labelling; if (_y_gave_labelling) { gr_Error("cannot draw y axis (internal error: cannot use 'labelling' keyword)"); } else { gr_Error("cannot draw y axis (internal error)"); } return; } double tmp, next_log; axis_path.push_back(x, next, 'l'); next_log = log10(next); tmp = next_log - floor(next_log); gr_usertocm(x, next, &xcm2, &ycm2); // NOTE: not using (xcm,ycm) if (-0.01 < tmp && tmp < 0.01) { // large tic & number double xuser, yuser; gr_cmtouser(xcm2 + tic, ycm2, &xuser, &yuser); axis_path.push_back(xuser, yuser, 'l'); gr_cmtouser(xcm2 + tic, ycm2 - 0.5 * FACTOR * CapHeight, &xuser, &yuser); tmp = next_log - decade_between_labels * floor(next_log / decade_between_labels); if (!user_gave_labels && gr_currentfontsize_pt() > SMALLFONTSIZE && -0.01 < tmp / yinc && tmp / yinc< 0.01 && strlen(_grNumFormat_y)) { // Draw "1" as a special case if (0.99 < next && next < 1.01) sprintf(_grTempString, "1"); else sprintf(_grTempString, "$10^{%.0f}$", log10(next)); slabel.assign(_grTempString); fix_negative_zero(slabel); label.fromSTR(slabel.c_str()); if (side == gr_axis_LEFT) label.draw(xcm2 + offset, ycm2 - 0.5 * CapHeight, TEXT_RJUST, 0.0); else label.draw(xcm2 + offset, ycm2 - 0.5 * CapHeight, TEXT_LJUST, 0.0); // Keep track of maximum width of axis numbers, so that // axis label can be offset right amount. gr_stringwidth(_grTempString, &tmp0, &tmp1, &tmp2); if (tmp0 > max_num_width_cm) max_num_width_cm = tmp0; } } else { // small tic double xuser, yuser; gr_cmtouser(xcm2 + tic_sml, ycm2, &xuser, &yuser); axis_path.push_back(xuser, yuser, 'l'); } axis_path.push_back(x, next, 'l'); present = next; } if (user_gave_labels) { angle = 0; for (unsigned int i = 0; i < _y_labels.size(); i++) { if (BETWEEN(yb, yt, _y_label_positions[i])) { label.fromSTR(_y_labels[i].c_str()); // BUG: should interpolate into this string gr_usertocm(x, _y_label_positions[i], &xcm, &ycm); labelx_cm = xcm + offset * cos(angle); labely_cm = ycm + offset * sin(angle) - 0.5 * CapHeight; #ifdef DEBUG_LABELS printf("DEBUG: %s:%d drawing %d-th label '%s' at y=%f angle=%f\n",__FILE__,__LINE__,i,_y_labels[i].c_str(),_y_label_positions[i],angle); #endif if (side == gr_axis_LEFT) label.draw(labelx_cm, labely_cm, TEXT_RJUST, DEG_PER_RAD * angle); else label.draw(labelx_cm, labely_cm, TEXT_LJUST, DEG_PER_RAD * angle); } else { #ifdef DEBUG_LABELS //printf("DEBUG: %s:%d SKIPPING %d-th label '%s' since x=%f\n",__FILE__,__LINE__,i,_y_labels[i].c_str(),_y_label_positions[i]); #endif } } } // Finish by drawing to end of axis (in case there was no tic there). axis_path.push_back(x, final, 'l'); axis_path.stroke(units_user, _griState.linewidth_axis()); break; default: gr_Error("unknown axis type (internal error)"); } // write label, rotated if necessary if (gr_currentfontsize_pt() > SMALLFONTSIZE) { // Start to calculate what x to put label at; this makes xcm be on // axis, so will have to shift depending on orientation of label. // Note: will now re-use 'angle' to mean angle of y axis if (_grTransform_y == gr_axis_LOG) { double x_cm, xx_cm, y_cm, yy_cm; gr_usertocm(x, sqrt(yb * yt), &x_cm, &y_cm); gr_usertocm(x, 0.001 + sqrt(yb * yt), &xx_cm, &yy_cm); angle = fabs(DEG_PER_RAD * atan2(yy_cm - y_cm, xx_cm - x_cm)); // abs() ensures from bottom to top } else { double x_cm, xx_cm, y_cm, yy_cm; gr_usertocm(x, 0.5 * (yb + yt), &x_cm, &y_cm); gr_usertocm(x, 0.01 * yinc + 0.5 * (yb + yt), &xx_cm, &yy_cm); angle = DEG_PER_RAD * atan2(yy_cm - y_cm, xx_cm - x_cm); } xcm = 0.5 * (gr_usertocm_x(x, yb) + gr_usertocm_x(x, yt)); ycm = 0.5 * (gr_usertocm_y(x, yb) + gr_usertocm_y(x, yt)); // Need at least max_num_width_cm, i.e., widest numeric label, plus // a little space (check against above). max_num_width_cm += FACTOR * CapHeight; // Need space for tics too max_num_width_cm += (_grTicsPointIn == true ? 0.0 : _grTicSize_cm); // Do by cases -- inelegant but flexible to change label.fromSTR(_grYAxisLabel); switch (_grAxisStyle_y) { default: case 0: // label parallel to axis if (side == gr_axis_LEFT) { label.draw(xcm - max_num_width_cm, ycm, TEXT_CENTERED, angle); } else { label.draw(xcm + max_num_width_cm, ycm, TEXT_CENTERED, angle - 180); } break; case 1: // horizontal label if (side == gr_axis_LEFT) { label.draw(xcm - max_num_width_cm, ycm - 0.5 * CapHeight, TEXT_RJUST, 90.0 - angle); } else { label.draw(xcm + max_num_width_cm, ycm - 0.5 * CapHeight, TEXT_LJUST, 90.0 - angle); } break; } } _griState.set_line_cap(old_linecap); _griState.set_line_join(old_linejoin); } #if 0 /* UNUSED -- Delete later BUG ?? */ #define NUM_LABEL 100 /* * create_labels - make clean labels for linear axes (clean by making same * number of decimals) */ static int create_labels(double y, double yb, double yinc, double yt, double smallinc, char *label[NUM_LABEL], int *num_label) { int i, max_decimals = 0; double zero = fabs(yt - yb) / 1.0e5; /* store a number * effectively 0 */ *num_label = 0; do { if (gr_multiple(y, yinc, 0.01 * smallinc)) { if (fabs(y) < zero) sprintf(_grTempString, _grNumFormat_y, 0.0); else sprintf(_grTempString, _grNumFormat_y, y); /* reserve 10 extra characters for 0s which might be appended */ GET_STORAGE(label[*num_label], char, 10 + strlen(_grTempString)); strcpy(label[*num_label], _grTempString); (*num_label)++; } y += smallinc; } while ((*num_label < NUM_LABEL) && ((yinc > 0.0 && y <= yt) || (yinc < 0.0 && y >= yt))); if (*num_label >= NUM_LABEL) { fprintf(stderr, "Internal error (graxes.c): %d > NUM_LABEL labels\n", *num_label); gri_exit(1); } for (i = 0; i < *num_label; i++) { int j; if (max_decimals < (j = num_decimals(label[i]))) max_decimals = j; } for (i = 0; i < *num_label; i++) { int n = num_decimals(label[i]); int l = strlen(label[i]); if (!n) /* don't meddle if e/E/d/D present */ continue; if (max_decimals > 0) { if (n < max_decimals) { int j; if (n == 0) { *(label[i] + l++) = '.'; n = 1; } for (j = max_decimals - n; j < max_decimals; j++) *(label[i] + l++) = '0'; } *(label[i] + l) = '\0'; } } return 1; } #endif #if 0 /* * num_decimals(s) -- return number of places to right of decimal, but return * 0 if there is an e/E/d/D in the number (in which case don't meddle */ static int num_decimals(char *s) { char * cp; int j = 0, jMax = strlen(s); /* * First search for e/E/d/D */ cp = s; do if (*cp == 'd' || *cp == 'D' || *cp == 'e' || *cp == 'E') return 0; while (*++cp != '\0'); /* * It doesn't have e/E/d/D */ cp = s + strlen(s) - 1; do if (*cp == '.') break; while (cp--, ++j < jMax); if (j >= jMax) j = 0; return j; } #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/get_font_metrics.pl�������������������������������������������������������������������������0000644�0001750�0001750�00000002235�13147557614�014501� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# works 2006-08-21 Macintosh OSX require PostScript::Fontmetrics; sub get_fm($); $dir = "/Applications/OpenOffice.org 2.0.app/Contents/MacOS/share/psprint/fontmetric/"; sub get_fm($) { my ($name) = @_; my $s = 1 / (72 / 2.54 * 1000); # or 28.35?? my $fm = new PostScript::FontMetrics("$dir/$name.afm"); printf("// Created by Perl script get_font_metrics.pl\nstruct font_metric %s = { %.6f, // XHeight %.6f, // CapHeight %.6f, // Ascender %.6f, // Descender { // Widths of first 128 characters\n", $fm->FontName, $fm->XHeight * $s, $fm->CapHeight * $s, $fm->Ascender * $s, $fm->Descender * $s); %c <- $fm->CharWidthData; printf(" "); for ($i = 0; $i < 128; $i++) { $c = sprintf("%c", $i); #printf("'%s'=%.7f", $c, $fm->stringwidth($c)*$s); printf("%.7f", $fm->stringwidth($c)*$s); printf(", ") if $i != 127; printf("\n ") if !(($i+1) % 5); } printf("\n }\n};\n"); #print $fm->MetricsData; } die "Need at least one font name\n\tUsage: get_font_metrics.pl [fontname [fontname]]" if $#ARGV < 0; for ($f = 0; $f <= $#ARGV; $f++) { get_fm($ARGV[$f]); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/differ.cc�����������������������������������������������������������������������������������0000644�0001750�0001750�00000015466�13147557614�012371� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include "gr.hh" #include "extern.hh" #include "private.hh" bool differentiateCmd(void); // `differentiate {{x|y} wrt index|{y|x}} | {grid wrt x|y}' bool differentiateCmd() { switch (_nword) { case 4: if (!strcmp(_word[2], "wrt") && !strcmp(_word[1], "grid")) { // `differentiate grid wrt ...' if (!_xgrid_exists && !_ygrid_exists && !_grid_exists) { err("`differentiate grid' -- no grid exists yet\n"); return false; } if (!strcmp(_word[3], "x")) { // `differentiate grid wrt x' if (_num_xmatrix_data < 3) { err("`differentiate grid wrt x' -- too few data"); return false; } std::vector ok((size_t)_num_xmatrix_data, false); std::vector tmp((size_t)_num_xmatrix_data, 0.0); for (unsigned int j = 0; j < _num_ymatrix_data; j++) { for (unsigned int i = 1; i < _num_xmatrix_data - 1; i++) { if (_legit_xy(i - 1, j) == true && _legit_xy(i + 1, j) == true && _xmatrix[i + 1] != _xmatrix[i - 1]) { tmp[i] = (_f_xy(i + 1, j) - _f_xy(i - 1, j)) / (_xmatrix[i + 1] - _xmatrix[i - 1]); ok[i] = true; } else { ok[i] = false; } } for (unsigned int i = 1; i < _num_xmatrix_data - 1; i++) { _f_xy(i, j) = tmp[i]; if (ok[i] == true) { _f_xy(i, j) = tmp[i]; _legit_xy(i, j) = true; } else { _legit_xy(i, j) = false; } } _f_xy(0, j) = _f_xy(1, j); _legit_xy(0, j) = _legit_xy(1, j); _f_xy(_num_xmatrix_data - 1, j) = _f_xy(_num_xmatrix_data - 2, j); _legit_xy(_num_xmatrix_data - 1, j) = _legit_xy(_num_xmatrix_data - 2, j); } } else if (!strcmp(_word[3], "y")) { // `differentiate grid wrt y' if (_num_ymatrix_data < 3) { err("`differentiate grid wrt y' -- too few data"); return false; } std::vector ok((size_t)_num_ymatrix_data, false); std::vector tmp((size_t)_num_ymatrix_data, 0.0); for (unsigned int i = 0; i < _num_xmatrix_data; i++) { for (unsigned int j = 1; j < _num_ymatrix_data - 1; j++) { if (_legit_xy(i, j - 1) == true && _legit_xy(i, j + 1) == true && _ymatrix[j + 1] != _ymatrix[j - 1]) { tmp[j] = (_f_xy(i, j + 1) - _f_xy(i, j - 1)) / (_ymatrix[j + 1] - _ymatrix[j - 1]); ok[j] = true; } else { ok[j] = false; } } for (unsigned int j = 1; j < _num_ymatrix_data - 1; j++) { if (ok[j] == true) { _f_xy(i, j) = tmp[j]; _legit_xy(i, j) = true; } else { _legit_xy(i, j) = false; } } _f_xy(i, 0) = _f_xy(i, 1); _legit_xy(i, 0) = _legit_xy(i, 1); _f_xy(i, _num_ymatrix_data - 1) = _f_xy(i, _num_ymatrix_data - 2); _legit_xy(i, _num_ymatrix_data - 1) = _legit_xy(i, _num_ymatrix_data - 2); } } else { err("Can only differentiate grid wrt to `x' or `y'"); return false; } matrix_limits(&_f_min, &_f_max); return true; } else if (!strcmp(_word[2], "wrt")) { // `differentiate ... wrt ...' if (!strcmp(_word[1], "x")) { // `differentiate x wrt ...' if (_colX.size() < 1) { err("No x column exists yet\n"); return false; } if (_colX.size() < 2) { err("Sorry, x column has only 1 element\n"); return false; } if (!strcmp(_word[3], "index")) { // `differentiate x wrt index' for (unsigned int i = 1; i < _colX.size(); i++) { double x0 = _colX[i]; double xleft = _colX[i - 1]; if (!gr_missingx(x0) && !gr_missingx(xleft)) { _colX[i - 1] = x0 - xleft; } else { _colX[i - 1] = gr_currentmissingvalue(); } } } else if (!strcmp(_word[3], "y")) { // `differentiate x wrt y' for (unsigned int i = 1; i < _colX.size(); i++) { double x0 = _colX[i]; double xleft = _colX[i - 1]; double y0 = _colY[i]; double yleft = _colY[i - 1]; if (!gr_missingx(x0) && !gr_missingy(y0) && !gr_missingx(xleft) && !gr_missingy(yleft)) { _colX[i - 1] = (x0 - xleft) / (y0 - yleft); } else { _colX[i - 1] = gr_currentmissingvalue(); } } } else { err("Wrong word; must be `index' or `x'"); return false; } // make something up for last point _colX[_colX.size() - 1] = _colX[_colX.size() - 2]; create_x_scale(); return true; } else if (!strcmp(_word[1], "y")) { // `differentiate y wrt ...' if (_colY.size() < 1) { err("No y column exists yet\n"); return false; } if (_colY.size() < 2) { err("Sorry, y column has only 1 element\n"); return false; } if (!strcmp(_word[3], "index")) { // `differentiate y wrt index' for (unsigned int i = 1; i < _colY.size(); i++) { double y0 = _colY[i]; double yleft = _colY[i - 1]; if (!gr_missingy(y0) && !gr_missingy(yleft)) { _colY[i - 1] = y0 - yleft; } else { _colY[i - 1] = gr_currentmissingvalue(); } } } else if (!strcmp(_word[3], "x")) { // `differentiate y wrt x' for (unsigned int i = 1; i < _colY.size(); i++) { double x0 = _colX[i]; double xleft = _colX[i - 1]; double y0 = _colY[i]; double yleft = _colY[i - 1]; if (!gr_missingy(y0) && !gr_missingx(x0) && !gr_missingy(y0) && !gr_missingy(yleft)) { _colY[i - 1] = (y0 - yleft) / (x0 - xleft); } else { _colY[i - 1] = gr_currentmissingvalue(); } } } else { err("Wrong word; must be `index' or `y'"); return false; } // make something up for last point _colY[_colY.size() - 1] = _colY[_colY.size() - 2]; create_y_scale(); return true; } else { err("Must be `differentiate x|y ...'"); demonstrate_command_usage(); err("Can't understand command."); return false; } } else { err("Need word `wrt'"); // not sure can get here demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } default: demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/debug.cc������������������������������������������������������������������������������������0000644�0001750�0001750�00000003401�13147557614�012202� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include "gr.hh" #include "debug.hh" #include "extern.hh" bool debugCmd() { int debug; switch (_nword) { case 2: /* debug .n.|off */ if (!strcmp(_word[1], "off")) { debug = 0; PUT_VAR("..debug..", debug); _debugFlag = 0; return 1; } getinum(_word[1], &debug); break; case 1: /* `debug' -- equivalent to `debug 1' */ debug = 1; _debugFlag = 1; break; case 6: /* `debug clipped values in draw commands' */ if (!strcmp(_word[1], "clipped") && !strcmp(_word[2], "values") && !strcmp(_word[3], "in") && !strcmp(_word[4], "draw") && !strcmp(_word[5], "commands")) { _debugFlag |= DEBUG_CLIPPED; return 1; } else { demonstrate_command_usage(); err("Can't understand command."); return 0; } default: demonstrate_command_usage(); NUMBER_WORDS_ERROR; return 0; } PUT_VAR("..debug..", debug); return 1; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/delete.cc�����������������������������������������������������������������������������������0000644�0001750�0001750�00000026506�13147557614�012371� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // #define DEBUG_STORAGE #include #include #include #include "gr.hh" #include "extern.hh" #include "private.hh" bool delete_columnsCmd(void); static void delete_all_columns(void); static bool delete_columns_randomly(void); bool delete_columns_where_missing(void); bool delete_gridCmd(void); extern char _grTempString[]; // `delete .variable.' // `delete \synonym' // `delete columns [randomly .fraction.]' // `delete grid' // `delete x|y scale' bool deleteCmd() { if (_nword == 1) { err("`delete' what?"); return false; } std::string w1(_word[1]); un_double_quote(w1); //un_double_slash(w1); //de_reference(w1); if (is_var(w1) || is_syn(w1)) { /* Deleting variable/synonym (s) */ for (unsigned int i = 1; i < _nword; i++) { //printf("DEBUG %s:%d should delete <%s>\n",__FILE__,__LINE__,_word[i]); w1.assign(_word[i]); un_double_quote(w1); //un_double_slash(w1); //de_reference(w1); if (is_var(w1)) { if (!delete_var(w1)) { warning("`delete' can't delete non-existent variable `\\", w1.c_str(), "'", "\\"); return false; } } else if (is_syn(w1)) { if (w1[1] == '@') { std::string clean("\\"); clean.append(w1.substr(2, w1.size())); std::string named; get_syn(clean.c_str(), named, false); //printf("DELETE IS AN ALIAS SYN %s:%d <%s> [%s]\n",__FILE__,__LINE__,clean.c_str(),named.c_str()); if (is_var(named.c_str())){ if (!delete_var(named.c_str())) { warning("`delete' can't delete non-existent variable `\\", w1.c_str(), "'", "\\"); return false; } return true; } else if (is_syn(named.c_str())) { if (!delete_syn(named.c_str())) { warning("`delete' can't delete non-existent synonym `\\", named.c_str(), "'", "\\"); return false; } } else { err("`delete' cannot decode `\\", w1.c_str(), "'", "\\"); return false; } return true; } else { // Non-aliased synonym. std::string value; if (get_syn(w1.c_str(), value, false)) { std::string coded_name; int coded_level = -1; //printf("DEBUG <%s>\n", value.c_str()); if (is_coded_string(value.c_str(), coded_name, &coded_level)) { //printf("DEBUG %s:%d is <%s> <%s> level %d\n",__FILE__,__LINE__,value.c_str(),coded_name.c_str(),coded_level); if (coded_name[0] == '.') { int index = index_of_variable(coded_name.c_str(), coded_level); //printf("should delete var at %d\n",index); if (index > -1) variableStack.erase(variableStack.begin() + index); continue; } else if (coded_name[0] == '\\') { int index = index_of_synonym(coded_name.c_str(), coded_level); //printf("should delete syn at %d\n",index); //show_syn_stack(); if (index > -1) synonymStack.erase(synonymStack.begin() + index); //printf("OK, is it gone?\n"); //show_syn_stack(); continue; } else { err("`delete' cannot decode `\\", w1.c_str(), "'", "\\"); return false; } } } if (!delete_syn(w1)) { warning("`delete' can't delete non-existent synonym `\\", w1.c_str(), "'", "\\"); return false; } } } else { warning("`delete' can't delete item `\\", w1.c_str(), "' since it is neither a synonym nor a variable", "\\"); return false; } } return true; } else if (word_is(1, "columns")) { return delete_columnsCmd(); } else if (word_is(1, "grid")) { /* Delete the grid */ if (_nword == 2) { delete_gridCmd(); return true; } else { demonstrate_command_usage(); err("Extra words in command."); return false; } } else if (word_is(1, "scale")) { /* Delete both the x and y scales */ _yincreasing = true; _xscale_exists = false; _need_x_axis = true; _yscale_exists = false; _need_y_axis = true; _user_set_x_axis = false; _user_set_y_axis = false; gr_setxtransform(gr_axis_LINEAR); gr_setxlabel("x"); gr_setytransform(gr_axis_LINEAR); gr_setylabel("y"); return true; } else if (word_is(1, "x")) { /* Delete the x scale */ if (word_is(2, "scale") && _nword == 3) { _xscale_exists = false; _need_x_axis = true; _user_set_x_axis = false; _xtype = gr_axis_LINEAR; _x_gave_labelling = false; gr_setxtransform(gr_axis_LINEAR); gr_setxlabel("x"); return true; } else { demonstrate_command_usage(); err("`delete x' what?"); return false; } } else if (word_is(1, "y")) { /* Delete the y scale */ if (word_is(2, "scale") && _nword == 3) { _yscale_exists = false; _need_y_axis = true; _yincreasing = true; _user_set_y_axis = false; _ytype = gr_axis_LINEAR; _y_gave_labelling = false; gr_setytransform(gr_axis_LINEAR); gr_setylabel("y"); return true; } else { demonstrate_command_usage(); err("`delete y' what?"); return false; } } else { demonstrate_command_usage(); err("`delete' what?"); return false; } } // `delete columns [{randomly .fraction.}|{where missing}]' bool delete_columnsCmd() { switch(_nword) { case 2: // `delete columns' delete_all_columns(); return true; case 4: // `delete columns randomly .fraction.' if (word_is(2, "randomly")) { return delete_columns_randomly(); } else if (word_is(2, "where") || word_is(3, "missing")) { return delete_columns_where_missing(); } else { demonstrate_command_usage(); err("Syntax must be `randomly .f.' or `where missing'"); return false; } default: demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } } static void delete_all_columns() { _colX.setDepth(0); _colX.compact(); _colY.setDepth(0); _colY.compact(); _colZ.setDepth(0); _colZ.compact(); _colU.setDepth(0); _colU.compact(); _colV.setDepth(0); _colV.compact(); _colWEIGHT.setDepth(0); _colWEIGHT.compact(); } static bool delete_columns_randomly() { double fraction; if (!getdnum(_word[3], &fraction)) { READ_WORD_ERROR(".fraction."); return false; } if (fraction < 0.0) { warning("`delete columns randomly' clipping .fraction. to 0 (did no deletions)"); return true; // do nothing } if (fraction > 1.0) { warning("`delete columns randomly' clipping .fraction. to 1"); delete_all_columns(); return true; } unsigned int length = _colX.size(); double miss = gr_currentmissingvalue(); int good = 0; std::vector ok((size_t)length, 0); unsigned int i; for (i = 0; i < length; i++) { ok[i] = (char)0; if (_colX.size() > 0 && (_colX[i] == miss)) continue; if (_colY.size() > 0 && (_colY[i] == miss)) continue; if (_colZ.size() > 0 && (_colZ[i] == miss)) continue; if (_colU.size() > 0 && (_colU[i] == miss)) continue; if (_colV.size() > 0 && (_colV[i] == miss)) continue; if (_colWEIGHT.size() > 0 && (_colWEIGHT[i] == miss)) continue; ok[i] = (char)1; good++; } // Create vector of whether to kill a given index std::vector kill((size_t)length, 0); // Laborously get correct number of data to discard. Originally // I just tried to remove the given number, but that adds // an extra element of randomness. unsigned int subset = (unsigned int)(floor(good * fraction + 0.5)); unsigned int collisions = 0; #if defined(HAVE_DRAND48) srand48(getpid()); #else srand(getpid()); #endif for (i = 0; i < subset; i++) { #if defined(HAVE_DRAND48) // range is 0 to 1, but do modulus in case int index = int(drand48() * length) % length; #else int index = int(rand() % length); #endif if (ok[index]) { if (kill[index]) { if (collisions++ > length) { sprintf(_grTempString, "`delete columns randomly' could only delete %d columns\n", i); warning(_grTempString); break; } i--; } else { kill[index] = 1; } } else { i--; } } for (i = 0; i < length; i++) { if (kill[i]) { if (_colX.size()) _colX[i] = miss; if (_colY.size()) _colY[i] = miss; if (_colZ.size()) _colZ[i] = miss; if (_colU.size()) _colU[i] = miss; if (_colV.size()) _colV[i] = miss; if (_colWEIGHT.size()) _colWEIGHT[i] = miss; } } return true; } bool delete_columns_where_missing() { int haveX, haveY, haveZ, haveU, haveV, haveWEIGHT; haveX = haveY = haveZ = haveU = haveV = haveWEIGHT = 0; unsigned int length = _colX.size(); unsigned int i; for (i = 0; i < length; i++) { if (_colX.size()) haveX = 1; if (_colY.size()) haveY = 1; if (_colZ.size()) haveZ = 1; if (_colU.size()) haveU = 1; if (_colV.size()) haveV = 1; if (_colWEIGHT.size()) haveWEIGHT = 1; } double *xP = _colX.begin(); double *yP = _colY.begin(); double *zP = _colZ.begin(); double *uP = _colU.begin(); double *vP = _colV.begin(); double *weightP = _colWEIGHT.begin(); std::vector kill((size_t)length, 0); int num_to_kill = 0; for (i = 0; i < length; i++) { if (haveX && gr_missing(xP[i])) { kill[i] = 1; num_to_kill++; continue; } if (haveY && gr_missing(yP[i])) { kill[i] = 1; num_to_kill++; continue; } if (haveZ && gr_missing(zP[i])) { kill[i] = 1; num_to_kill++; continue; } if (haveU && gr_missing(uP[i])) { kill[i] = 1; num_to_kill++; continue; } if (haveV && gr_missing(vP[i])) { kill[i] = 1; num_to_kill++; continue; } if (haveWEIGHT && gr_missing(weightP[i])) { kill[i] = 1; num_to_kill++; continue; } } if (!num_to_kill) { return true; } for (i = length - 1; i != 0; i--) { if (kill[i]) { if (haveX) _colX.erase(_colX.begin() + i); if (haveY) _colY.erase(_colY.begin() + i); if (haveZ) _colZ.erase(_colZ.begin() + i); if (haveU) _colU.erase(_colU.begin() + i); if (haveV) _colV.erase(_colV.begin() + i); if (haveWEIGHT) _colWEIGHT.erase(_colWEIGHT.begin() + i); } } PUT_VAR("..num_col_data..", double(_colX.size())); PUT_VAR("..num_col_data_missing..", 0); length -= num_to_kill; return true; } bool delete_gridCmd() { Require(_nword == 2, err("Must have `delete grid'")); if (!strcmp(_word[1], "grid")) { _f_xy.set_size(0, 0); _legit_xy.set_size(0, 0); if (_grid_exists == true) { _f_min = _f_max = gr_currentmissingvalue(); _grid_exists = false; } if (_xgrid_exists == true) { #if defined(DEBUG_STORAGE) printf("delete clearing _xmatrix=%x\n", _xmatrix); #endif delete [] _xmatrix; _num_xmatrix_data = 0; _xgrid_exists = false; } if (_ygrid_exists == true) { #if defined(DEBUG_STORAGE) printf("delete clearing _ymatrix=%x\n", _ymatrix); #endif delete [] _ymatrix; _num_ymatrix_data = 0; _ygrid_exists = false; } } else { err("Must have `delete grid'"); return false; } return true; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/GriColor.cc���������������������������������������������������������������������������������0000644�0001750�0001750�00000011433�13147557614�012640� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ //#define DEBUG_GRICOLOR #include "GriColor.hh" // from gr.hh anyway #include "gr.hh" #include "types.hh" #include "errors.hh" // for OUT_OF_MEMORY GriColor& GriColor::operator=(const GriColor& color) { t = color.get_type(); transparency = color.getT(); switch (t) { case rgb: a = color.getR(); b = color.getG(); c = color.getB(); break; case hsv: a = color.getH(); b = color.getS(); c = color.getV(); break; case cmyk: a = color.getC(); b = color.getM(); c = color.getY(); d = color.getK(); break; default: fprintf(stderr, "GriColor::operator= cannot handle this (%d) GriColor type\n", (int)t); exit(1); } return *this; } GriColor::GriColor(const GriColor& color) { t = color.get_type(); transparency = color.getT(); switch (t) { case rgb: a = color.getR(); b = color.getG(); c = color.getB(); break; case hsv: a = color.getH(); b = color.getS(); c = color.getV(); break; case cmyk: a = color.getC(); b = color.getM(); c = color.getY(); d = color.getK(); break; default: fprintf(stderr, "GriColor::GriColor cannot handle this (%d) GriColor type\n", t); exit(1); } } GriColor::~GriColor() { ; } void GriColor::setRGB(double R, double G, double B) { a = pin0_1(R); b = pin0_1(G); c = pin0_1(B); transparency = 0.0; t = rgb; } void GriColor::setHSV(double H, double S, double V) { a = pin0_1(H); b = pin0_1(S); c = pin0_1(V); transparency = 0.0; t = hsv; } void GriColor::setCMYK(double C, double M, double Y, double K) { a = pin0_1(C); b = pin0_1(M); c = pin0_1(Y); d = pin0_1(K); transparency = 0.0; t = cmyk; } GriNamedColor::GriNamedColor() { name = ""; a = b = c = d = 0.0; transparency = 0.0; t = rgb; } GriNamedColor::GriNamedColor(const char *n, double R, double G, double B) { name = n; a = R; b = G; c = B; transparency = 0.0; t = rgb; } GriNamedColor::GriNamedColor(const GriNamedColor& color) { #if defined(DEBUG_GRICOLOR) printf("GriNamedColor(const color) ENTER (assigning from '%s')\n",color.get_name().c_str()); #endif name.assign(color.get_name()); t = color.get_type(); transparency = 0.0; switch (t) { case rgb: a = color.getR(); b = color.getG(); c = color.getB(); break; case hsv: a = color.getH(); b = color.getS(); c = color.getV(); break; case cmyk: a = color.getC(); b = color.getM(); c = color.getY(); d = color.getK(); break; default: fprintf(stderr, "GriNamedColor::GriNamedColor cannot handle this (%d) GriColor type\n", t); exit(1); } #if defined(DEBUG_GRICOLOR) printf("GriNamedColor(const color) EXIT\n"); #endif } GriNamedColor::~GriNamedColor() { ; } GriNamedColor& GriNamedColor::operator=(const GriNamedColor& color) { #if defined(DEBUG_GRICOLOR) printf("GriNamedColor::operator= ENTER (source '%s'\n",color.get_name().c_str()); #endif name.assign(color.get_name()); t = color.get_type(); transparency = 0.0; switch (t) { case rgb: a = color.getR(); b = color.getG(); c = color.getB(); break; case hsv: a = color.getH(); b = color.getS(); c = color.getV(); break; case cmyk: a = color.getC(); b = color.getM(); c = color.getY(); d = color.getK(); break; default: fprintf(stderr, "GriNamedColor::operator= cannot handle this (%d) GriColor type\n", t); exit(1); } #if defined(DEBUG_GRICOLOR) printf("GriNamedColor::operator= EXIT\n"); #endif return *this; } void GriNamedColor::setNameRGB(const char *newName, double R, double G, double B) { name = newName; t = rgb; transparency = 0.0; a = pin0_1(R); b = pin0_1(G); c = pin0_1(B); } std::string GriColor::get_hexcolor() const { char hex_color[8]; // result is 7 chars long double r, g, b; getRGB(&r, &g, &b); sprintf(hex_color, "#%02x%02x%02x", int(r*255),int(g*255),int(b*255)); return(std::string(hex_color)); } void GriColor::getRGB(double *R, double *G, double *B) const { if (t == GriColor::rgb) { *R = a; *G = b; *B = c; } else if (t == GriColor::hsv) { gr_hsv2rgb(a, b, c, R, G, B); } else { gr_error("Internal error in GriColor::getRGB\n"); } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/heal.cc�������������������������������������������������������������������������������������0000644�0001750�0001750�00000012251�13147557614�012030� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include "extern.hh" #include "gr.hh" static bool heal_columnsCmd(void); static bool heal_gridCmd(void); void heal_col(double *c, unsigned int n); // `heal columns|{grid along x|y}' bool healCmd() { if (word_is(1, "columns")) { return heal_columnsCmd(); } else if (word_is(1, "grid")) { if (word_is(2, "along")) { return heal_gridCmd(); } else { err("third word must be `along'"); return false; } } else { err("second word must be `columns' or `grid'"); return false; } } // `heal columns' bool heal_columnsCmd() { if (_nword != 2) { NUMBER_WORDS_ERROR; demonstrate_command_usage(); return false; } if (_colX.size() > 0) heal_col(_colX.begin(), _colX.size()); if (_colY.size() > 0) heal_col(_colY.begin(), _colY.size()); if (_colU.size() > 0) heal_col(_colU.begin(), _colU.size()); if (_colV.size() > 0) heal_col(_colV.begin(), _colV.size()); if (_colZ.size() > 0) heal_col(_colZ.begin(), _colZ.size()); if (_colWEIGHT.size() > 0) heal_col(_colWEIGHT.begin(), _colWEIGHT.size()); return true; } void heal_col(double *c, unsigned int n) { unsigned int first_good; unsigned int last_good_index = 0; bool last_was_missing = false; // Find first good data point for (first_good = 0; first_good < n; first_good++) if (!gr_missing((double) *(c + first_good))) break; // Heal gaps, using last_good_value for (unsigned int i = first_good; i < n; i++) { if (!gr_missing((double) *(c + i))) { // This point is good. If last was bad, have a hole to fill if (last_was_missing) { double range = *(c + i) - *(c + last_good_index); for (unsigned int ii = last_good_index + 1; ii < i; ii++) { *(c + ii) = *(c + last_good_index) + (ii - last_good_index) * range / (i - last_good_index); } } last_was_missing = false; last_good_index = i; } else { last_was_missing = true; } } } // `heal columns|{grid along x|y}' bool heal_gridCmd() { bool doing_x; // Check for obvious errors. if (_nword != 4) { NUMBER_WORDS_ERROR; demonstrate_command_usage(); return false; } if (!strcmp(_word[3], "x")) { if (!_xgrid_exists) { err("First `read grid x' or `set x grid'"); return false; } if (!grid_exists()) { err("No grid exists yet\n"); return false; } doing_x = true; } else if (!strcmp(_word[3], "y")) { if (!_ygrid_exists) { err("First `read grid y' or `set y grid'"); return false; } if (!grid_exists()) { err("No grid exists yet\n"); return false; } doing_x = false; } else { err("Expecting `x' or `y', not `\\", _word[3], "'.", "\\"); demonstrate_command_usage(); return false; } if (doing_x) { // Heal across x. unsigned int i, j; for (j = 0; j < _num_ymatrix_data; j++) { for (i = 0; i < _num_xmatrix_data; i++) { if (_legit_xy(i, j) == false) { int last_good = i - 1; for (; i < _num_xmatrix_data; i++) { if (_legit_xy(i, j) == true) { // Got to other side of hole. Fill in if it is // interior. if (i < _num_xmatrix_data - 1 && last_good > -1) { unsigned int ii; double a, b; // y = a + bx a = _f_xy(last_good, j); b = (_f_xy(i, j) - _f_xy(last_good, j)) / (_xmatrix[i] - _xmatrix[last_good]); for (ii = last_good + 1; ii < i; ii++) { _f_xy(ii, j) = a + b * (_xmatrix[ii] - _xmatrix[last_good]); _legit_xy(ii, j) = true; } } break; } } } } } } else { // Heal across y. unsigned int i, j; for (i = 0; i < _num_xmatrix_data; i++) { for (j = 0; j < _num_ymatrix_data; j++) { if (_legit_xy(i, j) == false) { int last_good = j - 1; for (; j < _num_ymatrix_data; j++) { if (_legit_xy(i, j) == true) { // Got to other side of hole. Fill in if it is // interior. if (j < _num_ymatrix_data - 1 && last_good > -1) { unsigned int jj; double a, b; // y = a + bx a = _f_xy(i, last_good); b = (_f_xy(i, j) - _f_xy(i, last_good)) / (_ymatrix[j] - _ymatrix[last_good]); for (jj = last_good + 1; jj < j; jj++) { _f_xy(i, jj) = a + b * (_ymatrix[jj] - _ymatrix[last_good]); _legit_xy(i, jj) = true; } } break; } } } } } } return true; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/image.cc������������������������������������������������������������������������������������0000644�0001750�0001750�00000013670�13147557614�012207� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ //#define DEBUG_IMAGE 1 // for debugging #include #include #include "extern.hh" /* * Image things (shared by other files through image_ex.h) */ double _image0 = 0.0, _image255 = 0.0; /* uservalue <-> [0,255] * scale */ double _image_missing_color_red = 1.0; /* for missing data */ double _image_missing_color_green = 1.0; /* for missing data */ double _image_missing_color_blue = 1.0; /* for missing data */ double _image_llx, _image_lly, _image_urx, _image_ury; /* coords */ double *_imageHist; int _image_color_model = 0; /* 0=bw 1=rgb */ bool _imageTransform_exists = false; bool _imageHist_exists = false; IMAGE _image, _imageMask; unsigned char *_imageTransform; static bool x_image_scale_defined = false; static bool y_image_scale_defined = false; void show_image_transform(void); /* for debugging */ void show_image_transform() { if (_imageTransform_exists) { int i; printf("_imageTransform[0-255] is:\n"); for (i = 0; i < 256; i++) { printf("im_tr[%d] = %d\n", i, _imageTransform[i]); } } else { printf("_imageTransform[] NOT DEFINED YET\n"); } } bool define_image_scales(double llx, double lly, double urx, double ury) { if (llx != urx) { _image_llx = llx; _image_urx = urx; x_image_scale_defined = true; } if (lly != ury) { _image_lly = lly; _image_ury = ury; y_image_scale_defined = true; } return true; } bool image_scales_defined() { return ((x_image_scale_defined && y_image_scale_defined) ? true : false); } /* * Blank out image; make it be bw, not color. */ bool blank_image() { if (_image.storage_exists) { if (_image.image != NULL) free(_image.image); _image.image = NULL; _image.storage_exists = false; } _image.ras_width = _image.ras_height = _image.ras_length = 0; _image_llx = _image_lly = 0.0; _image_urx = _image_ury = 0.0; _image0 = _image255 = 0.0; /* used by image_range_exists() */ _image_color_model = 0; x_image_scale_defined = false; y_image_scale_defined = false; _imageHist_exists = false; /* * Make transform into an even ramp, for each or R, G, B. Note that val * will wrap around at 255. */ unsigned int i; unsigned char val; for (val = 0, i = 0; i < 768; i++, val++) _imageTransform[i] = val; _imageTransform_exists = true; #ifdef DEBUG_IMAGE printf("%s:%d blanked image with storage at %X\n",__FILE__,__LINE__,(int)(_image.image)); #endif return true; } bool blank_imageMask() { if (_imageMask.storage_exists) { free(_imageMask.image); _imageMask.image = NULL; _imageMask.storage_exists = false; } _imageMask.ras_width = _imageMask.ras_height = _imageMask.ras_length = 0; #ifdef DEBUG_IMAGE printf("%s:%d blanked imageMask with storage at %X\n",__FILE__,__LINE__,(int)(_imageMask.image)); #endif return true; } bool initialize_image() { _image.image = NULL; _image.storage_exists = false; GET_STORAGE(_imageTransform, unsigned char, 3 * 256); return blank_image(); } bool initialize_imageMask() { _imageMask.image = NULL; _imageMask.storage_exists = false; return blank_imageMask(); } // Tell if the image range exists (created by `set image range'). bool image_range_exists() { return _image0 != 0.0 || _image255 != 0.0; } #if 0 //bool //image_exists() //{ // return ((_image.ras_length > 0) ? true : false); //} //bool //imageMask_exists() //{ // return ((_imageMask.ras_length > 0) ? true : false); //} #endif /* * Calculate histogram of image, normalized to sum to 1 over all image * values. Histogram is defined in _imageHist[]; for example, _imageHist[0] * is the normalized fraction of pixels with value 0. * * NOTE this code assumes 8bit images; to change that, change the symbol NUM, * and change the unsigned char references to whatever makes sense. */ #define NUM 256 /* change if not 8 bit images */ bool calculate_image_histogram() { long good = 0, mhis[NUM]; int i; if (!_image.storage_exists) { err("no image exists"); return false; } if (_imageHist_exists) return true; for (i = 0; i < NUM; i++) mhis[i] = 0; if (_imageMask.storage_exists) { long max = _image.ras_width * _image.ras_height; unsigned char *im = _image.image; unsigned char *imMask = _imageMask.image; for (i = 0; i < max; i++) { if (!*(imMask)) { mhis[*im]++; good++; } im++; imMask++; } } else { long max = _image.ras_width * _image.ras_height; unsigned char *im = _image.image; for (i = 0; i < max; i++) { mhis[*im]++; good++; im++; } } for (i = 0; i < NUM; i++) _imageHist[i] = (double) mhis[i] / (double) good; _imageHist_exists = true; return true; } #undef NUM double image_to_value(int c) { return (double) (_image0 + c * (_image255 - _image0) / 255.0); } /* value_to_image() -- conv double to uchar image value */ /* * XREF convert_grid_to_imageCmd() */ unsigned char value_to_image(double v) { int I; I = (int) floor(0.5 + (255.0 * (v - _image0) / (_image255 - _image0))); if (I < 0) return ((unsigned char) 0); else if (I > 255) return ((unsigned char) 255); else return ((unsigned char) I); } ������������������������������������������������������������������������gri/src/math.cc�������������������������������������������������������������������������������������0000644�0001750�0001750�00000030531�13147557614�012051� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include "extern.hh" #include "image_ex.hh" bool mathCmd(); static bool column_math(double *Ptr, unsigned int n, int operator_position = 1); static bool image_math(void); static bool grid_data_math(void); extern void highpass_image(void); extern void lowpass_image(void); bool mathCmd() { if (_nword < 3) { err("Proper format: `.x. = 10.0', `.x. *= 2', or `.x. = { rpn ... }'"); return false; } double number, old_value = 0.0; // Variable if (is_var(_word[0])) { if (!getdnum(_word[2], &number)) return false; if (word_is(1, "=")) { // `.variable. = .value.' PUT_VAR(_word[0], number); } else if (word_is(1, "+=")) { get_var(_word[0], &old_value); old_value += number; PUT_VAR(_word[0], old_value); } else if (word_is(1, "-=")) { get_var(_word[0], &old_value); old_value -= number; PUT_VAR(_word[0], old_value); } else if (word_is(1, "*=")) { get_var(_word[0], &old_value); old_value *= number; PUT_VAR(_word[0], old_value); } else if (word_is(1, "/=")) { get_var(_word[0], &old_value); old_value /= number; PUT_VAR(_word[0], old_value); } else if (word_is(1, "^=")) { get_var(_word[0], &old_value); old_value = pow(old_value, number); PUT_VAR(_word[0], old_value); } else if (word_is(1, "_=")) { get_var(_word[0], &old_value); if (number < 0.0) { err("Cannot do log to negative base"); return false; } if (!gr_missing(old_value) && old_value > 0.0) { old_value = log(old_value) / log(number); PUT_VAR(_word[0], old_value); } else { PUT_VAR(_word[0], gr_currentmissingvalue()); } } else { err("`\\", _word[1], "' is not a known operator for variables", "'\\"); return false; } } else if (_nword > 3 && word_is(0, "grid") && word_is(1, "data")) { grid_data_math(); } else if (_nword > 3 && word_is(0, "grid") && word_is(1, "x")) { if (_num_xmatrix_data) column_math(_xmatrix, _num_xmatrix_data, 2); else { warning("Can't do math on xmatrix with no data in it already."); return true; } } else if (_nword > 3 && word_is(0, "grid") && word_is(1, "y")) { if (_num_ymatrix_data) column_math(_ymatrix, _num_ymatrix_data, 2); else { warning("Can't do math on ymatrix with no data in it already."); return true; } } else if (word_is(0, "u")) { if (_colU.size()) column_math(_colU.begin(), _colU.size()); else { warning("Can't do math on u-column with no data in it already."); return true; } } else if (word_is(0, "v")) { if (_colV.size()) column_math(_colV.begin(), _colV.size()); else { warning("Can't do math on v-column with no data in it already."); return true; } } else if (word_is(0, "x")) { if (_colX.size()) column_math(_colX.begin(), _colX.size()); else { warning("Can't do math on x-column with no data in it already."); return true; } } else if (word_is(0, "y")) { if (_colY.size()) column_math(_colY.begin(), _colY.size()); else { warning("Can't do math on y-column with no data in it already."); return true; } } else if (word_is(0, "z")) { if (_colZ.size()) column_math(_colZ.begin(), _colZ.size()); else { warning("Can't do math on z-column with no data in it already."); return true; } } else if (word_is(0, "image")) { image_math(); } else { err("Cannot do mathematical operation on unrecognized item `\\", _word[0], "'.", "\\"); return false; } return true; } static bool column_math(double *Ptr, unsigned int n, int operator_position /*= 1*/) { Require(n > 0, gr_Error("Trying to do column-math on non-existent column.")); // Ensure enough space if (word_is(0, "x")) {_colX.setDepth(n); Ptr = _colX.begin();} else if (word_is(0, "y")) {_colY.setDepth(n); Ptr = _colY.begin();} else if (word_is(0, "u")) {_colU.setDepth(n); Ptr = _colU.begin();} else if (word_is(0, "v")) {_colV.setDepth(n); Ptr = _colV.begin();} else if (word_is(0, "z")) {_colZ.setDepth(n); Ptr = _colZ.begin();} else if (word_is(0, "WEIGHT")) {_colWEIGHT.setDepth(n); Ptr = _colWEIGHT.begin();} // special case of `y = x...' if (_nword == 3 && word_is(0, "y") && word_is(1, "=") && word_is(2, "x")) { for (unsigned int i = 0; i < n; i++) _colY[i] = _colX[i]; if (word_is(0, "y") && _need_y_axis && !_user_set_y_axis) create_y_scale(); return true; } double number; if (!getdnum(_word[operator_position + 1], &number)) return false; // Special case of assignment if (word_is(operator_position, "=")) { // Make sure column can hold the data for (unsigned int i = 0; i < n; i++, Ptr++) { if (!gr_missing(*Ptr)) { *Ptr = number; } } if (word_is(0, "y") && _need_y_axis && !_user_set_y_axis) create_y_scale(); return true; } // Do modification (OP=) cases if (word_is(operator_position, "+=")) { for (unsigned int i = 0; i < n; i++, Ptr++) if (!gr_missing(*Ptr)) *Ptr += number; } else if (word_is(operator_position, "-=")) { for (unsigned int i = 0; i < n; i++, Ptr++) if (!gr_missing(*Ptr)) *Ptr -= number; } else if (word_is(operator_position, "*=")) { for (unsigned int i = 0; i < n; i++, Ptr++) if (!gr_missing(*Ptr)) *Ptr *= number; } else if (word_is(operator_position, "/=")) { for (unsigned int i = 0; i < n; i++, Ptr++) if (!gr_missing(*Ptr)) *Ptr /= number; } else if (word_is(operator_position, "^=")) { for (unsigned int i = 0; i < n; i++, Ptr++) if (!gr_missing(*Ptr)) *Ptr = pow(*Ptr, number); } else if (word_is(operator_position, "_=")) { if (number < 0.0) { err("Cannot do log to negative base"); return false; } double lbase = log(number); for (unsigned int i = 0; i < n; i++, Ptr++) if (!gr_missing(*Ptr) && *Ptr > 0.0) *Ptr = log(*Ptr) / lbase; else *Ptr = gr_currentmissingvalue(); } else { err("`\\", _word[operator_position], "' not a known operator", "'\\"); return false; } if (word_is(0, "x") && _need_x_axis && !_user_set_x_axis) create_x_scale(); if (word_is(0, "y") && _need_y_axis && !_user_set_y_axis) create_y_scale(); return true; } static bool grid_data_math() { if (_nword < 4) { err("No number for operation."); return false; } if (!_grid_exists) { err("First `read grid data'"); return false; } double number; if (!getdnum(_word[3], &number)) { err("Can't read number"); return false; } unsigned int row, col; if (word_is(2, "=")) { for (col = 0; col < _num_xmatrix_data; col++) { for (row = 0; row < _num_ymatrix_data; row++) { _f_xy(col, row) = number; _legit_xy(col, row) = true; } } _f_min = _f_max = number; return true; } else if (word_is(2, "+=")) { for (col = 0; col < _num_xmatrix_data; col++) for (row = 0; row < _num_ymatrix_data; row++) _f_xy(col, row) += number; _f_min += number; _f_max += number; return true; } else if (word_is(2, "-=")) { for (col = 0; col < _num_xmatrix_data; col++) for (row = 0; row < _num_ymatrix_data; row++) _f_xy(col, row) -= number; _f_min -= number; _f_max -= number; return true; } else if (word_is(2, "*=")) { for (col = 0; col < _num_xmatrix_data; col++) for (row = 0; row < _num_ymatrix_data; row++) _f_xy(col, row) *= number; _f_min *= number; _f_max *= number; return true; } else if (word_is(2, "/=")) { if (number == 0.0) { warning("Can't divide by zero"); return true; } for (col = 0; col < _num_xmatrix_data; col++) for (row = 0; row < _num_ymatrix_data; row++) _f_xy(col, row) /= number; _f_min /= number; _f_max /= number; return true; } else if (word_is(2, "^=")) { for (col = 0; col < _num_xmatrix_data; col++) for (row = 0; row < _num_ymatrix_data; row++) _f_xy(col, row) = pow(_f_xy(col, row), number); matrix_limits(&_f_min, &_f_max); return true; } else if (word_is(2, "_=")) { if (number < 0.0) { err("Cannot do log to negative base"); return false; } double lbase = log(number); for (col = 0; col < _num_xmatrix_data; col++) for (row = 0; row < _num_ymatrix_data; row++) if (!gr_missing(_f_xy(col, row)) && _f_xy(col, row) > 0.0) _f_xy(col, row) = log(_f_xy(col, row)) / lbase; else _f_xy(col, row) = gr_currentmissingvalue(); matrix_limits(&_f_min, &_f_max); return true; } else { err("`grid data' given unknown operator `\\", _word[2], ";", "\\"); return false; } } // `image [grayscale|colorscale] OPERATOR OPERAND' static bool image_math() { unsigned int n; unsigned char *Ptr; double number, number_scaled=0.0; switch (_nword) { case 3: // `image OPERATOR OPERAND' if (word_is(1, "=")) { if (word_is(2, "highpass")) highpass_image(); else if (word_is(2, "lowpass")) lowpass_image(); else { err("`image =' what?"); return false; } return true; } if (!getdnum(_word[2], &number)) return false; if (!_image.storage_exists) { err("First `read image' or `convert grid to image'"); return false; } // Convert to image units number_scaled *= 255.0 / (_image255 - _image0); Ptr = _image.image; n = _image.ras_length; if (word_is(1, "+=")) { for (unsigned int i = 0; i < n; i++, Ptr++) *Ptr = int(*Ptr + number_scaled); } else if (word_is(1, "-=")) { for (unsigned int i = 0; i < n; i++, Ptr++) *Ptr = int(*Ptr - number_scaled); } else if (word_is(1, "*=")) { for (unsigned int i = 0; i < n; i++, Ptr++) *Ptr = int(*Ptr * number); } else if (word_is(1, "/=")) { for (unsigned int i = 0; i < n; i++, Ptr++) *Ptr = int(*Ptr / number); } else if (word_is(1, "^=")) { for (unsigned int i = 0; i < n; i++, Ptr++) *Ptr = int(pow(double(*Ptr), number)); } else if (word_is(1, "_=")) { if (number < 0.0) { err("Cannot do log to negative base"); return false; } double lbase = log(number); for (unsigned int i = 0; i < n; i++, Ptr++) if (!gr_missing(*Ptr) && *Ptr > 0) *Ptr = int(log(double(*Ptr)) / lbase); else *Ptr = 0; // BUG -- should be something else } else { err("Cannot use operator `\\", _word[1], "' on images.", "'\\"); return false; } break; case 4: if (word_is(1, "colorscale") || word_is(1, "colourscale")) { n = 3 * 256; } else if (word_is(1, "greyscale") || word_is(1, "grayscale")) { n = 256; } else { err("Second word must be `colorscale', `colourscale', `grayscale' or `greyscale'"); return false; } if (!getdnum(_word[3], &number)) return false; Ptr = _imageTransform; if (word_is(2, "+=")) { for (unsigned int i = 0; i < n; i++, Ptr++) { *Ptr = (int) (255.0 * (double(*Ptr) / 255.0 + number)); } } else if (word_is(2, "-=")) { for (unsigned int i = 0; i < n; i++, Ptr++) { *Ptr = (int) (255.0 * (double(*Ptr) / 255.0 - number)); } } else if (word_is(2, "*=")) { for (unsigned int i = 0; i < n; i++, Ptr++) { *Ptr = (int) (255.0 * (double(*Ptr) / 255.0 * number)); } } else if (word_is(2, "/=")) { for (unsigned int i = 0; i < n; i++, Ptr++) { *Ptr = (int) (255.0 * (double(*Ptr) / 255.0 / number)); } } else if (word_is(2, "^=")) { for (unsigned int i = 0; i < n; i++, Ptr++) { *Ptr = (int) (255.0 * pow(double(*Ptr) / 255.0, number)); } } else if (word_is(2, "_=")) { if (number < 0.0) { err("Cannot do log to negative base"); return false; } double lbase = log(number); for (unsigned int i = 0; i < n; i++, Ptr++) *Ptr = int(255.0 * log(double(*Ptr) / 255.0) / lbase); } else { err("Cannot use operator `\\", _word[2], "' on image colorscale|grayscale", "'\\"); return false; } break; default: NUMBER_WORDS_ERROR; return false; } return true; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/draw.cc�������������������������������������������������������������������������������������0000644�0001750�0001750�00000272735�13147557614�012073� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2011 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include "gr.hh" #include "extern.hh" #include "defaults.hh" #include "types.hh" #include "image_ex.hh" #include "GriPath.hh" #include "GriTimer.hh" double _contour_space_first = -1.0; // <-> set.c double _contour_space_later = -1.0; // <-> set.c bool _contour_space_centered = false; // <-> set.c double _contour_minlength = 0.0; // <-> lines must exceed this extern char _grTempString[]; #define OFFSET_AFTER_TITLE 1.0 // title is this many cm above plot gr_symbol_type determine_symbol_code(const char * s); bool draw_symbolCmd(void); bool draw_circleCmd(void); bool draw_contourCmd(void); bool draw_arcCmd(void); bool draw_arrow_from_toCmd(void); bool draw_arrowsCmd(void); bool draw_axesCmd(void); bool draw_curveCmd(void); static bool draw_curve_filled_to_valueCmd(bool to_y, double value); bool draw_image_gridCmd(void); bool draw_image_histogramCmd(void); bool draw_image_paletteCmd(void); bool draw_imageCmd(void); bool draw_labelCmd(void); bool draw_line_from_toCmd(void); bool draw_patchesCmd(void); bool draw_polygonCmd(void); bool draw_titleCmd(void); bool draw_valuesCmd(void); bool draw_x_axisCmd(void); bool draw_y_axisCmd(void); bool draw_x_box_plotCmd(void); bool draw_y_box_plotCmd(void); bool draw_zero_lineCmd(void); bool draw_zeroline_horizontally(void); bool draw_zeroline_vertically(void); bool set_x_scale(void); void set_line_width_symbol() { double linewidthsymbol = LINEWIDTHSYMBOL_DEFAULT; if (!get_var("..linewidthsymbol..", &linewidthsymbol)) warning("Sorry ..linewidthsymbol.. undefined so using default"); _griState.set_linewidth_symbol(linewidthsymbol); if (_output_file_type == postscript) { extern FILE *_grPS; fprintf(_grPS, "%.3f w\n", _griState.linewidth_symbol()); } } void set_line_width_curve() { double linewidth = LINEWIDTH_DEFAULT; if (!get_var("..linewidth..", &linewidth)) warning("Sorry ..linewidth.. undefined so using default"); _griState.set_linewidth_line(linewidth); if (_output_file_type == postscript) { extern FILE *_grPS; fprintf(_grPS, "%.3f w\n", _griState.linewidth_line()); } } void set_line_width_axis() { double linewidthaxis = LINEWIDTHAXIS_DEFAULT; if (!get_var("..linewidthaxis..", &linewidthaxis)) warning("Sorry ..linewidthaxis.. undefined so using default"); _griState.set_linewidth_axis(linewidthaxis); } void no_scales_error() { err("Either x or y scale not defined. Try using `set x axis' or `set y axis'."); } // `draw box .xleft. .ybottom. .xright. .ytop. [cm|pt]' bool draw_boxCmd() { static GriPath p(5); // static since might be done often p.clear(); double llx, lly, urx, ury; if (4 == get_cmd_values(_word, _nword, "box", 4, _dstack)) { llx = _dstack[0]; lly = _dstack[1]; urx = _dstack[2]; ury = _dstack[3]; } else { demonstrate_command_usage(); READ_WORD_ERROR("(llx, lly, urx, ury)"); return false; } if (_nword == 6) { // Coordinates in user units set_x_scale(); set_y_scale(); set_environment(); p.push_back(llx, lly, 'm'); p.push_back(urx, lly, 'l'); p.push_back(urx, ury, 'l'); p.push_back(llx, ury, 'l'); p.push_back(llx, lly, 'l'); p.stroke(units_user); return true; } else if (_nword == 7) { // Require `cm' or 'pt' keyword to be present if (!word_is(6, "cm") && !word_is(6, "pt")) { demonstrate_command_usage(); MISSING_WORD_ERROR("cm or pt"); return false; } set_environment(); p.push_back(llx, lly, 'm'); p.push_back(urx, lly, 'l'); p.push_back(urx, ury, 'l'); p.push_back(llx, ury, 'l'); p.push_back(llx, lly, 'l'); if (word_is(6, "pt")) { p.stroke(units_pt); } else if (word_is(6, "cm")) { p.stroke(units_cm); } else { demonstrate_command_usage(); MISSING_WORD_ERROR("cm or pt"); return false; } return true; } else { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } } // `draw box filled .xleft. .ybottom. .xright. .ytop. [cm|pt]' bool draw_box_filledCmd() { static GriPath p(5); // static since might be done often p.clear(); double llx, lly, urx, ury; if (4 == get_cmd_values(_word, _nword, "filled", 4, _dstack)) { llx = _dstack[0]; lly = _dstack[1]; urx = _dstack[2]; ury = _dstack[3]; } else { READ_WORD_ERROR("(llx, lly, urx, ury)"); demonstrate_command_usage(); return false; } if (_nword == 7) { // Coordinates in user units set_x_scale(); set_y_scale(); set_environment(); p.push_back(llx, lly, 'm'); p.push_back(urx, lly, 'l'); p.push_back(urx, ury, 'l'); p.push_back(llx, ury, 'l'); p.push_back(llx, lly, 'l'); p.fill(units_user); } else if (_nword == 8) { // Require `cm' or 'pt' keyword to be present if (!word_is(7, "cm") && !word_is(7, "pt")) { demonstrate_command_usage(); MISSING_WORD_ERROR("cm or pt"); return false; } set_environment(); p.push_back(llx, lly, 'm'); p.push_back(urx, lly, 'l'); p.push_back(urx, ury, 'l'); p.push_back(llx, ury, 'l'); p.push_back(llx, lly, 'l'); if (word_is(7, "pt")) { p.fill(units_pt); } else if (word_is(7, "cm")) { p.fill(units_cm); } else { demonstrate_command_usage(); MISSING_WORD_ERROR("cm or pt"); return false; } } return true; } // `draw symbol .code.|\name at .x. .y. [cm|pt]' // `draw symbol [[.code.|\name] [color hue z|.h. [brightness z|.b.] [saturation // z|.s.]]]' // `draw symbol [[.code.|\name] [graylevel z]' bool draw_symbolCmd() { unsigned int num_drawn = 0; double x, y; bool fixedSymbol = true; bool old = _ignore_error; bool uses_color = false; bool hue_in_z = false, saturation_in_z = false, brightness_in_z = false; double hue = 1.0, saturation = 1.0, brightness = 1.0; gr_symbol_type symbolCode = gr_bullet_symbol; // will be changed if (!scales_defined()) { #if 0 // Fix SF bug #129856 (I hope!) no_scales_error(); return false; #else create_x_scale(); create_y_scale(); #endif } // Columns must exist, if not the "at" style, which is for a single point if (!word_is(3, "at")) { if (!_columns_exist) { warning("`draw symbol' noticed that no column data exist."); return false; } } // Scales must be defined unless symbol location given in cm or pt if (!word_is(_nword - 1, "cm") && !word_is(_nword - 1, "pt")) { if (!scales_defined()) { #if 0 // Fix SF bug #129856 (I hope!) no_scales_error(); return false; #else create_x_scale(); create_y_scale(); #endif } } // Is it brightness in z? bool uses_graylevel = false; if (word_is(2, "graylevel")) { // draw symbol graylevel z if (!word_is(3, "z")) { err("Word following 'graylevel' must be 'z'"); demonstrate_command_usage(); return false; } if (_nword != 4) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } uses_graylevel = true; } else if (word_is(3, "graylevel")) { // draw symbol NAME graylevel z if (!word_is(4, "z")) { err("Word following 'graylevel' must be 'z'"); demonstrate_command_usage(); return false; } if (_nword != 5) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } uses_graylevel = true; if (gr_unknown_symbol == (symbolCode = determine_symbol_code(_word[2]))) { demonstrate_command_usage(); err("Can't understand symbol \\`", _word[2], "'", "\\"); return false; } fixedSymbol = true; } // Is it colorrange in z? bool uses_colorrange = false; if (word_is(2, "colorrange")) { // draw symbol colorrange .h. if (_nword != 4) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (1 == get_cmd_values(_word, _nword, "colorrange", 1, _dstack)) hue = _dstack[0]; uses_colorrange = true; } else if (word_is(3, "colorrange")) { // draw symbol colorrange .h. if (_nword != 5) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (1 == get_cmd_values(_word, _nword, "colorrange", 1, _dstack)) hue = _dstack[0]; uses_colorrange = true; if (gr_unknown_symbol == (symbolCode = determine_symbol_code(_word[2]))) { demonstrate_command_usage(); err("Can't understand symbol \\`", _word[2], "'", "\\"); return false; } fixedSymbol = true; } // If it's neither graylevel nor colorrange, extract hue/saturation/brightness if (!(uses_graylevel || uses_colorrange)) { if (word_is(2, "color") || word_is(2, "colour") || word_is(3, "color") || word_is(3, "colour")) { bool OLD = _ignore_error; _ignore_error = true; // can't read "z" in "hue z" as number if (1 == get_cmd_values(_word, _nword, "saturation", 1, _dstack)) saturation = _dstack[0]; if (1 == get_cmd_values(_word, _nword, "brightness", 1, _dstack)) brightness = _dstack[0]; if (1 == get_cmd_values(_word, _nword, "hue", 1, _dstack)) hue = _dstack[0]; // Figure if anything coded into z column for (unsigned int i = 2; i < _nword; i++) { if (word_is(i, "z")) { if (word_is(i - 1, "brightness")) brightness_in_z = true; else if (word_is(i - 1, "saturation")) saturation_in_z = true; else if (word_is(i - 1, "hue")) { hue_in_z = true; } else { err("Unexpected word preceding word `z'"); return false; } } } _ignore_error = OLD; uses_color = true; // Get symbol type if given if (word_is(3, "color") || word_is(3, "colour")) { if (gr_unknown_symbol == (symbolCode = determine_symbol_code(_word[2]))) { demonstrate_command_usage(); err("Can't understand symbol \\`", _word[2], "'", "\\"); return false; } fixedSymbol = true; } } else { // Not color switch (_nword) { case 2: // `draw symbol' if (_colZ.size() <= 0) { fixedSymbol = true; symbolCode = gr_times_symbol; } else fixedSymbol = false; break; case 3: // `draw symbol [.code.|\name]' if (gr_unknown_symbol == (symbolCode = determine_symbol_code(_word[2]))) { demonstrate_command_usage(); err("Can't understand symbol \\`", _word[2], "'", "\\"); return false; } fixedSymbol = true; break; case 6: // `draw symbol .code.|\name at .x. .y.' if (gr_unknown_symbol == (symbolCode = determine_symbol_code(_word[2]))) { demonstrate_command_usage(); err("Can't understand symbol `\\", _word[2], "'", "\\"); return false; } if (strcmp(_word[3], "at")) { demonstrate_command_usage(); MISSING_WORD_ERROR("at"); return false; } _ignore_error = true; if (!getdnum(_word[4], &x)) { _ignore_error = old; READ_WORD_ERROR(".x."); demonstrate_command_usage(); return false; } else _ignore_error = old; _ignore_error = true; if (!getdnum(_word[5], &y)) { _ignore_error = old; READ_WORD_ERROR(".y."); demonstrate_command_usage(); return false; } else _ignore_error = old; if (inside_box(x, y)) { // ignore if clipped set_environment(); set_line_width_symbol(); double xcm, ycm; gr_usertocm(x, y, &xcm, &ycm); set_ps_color('p'); set_line_width_symbol(); gr_drawsymbol(xcm, ycm, symbolCode); PUT_VAR("..xlast..", x); PUT_VAR("..ylast..", y); } draw_axes_if_needed(); return true; case 7: // `draw symbol .code.|\name at .x. .y. cm' if (gr_unknown_symbol == (symbolCode = determine_symbol_code(_word[2]))) { demonstrate_command_usage(); err("Can't understand symbol `\\", _word[2], "'", "\\"); return false; } if (strcmp(_word[3], "at")) { demonstrate_command_usage(); MISSING_WORD_ERROR("at"); return false; } if (!word_is(6, "cm") && !word_is(6, "pt")) { demonstrate_command_usage(); MISSING_WORD_ERROR("cm or pt"); return false; } _ignore_error = true; if (!getdnum(_word[4], &x)) { _ignore_error = old; READ_WORD_ERROR(".x."); demonstrate_command_usage(); return false; } else _ignore_error = old; _ignore_error = true; if (!getdnum(_word[5], &y)) { _ignore_error = old; READ_WORD_ERROR(".y."); demonstrate_command_usage(); return false; } else _ignore_error = old; double xuser, yuser; if (word_is(6, "cm")) { gr_cmtouser(x, y, &xuser, &yuser); } else if (word_is(6, "pt")) { gr_cmtouser(x / PT_PER_CM, y / PT_PER_CM, &xuser, &yuser); } else { // duplicate check demonstrate_command_usage(); MISSING_WORD_ERROR("cm or pt"); return false; } if (inside_box(xuser, yuser)) { // ignore if clipped set_environment(); set_line_width_symbol(); set_ps_color('p'); set_line_width_symbol(); if (word_is(6, "pt")) gr_drawsymbol(x / PT_PER_CM, y / PT_PER_CM, symbolCode); else gr_drawsymbol(x, y, symbolCode); PUT_VAR("..xlast..", x); PUT_VAR("..ylast..", y); } return true; default: demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } } } // Note: the following only done for `draw symbol ...' double *xp = _colX.begin(); double *yp = _colY.begin(); double *zp = _colZ.begin(); set_environment(); if (!uses_color) set_ps_color('p'); set_line_width_symbol(); unsigned int num = _colX.size(); GriColor c, old_color = _griState.color_line(); set_line_width_symbol(); double xlast = gr_currentmissingvalue(); double ylast = gr_currentmissingvalue(); for (unsigned int i = 0; i < num; i++) { if (!gr_missingx((double) *xp) && !gr_missingy((double) *yp) && inside_box((double) *xp, (double) *yp)) { double xcm, ycm; gr_usertocm(*xp, *yp, &xcm, &ycm); num_drawn++; if (fixedSymbol == true) { // Fixed symbol, possibly in colour if (uses_color) { if (hue_in_z) hue = *zp; if (saturation_in_z) saturation = *zp; if (brightness_in_z) brightness = *zp; c.setHSV(hue, saturation, brightness); _griState.set_color_line(c); set_ps_color('p'); } else if (uses_graylevel) { brightness = *zp; c.setRGB(brightness, brightness, brightness); _griState.set_color_line(c); set_ps_color('p'); } else if (uses_colorrange) { saturation = 1.0-*zp; brightness = 0.3333+0.6666*(*zp); c.setHSV(hue, saturation, brightness); _griState.set_color_line(c); set_ps_color('p'); } gr_drawsymbol(xcm, ycm, symbolCode); xlast = *xp; ylast = *yp; } else { // Symbol stored in z if (!gr_missing((double) *zp)) { gr_drawsymbol(xcm, ycm, gr_symbol_type(int(floor((0.5 + *zp))))); xlast = *xp; ylast = *yp; } } } xp++; yp++; zp++; } if (uses_color || uses_graylevel || uses_colorrange) { _griState.set_color_line(old_color); set_ps_color('p'); } draw_axes_if_needed(); if (_chatty > 0) { if (num_drawn < _colX.size()) { sprintf(_grTempString, "\ `draw symbol' drew %d of the %d data; the remaining %d points\n\ were either missing or out of clip region.\n", num_drawn, (unsigned int)(_colX.size()), (unsigned int)(_colX.size()) - num_drawn); gr_textput(_grTempString); } } PUT_VAR("..xlast..", xlast); PUT_VAR("..ylast..", ylast); return true; } gr_symbol_type determine_symbol_code(const char * s) { double tmp; bool old = _ignore_error; _ignore_error = true; if (getdnum(s, &tmp)) { _ignore_error = old; return gr_symbol_type(int(floor(0.5 + (double) tmp))); } else if (!strcmp(s, "plus")) return gr_plus_symbol; else if (!strcmp(s, "times")) return gr_times_symbol; else if (!strcmp(s, "box")) return gr_box_symbol; else if (!strcmp(s, "circ")) return gr_circ_symbol; else if (!strcmp(s, "diamond")) return gr_diamond_symbol; else if (!strcmp(s, "triangleup")) return gr_triangleup_symbol; else if (!strcmp(s, "triangleright")) return gr_triangleright_symbol; else if (!strcmp(s, "triangledown")) return gr_triangledown_symbol; else if (!strcmp(s, "triangleleft")) return gr_triangleleft_symbol; else if (!strcmp(s, "asterisk")) return gr_asterisk_symbol; else if (!strcmp(s, "star")) return gr_star_symbol; else if (!strcmp(s, "filledbox")) return gr_filledbox_symbol; else if (!strcmp(s, "bullet")) return gr_bullet_symbol; else if (!strcmp(s, "filleddiamond")) return gr_filleddiamond_symbol; else if (!strcmp(s, "filledtriangleup")) return gr_filledtriangleup_symbol; else if (!strcmp(s, "filledtriangleright")) return gr_filledtriangleright_symbol; else if (!strcmp(s, "filledtriangledown")) return gr_filledtriangledown_symbol; else if (!strcmp(s, "filledtriangleleft")) return gr_filledtriangleleft_symbol; else if (!strcmp(s, "filledhalfmoonup")) return gr_filledhalfmoonup_symbol; else if (!strcmp(s, "filledhalfmoondown")) return gr_filledhalfmoondown_symbol; else return gr_unknown_symbol; } // draw circle with radius .r_cm. at .x_cm. .y_cm. bool draw_circleCmd() { double r_cm, x_cm, y_cm; double old_size = gr_currentsymbolsize_cm(); switch (_nword) { case 8: if (!getdnum(_word[4], &r_cm)) return false; if (!getdnum(_word[6], &x_cm)) return false; if (!getdnum(_word[7], &y_cm)) return false; gr_setsymbolsize_cm(2 * r_cm); set_ps_color('p'); set_line_width_symbol(); gr_drawsymbol(x_cm, y_cm, gr_circ_symbol); gr_setsymbolsize_cm(old_size); return true; default: return false; } } // `draw contour' `draw contour .value. [unlabelled|{labelled "\label"}]' // // `draw contour .min. .max. .inc. [.inc_unlabelled.] [unlabelled]' bool draw_contourCmd() { extern bool _contour_label_rotated; // <-> startup.c set.c extern bool _contour_label_whiteunder; // <-> startup.c set.c double min, inc, inc_unlabelled, max; double dlevel, dmin, dinc, dinc_unlabelled = 0.0, dmax; double contour_space_first = _contour_space_first; double contour_space_later = _contour_space_later; double contour_minlength = _contour_minlength; double xsize = XSIZE_DEFAULT; double ysize = YSIZE_DEFAULT; std::string user_label; int nword = _nword; bool user_gave_label = false; // only for .value. format bool have_unlabelled_and_labelled = false; bool labelled = true; int contour, numcontours = 0; // Check that data exist. if (!grid_exists()) return false; if (!scales_defined()) { #if 0 // Fix SF bug #129856 (I hope!) no_scales_error(); return false; #else create_x_scale(); create_y_scale(); #endif } // Decode command labelled = true; if (!strcmp(_word[nword - 1], "unlabelled")) { labelled = false; nword--; } if (nword == 2) { // `draw contour' -- Gri will pick levels int nlevels; min = _f_min; // matrix limits max = _f_max; // matrix limits gr_scale125((double) min, (double) max, 5, &dmin, &dmax, &nlevels); dinc = (dmax - dmin) / nlevels; } else if (nword == 3) { // `draw contour .value.' double level; if (!getdnum(_word[2], &level)) return false; dmin = level; dmax = level; dinc = level; numcontours = 1; } else if (nword == 5 && !strcmp(_word[3], "labelled")) { // `draw contour .value.' labelled "label" double level; if (!getdnum(_word[2], &level)) return false; user_gave_label = true; // label is _word[4] user_label.assign(_word[4]); un_double_quote(user_label); dmin = level; dmax = level; dinc = level; numcontours = 1; } else if (nword == 5) { // `draw contour .min. .max. .inc.' if (!getdnum(_word[2], &min) || !getdnum(_word[3], &max) || !getdnum(_word[4], &inc)) return false; if (inc > 0.0) { if ((min + inc) > max) { demonstrate_command_usage(); err("Increment has wrong sign to go between the stated min and max"); return false; } dmin = min; dmax = max; dinc = inc; } else if (inc < 0.0) { if ((min + inc) < max) { demonstrate_command_usage(); err("Increment has wrong sign to go between the stated min and max"); return false; } dmin = max; dmax = min; dinc = -inc; } else { err("Cannot use increment of zero."); return false; } if (!gr_multiple(dmax - dmin, dinc, 0.001 * dinc)) { demonstrate_command_usage(); err("Require (.max. - .min.) a multiple of .inc. to within 0.1%"); return false; } } else if (nword == 6) { // `draw contour .min. .max. .inc. .inc_unlabelled.' if (!getdnum(_word[2], &min) || !getdnum(_word[3], &max) || !getdnum(_word[4], &inc) || !getdnum(_word[5], &inc_unlabelled)) return false; if ((min + inc) > max) { demonstrate_command_usage(); err("Require (.min. + .inc.) <= .max."); return false; } // Ensure same sign for unlabelled increment if (inc < 0.0) inc_unlabelled = -fabs(inc_unlabelled); else inc_unlabelled = fabs(inc_unlabelled); dmin = min; dmax = max; dinc = inc; dinc_unlabelled = inc_unlabelled; if (!gr_multiple(dmax - dmin, dinc, 0.001 * dinc)) { demonstrate_command_usage(); err("Require (.max. - .min.) a multiple of .inc. to within 0.1%"); return false; } if (!gr_multiple(dmax - dmin, dinc_unlabelled, 0.001 * dinc_unlabelled)) { demonstrate_command_usage(); err("Require (.max. - .min.) a multiple of .inc_unlabelled. to within 0.1%"); return false; } have_unlabelled_and_labelled = true; } else { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (dinc == 0.0 && dmin != 0.0 && dmax != 0.0) { demonstrate_command_usage(); err("`draw contour .min. .max. 0' not allowed"); return false; } // Do contour(s) if (!get_var("..xsize..", &xsize)) warning("Don't know value of ..xsize.. so using XSIZE_DEFAULT"); if (!get_var("..ysize..", &ysize)) warning("Don't know value of ..ysize.. so using YSIZE_DEFAULT"); set_environment(); set_line_width_curve(); // If numcontours not already set, try to figure it out. if (!numcontours) { if (have_unlabelled_and_labelled) { if (dinc_unlabelled == 0.0 && dmin == 0.0 && dmax == 0.0) numcontours = 1; else numcontours = 1 + (int) fabs(0.5 + (dmax - dmin) / dinc_unlabelled); } else { if (dinc == dmin && dmax == dmin) numcontours = 1; else numcontours = 1 + (int) fabs(0.5 + (dmax - dmin) / dinc); } } dlevel = dmax; bool warned = false; GriTimer t; GriString label; for (contour = 0; contour < numcontours; contour++) { if (_chatty > 1) { sprintf(_grTempString, "`draw contour' drawing for value =%g\n", dlevel); gr_textput(_grTempString); } if (labelled && (numcontours == 1 || gr_multiple(dmax - dlevel, dinc, 0.001 * dinc))) { if (fabs(dlevel) <= 1.0e-6 * fabs(dinc)) { label.fromSTR("0"); } else { char tmp[1000]; sprintf(tmp, _contourFmt.c_str(), dlevel); label.fromSTR(tmp); } // Figure distance spacing for contours. Use stored values if // the space-later is > 0; otherwise do old default if (_contour_space_later < 0.0) { contour_space_first = 1.0; contour_space_later = labelled ? 0.5 * (xsize + ysize) : 0.0; } else { contour_space_first = _contour_space_first; contour_space_later = _contour_space_later; } } else { label.fromSTR(""); contour_space_first = 0.0; contour_space_later = 0.0; } if (user_gave_label) { if (_f_min <= dlevel && dlevel <= _f_max) { gr_contour(_xmatrix, _ymatrix, _f_xy, _legit_xy, _num_xmatrix_data, _num_ymatrix_data, dlevel, user_label.c_str(), _contour_label_rotated, _contour_label_whiteunder, _contour_space_centered, _griState.color_line(), _griState.color_text(), contour_minlength, contour_space_first, contour_space_later, NULL); } } else { if (_f_min <= dlevel && dlevel <= _f_max) { gr_contour(_xmatrix, _ymatrix, _f_xy, _legit_xy, _num_xmatrix_data, _num_ymatrix_data, dlevel, label.getValue(), _contour_label_rotated, _contour_label_whiteunder, _contour_space_centered, _griState.color_line(), _griState.color_text(), contour_minlength, contour_space_first, contour_space_later, NULL); } } if (have_unlabelled_and_labelled) dlevel -= dinc_unlabelled; else dlevel -= dinc; if (!warned) { double frac = (1.0 + contour) / numcontours; warned = warn_if_slow(&t, frac, "draw contour"); } } _drawingstarted = true; draw_axes_if_needed(); return true; } // draw arc [filled] .xc_cm. .yc_cm. .r_cm. .angle_1. .angle_2. bool draw_arcCmd(void) { bool filled = false; int start_word = 2; if (_nword == 8) { if (word_is(2, "filled")) { filled = true; start_word = 3; } else { err("`draw arc' expecting `filled' but got `\\", _word[2], "'.", "\\"); return false; } } else if (_nword != 7) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } double xc, yc, r, angle1, angle2; if (!getdnum(_word[start_word], &xc)) { READ_WORD_ERROR(".xc_cm."); demonstrate_command_usage(); return false; } if (!getdnum(_word[start_word + 1], &yc)) { READ_WORD_ERROR(".yc_cm."); demonstrate_command_usage(); return false; } if (!getdnum(_word[start_word + 2], &r)) { READ_WORD_ERROR(".r_cm."); demonstrate_command_usage(); return false; } if (!getdnum(_word[start_word + 3], &angle1)) { READ_WORD_ERROR(".angle_1."); demonstrate_command_usage(); return false; } if (!getdnum(_word[start_word + 4], &angle2)) { READ_WORD_ERROR(".angle_2."); demonstrate_command_usage(); return false; } gr_draw_arc_cm(filled, xc, yc, r, angle1, angle2); _drawingstarted = true; return true; } bool draw_arrow_from_toCmd() { double halfwidth = ARROWSIZE_DEFAULT; double x0, y0, x1, y1; if (2 == get_cmd_values(_word, _nword, "from", 2, _dstack)) { x0 = _dstack[0]; y0 = _dstack[1]; if (2 == get_cmd_values(_word, _nword, "to", 2, _dstack)) { x1 = _dstack[0]; y1 = _dstack[1]; } else { READ_WORD_ERROR("(.x1., .y1.)"); demonstrate_command_usage(); return false; } } else { READ_WORD_ERROR("(.x0., .y0.)"); demonstrate_command_usage(); return false; } set_environment(); set_line_width_curve(); // Convert to cm units if given in user units. if (strcmp(_word[_nword - 1], "cm")) { double x_cm, y_cm; if (!scales_defined()) { #if 0 // Fix SF bug #129856 (I hope!) no_scales_error(); return false; #else create_x_scale(); create_y_scale(); #endif } gr_usertocm(x0, y0, &x_cm, &y_cm); x0 = x_cm; y0 = y_cm; gr_usertocm(x1, y1, &x_cm, &y_cm); x1 = x_cm; y1 = y_cm; } if (!get_var("..arrowsize..", &halfwidth)) warning("Don't know ..arrowsize.. so using default _ARROWSIZE_PT_DEFAULT"); switch (_arrow_type) { case 0: gr_drawarrow_cm(x0, y0, x1, y1, halfwidth); break; case 1: gr_drawarrow2_cm(x0, y0, x1, y1, halfwidth); break; case 2: gr_drawarrow3_cm(x0, y0, x1, y1, halfwidth); break; } _drawingstarted = true; return true; } bool draw_arrowsCmd() { if (_nword != 2) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (!_columns_exist || _colU.size() <= 0) { warning("`draw arrows' noticed that no column data exist."); return true; } if (!scales_defined()) { #if 0 // Fix SF bug #129856 (I hope!) no_scales_error(); return false; #else create_x_scale(); create_y_scale(); #endif } if (!_uscale_exists) { demonstrate_command_usage(); err("First `set u scale'"); return false; } if (!_vscale_exists) { demonstrate_command_usage(); err("First `set v scale'"); return false; } set_environment(); set_line_width_curve(); double *xp = _colX.begin(); double *yp = _colY.begin(); double *up = _colU.begin(); double *vp = _colV.begin(); double halfwidth = ARROWSIZE_DEFAULT; if (!get_var("..arrowsize..", &halfwidth)) warning("Don't know ..arrowsize.. so using default _ARROWSIZE_PT_DEFAULT"); unsigned int i_max = _colX.size(); for (unsigned int i = 0; i < i_max; i++) { if (!gr_missingx((double) *xp) && !gr_missingy((double) *yp) && inside_box((double) *xp, (double) *yp) && !gr_missing((double) *up) && !gr_missing((double) *up) && (*up != 0.0 || *vp != 0.0)) { double x0, y0, x1, y1; gr_usertocm(*xp, *yp, &x0, &y0); x1 = x0 + *up * _cm_per_u; y1 = y0 + *vp * _cm_per_v; switch (_arrow_type) { case 0: gr_drawarrow_cm(x0, y0, x1, y1, halfwidth); break; case 1: gr_drawarrow2_cm(x0, y0, x1, y1, halfwidth); break; case 2: gr_drawarrow3_cm(x0, y0, x1, y1, halfwidth); break; } } xp++; yp++; up++; vp++; } _drawingstarted = true; draw_axes_if_needed(); return true; } bool draw_axesCmd() { double tmp; int type = 0; switch (_nword) { case 2: type = _axesStyle; draw_axes(type, 0.0, (gr_axis_properties) 0, true); return true; case 3: if (!strcmp(_word[2], "none")) { _drawingstarted = true; _need_x_axis = false; _need_y_axis = false; return true; } else if (!strcmp(_word[2], "frame")) { draw_axes(2, 0.0, (gr_axis_properties) 0, true); return true; } else if (!getdnum(_word[2], &tmp)) { demonstrate_command_usage(); err("`draw axes ?what?"); return false; } type = (int) fabs(0.5 + (double) tmp); draw_axes(type, 0.0, (gr_axis_properties) 0, true); return true; default: NUMBER_WORDS_ERROR; demonstrate_command_usage(); return false; } } void draw_outline_frame() { int old_line_cap = _griState.line_cap(); _griState.set_line_cap(0); GriPath p(5); p.push_back(_xleft, _ytop, 'm'); p.push_back(_xright, _ytop, 'l'); p.push_back(_xright, _ybottom, 'l'); p.push_back(_xleft, _ybottom, 'l'); p.push_back(_xleft, _ytop, 'l'); p.stroke(units_user, _griState.linewidth_axis()); _griState.set_line_cap(old_line_cap); } bool draw_axes(int type, double loc, gr_axis_properties side, bool allow_offset) { double tic_direction = 0; // tics extend out by default double tic_size = TICSIZE_DEFAULT; double ysize = YSIZE_DEFAULT; double ymargin = YMARGIN_DEFAULT; double xsize = XSIZE_DEFAULT; double xmargin = XMARGIN_DEFAULT; double fontsize = FONTSIZE_PT_DEFAULT; double oldFontsize_pt = gr_currentfontsize_pt(); gr_fontID old_font = gr_currentfont(); double tmpx, tmpx_cm, tmpy, tmpy_cm; double axes_offset; if (!scales_defined()) { #if 0 // Fix SF bug #129856 (I hope!) no_scales_error(); return false; #else create_x_scale(); create_y_scale(); #endif } if (allow_offset) axes_offset = _axes_offset; else axes_offset = 0.0; group_start("axis_frame"); gr_setxtransform(_xtype); gr_setytransform(_ytype); gr_setxlabel(_colX.getName()); gr_setylabel(_colY.getName()); gr_setxnumberformat(_xFmt.c_str()); gr_setynumberformat(_yFmt.c_str()); gr_setxsubdivisions(_xsubdiv); gr_setysubdivisions(_ysubdiv); if (!get_var("..tic_direction..", &tic_direction)) warning("(set_environment) ..tic_direction.. undefined so using OUT"); gr_setticdirection(int(floor(0.5 + tic_direction)) ? true : false); if (!get_var("..tic_size..", &tic_size)) warning("(set_environment) ..tic_size.. undefined so using default (0.2cm)"); gr_setticsize_cm(tic_size); if (!get_var("..fontsize..", &fontsize)) warning("(draw_axes) ..fontsize.. undefined so using 12"); gr_setfontsize_pt(fontsize); gr_setfont(old_font); if (!get_var("..xmargin..", &xmargin)) warning("draw_axes: don't know ..xmargin.. so using default."); if (!get_var("..xsize..", &xsize)) warning("draw_axes: don't know ..xsize.. so using default."); if (!get_var("..ymargin..", &ymargin)) warning("draw_axes: don't know ..ymargin.. so using default."); if (!get_var("..ysize..", &ysize)) warning("draw_axes: don't know ..ysize.. so using default."); set_x_scale(); set_y_scale(); // Set to proper linewidth, and turn dashing off set_line_width_axis(); std::vector old_dash; for (unsigned int i = 0; i < _dash.size(); i++) old_dash.push_back(_dash[i]); std::vector dash; _dash.erase(_dash.begin(), _dash.end()); switch (type) { case 0: // full axes if (_xatbottom) { gr_usertocm(_xleft, _ybottom, &tmpx_cm, &tmpy_cm); gr_cmtouser(tmpx_cm, tmpy_cm - axes_offset, &tmpx, &tmpy); gr_drawxaxis(tmpy, _xleft, _xinc, _xright, _x_labelling, gr_axis_BOTTOM); gr_setfontsize_pt(0.0); gr_usertocm(_xleft, _ytop, &tmpx_cm, &tmpy_cm); gr_cmtouser(tmpx_cm, tmpy_cm + axes_offset, &tmpx, &tmpy); gr_drawxaxis(tmpy, _xleft, _xinc, _xright, _x_labelling, gr_axis_TOP); gr_setfontsize_pt(fontsize); } else { gr_setfontsize_pt(0.0); gr_usertocm(_xleft, _ybottom, &tmpx_cm, &tmpy_cm); gr_cmtouser(tmpx_cm, tmpy_cm - axes_offset, &tmpx, &tmpy); gr_drawxaxis(tmpy, _xleft, _xinc, _xright, _x_labelling, gr_axis_BOTTOM); gr_setfontsize_pt(fontsize); gr_usertocm(_xleft, _ytop, &tmpx_cm, &tmpy_cm); gr_cmtouser(tmpx_cm, tmpy_cm + axes_offset, &tmpx, &tmpy); gr_drawxaxis(tmpy, _xleft, _xinc, _xright, _x_labelling, gr_axis_TOP); } if (_yatleft == true) { gr_usertocm(_xleft, _ybottom, &tmpx_cm, &tmpy_cm); gr_cmtouser(tmpx_cm - axes_offset, tmpy_cm, &tmpx, &tmpy); gr_drawyaxis(tmpx, _ybottom, _yinc, _ytop, _y_labelling, gr_axis_LEFT); gr_setfontsize_pt(0.0); gr_usertocm(_xright, _ybottom, &tmpx_cm, &tmpy_cm); gr_cmtouser(tmpx_cm + axes_offset, tmpy_cm, &tmpx, &tmpy); gr_drawyaxis(tmpx, _ybottom, _yinc, _ytop, _y_labelling, gr_axis_RIGHT); gr_setfontsize_pt(fontsize); } else { gr_setfontsize_pt(0.0); gr_usertocm(_xleft, _ybottom, &tmpx_cm, &tmpy_cm); gr_cmtouser(tmpx_cm - axes_offset, tmpy_cm, &tmpx, &tmpy); gr_drawyaxis(tmpx, _ybottom, _yinc, _ytop, _y_labelling, gr_axis_LEFT); gr_setfontsize_pt(fontsize); gr_usertocm(_xright, _ybottom, &tmpx_cm, &tmpy_cm); gr_cmtouser(tmpx_cm + axes_offset, tmpy_cm, &tmpx, &tmpy); gr_drawyaxis(tmpx, _ybottom, _yinc, _ytop, _y_labelling, gr_axis_RIGHT); } _need_x_axis = false; _need_y_axis = false; if ((ymargin + ysize) > _top_of_plot) _top_of_plot = ymargin + ysize; break; case 1: // axes at left and bottom + simple frame gr_usertocm(_xleft, _ybottom, &tmpx_cm, &tmpy_cm); gr_cmtouser(tmpx_cm, tmpy_cm - axes_offset, &tmpx, &tmpy); gr_drawxaxis(tmpy, _xleft, _xinc, _xright, _x_labelling, gr_axis_BOTTOM); gr_usertocm(_xleft, _ybottom, &tmpx_cm, &tmpy_cm); gr_cmtouser(tmpx_cm - axes_offset, tmpy_cm, &tmpx, &tmpy); gr_drawyaxis(tmpx, _ybottom, _yinc, _ytop, _y_labelling, gr_axis_LEFT); draw_outline_frame(); _need_x_axis = false; _need_y_axis = false; if ((ymargin + ysize) > _top_of_plot) _top_of_plot = ymargin + ysize; break; case 2: // simple frame, no axes draw_outline_frame(); _need_x_axis = false; _need_y_axis = false; if ((ymargin + ysize) > _top_of_plot) _top_of_plot = ymargin + ysize; break; case 3: // x axis only -- don't do frame if offset if (side == gr_axis_BOTTOM) { gr_usertocm(_xleft, loc, &tmpx_cm, &tmpy_cm); gr_cmtouser(tmpx_cm, tmpy_cm - axes_offset, &tmpx, &tmpy); gr_drawxaxis(tmpy, _xleft, _xinc, _xright, _x_labelling, side); } else { gr_usertocm(_xleft, loc, &tmpx_cm, &tmpy_cm); gr_cmtouser(tmpx_cm, tmpy_cm + axes_offset, &tmpx, &tmpy); gr_drawxaxis(tmpy, _xleft, _xinc, _xright, _x_labelling, side); } _need_x_axis = false; { // add space for tics (maybe), space, number, space, label, and // then some inter-axis space double x_cm, y_cm; extern double _grTicSize_cm; extern bool _grTicsPointIn; gr_usertocm(_xleft, loc, &x_cm, &y_cm); y_cm += _grTicsPointIn == true ? 0.0 : _grTicSize_cm; y_cm += 5.0 * gr_currentCapHeight_cm(); if (y_cm > _top_of_plot) _top_of_plot = y_cm; } break; case 4: // y axis only -- don't do frame if offset if (side == gr_axis_BOTTOM) { gr_usertocm(loc, _ybottom, &tmpx_cm, &tmpy_cm); gr_cmtouser(tmpx_cm - axes_offset, tmpy_cm, &tmpx, &tmpy); gr_drawyaxis(tmpx, _ybottom, _yinc, _ytop, _y_labelling, side); } else { gr_usertocm(loc, _ybottom, &tmpx_cm, &tmpy_cm); gr_cmtouser(tmpx_cm + axes_offset, tmpy_cm, &tmpx, &tmpy); gr_drawyaxis(tmpx, _ybottom, _yinc, _ytop, _y_labelling, side); } _need_y_axis = false; { // add space double x_cm, y_cm; gr_usertocm(loc, _ytop, &x_cm, &y_cm); if (y_cm > _top_of_plot) _top_of_plot = y_cm; } break; default: err("unknown axis type"); group_end(); return false; } gr_setfontsize_pt(oldFontsize_pt); _drawingstarted = true; draw_axes_if_needed(); for (unsigned int i = 0; i < old_dash.size(); i++) _dash.push_back(old_dash[i]); group_end(); return true; } bool draw_curveCmd() { //printf("%s:%d draw_curveCmd()...\n",__FILE__,__LINE__); if (!_columns_exist) { warning("`draw curve' noticed that no column data exist."); return true; } if (!scales_defined()) { #if 0 // Fix SF bug #129856 (I hope!) no_scales_error(); return false; #else create_x_scale(); create_y_scale(); #endif } bool filled = false; if (_nword == 6 && !strcmp(_word[2], "filled") && !strcmp(_word[3], "to")) { double tmp; if (!getdnum(_word[4], &tmp)) { demonstrate_command_usage(); err("Can't read value to fill to."); return false; } if (!strcmp(_word[5], "x")) { return draw_curve_filled_to_valueCmd(false, tmp); } else if (!strcmp(_word[5], "y")) { return draw_curve_filled_to_valueCmd(true, tmp); } else { demonstrate_command_usage(); err("Last word must be \"x\" or \"y\"."); return false; } } else if (_nword == 3 && !strcmp(_word[2], "filled")) { filled = true; } else if (_nword != 2) { NUMBER_WORDS_ERROR; demonstrate_command_usage(); return false; } double *xp = _colX.begin(); double *yp = _colY.begin(); double lastx = gr_currentmissingvalue(); double lasty = gr_currentmissingvalue(); bool first = true, last_OK = true; extern FILE *_grSVG; unsigned int i_max = _colX.size(); if (_output_file_type == svg) { fprintf(_grSVG, " \n", _cmdLine); } set_environment(); set_line_width_curve(); GriPath path(i_max); for (unsigned int i = 0; i < i_max; i++) { //printf("i %d x %f y %f\n", i, *xp, *yp); if (!gr_missingx((double) *xp) && !gr_missingy((double) *yp) && inside_box((double) *xp, (double) *yp)) { if (first) { path.push_back(*xp, *yp, 'm'); first = false; } else { if (last_OK) { path.push_back(*xp, *yp, 'l'); lastx = *xp; lasty = *yp; } else { path.push_back(*xp, *yp, 'm'); } } last_OK = true; } else { // Not ok. last_OK = false; } xp++; yp++; } if (filled) path.fill(units_user); else path.stroke(units_user); PUT_VAR("..xlast..", lastx); PUT_VAR("..ylast..", lasty); _drawingstarted = true; draw_axes_if_needed(); if (_output_file_type == svg) { fprintf(_grSVG, " \n", _cmdLine); } return true; } // `draw curve [filled [to {.y. y}|{.x. x}]]' bool draw_curve_filled_to_valueCmd(bool to_y, double value) { double *xp = _colX.begin(); double *yp = _colY.begin(); double lastx = 0.0, lasty = 0.0; // last good; assignment calms compiler bool path_exists = false; bool last_OK = false; if (!_columns_exist) { warning("`draw curve filled to' noticed that no column data exist."); return true; } if (!scales_defined()) { #if 0 // Fix SF bug #129856 (I hope!) no_scales_error(); return false; #else create_x_scale(); create_y_scale(); #endif } GriPath p; set_environment(); unsigned int i_max = _colX.size(); for (unsigned i = 0; i < i_max; i++) { if (!gr_missingx((double) *xp) && !gr_missingy((double) *yp) && inside_box((double) *xp, (double) *yp)) { // This point is not missing, and it's in the box. if (!last_OK) { // Last point was not OK (or this is the first point), so // start a new path, beginning at y=value so the fill will // work correctly. path_exists = true; if (to_y) p.push_back(*xp, value, 'm'); else p.push_back(value, *yp, 'm'); } p.push_back(*xp, *yp, 'l'); lastx = *xp; lasty = *yp; last_OK = true; } else { // This point is either missing or not in the box. if (last_OK) { // Must have just finished a run of good data. Continue the // path to y=value, then fill it. if (to_y) p.push_back(lastx, value, 'l'); else p.push_back(value, lasty, 'l'); p.fill(units_user); path_exists = false; } // Last was not OK. Nothing to do but wait. last_OK = false; } xp++; yp++; } if (path_exists) { if (to_y) p.push_back(lastx, value, 'l'); else p.push_back(value, lasty, 'l'); p.fill(units_user); } PUT_VAR("..lastx..", *(xp - 1)); PUT_VAR("..lasty..", *(yp - 1)); draw_axes_if_needed(); _drawingstarted = true; return true; } // CHANGE: before 2.052, put circles at missing points bool draw_gridCmd() { if (_nword != 2) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (!_grid_exists) { err("First create the grid"); return false; } if (!_xgrid_exists || _num_xmatrix_data < 1) { err("First `read grid x' or `set x grid'"); return false; } if (!_ygrid_exists || _num_ymatrix_data < 1) { err("First `read grid y' or `set y grid'"); return false; } set_environment(); set_line_width_symbol(); set_ps_color('p'); unsigned j = _num_ymatrix_data - 1; do { double xcm, ycm; for (unsigned int i = 0; i < _num_xmatrix_data; i++) { if (inside_box(_xmatrix[i], _ymatrix[j])) { if (_legit_xy(i,j) == true) { gr_usertocm(_xmatrix[i], _ymatrix[j], &xcm, &ycm); gr_drawsymbol(xcm, ycm, gr_plus_symbol); } } } } while (j-- != 0); return true; } // `Draw isopycnal [unlabelled] .density. [.P_sigma. [.P_theta.]]' bool draw_isopycnalCmd() { if (!scales_defined()) { #if 0 // Fix SF bug #129856 (I hope!) no_scales_error(); return false; #else create_x_scale(); create_y_scale(); #endif } bool labelled = true; double density, P_sigma = 0.0, P_theta = 0.0; int start = 2; if (!strcmp(_word[start], "unlabelled")) { labelled = false; start++; } switch (_nword - start) { case 1: // draw isopycnal [unlabelled] .density. if (!getdnum(_word[start], &density)) { READ_WORD_ERROR(".density."); demonstrate_command_usage(); return false; } break; case 2: // draw isopycnal [unlabelled] .density. .P_sigma. if (!getdnum(_word[start], &density)) { READ_WORD_ERROR(".density."); demonstrate_command_usage(); return false; } if (!getdnum(_word[1 + start], &P_sigma)) { READ_WORD_ERROR(".P_sigma."); demonstrate_command_usage(); return false; } break; case 3: // draw isopycnal [unlabelled] .density. .P_sigma. if (!getdnum(_word[start], &density)) { READ_WORD_ERROR(".density."); demonstrate_command_usage(); return false; } if (!getdnum(_word[1 + start], &P_sigma)) { READ_WORD_ERROR(".P_sigma."); demonstrate_command_usage(); return false; } if (!getdnum(_word[2 + start], &P_theta)) { READ_WORD_ERROR(".P_theta."); demonstrate_command_usage(); return false; } break; default: demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (density > 100.0) density -= 1000; // make in sigma-ish unit double Smin = _xleft, Smax = _xright; if (Smax <= Smin) { err("X-axis must have salinity, increasing to right."); demonstrate_command_usage(); return false; } set_environment(); // for scales bool T_ito_rho_S_p(double *T, double S1, double S2, double dS,double Terr); GriPath iso; const double T_tolerance = 0.0001; // stop when this close bool hit_top = false; // (if false, hit RHS) bool first = true; double Tlast = -999; double S, T = -999.0; // Next few lines determine how fine a mesh to use for S, // since a fine mesh is needed if the lines are nearly // vertical, but a coarser mesh is more efficient. double d_rho_dS = (rho(_xleft, _ybottom, 0.0) - rho(_xright, _ybottom, 0.0)) / (_xright - _xleft); double d_rho_dT = (rho(_xleft, _ytop, 0.0) - rho(_xleft, _ybottom, 0.0)) / (_ytop - _ybottom); double slope_on_page = d_rho_dS*(_xright-_xleft)/(d_rho_dT*(_ytop-_ybottom)); double dS; // BUG: the S increments are just a guess that seems ok now. if (slope_on_page > 5.0) dS = (Smax - Smin) / 500.0; else dS = (Smax - Smin) / 100.0; //printf("rho_x %f rho_y %f slope %f\n", d_rho_dS, d_rho_dT, d_rho_dS*(_xright-_xleft)/(d_rho_dT*(_ytop-_ybottom))); double S_cm, T_cm, S_cm_last = 0, T_cm_last = 0; std::vector S_label_cm; // where to put labels std::vector T_label_cm; double cum_dist = 0.0; extern double _contour_space_first, _contour_space_later; double contour_space_first, contour_space_later; if (_contour_space_later < 0.0) { double xsize = XSIZE_DEFAULT; double ysize = YSIZE_DEFAULT; if (!get_var("..xsize..", &xsize)) warning("Don't know value of ..xsize.. so using XSIZE_DEFAULT"); if (!get_var("..ysize..", &ysize)) warning("Don't know value of ..ysize.. so using YSIZE_DEFAULT"); contour_space_first = 1.0; contour_space_later = labelled ? 0.5 * (xsize + ysize) : 0.0; } else { contour_space_first = _contour_space_first; contour_space_later = _contour_space_later; } double contour_spacing = contour_space_first; for (S = Smin; S <= Smax + dS / 10.0; S += dS) { //printf("should calc for S=%f\n", S); T = -999.0; // the T where isopycnal hits double T1 = -2.0, T2 = 40; // must be between these double dev1 = rho(S, pot_temp(S, T1, P_theta, P_sigma), P_sigma) - 1000.0 - density; double dev2 = rho(S, pot_temp(S, T2, P_theta, P_sigma), P_sigma) - 1000.0 - density; if (dev1 * dev2 > 0.0) continue; // not bracketted at this salinity //printf("\n"); while (true) { //printf("T= %.4f T1= %.4f T2= %.4f\n", T,T1,T2); if (T2 - T1 < T_tolerance) break; T = (T1 + T2) / 2.0; // midpoint double dev = rho(S, pot_temp(S, T, P_theta, P_sigma), P_sigma) - 1000.0 - density; if (dev * dev1 < 0.0) { T2 = T; dev2 = dev; } else if (dev * dev2 < 0.0) { T1 = T; dev1 = dev; } else { break; // dev=0, so must have hit it exactly } } if (T < _ybottom) { Tlast = T; continue; } if (Tlast == -999.0 && _ytop < T) { //printf("S=%f T=%f -- no intersection\n",S,T); break; // didn't intersect regions } // Now know that _ybottom < T if (Tlast < _ybottom) { // interpolate to bottom side //printf("-- S,T %f %f ",S,T); if (Tlast != -999.0) { S = (S - dS) + dS * (_ybottom - Tlast) / (T - Tlast); T = _ybottom; } //printf("--> %f %f\n",S,T); gr_usertocm(S, T, &S_cm, &T_cm); if (!first) cum_dist += sqrt((S_cm - S_cm_last) * (S_cm - S_cm_last) + (T_cm - T_cm_last) * (T_cm - T_cm_last)); iso.push_back(S_cm, T_cm, first ? 'm' : 'l'); S_cm_last = S_cm; T_cm_last = T_cm; first = false; } else if (T > _ytop) { // interpolate S to intersection //printf("-- S,T %f %f ",S,T); if (Tlast != -999.0) { S = (S - dS) + dS * (_ytop - Tlast) / (T - Tlast); T = _ytop; } //printf("--> %f %f\n",S,T); gr_usertocm(S, T, &S_cm, &T_cm); if (!first) cum_dist += sqrt((S_cm - S_cm_last) * (S_cm - S_cm_last) + (T_cm - T_cm_last) * (T_cm - T_cm_last)); iso.push_back(S_cm, T_cm, first ? 'm' : 'l'); S_cm_last = S_cm; T_cm_last = T_cm; first = false; hit_top = true; break; } gr_usertocm(S, T, &S_cm, &T_cm); if (!first) { cum_dist += sqrt((S_cm - S_cm_last) * (S_cm - S_cm_last) + (T_cm - T_cm_last) * (T_cm - T_cm_last)); if (cum_dist > contour_spacing) { S_label_cm.push_back(S_cm); T_label_cm.push_back(T_cm); contour_spacing = contour_space_later; cum_dist = 0.0; // start over } } iso.push_back(S_cm, T_cm, first ? 'm' : 'l'); S_cm_last = S_cm; T_cm_last = T_cm; first = false; //printf(" -- S,T,cumdist = %.4f %.4f %.1f\n", S, T,cum_dist); Tlast = T; } if (iso.size() > 0) { set_line_width_curve(); iso.stroke(units_cm); if (labelled) { char clabel[20]; sprintf(clabel, _contourFmt.c_str(), density); GriString label(clabel); #if 0 // old way -- along sides double xcm, ycm; double tic_direction = 0; get_var("..tic_direction..", &tic_direction); double tic_size = TICSIZE_DEFAULT; get_var("..tic_size..", &tic_size); set_environment(); gr_usertocm(S, T, &xcm, &ycm); set_ps_color('t'); if (hit_top) { ycm += 2.0 * tic_size; // put above label.draw(xcm, ycm, TEXT_CENTERED, 0.0); } else { xcm += 2.0 * tic_size; // put to right ycm -= gr_currentfontsize_pt() / PT_PER_CM / 2; label.draw(xcm, ycm, TEXT_LJUST, 0.0); } #else set_ps_color('t'); GriColor white; white.setRGB(1.0, 1.0, 1.0); for (unsigned int ii = 0; ii < S_label_cm.size(); ii++) { gr_show_in_box(label, _griState.color_text(), white, S_label_cm[ii], T_label_cm[ii], 0.0); } #endif } _drawingstarted = true; draw_axes_if_needed(); } return true; } // `draw image histogram [box .xleft_cm. .ybottom_cm. .xright_cm. .ytop_cm.]' bool draw_image_histogramCmd() { #if 1 enum y_axis_type {log, percentage}; y_axis_type the_y_axis_type = log; #endif int i; double x_ll_cm = XMARGIN_DEFAULT, y_ll_cm, x_ur_cm, y_ur_cm; double dx = XSIZE_DEFAULT, dy; double xval, dxval, yMin = 1.e-4, yMax = 1.0; double left, right; int num; if (!scales_defined()) { #if 0 // Fix SF bug #129856 (I hope!) no_scales_error(); return false; #else create_x_scale(); create_y_scale(); #endif } if (!_image.storage_exists) { err("First `read image' or `convert grid to image'"); return false; } if (!_imageTransform_exists) { err("First `set image grayscale'"); return false; } #if 1 // The optional last word may indicate the type of y axis. int nword = _nword; if (strEQ(_word[_nword - 1], "percentage")) { the_y_axis_type = percentage; nword--; } else if (strEQ(_word[_nword - 1], "log")) { the_y_axis_type = log; nword--; } #endif switch (nword) { case 3: // `draw image histogram' if (!get_var("..xmargin..", &x_ll_cm)) warning("Don't know value of ..xmargin.. so using XMARGIN_DEFAULT"); y_ll_cm = _top_of_plot + 1.5; if (!get_var("..xsize..", &dx)) warning("Don't know value of ..xsize.. so using XSIZE_DEFAULT"); dy = 2.5; break; case 7: err("Sorry, but the old `draw histogram .xleft. .ybottom. .dx. .dy.' is\n\ now `draw image histogram [box .xleft_cm. .ybottom_cm. .xright_cm. .ytop_cm.]'.\n\ Note the extra word `box', and the new meaning of the last 2 parameters."); return false; case 8: // `draw image histogram [box .xleft_cm. .ybottom_cm. .xright_cm. .ytop_cm.]' if (4 == get_cmd_values(_word, nword, "box", 4, _dstack)) { x_ll_cm = _dstack[0]; y_ll_cm = _dstack[1]; x_ur_cm = _dstack[2]; y_ur_cm = _dstack[3]; } else { err("Cannot read the `box ...' part of command"); return false; } dx = x_ur_cm - x_ll_cm; dy = y_ur_cm - y_ll_cm; break; default: demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } calculate_image_histogram(); set_environment(); // Draw the histogram, using 125 scaling of x axis #if 1 if (the_y_axis_type == log) { yMin = 1.0e-4; yMax = 1.0; gr_setytransform(gr_axis_LOG); gr_setysubdivisions(1); gr_setxsubdivisions(1); gr_setxlabel(""); gr_setylabel(""); gr_scale125((double) _image0, (double) _image255, 4, &left, &right, &num); gr_setxscale((double) x_ll_cm, (double) x_ll_cm + dx, left, right); gr_setyscale((double) y_ll_cm, (double) y_ll_cm + dy, yMin, yMax); gr_drawxaxis(yMin, left, (right - left) / num, right, left, gr_axis_BOTTOM); gr_drawyaxis((double) left, yMin, 1., yMax, yMin, gr_axis_LEFT); GriPath p; p.push_back(left, yMin, 'm'); p.push_back(left, yMax, 'l'); p.push_back(right, yMax, 'l'); p.push_back(right, yMin, 'l'); xval = _image0; dxval = (_image255 - _image0) / 255.0; p.push_back(_image0, yMin, 'm'); gr_setytransform(gr_axis_LOG); gr_setysubdivisions(1); for (i = 0; i < 256; i++) { p.push_back(xval, yMin + _imageHist[i], 'l'); xval += dxval; } p.stroke(units_user); } else if (the_y_axis_type == percentage) { yMin = 0.0; yMax = 100.0; gr_setytransform(gr_axis_LINEAR); gr_setysubdivisions(1); gr_setxsubdivisions(1); gr_setxlabel(""); gr_setylabel(""); extern char _grNumFormat_y[]; string old_y_fmt; old_y_fmt.assign(_grNumFormat_y); gr_setynumberformat("%.0lf%%"); gr_scale125((double) _image0, (double) _image255, 4, &left, &right, &num); gr_setxscale((double) x_ll_cm, (double) x_ll_cm + dx, left, right); gr_setyscale((double) y_ll_cm, (double) y_ll_cm + dy, yMin, yMax); gr_drawxaxis(yMin, left, (right - left) / num, right, left, gr_axis_BOTTOM); gr_setysubdivisions(4); gr_drawyaxis((double) left, yMin, 25., yMax, yMin, gr_axis_LEFT); gr_setynumberformat(old_y_fmt.c_str()); GriPath p; p.push_back(left, yMin, 'm'); p.push_back(left, yMax, 'l'); p.push_back(right, yMax, 'l'); p.push_back(right, yMin, 'l'); xval = _image0; dxval = (_image255 - _image0) / 255.0; p.push_back(_image0, yMin, 'm'); for (i = 0; i < 256; i++) { p.push_back(xval, yMin + 100*_imageHist[i], 'l'); xval += dxval; } p.stroke(units_user); } else { err("'draw image histogram' cannot understand type `\\'", _word[_nword - 1], "'", "\\"); return false; } #endif gr_setytransform(gr_axis_LINEAR); if ((y_ll_cm + dy) > _top_of_plot) _top_of_plot = y_ll_cm + dy; return true; } bool draw_image_paletteCmd() { if (_output_file_type == svg) warning("svg mode may not handle image palettes properly yet"); extern FILE *_grPS; const double height = 1.0; // height of box (cm) const double space = 2.0; // space of box above top of plot const int LEN = 512; // length of tmp image int rotpal=0; int otherside=0; int i; double left_cm, bottom_cm, right_cm, top_cm; unsigned int words_understood = 3; // 3 in `draw image palette' unsigned char gray[LEN]; double left, inc = 0.0, right, grayVal, grayInc; int num; double llx, lly, dx = XSIZE_DEFAULT, urx, ury; if (!get_var("..xmargin..", &llx)) warning("Sorry, don't know value of ..xmargin.. so using XMARGIN_DEFAULT"); if (!get_var("..xsize..", &dx)) warning("Sorry, don't know value of ..xsize.. so using XSIZE_DEFAULT"); if (!scales_defined()) { #if 0 // Fix SF bug #129856 (I hope!) no_scales_error(); return false; #else create_x_scale(); create_y_scale(); #endif } // Check for old usage `draw image grayscale'. Give warning, but proceed // anyway. if (word_is(2, "grayscale") || word_is(2, "greyscale")) { warning("`draw image grayscale' RENAMED `draw image palette'; please change your cmdfile"); } if (word_is(3, "axistop")) { words_understood++; rotpal=0; otherside=1; } if (word_is(3, "axisbottom")) { words_understood++; rotpal=0; otherside=0; } if (word_is(3, "axisleft")) { words_understood++; rotpal=1; otherside=0; } if (word_is(3, "axisright")) { words_understood++; rotpal=1; otherside=1; } if (1 == get_cmd_values(_word, _nword, "left", 1, _dstack)) { // Getting light/dark levels from command. left = _dstack[0]; if (1 == get_cmd_values(_word, _nword, "right", 1, _dstack)) { right = _dstack[0]; words_understood += 4; } else { demonstrate_command_usage(); err("Missing `right' keyword"); return false; } } else { // Getting light/dark levels from image. if (!image_range_exists()) { err("Image range unknown. First `convert grid to image' or `set image range'"); return false; } gr_scale125((double) _image0, (double) _image255, 4, &left, &right, &num); inc = (right - left) / num; } if (1 == get_cmd_values(_word, _nword, "increment", 1, _dstack)) { inc = _dstack[0]; words_understood += 2; } else { if (inc == 0.0) { // Make guess, probably an ugly one inc = 0.2 * (right - left); } } if (!well_ordered(left, right, inc)) inc = -inc; if (4 == get_cmd_values(_word, _nword, "box", 4, _dstack)) { llx = _dstack[0]; lly = _dstack[1]; urx = _dstack[2]; ury = _dstack[3]; words_understood += 5; } else { llx = XMARGIN_DEFAULT; lly = _top_of_plot + space; urx = llx + dx; ury = lly + height; } // Check that command syntax was OK. if (words_understood != _nword) { NUMBER_WORDS_ERROR; demonstrate_command_usage(); return false; } // Draw image, then box. set_environment(); set_ps_color('p'); if (rotpal==0) { gr_setxlabel(""); gr_setxnumberformat(_xFmt.c_str()); gr_setxsubdivisions(1); gr_setysubdivisions(1); gr_setxscale(llx, urx, left, right); gr_setyscale(lly, ury, 0.0, 1.0); } else { gr_setylabel(""); gr_setynumberformat(_yFmt.c_str()); gr_setxsubdivisions(1); gr_setysubdivisions(1); gr_setxscale(llx, urx, 0.0, 1.0); gr_setyscale(lly, ury, left, right); } if (ury > _top_of_plot) _top_of_plot = ury; grayInc = (right - left) / (LEN - 1.0); grayVal = left; // - 0.5 * grayInc for (i = 0; i < LEN; i++) { int imval; imval = (int) floor(0.5 + (255.0 * (grayVal - _image0) / (_image255 - _image0))); if (imval < 0) imval = 0; else if (imval > 255) imval = 255; gray[i] = imval; grayVal += grayInc; } if (rotpal==0) { gr_usertocm(left, 0.0, &left_cm, &bottom_cm); gr_usertocm(right, 1.0, &right_cm, &top_cm); } else { gr_usertocm(0.0, left, &left_cm, &bottom_cm); gr_usertocm(1.0, right, &right_cm, &top_cm); } // Clip to this, because image overhangs if (_output_file_type == postscript) { fprintf(_grPS, "q n %% turn clipping on for image palette\n"); fprintf(_grPS, "%f %f moveto\n", left_cm * PT_PER_CM, bottom_cm * PT_PER_CM); fprintf(_grPS, "%f %f lineto\n", right_cm * PT_PER_CM, bottom_cm * PT_PER_CM); fprintf(_grPS, "%f %f lineto\n", right_cm * PT_PER_CM, top_cm * PT_PER_CM); fprintf(_grPS, "%f %f lineto\n", left_cm * PT_PER_CM, top_cm * PT_PER_CM); fprintf(_grPS, "%f %f lineto\n", left_cm * PT_PER_CM, bottom_cm * PT_PER_CM); fprintf(_grPS, "closepath W\n"); } if (rotpal==0) { gr_drawimage(gray, _imageTransform, _image_color_model, NULL, 0.0, 0.0, 0.0, LEN, 1, left_cm, bottom_cm, right_cm, top_cm, false); } else { gr_drawimage(gray, _imageTransform, _image_color_model, NULL, 0.0, 0.0, 0.0, 1, LEN, left_cm, bottom_cm, right_cm, top_cm, false); } if (_output_file_type == postscript) fprintf(_grPS, "Q %% turn clipping off for image palette\n"); double actual_linewidth = _griState.linewidth_line(); _griState.set_linewidth_line(_griState.linewidth_axis()); if (rotpal==0) { if (otherside==0) gr_drawxaxis(0.0, left, inc, right, left, gr_axis_BOTTOM); else gr_drawxaxis(1.0, left, inc, right, left, gr_axis_TOP); if (_output_file_type == postscript) fprintf(_grPS, "%.3f w %% test\n", _griState.linewidth_axis()); GriPath p(4); p.push_back(left, 0.0, 'm'); p.push_back(left, 1.0, 'l'); p.push_back(right, 1.0, 'l'); p.push_back(right, 0.0, 'l'); p.push_back(left, 0.0, 'l'); p.stroke(units_user); } else { if (otherside==0) gr_drawyaxis(0.0, left, inc, right, left, gr_axis_LEFT); else gr_drawyaxis(1.0, left, inc, right, left, gr_axis_RIGHT); if (_output_file_type == postscript) fprintf(_grPS, "%.3f w\n", _griState.linewidth_axis()); GriPath p(4); p.push_back(0.0, left, 'm'); p.push_back(1.0, left, 'l'); p.push_back(1.0, right, 'l'); p.push_back(0.0, right, 'l'); p.push_back(0.0, left, 'l'); p.stroke(units_user); } _griState.set_linewidth_line(actual_linewidth); return true; } // TODO - handle missingcolor in color images bool draw_imageCmd() { double llx_cm, lly_cm, urx_cm, ury_cm; if (!image_scales_defined()) { demonstrate_command_usage(); err("First define box containing image (`set x grid' and `set y grid')"); return false; } if (!scales_defined()) { create_x_scale(); create_y_scale(); } if (!_image.storage_exists) { demonstrate_command_usage(); err("First `read image' or `convert grid to image'"); return false; } if (!_imageTransform_exists) { demonstrate_command_usage(); err("First `set image grayscale'"); return false; } set_environment(); //printf("DEBUG [draw_imageCmd() %s:%d] _image_llx=%lf _image_lly=%lf _image_urx=%lf _image_ury=%lf\n",__FILE__,__LINE__,_image_llx,_image_lly,_image_urx,_image_ury); gr_usertocm(_image_llx, _image_lly, &llx_cm, &lly_cm); gr_usertocm(_image_urx, _image_ury, &urx_cm, &ury_cm); if (_imageMask.storage_exists) { //printf("DEBUG [draw_imageCmd() %s:%d] (have mask) llx_cm=%lf lly_cm=%lf urx_cm=%lf ury_cm=%lf\n",__FILE__,__LINE__,llx_cm,lly_cm,urx_cm,ury_cm); extern double _image_missing_color_red; // in set.c extern double _image_missing_color_green; // in set.c extern double _image_missing_color_blue; // in set.c double mask_r, mask_g, mask_b; mask_r = _image_missing_color_red; mask_g = _image_missing_color_green; mask_b = _image_missing_color_blue; //printf("%s:%d image mask at %x\n",__FILE__,__LINE__,(unsigned int)( _imageMask.image)); if (_output_file_type == svg) gr_drawimage_svg(_image.image, _imageTransform, _image_color_model, _imageMask.image, mask_r, mask_g, mask_b, _image.ras_width, _image.ras_height, llx_cm, lly_cm, urx_cm, ury_cm, true); else gr_drawimage(_image.image, _imageTransform, _image_color_model, _imageMask.image, mask_r, mask_g, mask_b, _image.ras_width, _image.ras_height, llx_cm, lly_cm, urx_cm, ury_cm, true); } else { //printf("DEBUG [draw_imageCmd() %s:%d] (no mask) llx_cm=%lf lly_cm=%lf urx_cm=%lf ury_cm=%lf\n",__FILE__,__LINE__,llx_cm,lly_cm,urx_cm,ury_cm); if (_output_file_type == svg) gr_drawimage_svg(_image.image, _imageTransform, _image_color_model, NULL, 0.0, 0.0, 0.0, _image.ras_width, _image.ras_height, llx_cm, lly_cm, urx_cm, ury_cm, true); else gr_drawimage(_image.image, _imageTransform, _image_color_model, NULL, 0.0, 0.0, 0.0, _image.ras_width, _image.ras_height, llx_cm, lly_cm, urx_cm, ury_cm, true); } _drawingstarted = true; draw_axes_if_needed(); return true; } bool draw_labelCmd() { gr_fontID old_font = gr_currentfont(); double fontsize = FONTSIZE_PT_DEFAULT; double textangle_deg = 0.0; double tmp1, tmp2; double xcm, ycm; bool user_units; bool left_justified = false, centered = false, right_justified = false; int coord_word = 0; if (_nword < 5) { NUMBER_WORDS_ERROR; demonstrate_command_usage(); return false; } // Find quote string std::string unquoted; int status = ExtractQuote(_cmdLine, unquoted); if (status == 0) { err("`draw label' needs a double-quoted string"); return false; } if (status < 0) { err("`draw label' found start of a double-quoted string, but not a closing double-quote"); return false; } int QuoteEnd = status; GriString label(unquoted.c_str()); chop_into_words(_cmdLine + QuoteEnd, _word, &_nword, MAX_nword); // Parse for text angle, in degrees from horizontal. If the option // [rotated .deg.] exists, interpret and then strip from the commandline. if (1 == get_cmd_values(_word, _nword, "rotated", 1, _dstack)) { textangle_deg = _dstack[0]; _nword--; _nword--; } // Parse for coordinates if (_nword < 3) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } // Figure out whether "at" or "centered at" or "rightjustified at" if (!strcmp(_word[0], "at")) { left_justified = true; coord_word++; } else if ((!strcmp(_word[0], "centered") || !strcmp(_word[0], "centred")) && !strcmp(_word[1], "at")) { centered = true; coord_word += 2; } else if (!strcmp(_word[0], "rightjustified") && !strcmp(_word[1], "at")) { right_justified = true; coord_word += 2; } else { demonstrate_command_usage(); err("Where do you want this label drawn? (missing `at' word)"); return false; } user_units = !word_is(_nword - 1, "cm") && !word_is(_nword - 1, "pt"); if (user_units) { set_environment(); if (!scales_defined()) { #if 0 // Fix SF bug #129856 (I hope!) no_scales_error(); return false; #else create_x_scale(); create_y_scale(); #endif } if (!getdnum(_word[coord_word], &tmp1)) { demonstrate_command_usage(); READ_WORD_ERROR(".x."); return false; } if (!getdnum(_word[coord_word + 1], &tmp2)) { demonstrate_command_usage(); READ_WORD_ERROR(".y."); return false; } gr_usertocm(tmp1, tmp2, &xcm, &ycm); } else { if (word_is(_nword - 1, "cm")) { if (!getdnum(_word[coord_word], &xcm)) { demonstrate_command_usage(); READ_WORD_ERROR(".xcm."); return false; } if (!getdnum(_word[coord_word + 1], &ycm)) { demonstrate_command_usage(); READ_WORD_ERROR(".ycm."); return false; } } else if (word_is(_nword - 1, "pt")) { if (!getdnum(_word[coord_word], &xcm)) { demonstrate_command_usage(); READ_WORD_ERROR(".xpt."); return false; } if (!getdnum(_word[coord_word + 1], &ycm)) { demonstrate_command_usage(); READ_WORD_ERROR(".ypt."); return false; } xcm /= PT_PER_CM; ycm /= PT_PER_CM; } else { err("Expecting 'cm' or 'pt', but got \\", _word[_nword - 1], "\\"); return false; } } if (!get_var("..fontsize..", &fontsize)) warning("Sorry, don't know value of ..fontsize.. so using _FONTSIZE_PT_DEFAULT"); gr_setfontsize_pt(fontsize); gr_setfont(old_font); _drawingstarted = true; if (user_units) draw_axes_if_needed(); if (left_justified) { label.draw(xcm, ycm, TEXT_LJUST, textangle_deg); } else if (right_justified) { label.draw(xcm, ycm, TEXT_RJUST, textangle_deg); } else if (centered) { label.draw(xcm, ycm, TEXT_CENTERED, textangle_deg); } else { err("Where do you want this label drawn?"); // never reached, I think return false; } return true; } bool draw_line_from_toCmd() { double x0, y0, x1, y1; if (2 == get_cmd_values(_word, _nword, "from", 2, _dstack)) { x0 = _dstack[0]; y0 = _dstack[1]; if (2 == get_cmd_values(_word, _nword, "to", 2, _dstack)) { x1 = _dstack[0]; y1 = _dstack[1]; } else { READ_WORD_ERROR("(.x1., .y1.)"); demonstrate_command_usage(); return false; } } else { READ_WORD_ERROR("(.x0., .y0.)"); demonstrate_command_usage(); return false; } // Check if zero-length line if (((x1 - x0)*(x1 - x0) + (y1 - y0) * (y1 - y0)) == 0.0) { warning("`draw line from ... to ...' is drawing a zero-length line"); } set_environment(); set_ps_color('p'); set_line_width_curve(); static GriPath p(2); p.clear(); if (!strcmp(_word[_nword - 1], "cm")) { p.push_back(x0, y0, 'm'); p.push_back(x1, y1, 'l'); p.stroke(units_cm); _drawingstarted = true; return true; } else if (!strcmp(_word[_nword - 1], "pt")) { p.push_back(x0, y0, 'm'); p.push_back(x1, y1, 'l'); p.stroke(units_pt); _drawingstarted = true; return true; } else { // User units -- draw axes if needed if (!scales_defined()) { #if 0 // Fix SF bug #129856 (I hope!) no_scales_error(); return false; #else create_x_scale(); create_y_scale(); #endif } if (!gr_missingx(x0) && !gr_missingx(x1) && !gr_missingy(y0) && !gr_missingy(y1)) { p.push_back(x0, y0, 'm'); p.push_back(x1, y1, 'l'); p.stroke(units_user); _drawingstarted = true; draw_axes_if_needed(); } return true; } } // `draw lines {vertically .left. .right. .inc.}|{horizontally .bottom. .top. // .inc.}' bool draw_linesCmd(void) { bool vert = false; double min, max, inc, tmp; static GriPath p(2); p.clear(); switch (_nword) { case 6: if (!strcmp(_word[2], "vertically")) vert = true; else if (!strcmp(_word[2], "horizontally")) vert = false; else { err("`\\", _word[2], "' not understood.", "\\"); demonstrate_command_usage(); return false; } set_environment(); set_line_width_curve(); if (!getdnum(_word[3], &min) || !getdnum(_word[4], &max) || !getdnum(_word[5], &inc)) { return false; } if (!well_ordered(min, max, inc)) inc = -inc; for (tmp = min; tmp <= (max + 0.25 * inc); tmp += inc) { if (vert == true) { p.push_back(tmp, _ybottom, 'm'); p.push_back(tmp, _ytop, 'l'); } else { p.push_back(_xleft, tmp, 'm'); p.push_back(_xright, tmp, 'l'); } } p.stroke(units_user); _drawingstarted = true; return true; default: NUMBER_WORDS_ERROR; demonstrate_command_usage(); return false; } } // `draw patches .width. .height. [cm]' bool draw_patchesCmd() { double *xp = _colX.begin(); double *yp = _colY.begin(); double *zp = _colZ.begin(); double dx, dx2, dy, dy2; GriColor old_color = _griState.color_line(); bool cmUnits; if (_nword < 4 || _nword > 5) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } if (!_columns_exist || _colZ.size() <= 0) { warning("`draw patches' noticed that no column data exist."); return true; } if (!scales_defined()) { #if 0 // Fix SF bug #129856 (I hope!) no_scales_error(); return false; #else create_x_scale(); create_y_scale(); #endif } if (!_imageTransform_exists) { err("Image transform doesn't exist yet. First `set image grayscale'"); return false; } // Figure out units for patch size cmUnits = (!strcmp(_word[_nword - 1], "cm")) ? true : false; // Figure out patch size if (!getdnum(_word[2], &dx) || !getdnum(_word[3], &dy)) { demonstrate_command_usage(); if (cmUnits) { READ_WORD_ERROR(".x_cm. and .y_cm."); } else { READ_WORD_ERROR(".x. and .y."); } return false; } if (dx <= 0. || dy <= 0.0) { demonstrate_command_usage(); if (cmUnits) err("Can't have .dx_cm. <= 0 or .dy_cm. <= 0"); else err("Can't have .dx. <= 0 or .dy. <= 0"); return false; } dx2 = dx / 2.0; dy2 = dy / 2.0; set_environment(); unsigned int i_max = _colX.size(); static GriPath p(5); GriColor gray_level; for (unsigned int i = 0; i < i_max; i++) { p.clear(); double xl, yb, xr, yt; if (!gr_missingx((double) *xp) && !gr_missingy((double) *yp) && !gr_missing((double) *zp) && inside_box((double) *xp, (double) *yp)) { // Set grayscale gray_level.setRGB(_imageTransform[value_to_image(*zp)] / 255.0, _imageTransform[value_to_image(*zp)] / 255.0, _imageTransform[value_to_image(*zp)] / 255.0); _griState.set_color_line(gray_level); if (cmUnits) { gr_usertocm((double) *xp, (double) *yp, &xl, &yb); xl -= dx2; xr = xl + dx; yb -= dy2; yt = yb + dy; p.push_back(xl, yb, 'm'); p.push_back(xr, yb, 'l'); p.push_back(xr, yt, 'l'); p.push_back(xl, yt, 'l'); p.push_back(xl, yb, 'l'); p.fill(units_cm); } else { xl = *xp; yb = *yp; xl -= dx2; xr = xl + dx; yb -= dy2; yt = yb + dy; p.push_back(xl, yb, 'm'); p.push_back(xr, yb, 'l'); p.push_back(xr, yt, 'l'); p.push_back(xl, yt, 'l'); p.push_back(xl, yb, 'l'); p.fill(units_user); } } xp++; yp++; zp++; } _griState.set_color_line(old_color); _drawingstarted = true; draw_axes_if_needed(); return true; } // `draw polygon [filled] .x0. .y0. .x1. .y1. .x2. .y2. [...] [cm|pt|user]' bool draw_polygonCmd(void) { int i, start = 0, num; bool filled = false; units the_unit = units_user; int nword = _nword; if (nword < 4) { NUMBER_WORDS_ERROR; return false; } if (word_is(nword - 1, "cm")) { the_unit = units_cm; nword--; // trim this last word } else if (word_is(nword - 1, "pt")) { the_unit = units_pt; nword--; // trim this last word } else if (word_is(nword - 1, "user")) { the_unit = units_user; nword--; // trim this last word } if (word_is(2, "filled")) { start = 3; filled = true; num = nword - 3; } else { start = 2; num = nword - 2; } if (2 * (num / 2) != num) { err("Need matched (x,y) pairs"); return false; } set_x_scale(); set_y_scale(); set_environment(); GriPath p; for (i = 0; i < num; i += 2) { double x, y; if (!getdnum(_word[i + start], &x)) { err("Cannot read x"); return false; } if (!getdnum(_word[1 + i + start], &y)) { err("Cannot read x"); return false; } p.push_back(x, y, i == 0 ? 'm' : 'l'); } if (filled) p.fill(the_unit); else p.stroke(the_unit); return true; } bool draw_titleCmd() { if (_nword > 2) { // find quote string std::string unquoted; int status = ExtractQuote(_cmdLine, unquoted); if (status == 0) { err("`draw title' found no double-quoted string to use."); return false; } if (status < 0) { err("`draw title' found no starting double-quote, but no ending double-quote."); return false; } if (!unquoted.empty()) { double xmargin = XMARGIN_DEFAULT; double xsize = XSIZE_DEFAULT; //set_environment(); if (!get_var("..xmargin..", &xmargin)) warning("Sorry, don't know value of ..xmargin.. so using XMARGIN_DEFAULT"); if (!get_var("..xsize..", &xsize)) warning("Sorry, don't know value of ..xsize.. so using XSIZE_DEFAULT"); GriString label; label.fromSTR(unquoted.c_str()); label.draw(xmargin + 0.5 * xsize, _top_of_plot + OFFSET_AFTER_TITLE, TEXT_CENTERED, 0.0); _top_of_plot += OFFSET_AFTER_TITLE + gr_currentfontsize_pt() / PT_PER_CM; } } else { err("`draw title' what?"); return false; } return true; } // draw values [.dx. .dy.] [\format] [separation .dist_cm.] bool draw_valuesCmd() { if (!_columns_exist || _colZ.size() <= 0) { err("First `read columns'"); return false; } if (!scales_defined()) { #if 0 // Fix SF bug #129856 (I hope!) no_scales_error(); return false; #else create_x_scale(); create_y_scale(); #endif } // Get separation x and y if they are given unsigned int gave_separation = 0; double xseparation = 0.0, yseparation = 0.0; if (2 == get_cmd_values(_word, _nword, "separation", 2, _dstack)) { xseparation = _dstack[0]; yseparation = _dstack[1]; if (xseparation < 0.0 || yseparation < 0.0) { warning("`draw values ... separation .xcm. .ycm.' ignoring negative values"); xseparation = 0.0; yseparation = 0.0; } gave_separation = 1; } // Get format if it is given unsigned int gave_fmt = 0; char fmt[20]; strcpy(fmt, "%g"); for (unsigned int word = 2; word < _nword; word++) { if ('%' == *_word[word]) { strcpy(fmt, _word[word]); gave_fmt = 1; break; } } set_environment(); double dx_cm, dy_cm; if (_nword == 4 + gave_fmt + 3 * gave_separation) { if (!getdnum(_word[2], &dx_cm) || !getdnum(_word[3], &dy_cm)) { err("`draw values' can't read dx_cm and dy_cm"); return false; } } else if (_nword == 2 + gave_fmt + 3 * gave_separation) { double width_cm, ascent_cm, descent_cm; gr_stringwidth("M", &width_cm, &ascent_cm, &descent_cm); dx_cm = 0.5 * width_cm; dy_cm = -0.5 * ascent_cm; } else { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } // Now start drawing double *xp = _colX.begin(); double *yp = _colY.begin(); double *zp = _colZ.begin(); unsigned int num = _colX.size(); double xcm, ycm; double xcm_last = 0.0, ycm_last = 0.0; // assignment calms compiler bool first = true; GriString label; for (unsigned int i = 0; i < num; i++) { if (!gr_missing(*zp) && !gr_missingx(*xp) && !gr_missingy(*yp) && inside_box(*xp, *yp)) { gr_usertocm(*xp, *yp, &xcm, &ycm); xcm += dx_cm; ycm += dy_cm; if (first || fabs(xcm - xcm_last) >= xseparation || fabs(ycm - ycm_last) >= yseparation) { sprintf(_grTempString, fmt, *zp); label.fromSTR(_grTempString); label.draw(xcm, ycm, TEXT_LJUST, 0.0); xcm_last = xcm; ycm_last = ycm; first = false; } } xp++; yp++; zp++; } if (!first) { _drawingstarted = true; draw_axes_if_needed(); } return true; } bool draw_x_axisCmd() { double tmp; gr_axis_properties side; int n = _nword; bool position_in_cm = false; set_x_scale(); set_y_scale(); // see if lower|upper specified if (!strcmp(_word[n - 1], "lower") && strcmp(_word[n - 2], "at")) { side = gr_axis_BOTTOM; n--; } else if (!strcmp(_word[n - 1], "upper") && strcmp(_word[n - 2], "at")) { side = gr_axis_TOP; n--; } else side = gr_axis_BOTTOM; if (!strcmp(_word[n - 1], "cm")) { position_in_cm = true; n--; } switch (n) { case 3: // `draw x axis' draw_axes(3, _ybottom, gr_axis_BOTTOM, true); break; case 5: // `draw x axis at bottom|top|.y.' if (!strcmp(_word[n - 1], "bottom")) draw_axes(3, _ybottom, gr_axis_BOTTOM, true); else if (!strcmp(_word[n - 1], "top")) { draw_axes(3, _ytop, gr_axis_TOP, true); } else if (getdnum(_word[n - 1], &tmp)) { if (position_in_cm) { double xuser, yuser; gr_cmtouser((double) 1.0, (double) tmp, &xuser, &yuser); tmp = yuser; } draw_axes(3, tmp, side, false); } else { demonstrate_command_usage(); err("`draw x axis at ?where?'"); return false; } break; default: demonstrate_command_usage(); err("`draw x axis ?what?"); return false; } return true; } bool draw_y_axisCmd() { double tmp; gr_axis_properties side; int n = _nword; bool position_in_cm = false; set_x_scale(); set_y_scale(); // see if `left|right' specified if (!strcmp(_word[n - 1], "left") && strcmp(_word[n - 2], "at")) { side = gr_axis_LEFT; n--; } else if (!strcmp(_word[n - 1], "right") && strcmp(_word[n - 2], "at")) { side = gr_axis_RIGHT; n--; } else side = gr_axis_LEFT; if (!strcmp(_word[n - 1], "cm")) { position_in_cm = true; n--; } switch (n) { case 3: // `draw y axis' draw_axes(4, _xleft, gr_axis_LEFT, true); break; case 5: // `draw y axis at left|right|.x.' if (!strcmp(_word[n - 1], "left")) { draw_axes(4, _xleft, gr_axis_LEFT, true); } else if (!strcmp(_word[n - 1], "right")) { draw_axes(4, _xright, gr_axis_RIGHT, true); } else if (getdnum(_word[n - 1], &tmp)) { if (position_in_cm) { double xuser, yuser; gr_cmtouser((double) tmp, (double) 1.0, &xuser, &yuser); tmp = xuser; } draw_axes(4, tmp, side, false); } else { demonstrate_command_usage(); err("`draw y axis at ?where?'"); return false; } break; default: demonstrate_command_usage(); err("`draw y axis ?what?"); return false; } return true; } static const double FRAC = 0.3; // size of symbols compared to box bool draw_x_box_plotCmd() { double q1_cm, q2_cm, q3_cm; // quartiles in cm double y_cm, ymin_cm, ymax_cm; // box boundaries in cm double old_symbol_size = gr_currentsymbolsize_pt(); // store old double size_cm = 0.5; // box size double y; // location double q1, q2, q3; // quartiles double upper_adjacent_value; // whisker>q3 double lower_adjacent_value; // whisker q3 && x < upper && x > upper_adjacent_value) upper_adjacent_value = x; if (x < q1 && x > lower && x < lower_adjacent_value) lower_adjacent_value = x; } } set_line_width_symbol(); gr_setsymbolsize_cm(FRAC * size_cm); if (upper_adjacent_value > q3) { // draw whisker > q3 gr_usertocm(q3, y, &xcm, &ycm); p.push_back(xcm, ycm, 'm'); gr_usertocm(upper_adjacent_value, y, &xcm, &ycm); p.push_back(xcm, ycm, 'l'); p.stroke(units_cm); gr_drawsymbol(xcm, ycm, gr_times_symbol); } if (lower_adjacent_value < q1) { // draw whisker < q1 gr_usertocm(q1, y, &xcm, &ycm); p.push_back(xcm, ycm, 'm'); gr_usertocm(lower_adjacent_value, y, &xcm, &ycm); p.push_back(xcm, ycm, 'l'); p.stroke(units_cm); gr_drawsymbol(xcm, ycm, gr_times_symbol); } // draw outliers > q3 lower = q3 + 1.5 * iqr; upper = q3 + 3.0 * iqr; for (unsigned int i = 0; i < _colX.size(); i++) { double val = _colX[i]; if (!gr_missingx((double)val)) { if (val > lower) { gr_usertocm(val, y, &xcm, &ycm); if (val <= upper) // minor outlier gr_drawsymbol(xcm, ycm, gr_circ_symbol); else // major outlier gr_drawsymbol(xcm, ycm, gr_bullet_symbol); } } } // draw outliers < q1 lower = q1 - 3.0 * iqr; upper = q1 - 1.5 * iqr; for (unsigned int i = 0; i < _colX.size(); i++) { double val = _colX[i]; if (!gr_missingx((double)val)) { if (val < upper) { gr_usertocm(val, y, &xcm, &ycm); if (val >= lower) // minor outlier gr_drawsymbol(xcm, ycm, gr_circ_symbol); else // major outlier gr_drawsymbol(xcm, ycm, gr_bullet_symbol); } } } _drawingstarted = true; draw_axes_if_needed(); gr_setsymbolsize_pt(old_symbol_size); return true; } bool draw_y_box_plotCmd() { double q1_cm, q2_cm, q3_cm; // quartiles in cm double x_cm, xmin_cm, xmax_cm; // box boundaries in cm double old_symbol_size = gr_currentsymbolsize_pt(); // store old double size_cm = 0.5; // box size double x; // location double q1, q2, q3; // quartiles double upper_adjacent_value; // whisker>q3 double lower_adjacent_value; // whisker q3 && y < upper && y > upper_adjacent_value) upper_adjacent_value = y; if (y < q1 && y > lower && y < lower_adjacent_value) lower_adjacent_value = y; } } gr_setsymbolsize_cm(FRAC * size_cm); set_line_width_symbol(); if (upper_adjacent_value > q3) { // draw whisker > q3 gr_usertocm(x, q3, &xcm, &ycm); p.push_back(xcm, ycm, 'm'); gr_usertocm(x, upper_adjacent_value, &xcm, &ycm); p.push_back(xcm, ycm, 'l'); p.stroke(units_cm); gr_drawsymbol(xcm, ycm, gr_times_symbol); } if (lower_adjacent_value < q1) { // draw whisker < q1 gr_usertocm(x, q1, &xcm, &ycm); p.push_back(xcm, ycm, 'm'); gr_usertocm(x, lower_adjacent_value, &xcm, &ycm); p.push_back(xcm, ycm, 'l'); p.stroke(units_cm); gr_drawsymbol(xcm, ycm, gr_times_symbol); } // Draw outliers > q3 lower = q3 + 1.5 * iqr; upper = q3 + 3.0 * iqr; gr_setsymbolsize_cm(FRAC * size_cm); for (unsigned int i = 0; i < _colY.size(); i++) { double val = _colY[i]; if (!gr_missingy((double)val)) { if (val > lower) { gr_usertocm(x, val, &xcm, &ycm); if (val <= upper) // minor outlier gr_drawsymbol(xcm, ycm, gr_circ_symbol); else // major outlier gr_drawsymbol(xcm, ycm, gr_bullet_symbol); } } } // Draw outliers < q1 lower = q1 - 3.0 * iqr; upper = q1 - 1.5 * iqr; for (unsigned int i = 0; i < _colY.size(); i++) { double val = _colY[i]; if (!gr_missingy((double)val)) { if (val < upper) { gr_usertocm(x, val, &xcm, &ycm); if (val >= lower) // minor outlier gr_drawsymbol(xcm, ycm, gr_circ_symbol); else // major outlier gr_drawsymbol(xcm, ycm, gr_bullet_symbol); } } } _drawingstarted = true; draw_axes_if_needed(); gr_setsymbolsize_pt(old_symbol_size); return true; } #undef FRAC bool draw_zero_lineCmd() { if (!scales_defined()) { #if 0 // Fix SF bug #129856 (I hope!) no_scales_error(); return false; #else create_x_scale(); create_y_scale(); #endif } switch (_nword) { case 3: // `draw zero line' draw_zeroline_horizontally(); break; case 4: if (!strcmp(_word[3], "horizontally")) draw_zeroline_horizontally(); else if (!strcmp(_word[3], "vertically")) draw_zeroline_vertically(); else { err("How should I draw this zero line?"); demonstrate_command_usage(); return false; } break; default: NUMBER_WORDS_ERROR; demonstrate_command_usage(); return false; } return true; } bool draw_zeroline_horizontally() { if ((_ybottom * _ytop) < 0.0) { set_environment(); set_line_width_curve(); GriPath p(2); p.push_back(_xleft, 0.0, 'm'); p.push_back(_xright, 0.0, 'l'); p.stroke(units_user); _drawingstarted = true; draw_axes_if_needed(); } return true; } bool draw_zeroline_vertically() { if ((_xleft * _xright) < 0.0) { set_environment(); set_line_width_curve(); GriPath p(2); p.push_back(0.0, _ybottom, 'm'); p.push_back(0.0, _ytop, 'l'); p.stroke(units_user); _drawingstarted = true; draw_axes_if_needed(); } return true; } bool set_x_scale() { double xsize = XSIZE_DEFAULT; double xmargin = XMARGIN_DEFAULT; if (!get_var("..xmargin..", &xmargin)) warning("(draw_axes) don't know ..xmargin.. so using XMARGIN_DEFAULT"); if (!get_var("..xsize..", &xsize)) warning("(draw_axes) don't know ..xsize.. so using XSIZE_DEFAULT"); gr_setxtransform(_xtype); gr_setxscale(xmargin, xmargin + xsize, _xleft, _xright); _xscale_exists = true; return true; } bool set_y_scale() { double ysize = YSIZE_DEFAULT; double ymargin = YMARGIN_DEFAULT; if (!get_var("..ymargin..", &ymargin)) warning("(draw_axes) don't know ..ymargin.. so using YMARGIN_DEFAULT"); if (!get_var("..ysize..", &ysize)) warning("(draw_axes) don't know ..ysize.. so using YSIZE_DEFAULT"); gr_setytransform(_ytype); gr_setyscale(ymargin, ymargin + ysize, _ybottom, _ytop); _yscale_exists = true; return true; } //`Draw gri logo .x_cm. .y_cm. .height_cm. .style. \fgcolor \bgcolor' // 0 1 2 3 4 5 6 7 8 bool draw_gri_logoCmd() { double dx=0.03, dy=0.03; // Q: should these be arguments? // // Process args double x_cm, y_cm, height_cm; int style; if (_nword != 9) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } Require(getdnum(_word[3], &x_cm), READ_WORD_ERROR(".x_cm.")); Require(getdnum(_word[4], &y_cm), READ_WORD_ERROR(".y_cm.")); Require(getdnum(_word[5], &height_cm), READ_WORD_ERROR(".height_cm.")); Require(getinum(_word[6], &style), READ_WORD_ERROR(".style.")); double fg_r, fg_g, fg_b; double bg_r, bg_g, bg_b; Require(look_up_color(_word[7], &fg_r, &fg_g, &fg_b), err("unknown colorname `\\", _word[7], "'", "\\")); Require(look_up_color(_word[8], &bg_r, &bg_g, &bg_b), err("unknown colorname `\\", _word[8], "'", "\\")); GriColor bg_color; bg_color.setRGB(bg_r, bg_g, bg_b); GriColor fg_color; fg_color.setRGB(fg_r, fg_g, fg_b); // // Read data char fname[256]; sprintf(fname, "%s%s", _lib_directory.c_str(), "logo.dat"); FILE *fp = fopen(fname, "r"); if (!fp) { warning("Could not open logo data file `\\", fname, "'.\n Continuing with rest of commandfile.", "\\"); return true; } GriPath p; double xx, yy; // // Save entry values GriColor old_color = _griState.color_line(); bool was_using_missing_value = gr_using_missing_value(); double old_grMissingValue = gr_currentmissingvalue(); gr_set_missing_value(-999.0); bool first = true, last_OK = true; while (2 == fscanf(fp, "%lf %lf", &xx, &yy)) { if (!gr_missing(xx)) { xx = x_cm + xx * height_cm; yy = y_cm + yy * height_cm; if (first) { p.push_back(xx, yy, 'm'); first = false; } else { if (last_OK) { p.push_back(xx, yy, 'l'); } else { p.push_back(xx, yy, 'm'); } } last_OK = true; } else { last_OK = false; } } fclose(fp); GriPath bg; double xmax = 1.81291; // of data in logo double ymax = 1.0; // of data in logo switch (style) { case 0: // stroke it _griState.set_color_line(fg_color); p.stroke(units_cm); break; default: case 1: // fill it with no background _griState.set_color_line(fg_color); p.fill(units_cm); break; case 2: // fill it in tight box _griState.set_color_line(bg_color); bg.push_back(x_cm - height_cm * 0.05, y_cm - height_cm * 0.05, 'm'); bg.push_back(x_cm + xmax * height_cm * 1.05, y_cm - height_cm * 0.05, 'l'); bg.push_back(x_cm + xmax * height_cm * 1.05, y_cm + ymax * height_cm * 1.05, 'l'); bg.push_back(x_cm - height_cm * 0.05, y_cm + ymax * height_cm * 1.05, 'l'); bg.fill(units_cm); _griState.set_color_line(fg_color); p.fill(units_cm); break; case 3: // fill it in square box _griState.set_color_line(bg_color); bg.push_back(x_cm - height_cm * 0.05, y_cm - height_cm * 0.05, 'm'); bg.push_back(x_cm + xmax * height_cm * 1.05, y_cm - height_cm * 0.05, 'l'); bg.push_back(x_cm + xmax * height_cm * 1.05, y_cm + xmax * height_cm * 1.05, 'l'); bg.push_back(x_cm - height_cm * 0.05, y_cm + xmax * height_cm * 1.05, 'l'); bg.fill(units_cm); _griState.set_color_line(fg_color); p.fill(units_cm); break; case 4: // draw over offset underlay _griState.set_color_line(bg_color); p.translate(+height_cm * dx, -height_cm * dy); p.fill(units_cm); p.translate(-height_cm * dx, +height_cm * dy); _griState.set_color_line(fg_color); p.fill(units_cm); break; } // // Reset to entry values _griState.set_color_line(old_color); if (was_using_missing_value) gr_set_missing_value(old_grMissingValue); else gr_set_missing_value_none(); return true; } �����������������������������������gri/src/gr.cc���������������������������������������������������������������������������������������0000644�0001750�0001750�00000152314�13147557614�011534� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define NEW_TRANSFORM 1 // 11jun95, try new mapping method // Global variable/function names begin with _gr. // Sections of uncertain or buggy code are sometimes marked by // comments containing the strings "BUG" or "??". // Cross-dependent code is sometimes marked with comments // containing the string XREF. #include #include #include #include #include #include #include #include // Local includes #include "gr.hh" #include "postscpt.hh" #include "private.hh" #include "macro.hh" #include "GriPath.hh" #include "GriState.hh" #include "defaults.hh" #include "superus.hh" static void close_ps_file(FILE * fp); static void handle_landscape_scale(FILE * fp); static void insert_ps_header(FILE * fp, bool privacy); static void skip_ps_header(FILE * PSfile); static void create_font_encoding(const char *fontname); static char creator_name[256] = ""; static char ps_filename[256] = "gri.ps"; /* basename */ static char ps_filename_used[256] = ""; /* actual name used */ static bool user_gave_ps_filename = false; /* did user give the name? */ static int which_page = 0; /* page counter */ bool _no_bounding_box = false; extern GriState _griState; // <-> gri.cc extern bool _drawingstarted; extern int _debugFlag; // // Utilities. // // gr_multiple - is x a multiple of d (to given precision)? bool gr_multiple(double x, double d, double precision) { double epsilon; if (d < 0.0) d = -d; if (x < 0.0) x = -x; if (precision < 0.0) precision = -precision; epsilon = GRI_ABS(x - d * (floor(0.5 + x / d))); return ((epsilon < precision) ? true : false); } // // UNIVERSAL GLOBALS #define default_linewidth 0.5 #define LEN_num 50 #define LEN_lab 256 gr_pen _grCurrentPen; char _grXAxisLabel[LEN_lab]; // name of x axis char _grYAxisLabel[LEN_lab]; // name of y axis char _grNumFormat_x[LEN_num]; // format for x axis char _grNumFormat_y[LEN_num]; // format for y axis char grTempString[_grTempStringLEN]; // local scratch string char grTempString2[_grTempStringLEN]; // local scratch string double _clip_ps_xleft = 0.0, _clip_ps_ybottom = 0.0, _clip_ps_xright = 0.0, _clip_ps_ytop = 0.0; bool _clipping_is_postscript_rect = true; bool _clipping_postscript = false; /* * stdin buffer */ FBUFFER stdin_buffer = {stdin, 0, 0, 0}; /* note 0 for buffer */ /* GLOBAL scratch strings */ char _grTempString[_grTempStringLEN]; char _grTempString2[_grTempStringLEN]; // Missing values bool _grMissingValueUsed = true; double _grMissingValue = 1.0e22, _grMissingValue_tolerance = 1.0e20; double _grCmPerUser_y, /* y cm-on-page / user-unit */ _grCmPerUser_x, /* x cm-on-page / user-unit */ _grCurrentPoint_x, /* current x coordinate of pen */ _grCurrentPoint_y, /* current y coordinate of pen */ _grGrayScreenQuantum = .0625, /* gray step on mac */ _grMagx = 1.0, /* x magnification on screen */ _grMagy = 1.0, /* y magnification on screen */ _grOriginx = 0.0, /* x origin on screen */ _grOriginy = 0.0, /* y origin on screen */ _grPageHeight_cm = 27.94, /* page height in cm */ _grPageWidth_cm = 21.59, /* page width in cm */ _grPSScale_x = 1.0, /* _Mag factor for x scale on ps */ _grPSScale_y = 1.0, /* _Mag factor for y */ _grPtPerUser_x = PT_PER_CM, /* x pt-on-page / user-unit * (assume cm) */ _grPtPerUser_y = PT_PER_CM, /* y pt-on-page / user-unit * (assume cm) */ _grSymbolSize_pt, /* symbol size in point */ _grTicSize_cm, /* axis tic size */ _grPROJx0, _grPROJxfac, _grPROJy0, _grPROJyfac, _grxl, /* x left - user units */ _grxl_pt, /* x left - points */ _gryb, /* y bottom - user units */ _gryb_pt; /* y bottom - points */ double _ll_x_pt, _ll_y_pt, _ur_x_pt, _ur_y_pt; // lower-left, point units double _ll_x_us, _ll_y_us, _ur_x_us, _ur_y_us; // upper-right, user units gr_axis_properties _grTransform_x = gr_axis_LINEAR; gr_axis_properties _grTransform_y = gr_axis_LINEAR; bool _grTicsPointIn = false; int _grAxisStyle_x = 0; /* always 0 */ int _grAxisStyle_y = 0; /* 0 = falsermal, 1 = label horizontal */ bool _grDrawingDash = false; /* =1 if drawing dash part of a line */ bool _grPS_Landscape = false; /* flag for landscape */ //bool _grPS_Landscape = true; /* flag for landscape */ int _grSpecifications = 1; /* specifications in gr_begin */ int _grNumSubDiv_x; /* # x-subdivision per labelled tic */ int _grNumSubDiv_y; /* # x-subdivision per labelled tic */ bool _grNeedBegin = true; /* Need to call gr_begin()? */ bool _grPathExists = false; /* does a postscript 'path' exist? */ bool _grWritePS = true; /* ==1 if postscript to be written */ // The output may be in PostScript or SVG FILE *_grPS; FILE *_grSVG; // Local prototypes. static void set_page_characteristics(); // Always returns true bool gr_textsave(const char *s) { static bool first = true; unsigned int len; len = strlen(s); if (first == true) { stdin_buffer.fp = stdin; GET_STORAGE(stdin_buffer.buf, char, 2 + len); strcpy(stdin_buffer.buf, s); first = false; } else { stdin_buffer.buf = (char *)realloc(stdin_buffer.buf, 2 + len + stdin_buffer.buf_capacity); strcat(stdin_buffer.buf, s); } strcat(stdin_buffer.buf, "\n"); stdin_buffer.buf_capacity += 1 + len; return true; } /* * gr_textget (s, max) Get a line of text. If the line ends in backslash, * get next line and concatenate the two together; if succeeding lines end in * backslash, continue the contatenation. RETURN VALUE 1 if got text; 0 if * got EOF. */ bool gr_textget(char *s, int max) { int most = max; bool got_eof = gr_buffgets(s, most, &stdin_buffer); //printf("DEBUG %s:%d in gr_textget. got_eof=%d\n",__FILE__,__LINE__,int(got_eof)); if (got_eof) { /* * No newline at end of file. Paste one on. */ strcat(s, "\n"); return false; } else { int len; while ((len = strlen(s)) > 1 && s[len - 2] == '\\' && most > 0) { most += len - 1; got_eof = gr_buffgets(s + len - 2, most, &stdin_buffer); if (got_eof) { /* * No newline at end of file. Paste one on. */ strcat(s, "\n"); return true; } } return true; } } /* * Get string from io buffer, or from io file, if buffer empty. Stop reading * when newline or eof encountered. * * Return true if got to eof of the file. */ bool gr_buffgets(char *s, unsigned int most, FBUFFER * fbuf) { //printf("DEBUG %s:%d in gr_buffgets fbuf at %x\n",__FILE__,__LINE__,int(fbuf)); if (fbuf->buf_position < fbuf->buf_capacity) { //printf("DEBUG getting from buf...\n"); unsigned int i; for (i = 0; i < most - 1; i++) { s[i] = fbuf->buf[fbuf->buf_position++]; if (s[i] == '\n') break; if (fbuf->buf_position >= fbuf->buf_capacity) break; /* will lose some characters, but no warning */ } s[i + 1] = '\0'; //printf("DEBUG buf provided <%s>\n",s); } else { #ifdef HAVE_LIBREADLINE char *line; line = readline("gri: "); if (line) { if (strlen(line) > 0) { add_history(line); } } else { return true; } // Tack a newline on end strcpy(s, line); int n = strlen(s); s[n] = '\n'; s[n+1] = '\0'; free(line); if (feof(stdin)) return true; #else fgets(s, most, (FILE *) fbuf->fp); if (feof(fbuf->fp)) return true; #endif } return false; } // print string void gr_textput(const char *s) { unsigned int l = strlen(s); for (unsigned int i = 0; i < l; i++) { if (s[i] == '\\') { if (i < l - 2) { if (s[i + 1] == '>' && s[i + 2] == '>') { putc('\t', stdout); i++; i++; continue; } else if (s[i + 1] == '<' && s[i + 2] == '<') { putc('\n', stdout); i++; i++; continue; } } } putc(s[i], stdout); } } bool delete_ps_file() { //printf("%s:%d delete_ps_file. _grPS at %x\n",__FILE__,__LINE__,int(_grPS)); extern output_file_type _output_file_type; if (_output_file_type == postscript) { if (_grPS != NULL) { fclose(_grPS); _grPS = NULL; } return delete_file(ps_filename_used); } else { return true; } } // gr_begin() -- prepare for plotting. // specifications==1 normal case // specifications==2 restarting, so don't default stuff void gr_begin(int specifications) { extern output_file_type _output_file_type; if (_output_file_type == postscript) { int version; _grNeedBegin = false; _grSpecifications = specifications; // open gri.ps file, avoiding overwriting existing ones //printf("DEBUG 1\n"); if (user_gave_ps_filename) { //printf("DEBUG 2. '%s'\n",ps_filename); strcpy(ps_filename_used, ps_filename); } else { #if defined(VMS) // On vax, just use version numbers sprintf(ps_filename_used, "%s", ps_filename); #else for (version = 0; version < 9999; version++) { FILE *trial; sprintf(ps_filename_used, "gri-%02d.ps", version); trial = fopen(ps_filename_used, "r"); if (NULL == trial) break; fclose(trial); } #endif } _grPS = fopen(ps_filename_used, "w+"); //printf("%s:%d opened _grPS at %x\n",__FILE__,__LINE__,int(_grPS)); // if can't open file, try again if (_grPS == NULL) { int ok_after_all = false; #if defined(HAVE_GETENV) char homename[100]; if (getenv("home")) { strcpy(homename, getenv("home")); strcat(homename, "/gri.ps"); strcpy(ps_filename_used, homename); _grPS = fopen(ps_filename_used, "w+"); if (_grPS == NULL) { sprintf(_grTempString, "\ Cannot open output PostScript file named\n\t`%s'\nin this directory. Do you have write permission here?", ps_filename_used); gr_textput(_grTempString); gri_exit(1); } else { ok_after_all = 1; } } #endif if (ok_after_all) { sprintf(_grTempString, "Couldn't create intended postscript file, so created `%s' instead\n", ps_filename_used); warning(_grTempString); } else { sprintf(_grTempString, "\ Cannot open output PostScript file named\n\t`%s'\nin this directory. Do you have write permission here?", ps_filename); gr_textput(_grTempString); gri_exit(1); } } // write some header stuff in postscript file _grWritePS = true; // define postscript abbreviations insert_ps_header(_grPS, true); } if (specifications == 1) set_page_characteristics(); } static void set_page_characteristics() { gr_setfont(gr_font_Helvetica); gr_setfontsize_pt(-1.0); _griState.set_linewidth_line(LINEWIDTH_DEFAULT); gr_setsymbolsize_cm(0.2); gr_setticdirection(false); // point out gr_setticsize_cm(0.2); gr_setxlabel("x"); gr_setylabel("y"); gr_setxnumberformat("%g"); gr_setynumberformat("%g"); gr_setxpagesize_cm(21.59); gr_setypagesize_cm(27.94); gr_setxtransform(gr_axis_LINEAR); gr_setytransform(gr_axis_LINEAR); gr_setxscale(0.0, 1.0, 0.0, 1.0); gr_setyscale(0.0, 1.0, 0.0, 1.0); gr_setxsubdivisions(1); gr_setysubdivisions(1); _grPathExists = true; } static void insert_ps_header(FILE * fp, bool privacy) { extern output_file_type _output_file_type; if (_output_file_type == postscript) { /* * write conforming postscript prolog */ fprintf(fp, "%%!PS-Adobe-2.0 EPSF-1.2\n"); if (privacy) fprintf(fp, "%%%%Creator: %s\n", ""); else fprintf(fp, "%%%%Creator: %s\n", creator_name); fprintf(fp, "%%%%Title: %s\n", ps_filename_used); SECOND_TYPE sec; time(&sec); fprintf(fp, "%%%%CreationDate: %s", asctime(localtime(&sec))); fprintf(fp, "%%%%Pages: (atend)\n"); fprintf(fp, "%%%%BoundingBox: (atend)\n"); extern rectangle _bounding_box; fprintf(fp, "%% trial bounding box %f %f %f %f\n", _bounding_box.llx(), _bounding_box.lly(), _bounding_box.urx(), _bounding_box.ury()); fprintf(fp, "%%%%TemplateBox: %d %d %d %d\n", 0, 0, (int) (8.5 * 72.0), (int) (11.0 * 72.0)); fprintf(fp, "%%%%DocumentFonts: (atend)\n"); fprintf(fp, "%%%%Orientation: (atend)\n"); fprintf(fp, "%%%%Endcomments\n"); int i = 0; while (PS_dict[i]) fprintf(fp, "%s\n", PS_dict[i++]); handle_landscape_scale(fp); fprintf(fp, "10.0 M\n"); fprintf(fp, "1 j\n"); create_font_encoding("Courier"); create_font_encoding("Courier-Oblique"); create_font_encoding("Courier-Bold"); create_font_encoding("Courier-BoldOblique"); create_font_encoding("Helvetica"); create_font_encoding("Helvetica-Bold"); create_font_encoding("Helvetica-Oblique"); create_font_encoding("Palatino-Roman"); create_font_encoding("Palatino-Italic"); create_font_encoding("Palatino-Bold"); create_font_encoding("Palatino-BoldItalic"); create_font_encoding("Symbol"); create_font_encoding("Century"); create_font_encoding("Times-Roman"); create_font_encoding("Times-Italic"); create_font_encoding("Times-Bold"); create_font_encoding("Times-BoldItalic"); fprintf(fp, "%%%%EndProlog\n"); which_page++; fprintf(_grPS, "%%%%Page: %d %d\ngsave\n", which_page, which_page); } } static void create_font_encoding(const char *fontname) { extern output_file_type _output_file_type; if (_output_file_type == postscript) { fprintf(_grPS, "/%s findfont dup length dict begin\n" " {1 index /FID ne {def} {pop pop} ifelse } forall\n" " /Encoding ISOLatin1Encoding def\n" " currentdict\n" "end\n" "/%s-ISOLatin1 exch definefont pop\n", fontname, fontname); } } static void handle_landscape_scale(FILE * fp) { extern output_file_type _output_file_type; if (_output_file_type == postscript) { /* put landscape and scale commands in ps output file */ if (_grPS_Landscape) { fprintf(fp, "%g 0 translate 90 rotate %% Landscape\n", 8.5 * 72.0); } else { ; } fprintf(fp, "%g %g scale\n", _grPSScale_x, _grPSScale_y); } } // gr_cmtouser() -- convert cm on page to user units. COMPARE gr_usertopt(), // which is the inverse void gr_cmtouser(double x_cm, double y_cm, double *x, double *y) { // XREF -- axis transform // Do X. switch (_grTransform_x) { case gr_axis_LINEAR: *x = _grxl + (x_cm - _grxl_pt / PT_PER_CM) / _grCmPerUser_x; break; case gr_axis_LOG: *x = _grxl * pow(10.0, (x_cm - _grxl_pt / PT_PER_CM) / _grCmPerUser_x); break; default: gr_Error("unknown axis mapping (internal error)"); break; } // Do Y. switch (_grTransform_y) { case gr_axis_LINEAR: *y = _gryb + (y_cm - _gryb_pt / PT_PER_CM) / _grCmPerUser_y; break; case gr_axis_LOG: *y = _gryb * pow(10.0, (y_cm - _gryb_pt / PT_PER_CM) / _grCmPerUser_y); break; default: gr_Error("unknown axis mapping (internal error)"); break; } } // gr_comment() -- write message in postscript file (without inserting // newline) void gr_comment(const char *message) { extern output_file_type _output_file_type; if (_output_file_type == postscript && _grWritePS) fprintf(_grPS, PS_comment, message); } /* * gr_currentPSfilename() -- get name of Postscript file SYNOPSIS char * *gr_currentPSfilename(); DESCRIPTION Returns pointer to name of Postscript * file */ char *gr_currentPSfilename() { return ps_filename_used; } /* * gr_currentPSFILEpointer() -- get pointer Postscript file SYNOPSIS char * *gr_currentPSFILEpointer(); DESCRIPTION Returns pointer to Postscript file */ FILE *gr_currentPSFILEpointer() { return _grPS; } /* * gr_current_ps_landscape() -- get present landscape mode RETURN VALUE 0 if * portrait; 1 if landscape */ bool gr_current_ps_landscape() { return _grPS_Landscape; } /* * gr_currentmissingvalue() -- return current missing value */ double gr_currentmissingvalue() { return _grMissingValue; } /* * gr_currentsymbolsize_pt() -- return current symbol size in points */ double gr_currentsymbolsize_pt() { return _grSymbolSize_pt; } /* * gr_currentticsize_cm() -- get current axis ticsize in cm */ double gr_currentticsize_cm() { return _grTicSize_cm; } void gr_draw_arc_cm(bool filled, double xc, double yc, double r, double angle1, double angle2) { extern output_file_type _output_file_type; if (_output_file_type == postscript) { extern FILE *_grPS; set_environment(); set_ps_color('p'); set_line_width_curve(); if (filled) { // this block corrected by Wolfgang Voegeli, fixing SF bug 930259 fprintf(_grPS, "%.1f %.1f m %.1f %.1f %.1f %.1f %.1f arc fill\n", xc * PT_PER_CM + r * PT_PER_CM * cos(angle1 / DEG_PER_RAD), yc * PT_PER_CM + r * PT_PER_CM * sin(angle1 / DEG_PER_RAD), xc * PT_PER_CM, yc * PT_PER_CM, r * PT_PER_CM, angle1, angle2); } else { fprintf(_grPS, "%.1f %.1f m %.1f %.1f %.1f %.1f %.1f arc stroke\n", xc * PT_PER_CM + r * PT_PER_CM * cos(angle1 / DEG_PER_RAD), yc * PT_PER_CM + r * PT_PER_CM * sin(angle1 / DEG_PER_RAD), xc * PT_PER_CM, yc * PT_PER_CM, r * PT_PER_CM, angle1, angle2); } double lw = _griState.linewidth_line() / 2.0 / PT_PER_CM; rectangle bbox(xc - r - lw, yc - r - lw, xc + r + lw, yc + r + lw); bounding_box_update(bbox); } else { warning("Sorry, can only draw arcs in postscript files."); } } // gr_drawarrow_cm -- Draw a stroke-line arrow // If halfwidth>0, width of arrow head is 2*halfwidth. // If halfwidth<0, width of arrow head is 2*halfwidth*length_of_arrow. void gr_drawarrow_cm(double x, double y, double xend, double yend, double halfwidth) { double length = (xend - x) * (xend - x) + (yend - y) * (yend - y); if (length <= 0.0) return; length = sqrt(length); if (halfwidth < 0) halfwidth = -halfwidth * length; halfwidth /= length; static GriPath p(5); // use static for reuse p.clear(); p.push_back(0.0, 0.0, 'm'); p.push_back(1.0, 0.0, 'l'); p.push_back(1.0 - 3.0 * halfwidth, halfwidth, 'm'); p.push_back(1.0, 0.0, 'l'); p.push_back(1.0 - 3.0 * halfwidth, -halfwidth, 'l'); p.rotate(atan2(yend - y, xend - x) * DEG_PER_RAD); p.scale(length); p.translate(x, y); p.stroke(units_cm); } // gr_drawarrow2_cm -- Draw an outlined arrow // If halfwidth>0, width of arrow head is 2*halfwidth. // If halfwidth<0, width of arrow head is 2*halfwidth*length_of_arrow. void gr_drawarrow2_cm(double x, double y, double xend, double yend, double halfwidth) { double length = (xend - x) * (xend - x) + (yend - y) * (yend - y); if (length <= 0.0) return; // ignore zero length arrows length = sqrt(length); if (halfwidth < 0) halfwidth = -halfwidth * length; static GriPath p(9); // use static for reuse p.clear(); halfwidth /= length; p.push_back(0.0, 0.4 * halfwidth, 'm'); p.push_back(0.0, -0.4 * halfwidth, 'l'); p.push_back(1.0 - 3. * halfwidth, -0.4 * halfwidth, 'l'); p.push_back(1.0 - 3. * halfwidth, -halfwidth, 'l'); p.push_back(1.0, 0.0, 'l'); p.push_back(1.0 - 3. * halfwidth, halfwidth, 'l'); p.push_back(1.0 - 3. * halfwidth, 0.4 * halfwidth, 'l'); p.push_back(0.0, 0.4 * halfwidth, 'l'); p.push_back(0.0, -0.4 * halfwidth, 'l'); p.rotate(atan2(yend - y, xend - x) * DEG_PER_RAD); p.scale(length); p.translate(x, y); p.stroke(units_cm); } // gr_drawarrow3_cm -- Draw swept-back filled arrow // // If halfwidth>0, width of arrow head is 2*halfwidth. // If halfwidth<0, width of arrow head is 2*halfwidth*length_of_arrow. void gr_drawarrow3_cm(double x, double y, double xend, double yend, double halfwidth) { // METHOD: define arrow on unit square from (0,0) to (1,0) and then // rotate and scale as needed. double length = (xend - x) * (xend - x) + (yend - y) * (yend - y); if (length <= 0.0) return; // ignore zero length arrows length = sqrt(length); if (halfwidth < 0) halfwidth = -halfwidth * length; static GriPath p(5); // static to allow re-use of storage halfwidth /= length; // Determine angle of rotation, in degrees. double angle_deg = atan2(yend - y, xend - x) * DEG_PER_RAD; // ... fill, and then stroke, the arrow part ... p.clear(); // clear storage p.push_back(1 - 2.25 * halfwidth, 0.0, 'm'); p.push_back(1 - 3. * halfwidth, halfwidth, 'l'); p.push_back(1.0, 0.0, 'l'); p.push_back(1 - 3. * halfwidth, -halfwidth, 'l'); p.push_back(1 - 2.25 * halfwidth, 0.0, 'l'); p.rotate(angle_deg); p.scale(length); p.translate(x, y); p.fill(units_cm); p.stroke(units_cm); // ... then stroke the line. p.clear(); // clear storage p.push_back(0.0, 0.0, 'm'); p.push_back(1.0, 0.0, 'l'); p.rotate(angle_deg); p.scale(length); p.translate(x, y); p.stroke(units_cm); } /* * gr_drawerrorbars() -- draw error bars about a point SYNOPSIS void * gr_drawerrorbars (double x, double xmin, double xmax, double y, double * ymin, double ymax, int type); DESCRIPTION: Draws error bars extending from * xmin to xmax and ymin to ymax. The type of error bars is controlled by * 'type' as follows: * * 0 -> error bars done as lines drawn between the limits * * 1 -> right-angled tags added at ends of limits (NOT IMPLEMENTED) NOTE: The * pen is left at (x,y), so that to draw a symbol with error bars, do * something like this: gr_drawerrorbars(x,x-dx,x+dx,y,y-dy,y+dy,0); * gr_drawsymbol(...,gr_circ_symbol); */ void gr_drawerrorbars(double x, double xmin, double xmax, double y, double ymin, double ymax, int type) { GriPath p(5); switch (type) { case 0: default: p.push_back(xmin, y, 'm'); p.push_back(xmax, y, 'l'); p.push_back(x, ymin, 'm'); p.push_back(x, ymax, 'l'); p.push_back(x, y, 'm'); p.stroke(units_user); break; } } // gr_drawsymbol() -- draw symbol at indicated location in cm // BUG: remove the "n" and "S" when newpath/stroke business sorted void gr_drawsymbol(double xcm, double ycm, gr_symbol_type symbol_name) { extern output_file_type _output_file_type; if (_output_file_type != postscript) { warning("Sorry, can only draw symbols in postscript mode"); return; } double xpt = xcm * PT_PER_CM; double ypt = ycm * PT_PER_CM; if (_clipping_postscript && _clipping_is_postscript_rect) { if (xpt > _clip_ps_xright || xpt < _clip_ps_xleft || ypt > _clip_ps_ytop || ypt < _clip_ps_ybottom) { //printf("clip xrange (%f %f) pt\n",_clip_ps_xleft,_clip_ps_xright); //printf("clip yrange (%f %f) pt\n",_clip_ps_ybottom,_clip_ps_ytop); //printf("clipping (%.0f , %.0f)\n",xpt,ypt); return; } } extern bool _warn_offpage; if (_warn_offpage && ( xcm < OFFPAGE_LEFT || xcm > OFFPAGE_RIGHT || ycm < OFFPAGE_BOTTOM || ycm > OFFPAGE_TOP)) { warning("Drawing a symbol at a location that is offpage."); } switch (symbol_name) { case gr_plus_symbol: fprintf(_grPS, "n %.1f %.1f m %.1f _plus S\n", xpt, ypt, _grSymbolSize_pt); break; case gr_times_symbol: fprintf(_grPS, "n %.1f %.1f m %.1f _times S\n", xpt, ypt, _grSymbolSize_pt); break; case gr_box_symbol: fprintf(_grPS, "n %.1f %.1f m %.1f _box S\n", xpt, ypt, _grSymbolSize_pt); break; case gr_circ_symbol: fprintf(_grPS, "n %.1f %.1f m %.1f _circ S\n", xpt, ypt, _grSymbolSize_pt); break; case gr_diamond_symbol: fprintf(_grPS, "n %.1f %.1f m %.1f _diamond S\n", xpt, ypt, _grSymbolSize_pt); break; case gr_triangleup_symbol: fprintf(_grPS, "n %.1f %.1f m %.1f _triangleup S\n", xpt, ypt, _grSymbolSize_pt); break; case gr_triangleright_symbol: fprintf(_grPS, "n %.1f %.1f m %.1f _triangleright S\n", xpt, ypt, _grSymbolSize_pt); break; case gr_triangledown_symbol: fprintf(_grPS, "n %.1f %.1f m %.1f _triangledown S\n", xpt, ypt, _grSymbolSize_pt); break; case gr_triangleleft_symbol: fprintf(_grPS, "n %.1f %.1f m %.1f _triangleleft S\n", xpt, ypt, _grSymbolSize_pt); break; case gr_asterisk_symbol: fprintf(_grPS, "n %.1f %.1f m %.1f _plus S\n", xpt, ypt, _grSymbolSize_pt); fprintf(_grPS, "n %.1f %.1f m %.1f _times S\n", xpt, ypt, _grSymbolSize_pt); break; case gr_star_symbol: fprintf(_grPS, "n %.1f %.1f m %.1f _triangleup S\n", xpt, ypt, _grSymbolSize_pt); fprintf(_grPS, "n %.1f %.1f m %.1f _triangledown S\n", xpt, ypt, _grSymbolSize_pt); break; case gr_filledbox_symbol: fprintf(_grPS, "n %.1f %.1f m %.1f _filledbox S\n", xpt, ypt, _grSymbolSize_pt); break; case gr_bullet_symbol: fprintf(_grPS, "n %.1f %.1f m %.1f _bull S\n", xpt, ypt, _grSymbolSize_pt); break; case gr_filleddiamond_symbol: fprintf(_grPS, "n %.1f %.1f m %.1f _filleddiamond S\n", xpt, ypt, _grSymbolSize_pt); break; case gr_filledtriangleup_symbol: fprintf(_grPS, "n %.1f %.1f m %.1f _filledtriangleup S\n", xpt, ypt, _grSymbolSize_pt); break; case gr_filledtriangleright_symbol: fprintf(_grPS, "n %.1f %.1f m %.1f _filledtriangleright S\n", xpt, ypt, _grSymbolSize_pt); break; case gr_filledtriangledown_symbol: fprintf(_grPS, "n %.1f %.1f m %.1f _filledtriangledown S\n", xpt, ypt, _grSymbolSize_pt); break; case gr_filledtriangleleft_symbol: fprintf(_grPS, "n %.1f %.1f m %.1f _filledtriangleleft S\n", xpt, ypt, _grSymbolSize_pt); break; case gr_filledhalfmoonup_symbol: fprintf(_grPS, "n %.1f %.1f m %.1f _filledhalfmoonup S\n", xpt, ypt, _grSymbolSize_pt); break; case gr_filledhalfmoondown_symbol: fprintf(_grPS, "n %.1f %.1f m %.1f _filledhalfmoondown S\n", xpt, ypt, _grSymbolSize_pt); break; default: // tiny (1.0 mm) triangle { double old_grSymbolSize_pt = gr_currentsymbolsize_pt(); gr_setsymbolsize_cm(0.1); fprintf(_grPS, "n %.1f %.1f m %.1f _triangledown S\n", xpt, ypt, _grSymbolSize_pt); gr_setsymbolsize_pt(old_grSymbolSize_pt); } break; } rectangle box(xcm - _grSymbolSize_pt / 2 / PT_PER_CM, ycm - _grSymbolSize_pt / 2 / PT_PER_CM, xcm + _grSymbolSize_pt / 2 / PT_PER_CM, ycm + _grSymbolSize_pt / 2 / PT_PER_CM); bounding_box_update(box); _drawingstarted = true; } // // gr_end() -- end this plot // If filename == "" then the window stays open, and the gri-00.ps PostScript // file is closed. // // If filename == "!" then the window is closed. If the filename is a valid // filename, then the window stays open, and the PostScript file is copied // into the indicated file. // // If the filename is "!" followed by a valid filename, then the window // is closed and the PostScript is copied to the indicated file. void gr_end(const char *filename) { extern bool _drawingstarted; if (!_drawingstarted) { delete_ps_file(); return; } extern output_file_type _output_file_type; if (_output_file_type == postscript || _output_file_type == gif) { extern bool _grNeedBegin; extern bool _grPathExists; extern FILE *_grPS; if (_grNeedBegin) return; fprintf(_grPS, PS_showpage); fprintf(_grPS, "%%%%Trailer\n"); extern rectangle _bounding_box; extern rectangle _page_size; if (_no_bounding_box) { // use fullpage if (_page_size.llx() != _page_size.urx()) { fprintf(_grPS, "%%%%BoundingBox: %d %d %d %d\n", int(_page_size.llx()), int(_page_size.lly()), int(_page_size.urx()), int(_page_size.ury())); } else { fprintf(_grPS, "%%%%BoundingBox: %d %d %d %d\n", 0, 0, int( 8.5 * PT_PER_IN), int(11.0 * PT_PER_IN)); } } else { extern bool _user_gave_bounding_box; rectangle bbox; if (_user_gave_bounding_box) { extern rectangle _bounding_box_user; bbox.set(_bounding_box_user.llx(), _bounding_box_user.lly(), _bounding_box_user.urx(), _bounding_box_user.ury()); } else { if (_page_size.llx() == _page_size.urx()) { bbox.set(_bounding_box.llx(), _bounding_box.lly(), _bounding_box.urx(), _bounding_box.ury()); } else { bbox.set(LARGER_ONE(_bounding_box.llx(), _page_size.llx()), LARGER_ONE(_bounding_box.lly(), _page_size.lly()), SMALLER_ONE(_bounding_box.urx(), _page_size.urx()), SMALLER_ONE(_bounding_box.ury(), _page_size.ury())); } } double ll_x, ll_y, ur_x, ur_y; if (_grPS_Landscape) { gr_rotate_xy(bbox.llx(), bbox.lly(), 90, &ll_x, &ll_y); gr_rotate_xy(bbox.urx(), bbox.ury(), 90, &ur_x, &ur_y); ll_x += 2.54 * 8.5; ur_x += 2.54 * 8.5; double tmp = ll_x; ll_x = ur_x; ur_x = tmp; } else { ll_x = bbox.llx(); ll_y = bbox.lly(); ur_x = bbox.urx(); ur_y = bbox.ury(); } #define POS(x) ((x) > 0 ? int(x) : 0) if (_user_gave_bounding_box) { fprintf(_grPS, "%%%%BoundingBox: %d %d %d %d\n", POS(ll_x * PT_PER_CM), POS(ll_y * PT_PER_CM), POS(ur_x * PT_PER_CM), POS(ur_y * PT_PER_CM)); } else { fprintf(_grPS, "%%%%BoundingBox: %d %d %d %d\n", POS(floor(-1.5 + ll_x * PT_PER_CM)), POS(floor(-1.5 + ll_y * PT_PER_CM)), POS(floor( 2.5 + ur_x * PT_PER_CM)), POS(floor( 2.5 + ur_y * PT_PER_CM))); } #undef POS } fprintf(_grPS, "%%%%DocumentFonts: Courier Helvetica Palatino-Roman Palatino-Italic Symbol Times-Roman\n"); fprintf(_grPS, "%%%%Pages: %d\n", which_page); fprintf(_grPS, "%%%%Orientation: %s\n",_grPS_Landscape?"Landscape":"Portrait"); _grPathExists = false; user_gave_ps_filename = false; // See if filename was specified if ((strlen(filename) > 0)) { if (filename[0] == '!') { if (strlen(filename) > 1 && filename[1] != ' ') { // save to named file gr_save_postscript(filename + 1, 1); close_ps_file(_grPS); return; } else { // close without renaming close_ps_file(_grPS); return; } } else if (filename[0] != ' ') { gr_save_postscript(filename, 1); close_ps_file(_grPS); } } } else if (_output_file_type == svg) { fprintf(_grSVG, "\n"); // FIXME: should perhaps compress it... } } // gr_end() static void close_ps_file(FILE * fp) { #if 0 extern rectangle _bounding_box; printf("FILE %s | %d | close_ps_file() | bounding box LLx LLy URx URy %d %d %d %d\n", __FILE__, __LINE__, int(_bounding_box.llx() * PT_PER_CM), int(_bounding_box.lly() * PT_PER_CM), int(_bounding_box.urx() * PT_PER_CM), int(_bounding_box.ury() * PT_PER_CM)); #endif fclose(fp); _grNeedBegin = true; } // gr_error() -- write an fatal message, then die void gr_error(const char *lab) { sprintf(grTempString, "\nFATAL error: %s\n", lab); gr_textput(grTempString); abort_gri(); } void abort_gri() { //abort(); exit(1); } /* * (hue, saturation, value) in (enforced) range from 0 to 1 is translated * to (red, green, blue) in range 0 to 1. Inputs are clipped to range 0 * to 1 if they are outside the range. * * Algorithm: Foley + Van Dam */ void gr_hsv2rgb(double h, double s, double v, double *r, double *g, double *b) { h = 6.0 * pin0_1(h); s = pin0_1(s); v = pin0_1(v); int i = (int) floor(h); if (i > 5) i = 5; // Prevent problem if hue is exactly 1 double f = h - i; double p = v * (1.0 - s); double q = v * (1.0 - s * f); double t = v * (1.0 - s * (1.0 - f)); switch (i) { case 0: *r = v; *g = t; *b = p; break; case 1: *r = q; *g = v; *b = p; break; case 2: *r = p; *g = v; *b = t; break; case 3: *r = p; *g = q; *b = v; break; case 4: *r = t; *g = p; *b = v; break; case 5: default: *r = v; *g = p; *b = q; break; } } // Is value missing? (No notice of whether x or y.) bool gr_missing(double x) { //printf("gr_missing(%lf) ... ",x); if (_grMissingValueUsed) { //printf("GRI MISSING VALUE USED ... "); if (_grMissingValue == 0.0) // ignore tolerance if 0 return (x == 0.0); if (x == _grMissingValue) { // speed up (?) //printf("GRI MISSING VALUE was exact match\n"); return true; } x = GRI_ABS(x - _grMissingValue); if (x < _grMissingValue_tolerance) { //printf("GRI MISSING VALUE was match within tolerance\n"); return true; } else { //printf("GRI MISSING VALUE no match within tolerance\n"); return false; } } else { //printf("GRI MISSING VALUE no missing value used\n"); return false; } } // Is x-value missing? (Notice the x-transform.) bool gr_missingx(double x) { extern gr_axis_properties _grTransform_x; if (_grTransform_x == gr_axis_LOG && x <= 0.0) return true; if (_grMissingValue == 0.0) return (x == 0.0); if (x == _grMissingValue) return true; x = GRI_ABS(x - _grMissingValue); if (x < _grMissingValue_tolerance) return true; else return false; } // Is y-value missing? bool gr_missingy(double y) { extern gr_axis_properties _grTransform_y; if (_grTransform_y == gr_axis_LOG && y <= 0.0) return true; if (_grMissingValue == 0.0) return (y == 0.0); if (y == _grMissingValue) return true; y = GRI_ABS(y - _grMissingValue); if (y < _grMissingValue_tolerance) return true; else return false; } // Move the pen to new location given in points void gr_moveto_cm(double x_cm, double y_cm) { double x_pt = x_cm * PT_PER_CM; double y_pt = y_cm * PT_PER_CM; extern FILE *_grPS; // take care of postscript stuff extern output_file_type _output_file_type; if (_output_file_type == postscript) { if (_grWritePS) { if (_grPathExists) { // a path exists fprintf(_grPS, PS_stroke); fprintf(_grPS, PS_weak_newpath); fprintf(_grPS, PS_moveto, x_pt, y_pt); } else { // make new path _grPathExists = true; fprintf(_grPS, PS_weak_newpath); fprintf(_grPS, PS_moveto, x_pt, y_pt); } } _grCurrentPoint_x = x_pt; _grCurrentPoint_y = y_pt; } } // See gr_onxpage_cm() -- see if point is on the page bool gr_onxpage_cm(double x_cm) { return ((x_cm >= 0.0 && x_cm <= _grPageWidth_cm) ? true : false); } // See if point is on the page bool gr_onypage_cm(double y_cm) { return ((y_cm >= 0.0 && y_cm <= _grPageHeight_cm) ? true : false); } // gr_record_handle() -- record a handle in the Postscript file (for later // use by X window previewer, etc) void gr_record_handle(double x_cm, double y_cm) { sprintf(grTempString, "^ handle %g %g\n", x_cm, y_cm); gr_comment(grTempString); } // gr_record_scale() -- record the scale in the Postscript file (for later // use by X window previewer, etc) void gr_record_scale() { extern output_file_type _output_file_type; if (_output_file_type == postscript) { fprintf(_grPS, "%%^ scale %d %g %g %g %d %g %g %g\n", _grTransform_x, _grxl_pt, _grxl, _grPtPerUser_x, _grTransform_y, _gryb_pt, _gryb, _grPtPerUser_y); } } // rgb values each in range 0 to 1; result in same range void gr_rgb2cmyk(double R[], double G[], double B[], unsigned int n, double c[], double m[], double y[], double k[]) { double Cp, Mp, Yp; for( unsigned int i = 0; i < n; i += 1 ) { Cp = 1.0 - R[i]; Mp = 1.0 - G[i]; Yp = 1.0 - B[i]; k[i] = Cp; if (Mp < k[i]) k[i] = Mp; if (Yp < k[i]) k[i] = Yp; // min if (k[i] == 1.0) { c[i] = 0.0; m[i] = 0.0; y[i] = 0.0; } else { c[i] = (Cp - k[i]) / (1.0 - k[i]); m[i] = (Mp - k[i]) / (1.0 - k[i]); y[i] = (Yp - k[i]) / (1.0 - k[i]); } } } /* * (red, green, blue) in range from 0 to 1 is translated to (hue, saturation, * brightness) in same range. * * NOTE: false checking on range of (r,g,b) is done, and strange results may result * outside this range. * * Algorithm: Foley + Van Dam */ void gr_rgb2hsb(double r, double g, double b, double *h, double *s, double *br) { double mx, mn; double rc, gc, bc; mx = r; if (g > mx) mx = g; if (b > mx) mx = b; mn = r; if (g < mn) mn = g; if (b < mn) mn = b; *br = mx; if (mx) *s = (mx - mn) / mx; else *s = 0.0; if (*s) { rc = (mx - r) / (mx - mn); gc = (mx - g) / (mx - mn); bc = (mx - b) / (mx - mn); if (r == mx) *h = bc - gc; else if (g == mx) *h = 2.0 + rc - bc; else if (b == mx) *h = 4.0 + gc - rc; *h /= 6.0; if (*h < 0.0) *h = *h + 1.0; } else { *h = 0.0; /* doesn't matter, since black anyway */ } } // Move the pen to new location given in cm void gr_rmoveto_cm(double rx_cm, double ry_cm) { rx_cm *= PT_PER_CM; ry_cm *= PT_PER_CM; gr_rmoveto_pt(rx_cm, ry_cm); } // Move the pen to new location given in pt void gr_rmoveto_pt(double rx_pt, double ry_pt) { extern FILE *_grPS; if (!_grPathExists) warning("IGNORING gr_rmoveto() NOT FOLLOWING gr_moveto()"); else { _grCurrentPoint_x += rx_pt; _grCurrentPoint_y += ry_pt; if (_grWritePS) fprintf(_grPS, PS_rmoveto, rx_pt, ry_pt); } } // // change to putting output into named file bool gr_reopen_postscript(const char *new_name) { FILE *new_file; int i = 0; fflush(_grPS); rewind(_grPS); if ((new_file = fopen((char *) new_name, "w")) == NULL) return false; // couldn't open it while (!feof(_grPS)) { i++; if (NULL == fgets(grTempString, _grTempStringLEN, _grPS)) break; if (feof(_grPS)) break; fputs(grTempString, new_file); } fclose(_grPS); #ifdef VMS sprintf(grTempString, "DEL %s;*", gr_currentPSfilename()); call_the_OS(grTempString, __FILE__, __LINE__); strcpy(ps_filename_used, new_name); #else sprintf(grTempString, "rm -f %s", gr_currentPSfilename()); call_the_OS(grTempString, __FILE__, __LINE__); strcpy(ps_filename_used, new_name); #endif _grPS = new_file; return true; } // gr_save_postscript() -- save postscript file SYNOPSIS void // gr_save_postscript(char *PS_name, int normal_scale) DESCRIPTION: Saves the // postscript commands into the file named 'PS_name'. If normal_scale==1, // it's at normal scale; otherwise, it's at screen scale void gr_save_postscript(const char *PS_name, int normal_scale) { FILE *PS_file; // Rewind gr file. Then skip header rewind(_grPS); skip_ps_header(_grPS); // Open the postscript output file, then write header if ((PS_file = fopen((char *) PS_name, "w")) == NULL) { sprintf(grTempString, "Can't open postscript file `%s'", PS_name); gr_Error(grTempString); } extern rectangle _bounding_box; printf("%s%d gr_save_postscript() ... bounding box %f %f %f %f\n", __FILE__, __LINE__, _bounding_box.llx(), _bounding_box.lly(), _bounding_box.urx(), _bounding_box.ury()); if (normal_scale) { double old_grMagx = _grMagx, old_grMagy = _grMagy; double old_grOriginx = _grOriginx, old_grOriginy = _grOriginy; _grMagx = 1.0; _grMagy = 1.0; _grOriginx = 0.0; _grOriginy = 0.0; insert_ps_header(PS_file, true); _grMagx = old_grMagx; _grMagy = old_grMagy; _grOriginx = old_grOriginx; _grOriginy = old_grOriginy; } else insert_ps_header(PS_file, true); while (!feof(_grPS)) { if (NULL == fgets(grTempString, _grTempStringLEN, _grPS)) break; if (feof(_grPS)) break; fputs(grTempString, PS_file); } fclose(PS_file); } // gr_save_postscript() static void skip_ps_header(FILE * PSfile) { char S[256]; int header_lines; /* * Skip header if it exists */ if (NULL == fgets(S, 256, PSfile)) gr_Error("PostScript file is empty"); if (feof(PSfile)) gr_Error("PostScript file is empty"); if (!strcmp(S, "%!\n")) { /* old-style */ if (NULL == fgets(S, 256, PSfile)) gr_Error("PostScript file is nearly empty"); if (feof(PSfile)) gr_Error("PostScript file is nearly empty"); if (1 == sscanf(&S[1], "%d header lines follow\n", &header_lines)) { while (header_lines-- > 0) { if (NULL == fgets(S, 256, PSfile)) gr_Error("badly formed (old-style) header"); if (feof(PSfile)) gr_Error("badly formed (old-style) header"); } } else { gr_Error("badly formed (old-style) header"); } } else if (!strcmp(S, "%!PS-Adobe-1.0\n")) /* new-style */ while (strncmp(S, "%%Page:", 7)) { if (NULL == fgets(S, 256, PSfile)) gr_Error("badly formed header"); if (feof(PSfile)) gr_Error("badly formed header"); } } bool gr_using_missing_value() { return _grMissingValueUsed; } void gr_set_missing_value(double x) { _grMissingValueUsed = true; _grMissingValue = x; _grMissingValue_tolerance = 0.0001 * GRI_ABS(x); } void gr_set_missing_value_none() { //printf("%s:%d TURNING OFF missing value.\n",__FILE__,__LINE__); _grMissingValueUsed = false; } /* * gr_setxaxisstyle(int xstyle) Set style for x axis. Presently there are no * options, so xstyle is ignored. */ void gr_setxaxisstyle(int xstyle) { _grAxisStyle_x = xstyle; } /* * gr_setyaxisstyle(int ystyle) Set style for y axis. If ystyle = 0 (the * default), the y label is written vertically. If ystyle = 1, the y label * is written horizontally. */ void gr_setyaxisstyle(int ystyle) { _grAxisStyle_y = ystyle; } /* * gr_setscale() -- set scale for PostScript */ void gr_setscale(double xfactor, double yfactor) { fprintf(_grPS, "%g %g scale\n", xfactor, yfactor); } /* * gr_setsymbolsize_pt() -- set symbol size in pt */ void gr_setsymbolsize_pt(double size_pt) { _grSymbolSize_pt = size_pt; } // Specify whether tics point in void gr_setticdirection(bool tics_point_in) { _grTicsPointIn = tics_point_in ? true : false; } /* * gr_setticsize_cm() -- set tic size SYNOPSIS void gr_setticsize_cm(double * new_size) DESCRIPTION: Sets the size of tics on further axis drawing to * 'new_size',in cm. */ void gr_setticsize_cm(double new_size) { _grTicSize_cm = new_size; } /* * gr_settranslate() -- set translation (x,y) for PostScript */ void gr_settranslate(double xcm, double ycm) { fprintf(_grPS, "%g %g translate\n", xcm * PT_PER_CM, ycm * PT_PER_CM); } // gr_setup_creatorname() -- set up creator name for PostScript prolog // SYNOPSIS void gr_setup_creatorname(char *s) DESCRIPTION: Sets up // creator name for PostScript prolog void gr_setup_creatorname(const char *s) { strcat(creator_name, s); } // gr_setup_ps_filename() -- name file for postscript output // DESCRIPTION: Set the name for the // postscript output. If this function isn't called prior to gr_begin(), the // filename will be 'gri-00.ps'. As with all gr functions begining with the // letters 'gr_setup_ps_', this has an effect ONLY if it preceeds plotting // calls which affect the pen. void gr_setup_ps_filename(const char *new_name) { //printf("%s:%d gr_setup_ps_filename(%s)\n",__FILE__,__LINE__,new_name); if (_grNeedBegin) { user_gave_ps_filename = true; if (strlen(new_name) > 0) strcpy(ps_filename, new_name); else strcpy(ps_filename, "gri.ps"); } } /* * gr_setup_ps_landscape() -- set ps printer to landscape mode * * NOTE: Must call before gr_begin() */ void gr_setup_ps_landscape() { double t0 = _grPageWidth_cm; _grPS_Landscape = true; _grPageWidth_cm = _grPageHeight_cm; _grPageHeight_cm = t0; } void gr_setup_ps_portrait() { //double t0 = _grPageWidth_cm; _grPS_Landscape = false; //_grPageWidth_cm = _grPageHeight_cm; //_grPageHeight_cm = t0; } /* * gr_setup_ps_scale() -- set enlargement factors for x and y on ps printer * SYNOPSIS void gr_setup_ps_scale(double xfactor,double yfactor) * DESCRIPTION: Scales the plot on the page,by multiplying by the factors * 'xfactor' and 'yfactor'. Note that x and y are exchanged on page if * gr_setup_grPS_Landscape() is also called. NOTE: Must call before * gr_begin(). */ void gr_setup_ps_scale(double xfactor, double yfactor) { _grPSScale_x = xfactor; _grPSScale_y = yfactor; _grPageWidth_cm *= xfactor; _grPageHeight_cm *= yfactor; } // gr_setxlabel() -- set name for x-axis void gr_setxlabel(const char *xlab) { strncpy(_grXAxisLabel, xlab, LEN_lab); } // gr_setxnumberformat() -- set format for numbers void gr_setxnumberformat(const char *xformat) { strncpy(_grNumFormat_x, xformat, LEN_num); } // gr_setxpagesize_cm() -- set page size for x // DESCRIPTION: Sets page size to 'x_cm'. // Future x pen locations should be in range [0,x_cm]. If 'x_cm'<0,use // default of 21.59. void gr_setxpagesize_cm(double x_cm) { if (x_cm <= 0.0) { double default_value = 21.59; sprintf(grTempString, "(gr_setxpagesize_cm): USED %g INSTEAD OF 'x_cm'=%g", default_value, x_cm); warning(grTempString); _grPageWidth_cm = default_value; } else { _grPageWidth_cm = x_cm; } } // gr_setxscale() -- set the scale for x void gr_setxscale(double xl_cm, double xr_cm, double xl, double xr) { // XREF -- axis transform /* set up scale */ _grxl_pt = xl_cm * PT_PER_CM; switch (_grTransform_x) { case gr_axis_LINEAR: _grxl = xl; _grCmPerUser_x = (xr_cm - xl_cm) / (xr - xl); #if 1 _ll_x_pt = xl_cm * PT_PER_CM; _ur_x_pt = xr_cm * PT_PER_CM; _ll_x_us = xl; _ur_x_us = xr; #endif break; case gr_axis_LOG: if (xl <= 0.0 || xr <= 0.0) { gr_Error("Log axis requires x values to exceed 0.\n"); } _grxl = xl; _grCmPerUser_x = (xr_cm - xl_cm) / log10(xr / xl); break; default: gr_Error("unknown axis transformation (internal error)"); break; } _grPtPerUser_x = _grCmPerUser_x * PT_PER_CM; /* test for weirdness */ double error_test = GRI_ABS(_grxl_pt / PT_PER_CM - xr_cm); if (error_test < 0.1) { sprintf(grTempString, "(gr_setxscale): _grxl_pt/PT_PER_CM=%g VERY CLOSE TO xr_cm=%g", _grxl_pt / PT_PER_CM, xr_cm); warning(grTempString); } if (error_test == 0.0) { sprintf(grTempString, "(gr_setxscale): _grxl_pt/PT_PER_CM = %g == xr_cm=%g", _grxl_pt / PT_PER_CM, xr_cm); warning(grTempString); } } /* * gr_setxsubdivisions() -- set # subdivisions on x-axis SYNOPSIS void * gr_setxsubdivisions(int num) DESCRIPTION: Sets the number of subdivisions * between numbered tics to 'num' */ void gr_setxsubdivisions(int num) { if (num > 0 && num < 100) _grNumSubDiv_x = num; else _grNumSubDiv_x = 1; } // gr_setxtransform() -- set transform for x-mapping void gr_setxtransform(gr_axis_properties xstyle) { // XREF -- axis transform _grTransform_x = xstyle; } // gr_setylabel() -- set name for y-axis void gr_setylabel(const char *ylab) { strncpy(_grYAxisLabel, ylab, LEN_lab); } // gr_setynumberformat() -- set format for numbers on y-axis void gr_setynumberformat(const char *yformat) { strncpy(_grNumFormat_y, yformat, LEN_num); } // gr_setypagesize_cm() -- set page size for y void gr_setypagesize_cm(double y_cm) { if (y_cm <= 0.0) { double default_value = 27.94; sprintf(grTempString, "(gr_setypagesize_cm): USED %g INSTEAD OF 'y_cm'=%g", default_value, y_cm); warning(grTempString); _grPageHeight_cm = default_value; } else { _grPageHeight_cm = y_cm; } } // gr_setyscale() -- set the scale for y void gr_setyscale(double yb_cm, double yt_cm, double yb, double yt) { // XREF -- axis transform /* set up scale */ _gryb_pt = yb_cm * PT_PER_CM; switch (_grTransform_y) { case gr_axis_LINEAR: _gryb = yb; _grCmPerUser_y = (yt_cm - yb_cm) / (yt - yb); #if 1 _ll_y_pt = yb_cm * PT_PER_CM; _ur_y_pt = yt_cm * PT_PER_CM; _ll_y_us = yb; _ur_y_us = yt; #endif break; case gr_axis_LOG: if (yb <= 0.0 || yt <= 0.0) { gr_Error("Log axis requires y values to exceed 0.\n"); } _gryb = yb; _grCmPerUser_y = (yt_cm - yb_cm) / log10(yt / yb); break; default: gr_Error("unknown y transform"); // impossible to get here break; } _grPtPerUser_y = _grCmPerUser_y * PT_PER_CM; /* test for weirdness */ double error_test = GRI_ABS(_gryb_pt / PT_PER_CM - yt_cm); if (error_test < 0.1) { sprintf(grTempString, "(gr_setyscale): _gryb_pt/PT_PER_CM=%g VERY CLOSE TO yt_cm=%g", _gryb_pt / PT_PER_CM, yt_cm); warning(grTempString); } if (error_test == 0.0) { sprintf(grTempString, "(gr_setyscale): _gryb_pt/PT_PER_CM=%g == yt_cm=%g", _gryb_pt / PT_PER_CM, yt_cm); warning(grTempString); } } /* end of gr_setyscale() */ /* * gr_setysubdivisions() -- set # subdivisions on y-axis SYNOPSIS void * gr_setysubdivisions(int num) DESCRIPTION: Corresponds to * gr_setxsubdivisions(). */ void gr_setysubdivisions(int num) { if (num > 0 && num < 100) _grNumSubDiv_y = num; else _grNumSubDiv_y = 1; } // gr_setytransform() -- set transform for y-mapping void gr_setytransform(gr_axis_properties ystyle) { _grTransform_y = ystyle; } // gr_showpage() -- print this page, and start a new one void gr_showpage() { fprintf(_grPS, PS_showpage); handle_landscape_scale(_grPS); which_page++; fprintf(_grPS, "grestore\n%%%%Page: %d %d\ngsave\n", which_page, which_page); #if 0 // as per PSG change, 98-oct-1 fprintf(_grPS, "/Helvetica findfont 12.00 sc sf\n"); // need some font (guess this one)! #endif } // Convert user units to cm on page,, using gr_usertopt void gr_usertocm(double x, double y, double *x_cm, double *y_cm) { gr_usertopt(x, y, x_cm, y_cm); *x_cm /= PT_PER_CM; *y_cm /= PT_PER_CM; } double gr_usertocm_x(double x, double y) { double x_cm, y_cm; gr_usertopt(x, y, &x_cm, &y_cm); return (x_cm / PT_PER_CM); } double gr_usertocm_y(double x, double y) { double x_cm, y_cm; gr_usertopt(x, y, &x_cm, &y_cm); return (y_cm / PT_PER_CM); } /* * gr_usertopt() -- convert user units to points on the page. This is a base * routine used by all drawing routines. * * Adding projections: change this, also gr_cmtouser(), also * show_axesCmd()/show.c. * * * Known projections: * * LINEAR: scale to page units, then plot. * * LOG: log transform, scale to page units, then plot. * */ void gr_usertopt(double x, double y, double *x_pt, double *y_pt) { // XREF -- axis transform double xx, yy; switch (_grTransform_x) { case gr_axis_LINEAR: #if NEW_TRANSFORM *x_pt = interpolate_linear(x, _ll_x_us, _ll_x_pt, _ur_x_us, _ur_x_pt); #else *x_pt = _grxl_pt + (x - _grxl) * _grPtPerUser_x; #endif break; case gr_axis_LOG: if (x <= 0.0) { sprintf(_grTempString, "can't use negative x (%g) with LOG axis.", x); gr_Error(_grTempString); } else { xx = log10(x / _grxl); *x_pt = _grxl_pt + xx * _grPtPerUser_x; } break; default: gr_Error("unknown x transform"); // impossible to get here } switch (_grTransform_y) { case gr_axis_LINEAR: #if NEW_TRANSFORM *y_pt = interpolate_linear(y, _ll_y_us, _ll_y_pt, _ur_y_us, _ur_y_pt); #else *y_pt = _gryb_pt + (y - _gryb) * _grPtPerUser_y; #endif break; case gr_axis_LOG: if (y <= 0.0) { sprintf(_grTempString, "can't use negative y (%g) with LOG axis.", y); gr_Error(_grTempString); } else { yy = log10(y / _gryb); *y_pt = _gryb_pt + yy * _grPtPerUser_y; } break; default: gr_Error("unknown y transform"); } } void gr_set_clip_ps_off() { if (_clipping_postscript) { fprintf(_grPS, "S Q %% turn clipping off\n"); check_psfile(); _clipping_postscript = false; } } void gr_set_clip_ps_rect(double ll_x_pt, double ll_y_pt, double ur_x_pt, double ur_y_pt) { extern output_file_type _output_file_type; if (_output_file_type == svg) { warning("cannot yet clip in svg files"); } else if (_output_file_type == postscript) { if (_clipping_postscript) { fprintf(_grPS, "S Q %% turn existing clipping off since user forgot to\n"); check_psfile(); } _clip_ps_xleft = SMALLER_ONE(ll_x_pt, ur_x_pt); _clip_ps_ybottom = SMALLER_ONE(ll_y_pt, ur_y_pt); _clip_ps_xright = LARGER_ONE(ll_x_pt, ur_x_pt); _clip_ps_ytop = LARGER_ONE(ll_y_pt, ur_y_pt); /*DEK*/ //printf("DEBUG: am setting clip to xl=%f xr=%f yb=%f yt=%f\n", _clip_ps_xleft, _clip_ps_xright, _clip_ps_ybottom, _clip_ps_ytop); /*DEK*/ // why do I not have "Q" to finish it off? // why do I not have "W*" to finish it off? /*DEK*/ fprintf(_grPS, "q n\n"); fprintf(_grPS, "%f %f moveto\n", _clip_ps_xleft, _clip_ps_ybottom); fprintf(_grPS, "%f %f lineto\n", _clip_ps_xright, _clip_ps_ybottom); fprintf(_grPS, "%f %f lineto\n", _clip_ps_xright, _clip_ps_ytop); fprintf(_grPS, "%f %f lineto\n", _clip_ps_xleft, _clip_ps_ytop); fprintf(_grPS, "h W\n"); fprintf(_grPS, "n %% turn clipping on\n"); check_psfile(); _clipping_is_postscript_rect = true; //printf("%s:%d set RECT ps clip\n",__FILE__,__LINE__); _clipping_postscript = true; } } void gr_set_clip_ps_curve(const double *xc, const double *yc, unsigned int len) { if (_clipping_postscript) { fprintf(_grPS, "S Q %% `set clip to curve' first must turn remnant clipping off\n"); check_psfile(); } fprintf(_grPS, "q n %% `set clip to curve' setting clipping on\n"); bool need_moveto = true; for (unsigned int i = 0; i < len; i++) { if (!gr_missingx(double(*xc)) && !gr_missingy(double(*yc))) { double xpt, ypt; gr_usertopt(*xc, *yc, &xpt, &ypt); if (need_moveto) fprintf(_grPS, "%f %f moveto\n", xpt, ypt); else fprintf(_grPS, "%f %f lineto\n", xpt, ypt); need_moveto = false; } else { need_moveto = true; } xc++; yc++; } fprintf(_grPS, "h W\n"); fprintf(_grPS, "n %% turn clipping on\n"); check_psfile(); //printf("%s:%d set CURVE ps clip\n",__FILE__,__LINE__); _clipping_is_postscript_rect = false; _clipping_postscript = true; //_clipData = -1; // KEEP?? } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/GriState.cc���������������������������������������������������������������������������������0000644�0001750�0001750�00000010631�13147557614�012641� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ //#define DEBUG_DASH 1 #include #include "GriColor.hh" #include "GriState.hh" #include "gr.hh" #include "types.hh" #include "errors.hh" #include "defaults.hh" GriState::GriState() { the_line_cap = 0; the_line_join = 1; the_linewidth_axis = LINEWIDTHAXIS_DEFAULT; the_linewidth_line = LINEWIDTH_DEFAULT; the_linewidth_symbol = LINEWIDTHSYMBOL_DEFAULT; the_font.size_pt = FONTSIZE_PT_DEFAULT; the_font.id = FONT_DEFAULT; is_separate_text_color = false; the_trace = false; the_superuser = 0; colorLine.setRGB(0.0, 0.0, 0.0); colorText.setRGB(0.0, 0.0, 0.0); } GriState::GriState(const GriState& n) { if ((n.color_line()).get_type() == GriColor::rgb) colorLine.setRGB((n.color_line()).getR(), (n.color_line()).getG(), (n.color_line()).getB()); else colorLine.setHSV((n.color_line()).getH(), (n.color_line()).getS(), (n.color_line()).getV()); colorLine.setT(n.color_line().getT()); if (n.color_text().get_type() == GriColor::rgb) colorText.setRGB((n.color_text()).getR(), (n.color_text()).getG(), (n.color_text()).getB()); else colorText.setHSV((n.color_text()).getH(), (n.color_text()).getS(), (n.color_text()).getV()); colorText.setT(n.color_text().getT()); the_font.id = (n.font()).id; the_font.size_pt = (n.font()).size_pt; the_line_cap = n.line_cap(); the_line_join = n.line_join(); the_linewidth_axis = n.linewidth_axis(); the_linewidth_line = n.linewidth_line(); the_linewidth_symbol = n.linewidth_symbol(); the_superuser = n.superuser(); the_trace = n.trace(); the_dash.erase(the_dash.begin(), the_dash.end()); for (unsigned int i = 0; i < (n.the_dash).size(); i++) the_dash.push_back(n.the_dash[i]); #ifdef DEBUG_DASH printf("GriState COPY CONSTRUCTOR LEAVING dash: "); for (unsigned int i = 0; i < (n.the_dash).size(); i++) printf(" %f ", the_dash[i]); printf("\n"); #endif } GriState& GriState::operator=(const GriState& n) { if (n.color_line().get_type() == GriColor::rgb) { colorLine.setRGB((n.color_line()).getR(), (n.color_line()).getG(), (n.color_line()).getB()); } else { colorLine.setHSV((n.color_line()).getH(), (n.color_line()).getS(), (n.color_line()).getV()); } colorLine.setT(n.color_line().getT()); if (n.color_text().get_type() == GriColor::rgb) { colorText.setRGB((n.color_text()).getR(), (n.color_text()).getG(), (n.color_text()).getB()); } else { colorText.setHSV((n.color_text()).getH(), (n.color_text()).getS(), (n.color_text()).getV()); } colorText.setT(n.color_text().getT()); the_font.id = (n.font()).id; the_font.size_pt = (n.font()).size_pt; the_line_cap = n.line_cap(); the_line_join = n.line_join(); the_linewidth_axis = n.linewidth_axis(); the_linewidth_line = n.linewidth_line(); the_linewidth_symbol = n.linewidth_symbol(); the_superuser = n.superuser(); the_trace = n.trace(); the_dash.erase(the_dash.begin(), the_dash.end()); // for (unsigned int i = 0; i < (n.the_dash).size(); i++) // the_dash.push_back(n.the_dash[i]); std::vector n_dash(n.dash()); for (unsigned int i = 0; i < n_dash.size(); i++) the_dash.push_back(n_dash[i]); #ifdef DEBUG_DASH printf("GriState ASSIGNMENT CONSTRUCTOR LEAVING dash: "); for (unsigned int i = 0; i < (n.the_dash).size(); i++) printf(" %f ", the_dash[i]); printf("\n"); #endif return *this; } GriState::~GriState() { colorText.~GriColor(); // BUG: should I be calling the destructor?? colorLine.~GriColor(); // BUG: should I be calling the destructor?? } �������������������������������������������������������������������������������������������������������gri/src/smooth.cc�����������������������������������������������������������������������������������0000644�0001750�0001750�00000015001�13147557614�012424� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include "gr.hh" #include "extern.hh" #include "GMatrix.hh" bool smooth_grid_dataCmd(void); bool smoothCmd(void); bool smooth_xCmd(void); bool smooth_yCmd(void); bool smoothCmd() { if (_nword > 1) { if (!strcmp(_word[1], "grid")) smooth_grid_dataCmd(); else if (!strcmp(_word[1], "x")) smooth_xCmd(); else if (!strcmp(_word[1], "y")) smooth_yCmd(); else err("`smooth' what?? (valid options x|y|grid)"); } else { err("`smooth' needs more info (valid options x|y|grid)"); return false; } return true; } bool smooth_xCmd() { if (!_columns_exist) { warning("No x data exist yet. Try `read columns x y'"); return false; } if (_nword < 2 || _nword > 3) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } unsigned int n = _colX.size() - 1; std::vector copy(_colX.size(), 0.0); // Copy all, to get endparts for (unsigned int i = 0; i < n; i++) copy[i] = _colX[i]; if (_nword == 2) { copy[0] = _colX[0]; copy[_colX.size() - 1] = _colX[_colX.size() - 1]; for (unsigned int i = 1; i < n; i++) { double x0 = _colX[i]; double xleft = _colX[i - 1]; double xright = _colX[i + 1]; if (!gr_missingx(x0) && !gr_missingx(xleft) && !gr_missingx(xright)) { copy[i] = 0.25 * (xleft + xright) + 0.5 * x0; } else { copy[i] = gr_currentmissingvalue(); } } } else if (_nword == 3) { double tmp; unsigned int halfwidth; if (!getdnum(_word[2], &tmp)) { err("Can't read .n. in `\\", _word[2], "'.", "\\"); return false; } halfwidth = int(0.5 + floor(tmp) / 2); if (halfwidth < 1) { err("Improper .n.; require >= 3"); return false; } if (halfwidth >= n) { err("Improper .n.; require < n / 2"); return false; } for (unsigned int i = halfwidth; i <= n - halfwidth; i++) { int j, nsum = 0; double sum = 0.0; for (j = -int(halfwidth); j <= int(halfwidth); j++) { double tmp = _colX[i + j]; if (0 < (1 + (i + j)) && (i + j) <= n && !gr_missingx(tmp)) { sum += tmp; nsum++; } } if (nsum > 0) { copy[i] = sum / nsum; } else { copy[i] = gr_currentmissingvalue(); } } } else { fatal_err("Programming error in `smooth x'"); } for (unsigned int i = 0; i < n; i++) _colX[i] = copy[i]; return true; } bool smooth_yCmd() { if (!_columns_exist) { warning("No y data exist yet. Try `read columns x y'"); return false; } if (_nword < 2 || _nword > 3) { demonstrate_command_usage(); NUMBER_WORDS_ERROR; return false; } unsigned int n = _colY.size() - 1; // Copy all, to get endparts std::vector copy(_colY.size(), 0.0); for (unsigned int i = 0; i < n; i++) copy[i] = _colY[i]; if (_nword == 2) { copy[0] = _colY[0]; copy[_colY.size() - 1] = _colY[_colY.size() - 1]; for (unsigned int i = 1; i < n; i++) { double y0 = _colY[i]; double yleft = _colY[i - 1]; double yright = _colY[i + 1]; if (!gr_missingy(y0) && !gr_missingy(yleft) && !gr_missingy(yright)) { copy[i] = 0.25 * (yleft + yright) + 0.5 * y0; } else { copy[i] = gr_currentmissingvalue(); } } } else if (_nword == 3) { double tmp; unsigned int halfwidth; if (!getdnum(_word[2], &tmp)) { err("Can't read .n. in `\\", _word[2], "'.", "\\"); return false; } halfwidth = int(0.5 + floor(tmp) / 2); if (halfwidth < 1) { err("Improper .n.; require >= 3"); return false; } if (halfwidth >= n) { err("Improper .n.; require < n / 2"); return false; } for (unsigned int i = halfwidth; i <= n - halfwidth; i++) { int j, nsum = 0; double sum = 0.0; for (j = -halfwidth; j <= int(halfwidth); j++) { double tmp = _colY[i + j]; if (0 < (1 + (i + j)) && (i + j) <= n && !gr_missingy(tmp)) { sum += tmp; nsum++; } } if (nsum > 0) { copy[i] = sum / nsum; } else { copy[i] = gr_currentmissingvalue(); } } } else { fatal_err("Programming error in `smooth y'"); } for (unsigned int i = 0; i < n; i++) _colY[i] = copy[i]; return true; } // `smooth grid data [.f.|{along x|y}]' bool smooth_grid_dataCmd() { if (!word_is(1, "grid")) { // should not occur err("correct syntax 'smooth grid data [.f]'"); return false; } // check that data exist if (!grid_exists()) { err("grid does not exist yet"); return false; } int method; double f = 1.0; switch (_nword) { case 3: // `smooth grid data' f = 1.0; method = 0; break; case 4: // `smooth grid data .f.' getdnum(_word[3], &f); if (f < 0.0) { warning("`smooth grid data .f.' clipping .f. to 0"); f = 0.0; } else if (f > 1.0) { warning("`smooth grid data .f.' clipping .f. to 1"); f = 1.0; } method = 0; break; case 5: // `smooth grid data along x|y' if (!word_is(3, "along")) { err("Fourth word must be `along'"); return false; } if (word_is(4, "x")) { method = 1; } else if (word_is(4, "y")) { method = 2; } else { err("Last word must be `x' or `y'"); return false; } f = 1.0; break; default: NUMBER_WORDS_ERROR; return false; } GriMatrix legitS; GriMatrix zS; zS.set_size(_num_xmatrix_data, _num_ymatrix_data); legitS.set_size(_num_xmatrix_data, _num_ymatrix_data); // // NOTE: I noticed in 2.068 that I was filling in the holes // which is stupid, as Peggy Sullivan from UW pointed out. So // from 2.069 on I don't fill in the holes. gr_smootharray(1.0, 1.0, 1.0, _f_xy, zS, _legit_xy, legitS, _num_xmatrix_data, _num_ymatrix_data, method); for (unsigned int i = 0; i < _num_xmatrix_data; i++) { for (unsigned int j = 0; j < _num_ymatrix_data; j++) { _f_xy(i, j) = (1.0 - f) * _f_xy(i, j) + f * zS(i, j); _legit_xy(i, j) = legitS(i, j); } } return true; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/GriState.hh���������������������������������������������������������������������������������0000644�0001750�0001750�00000006632�13147557614�012661� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define DASH #if !defined(_GriState_h_) #define _GriState_h_ //#define DEBUG_GRISTATE // Debug #include #include // part of STL #include "gr.hh" #include "GriColor.hh" // The graphics state. Important global object; see also state.cc. class GriState { public: GriState(); GriState(const GriState& n); GriState& operator=(const GriState& n); ~GriState(); // // Members to set values... void set_color_line(const GriColor& c) {colorLine = c; } void set_color_text(const GriColor& c) {colorText = c; } #ifdef DASH void set_dash(std::vector d) {the_dash = d; } #endif void set_transparency_line(double tr) {colorLine.setT(tr); } void set_transparency_text(double tr) {colorText.setT(tr); } void set_separate_text_color(bool f) {is_separate_text_color = f; } void set_fontsize(double fs) {the_font.size_pt = fs; } void set_font(gr_font f) {the_font = f; } void set_line_cap(int c) {the_line_cap = c; } void set_line_join(int j) {the_line_join = j; } void set_linewidth_axis(double w) {the_linewidth_axis = w; } void set_linewidth_line(double w) {the_linewidth_line = w; } void set_linewidth_symbol(double w) {the_linewidth_symbol = w; } void set_superuser(unsigned int s) {the_superuser = s; } void set_trace(bool t) {the_trace = t; } // // Members to get values... const GriColor& color_line() const {return colorLine; } const GriColor& color_text() const {return colorText; } bool separate_text_color() const {return is_separate_text_color; } gr_font font() const {return the_font; } int line_cap() const {return the_line_cap; } int line_join() const {return the_line_join; } double linewidth_axis() const {return the_linewidth_axis; } double linewidth_line() const {return the_linewidth_line; } double linewidth_symbol() const {return the_linewidth_symbol; } unsigned int superuser() const {return the_superuser; } bool trace() const {return the_trace; } #ifdef DASH const std::vector dash() const { //printf("DEBUG: GriState returning dash of length %d\n",the_dash.size()); return the_dash;} #endif private: double the_linewidth_axis; double the_linewidth_line; double the_linewidth_symbol; int the_line_cap; int the_line_join; gr_font the_font; GriColor colorLine; GriColor colorText; bool is_separate_text_color; bool the_trace; unsigned int the_superuser; #ifdef DASH std::vector the_dash; #endif // FOR MORE, SEE extern.hh:21 }; #endif ������������������������������������������������������������������������������������������������������gri/src/DataFile.hh���������������������������������������������������������������������������������0000644�0001750�0001750�00000010411�13147557614�012576� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // Object for data files #if !defined(_DATAFILE_HH_) #define _DATAFILE_HH_ #include #include // part of STL #include #include "types.hh" #include "macro.hh" #include "CmdFile.hh" class DataFile { public: enum type {from_cmdfile, ascii, bin_unknown, bin_uchar, bin_16bit, bin_int, bin_float, bin_double, bin_netcdf}; DataFile() { extern std::vector _cmdFILE; name.assign("stdin"); if (_cmdFILE.size() > 0) { fp = _cmdFILE.end()->get_fp(); if (superuser() & FLAG_AUT1)printf(" DEBUG: %s:%d construct from cmdFILE fp= %lx ",__FILE__,__LINE__,(long unsigned int)(fp)); } else { if (superuser() & FLAG_AUT1)printf(" DEBUG: %s:%d construct from stdin fp= %lx ",__FILE__,__LINE__,(long unsigned int)(stdin)); fp = stdin; } if (fp == (FILE*)NULL) {printf("ERROR. Null fp [blank-constructor phase] %s:%d\n",__FILE__, __LINE__);} the_type = from_cmdfile; line = 1; delete_when_close = false; if (superuser() & FLAG_AUT1)printf(" ... %s:%d name= '%s'\t fp= %lx this= %lx\n",__FILE__,__LINE__,name.c_str(),long(fp),long(this)); } DataFile(const DataFile& d) { name.assign(d.get_name()); fp = d.get_fp(); //if (fp == (FILE*)NULL) {printf("ERROR. Null fp [copy-constructor phase] %s:%d\n",__FILE__, __LINE__);} netCDF_id = d.get_netCDF_id(); the_type = d.get_type(); line = d.get_line(); delete_when_close = d.get_delete_when_close(); if (superuser() & FLAG_AUT1)printf(" DEBUG: %s:%d DataFile(%lx) name= '%s'\t fp= %lx this= %lx\n",__FILE__,__LINE__,long(&d),name.c_str(),long(fp),long(this)); } DataFile(FILE* a_fp, const char* a_name, int a_netCDF_id, type a_the_type, bool a_delete_when_close) { fp = a_fp; name.assign(a_name); netCDF_id = a_netCDF_id; the_type = a_the_type; line = 0; delete_when_close = a_delete_when_close; if (superuser() & FLAG_AUT1)printf(" DEBUG: %s:%d DataFile(fp= %lx, name= '%s', ...) this= %lx\n",__FILE__,__LINE__,long(a_fp),a_name,long(this)); } ~DataFile() { if (superuser() & FLAG_AUT1)printf(" DEBUG: %s:%d DataFile::~DataFile() name= '%s'\t fp= %lx this= %lx\n",__FILE__,__LINE__, name.c_str(), long(fp), long(this)); #if 0 // BUG 2001-feb-17 -- not sure on next 2 lines name.string::~string(); // not executed #endif } DataFile& operator=(const DataFile& d) { name.assign(d.get_name()); fp = d.get_fp(); if (fp == (FILE*)NULL) {printf("ERROR. Null fp [operator= phase] %s:%d\n",__FILE__, __LINE__);} netCDF_id = d.get_netCDF_id(); the_type = d.get_type(); line = d.get_line(); delete_when_close = d.get_delete_when_close(); if (superuser() & FLAG_AUT1)printf(" DEBUG: %s:%d DataFile::operator= name= '%s'\t fp= %lx this= %lx\n",__FILE__,__LINE__, name.c_str(), long(fp), long(this)); return *this; } void set_line(int new_line) {line = new_line > 1 ? new_line : 1;} void increment_line() {line++; } const char *get_name() const {return name.c_str(); } FILE* get_fp() const {return fp; } int get_netCDF_id() const {return netCDF_id; } type get_type() const {return the_type; } int get_line() const {return line; } bool get_delete_when_close() const {return delete_when_close; } private: FILE* fp; // file pointer std::string name; // name of file, or stdin int netCDF_id; // only used if FILE_BIN_NETCDF type the_type; // int line; // current line number bool delete_when_close; // for open "...|" }; #endif // _DATAFILE_HH_ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/startup.msg���������������������������������������������������������������������������������0000644�0001750�0001750�00000000542�13147557614�013022� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� gri - scientific graphic program (version VERSION) Copyright 2017 by Dan E. Kelley; GPLv2+ licensing. Type `help' to view list of commands. Type `show license' to view license. Examples at: PREFIX/share/gri/doc/examples Manual at: PREFIX/share/gri/doc/html/index.html Info Manual at: gri Resources at: http://gri.sourceforge.net ��������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/query.cc������������������������������������������������������������������������������������0000644�0001750�0001750�00000017134�13147557614�012271� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // #define DEBUG #include #include #include "extern.hh" #include "private.hh" #include "gr.hh" extern char _grTempString[]; static bool find_hint_and_def(char *hint, char *def); static void show_valid_choices(char *hint, char *def_word[], int def_words); // `query \synonym|.variable ["\prompt" [(DEFAULT[s])]' #define NCHAR 256 bool queryCmd() { char hint[NCHAR]; char answer[NCHAR]; char def[NCHAR], *def_word[NCHAR]; unsigned int def_words = 0; bool user_replied = true; if (_nword < 2) { demonstrate_command_usage(); err("`query' what?"); return false; } // Check that target synonym or variable is well-formed. if (!is_syn(_word[1]) && !is_var(_word[1])) { demonstrate_command_usage(); err("Can't interpret `\\", _word[1], "' as a synonym or variable name.", "\\"); return false; } answer[0] = '\0'; // prevent problems later if (!find_hint_and_def(hint, def)) { return false; } *def_word[0] = '\0'; chop_into_words(def, def_word, &def_words, NCHAR); // Strip off double-quotes form list of defaults for (unsigned int i = 0; i < def_words; i++) { if (*def_word[i] == '"') { def_word[i] = 1 + def_word[i]; if (*(def_word[i] + strlen(def_word[i]) - 1) == '"') { *(def_word[i] + strlen(def_word[i]) - 1) = '\0'; } } } if (_use_default_for_query) { strcpy(answer, def_word[0]); } else { // In non-batch mode, print prompt and default if (!batch()) { if (hint[0] != '\0') { switch (def_words) { case 0: sprintf(_grTempString, "%s : ", hint); gr_textput(_grTempString); break; default: show_valid_choices(hint, def_word, def_words); break; } } else { sprintf(_grTempString, "Please give value of %s ", _word[1]); gr_textput(_grTempString); } beep_terminal(); } // Get the answer gr_textget(answer, NCHAR); answer[strlen(answer) - 1] = '\0'; // If no string supplied, use default if have one if (strlen(answer) < 1) { if (def[0] != '\0') { strcpy(answer, def_word[0]); } else { err("No response and no default, so I won't define the synonym"); return false; } user_replied = false; } else { // They gave a string. If there was a list of acceptable // choices, check that string was in list. if (def_words > 1) { bool acceptable = false; while (!acceptable) { for (unsigned int i = 0; i < def_words; i++) { if (!strcmp(def_word[i], answer)) { acceptable = true; break; } } if (acceptable) break; gr_textput(" Sorry, this is an invalid answer. Try again.\n"); show_valid_choices(hint, def_word, def_words); gr_textget(answer, LineLength_1); answer[strlen(answer) - 1] = '\0'; if (strlen(answer) < 1) { strcpy(answer, def_word[0]); break; } } } } } // Store result into the target variable or synonym if (is_syn(_word[1])) { if (!put_syn(_word[1], answer, true)) { sprintf(_grTempString, "Sorry, synonym stack exhausted; no space for `%s'", _word[1]); fatal_err(_grTempString); return false; } } else if (is_var(_word[1])) { double value; bool old = _ignore_error; _ignore_error = true; if (getdnum(answer, &value)) { PUT_VAR(_word[1], value); } else { if (user_replied) { if (!_cmdFILE.back().get_interactive()) { fatal_err("`query' cannot understand number in reply `\\", answer, "'.", "\\"); } else { err("`query' cannot understand number in reply `\\", answer, "'.", "\\"); } } else { if (!_cmdFILE.back().get_interactive()) { fatal_err("`query' cannot understand number in default `\\", answer, "'.", "\\"); } else { err("`query' cannot understand number in default `\\", answer, "'.", "\\"); } } _ignore_error = old; } } else { // Actually, this code is a repeat of code above, and this line can // never be reached in present version. But I'll keep it here for // safety upon changes. demonstrate_command_usage(); err("Can't interpret `\\", _word[1], "' as a synonym or variable name.", "\\"); return false; } return true; } static void show_valid_choices(char *hint, char *def_word[], int def_words) { if (def_words == 1) { sprintf(_grTempString, "%s (default = `%s'): ", hint, def_word[0]); gr_textput(_grTempString); } else { int i; sprintf(_grTempString, "%s (default = `%s'; choices are", hint, def_word[0]); gr_textput(_grTempString); for (i = 0; i < def_words; i++) { gr_textput(" `"); gr_textput(def_word[i]); gr_textput("'"); } gr_textput(") : "); } } // find_hint_and_def -- find hint and default. (make def="" if no default) // return true if ok, NO if deformed commandline static bool find_hint_and_def(char *hint, char *def) { hint[0] = '\0'; def[0] = '\0'; // Find and extract hint, as first quoted string. #ifdef DEBUG printf("CMDLINE [%s]\n",_cmdLine); #endif int i; int len = strlen(_cmdLine); char lastc = '\0'; int ii = 0; for (i = 0; i < len; i++) { if (*(_cmdLine + i) == '\"') { bool valid = false; i++; for (ii = 0; ii < len - i; ii++) { if (_cmdLine[i + ii] == '"' && lastc != '\\') { hint[ii] = '\0'; valid = true; break; } else { hint[ii] = _cmdLine[i + ii]; } lastc = _cmdLine[i + ii]; } if (valid) { break; } } } // Return now if no default was given ... if (i + ii == len - 1) return true; // ... or extract it, if it was given. int def_start = -1, def_end = -1; int level = 0; for (i = len - 1; i > 0; i--) { if (_cmdLine[i] == ')') { if (level++ == 0) def_end = i - 1; } else if (_cmdLine[i] == '(') { if (--level == 0) { def_start = i + 1; break; } } } if (def_start && !def_end) { err("Default is malformed; have `(' but no `)'"); return false; } if (def_end && !def_start) { err("Default is malformed; have `)' but no `('"); return false; } if (def_start > def_end) { err("No default value found inside parentheses"); return false; } if (def_start > -1 && def_end > -1) { for (i = def_start; i <= def_end; i++) def[i - def_start] = _cmdLine[i]; def[1 + def_end - def_start] = '\0'; } #ifdef DEBUG printf("HINT [%s] DEFAULT [%s]\n", hint, def); #endif // If the default is a variable, parse it into the hint // that will be presented to the user. if (is_var(def)) { #ifdef DEBUG printf("it is a var [%s]\n",def); #endif double def_value; bool ok = get_var(def, &def_value); if (ok) { sprintf(def, "%f", def_value); // BUG: assume will fit #ifdef DEBUG printf("WROTE [%s]\n",def); #endif } #ifdef DEBUG printf("def is now [%s]\n",def); #endif } return true; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/private.hh����������������������������������������������������������������������������������0000644�0001750�0001750�00000033121�13147557614�012602� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // Private definitions for gri. See also extern.hh #if !defined(_private_) #define _private_ #include #include #include #include // part of STL #include "gr.hh" #include "gr_coll.hh" #include "errors.hh" #include "files.hh" #include "GriTimer.hh" #include "DataFile.hh" #define cmd_being_done_LEN 100 // cmd stack #define LineLength 32768 // = 2^15 = max length of line #define LineLength_1 32767 // -1 + max length of line #define MAX_cmd_word 8192 // words/command #define MAX_nword 8192 // words/line #define _num_dstackMAX 50 // length of dstack #define _imageBLANK 255 // blank images with white // Next used by command.cc and utility.cc to encode & items. #define AMPERSAND_CODING "#\bn\ba\bm\be\b:\b%s \b_ \bl\be\bv\be\bl\b:\b%d#\b" // Image storage. typedef struct { int ras_magic; // magic number unsigned int ras_width; // width (pixels) of image unsigned int ras_height; // height (pixels) of image unsigned int ras_depth; // depth (1, 8, or 24 bits) of pixel unsigned int ras_length; // length (bytes) of image unsigned int ras_type; // type of file; see RT_* below unsigned int ras_maptype;// type of colormap; see RMT_* below unsigned int ras_maplength; // length (bytes) of following map unsigned char *map; // map unsigned char *image; // image bool storage_exists; // always toggle when allocating/deleting/checking memory } IMAGE; // From Sun's /usr/include/rasterfile.h #define RAS_MAGIC 0x59a66a95 #define RT_STANDARD 1 #define RMT_NONE 0 #define RMT_EQUAL_RGB 1 #define RMT_RAW 2 bool allocate_grid_storage(int nx, int ny); bool allocate_image_storage(int nx, int ny); bool allocate_imageMask_storage(int nx, int ny); bool allocate_xmatrix_storage(int n); bool allocate_ymatrix_storage(int n); bool assign_synonym(void); bool assign_to_column(int index, double value, const char* c); bool batch(void); void beep_terminal(void); bool blank_image(void); bool blank_imageMask(void); int block_level(void); const char *block_source_file(void); unsigned int block_source_line(void); unsigned int block_offset_line(void); void bounding_box_display(const char *msg); void bounding_box_update(const rectangle& box); bool locate_i_j(double xx, double yy, int *ii, int *jj); #if defined(OLD_IMAGE_INTERPOLATION) bool value_i_j(unsigned int ii, unsigned int jj, double xx, double yy, double *value); #else bool value_i_j(unsigned int ii, unsigned int jj, double xx, double yy, double *value); #endif bool calculate_image_histogram(void); int call_the_OS(const char* cmd, const char* calling_filename, int calling_line); void check_psfile(void); int chop_into_words(char *s, char **w, unsigned int *nw, unsigned int max); bool chop_into_data_words(char *s, char **w, unsigned int *nw, unsigned int max); void clear_eof_flag_on_data_file(void); void clean_blanks_quotes(std::string& c); void close_data_files(); int cmd_being_done(void); bool create_commands(const char *filename, bool user_gave_directory); bool create_color(const char *name, double r, double g, double b); bool create_new_command(FILE * fp, char *line); bool create_synonym(const char *name, const char *value); bool create_variable(const char *name, double value); bool create_x_scale(void); bool create_y_scale(void); int data_file_index(const char *name); bool define_image_scales(double llx, double lly, double urx, double ury); bool delete_file(const char *filename); bool delete_syn(const std::string& name); bool delete_var(const std::string& name); bool demonstrate_command_usage(void); void de_reference(std::string& word); void display_cmd_being_done_stack(); void display_cmd_stack(const char *s); void display_data_stack(const char *s); void display_unused_var(void); void display_unused_syn(void); bool do_command_line(void); bool draw_axes(int type, double loc, gr_axis_properties side, bool allow_offset); bool draw_axes_if_needed(void); bool draw_gri_logo(void); char *egetenv(const char *s); void end_up(void); unsigned int endian_swap_uint(unsigned int v); void expand_blanks(char *cmdline); int ExtractQuote(const char *s, std::string& sout); char *file_in_list(const char *name, bool show_nonlocal_files, bool show_local_files); const char *filename_sans_dir(const char *fullfilename); bool find_min_max(double *data, int num, double *min, double *max); bool find_min_max_v(void); bool find_min_max_x(void); bool find_min_max_y(void); bool find_min_max_z(void); void fix_negative_zero(std::string& number); void fix_line_ending(char *line); int get_cmd_values(char **w, int nw, const char *key, int nobjects, double *objects); bool get_cmdword(unsigned int index, std::string& cmdword); // index=1 gives value of \.word1. bool get_c_file_name(int old, const char *prompt, const char *name); bool get_command_line(void); bool getdnum(const char *snum, double *number); bool get_flag(const char *name); bool getinum(const char *snum, int *number); bool get_coded_value(const std::string& name, int level, std::string& result); // cf is_coded_value() bool get_nth_word(const std::string& s, unsigned int which, std::string& result); unsigned int get_number_of_words(const std::string& s); bool get_syn(const char *name, std::string& value, bool do_encoding = true); bool get_var(const char *name, double *value); void give_help(void); void gri_abort(void); void gri_exit(int code); bool gri_version_exceeds(unsigned int n1, unsigned int n2, unsigned int n3); bool grid_interp(double xx, double yy, double *value); bool grid_exists(void); bool group_end(); bool group_start(const char *id =""); bool gr_missing(double x); double gr_page_height_pt(); bool handle_if_block(void); void highpass_image(void); void histogram_stats(const double *x, unsigned int nx, double *q1, double *q2, double *q3); bool ignoreCmd(void); //bool image_exists(void); bool image_mapping_exists(void); bool image_range_exists(void); //bool imageMask_exists(void); bool image_scales_defined(void); double image_to_value(int c); int index_of_variable(const char *name, int mark = -1); int index_of_synonym(const char *name, int mark = -1); void insert_cmd_in_ps(const char *cmd, const char *note=""); bool inside_box(double x, double y); bool is_assignment_op(const char *s); bool is_column_name(const char *s); bool is_coded_string(const std::string&s, std::string& name, int* mark_level); // cvs get_coded_value() bool is_even_integer(double v); bool is_odd_integer(double v); bool is_create_new_command(const char *cmdline); bool is_punctuation(int c); bool is_syn(const char *name); bool is_syn(const std::string& name); bool is_system_command(const char *s); bool is_var(const char *name); bool is_var(const std::string& name); char last_character(const char *s); bool look_up_color(const char *name, double *red, double *green, double *blue); void lowpass_image(void); bool marker_draw(); bool marker_erase(); int marker_count(); bool massage_command_line(char *cmdline); int match_gri_syntax(const char *cmdline, int flag); bool mathCmd(void); void matrix_limits(double *min, double *max); void moment(double *data, int n, double *ave, double *adev, double *sdev, double *svar, double *skew, double *kurt); void more_file_to_terminal(const char *filename); void no_scales_error(void); int number_good_xyz(double x[], double y[], double f[], int n); unsigned int number_missing_cols(void); int parse_C_commandCmd(const char *s); bool perform_block(const char *s, const char *source_file, int source_line); bool perform_command_line(FILE * fp, bool is_which); int perform_gri_cmd(int cmd); bool perform_gri_program(void); bool perform_while_block(const char *buffer, const char *test, int lines); void pop_command_word_buffer(void); void pop_cmd_being_done_stack(void); bool pop_data_file(int file); bool print_rpn_stack(const char* msg=""); void push_cmd_being_done_stack(int cmd); bool push_cmd_file(const char *fname, bool interactive, bool allow_warning, const char *status); void push_command_word_buffer(void); bool put_var(const char *name, double value, bool replace_existing); bool put_syn(const char *name, const char *value, bool replace_existing); bool push_data_file(const char *name, DataFile::type the_type, const char *status, bool delete_when_close); bool push_data_file_to_top(const char *name); char *pwd(void); double quantize(double x, int levels, double dx); bool quoted(const char *string); bool re_compare(const char *string, const char *pattern); bool remove_comment(char *cmdline); void remove_esc_quotes(char *w); void remove_trailing_blanks(char *s); void remove_trailing_blanks(std::string& s); bool resolve_filename(std::string& fn, bool trace_path, char d_or_c); bool rpn_create_function(char *name, char **w, unsigned int nw); bool same_syntax(const char *cmdline, const char *syntax, int flag); bool same_word(const char *cp, const char *sp); bool scales_defined(void); bool set_environment(void); bool set_flagCmd(void); void set_eof_flag_on_data_file(void); void set_line_width_axis(void); void set_line_width_curve(void); void set_line_width_symbol(void); void set_ps_color(char path_or_text); void set_up_command_word_buffer(void); bool set_x_scale(void); bool set_y_scale(void); bool show_grid_maskCmd(void); bool show_next_lineCmd(void); void show_words(void); void show_var_stack(void); void show_syn_stack(); int skip_space(const char *s); int skip_nonspace(const char *s); bool skipping_through_if(void); bool start_up(int argc, char **argv); bool stop_replay_if_error(void); void strcat_c(char *s, int c); bool string_is_blank(const char *s); bool substitute_rpn_expressions(const char *cmdline, char *cmdlinecopy); bool substitute_synonyms_cmdline(const char *s, std::string& sout, bool allow_math); bool substitute_synonyms(const char *s, std::string& sout, bool allow_math); unsigned int superuser(void); void swap(double& a, double& b); bool systemCmd(void); char* tmp_file_name(); bool tracing(void); bool update_readfrom_file_name(void); void unbackslash(const char *s, std::string& res); void un_double_quote(std::string& word); void un_double_slash(std::string& word); unsigned char value_to_image(double v); void vector_reverse(double *x, int n); double vector_min(double *x, unsigned n); double vector_max(double *x, unsigned n); #if defined(VMS) void warning(va_dcl va_alist); #else void warning(const char *string, ...); #endif bool warn_if_slow(GriTimer *t, double fraction_done, const char *cmd); int what_line(void); const char *what_file(void); bool well_ordered(double min, double max, double inc); bool inc_with_range(double min, double max, double inc); bool word_is(int i, const char *word); void write_prompt(void); bool xy_to_cm(double xin, double yin, units u, double *xout, double *yout); bool xy_to_pt(double xin, double yin, units u, double *xout, double *yout); #endif // not _private_ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/Makefile.dj2��������������������������������������������������������������������������������0000644�0001750�0001750�00000005553�13147557614�012735� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Instructions for compiling on MSDOS. # # 1) There is a good chance that this Makefile will work as is, # so try that first. # # 2) If you have the 'netcdf' library (used for certain types # of atmospheric and oceanographic datasets), then un-comment # and possibly edit the appropriate NETCDF_... lines below, as # instructed by the comments preceding these lines. # # 3) If you don't want Gri inserted in the directory "c:\gri", # edit the "instdir = ..." line below. # # 4) If you get error messages about the 'stdcxx' library, edit # the "LIBS" line below, rewriting "-lstdcxx' as '-lstdcx'. # # 5) If you get compilation errors relating to 'time' or to 'ftime', # try putting the token "-DHAVE_FTIME=1" in the list of similar # token in the "DEFS = ..." line. For consistency (basically, # so the author can help you if you do this), put it right # after the "-D_GRI_=1" token. # <<> #NETCDF_DEFS = -DHAVE_NETCDF=1 #NETCDF_INCLUDE = -I/netcdf24/include #NETCDF_LIBS = -L/netcdf24/lib -lnetcdf instdir = c:\gri srcdir = . VPATH = . CC = gcc # No other compiler will do CXX = gxx AWK = gawk INSTALL = copy INSTALL_PROGRAM = $(INSTALL) INSTALL_DATA = $(INSTALL) LIBS = -lm -lstdcxx $(DBMALLOC_LIBS) $(NETCDF_LIBS) DEFS = -D_GRI_=1 -DHAVE_STDLIB_H=1 -DHAVE_ISNAN=1 -DHAVE_ISINF=1 -DHAVE_ACOSH=1 -DHAVE_GETENV=1 -DHAVE_POPEN=1 -DHAVE_TMPNAM=1 -DDEFAULT_GRI_DIR=\"$(bindir)\" -DAWK=\"$(AWK)\" $(DBMALLOC_DEFS) $(KELLEY_DEFS) -DHAVE_UNISTD_H=1 -DSTDC_HEADERS=1 -DHAVE_BOOL=1 -DHAVE_STL=1 $(NETCDF_DEFS) CFLAGS = -m486 -Wall LDFLAGS = prefix = c:/gri exec_prefix = $(prefix) binprefix = manprefix = bindir = $(exec_prefix) manext = 1 #### End of system configuration section. #### OBJS = assert.o chopword.o close.o command.o convert.o debug.o delete.o \ differ.o doline.o draw.o endup.o expect.o file.o filter.o flip.o \ graxes.o grcntour.o gr_coll.o GriColor.o grimage.o grinterp.o gri.o \ GriPath.o GriState.o gr.o grsmooth.o grstring.o G_string.o heal.o \ help.o if.o ignore.o image.o input.o insert.o interp.o mask.o math.o \ new.o open.o popen.o query.o quit.o read.o regress.o reorder.o \ rescale.o rewind.o rpncalc.o rpn.o scales.o set.o show.o skip.o \ sleep.o smooth.o source.o startup.o state.o stats.o storage.o \ synonyms.o template.o timer.o utility.o variable.o version.o while.o write.o all: gri .SUFFIXES: .cc .cc.o: $(CC) -c $(CFLAGS) $(CPPFLAGS) $(DEFS) -I$(srcdir) $(KELLEY_INCLUDE) $(NETCDF_INCLUDE) $< install: all $(INSTALL_PROGRAM) gri.exe $(instdir)\gri.exe $(INSTALL_PROGRAM) gri.cmd $(instdir)\gri.cmd gri: $(OBJS) $(CXX) -o gri $(LDFLAGS) $(OBJS) $(LIBS) del $@ clean: del gri.exe del *.o del core del *.bak del *~ mostlyclean: clean distclean: clean del Makefile del config.status realclean: distclean del TAGS �����������������������������������������������������������������������������������������������������������������������������������������������������gri/src/assert.cc�����������������������������������������������������������������������������������0000644�0001750�0001750�00000003567�13147557614�012432� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include #include "gr.hh" #include "extern.hh" #include "defaults.hh" #include "files.hh" #include "superus.hh" bool assertCmd(void); bool assertCmd() { if (_nword > 3) { demonstrate_command_usage(); err("Too many words in `assert'"); return false; } if (_nword < 2) { demonstrate_command_usage(); err("Too few words in `assert'"); return false; } double cond; if (!getdnum(_word[1], &cond)) { err("`assert' cannot decode the condition"); return false; } if (cond) { return true; } else { std::string msg; if (_nword == 3) { msg = _word[2]; clean_blanks_quotes(msg); } if (msg.empty()) { printf("Failed assertion at ?file? line ?line?.\n"); } else { if (msg.size() > 2 && msg[msg.size() - 1] == 'n' && msg[msg.size() - 2] == '\\') { ShowStr(msg.c_str()); } else { ShowStr(msg.c_str()); printf(" at ?file? line ?line?.\n"); } } gri_exit(1); return false; // never executed } } �����������������������������������������������������������������������������������������������������������������������������������������gri/src/storage.cc����������������������������������������������������������������������������������0000644�0001750�0001750�00000010605�13147557614�012564� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ //#define DEBUG_STORAGE 1 // Debug #include #include "gr.hh" #include "extern.hh" #include "image_ex.hh" #include "private.hh" extern char _grTempString[]; /* * Allocate storage. */ #define CHARLEN 50 bool create_arrays() { GET_STORAGE(_dstack, double, _num_dstackMAX); GET_STORAGE(_errorMsg, char, LineLength); GET_STORAGE(_cmdLine, char, LineLength); GET_STORAGE(_cmdLineCOPY, char, LineLength); GET_STORAGE(_imageHist, double, 256); return true; } bool allocate_image_storage(int nx, int ny) { #ifdef DEBUG_STORAGE printf("%s:%d ENTERING allocate_image_storage(%d, %d)\n",__FILE__,__LINE__,nx,ny); #endif if (nx < 0 || ny < 0) return false; _image.ras_magic = RAS_MAGIC; _image.ras_width = nx; _image.ras_height = ny; _image.ras_depth = 8; _image.ras_length = _image.ras_width * _image.ras_height; _image.ras_type = RT_STANDARD; _image.ras_maptype = RMT_NONE; _image.ras_maplength = 0; if (_image.storage_exists) free(_image.image); GET_STORAGE(_image.image, unsigned char, _image.ras_length); if (!_image.image) OUT_OF_MEMORY; _image.storage_exists = true; _imageHist_exists = false; #ifdef DEBUG_STORAGE printf("%s:%d allocate_image_storage() got storage for image %d wide and %d tall\n",__FILE__,__LINE__,_image.ras_width,_image.ras_height); #endif return true; } bool allocate_imageMask_storage(int nx, int ny) { #ifdef DEBUG_STORAGE printf("%s:%d ENTERING allocate_imageMask_storage(%d, %d)\n",__FILE__,__LINE__,nx,ny); #endif if (nx < 0 || ny < 0) return false; _imageMask.ras_magic = RAS_MAGIC; _imageMask.ras_width = nx; _imageMask.ras_height = ny; _imageMask.ras_depth = 8; _imageMask.ras_length = _imageMask.ras_width * _imageMask.ras_height; _imageMask.ras_type = RT_STANDARD; _imageMask.ras_maptype = RMT_NONE; _imageMask.ras_maplength = 0; if (_imageMask.storage_exists) { #ifdef DEBUG_STORAGE printf("%s:%d allocate_imageMask_storage() freeing up storage\n",__FILE__,__LINE__); #endif free(_imageMask.image); } GET_STORAGE(_imageMask.image, unsigned char, _imageMask.ras_length); if (!_imageMask.image) OUT_OF_MEMORY; _imageMask.storage_exists = true; for (unsigned int i = 0; i < _imageMask.ras_length; i++) *(_imageMask.image + i) = 0; _imageHist_exists = false; #ifdef DEBUG_STORAGE printf("%s:%d allocate_imageMask_storage() got storage for imageMask %d wide and %d tall\n",__FILE__,__LINE__,_imageMask.ras_width,_imageMask.ras_height); #endif return true; } bool allocate_grid_storage(int nx, int ny) { if (nx < 0 || ny < 0) return false; _num_xmatrix_data = nx; _num_ymatrix_data = ny; _f_xy.set_size(_num_xmatrix_data, _num_ymatrix_data); _f_xy.set_value(0.0); _legit_xy.set_size(_num_xmatrix_data, _num_ymatrix_data); _legit_xy.set_value(true); _grid_exists = true; return true; } bool allocate_xmatrix_storage(int cols) { if (_xgrid_exists == true) { #if defined(DEBUG_STORAGE) printf("allocate_xmatrix_storage(%d) deleting storage\n", cols); #endif delete [] _xmatrix; } _num_xmatrix_data = cols; _xmatrix = new double [_num_xmatrix_data]; if (!_xmatrix) OUT_OF_MEMORY; #if defined(DEBUG_STORAGE) printf("allocate_xmatrix_storage(%d) allocating\n", cols); #endif _xgrid_exists = true; return true; } bool allocate_ymatrix_storage(int rows) { if (_ygrid_exists == true) { #if defined(DEBUG_STORAGE) printf("allocate_ymatrix_storage(%d) deleting\n", rows); #endif delete [] _ymatrix; } _num_ymatrix_data = rows; _ymatrix = new double [_num_ymatrix_data]; if (!_ymatrix) OUT_OF_MEMORY; #if defined(DEBUG_STORAGE) printf("allocate_ymatrix_storage(%d) allocating\n", rows); #endif _ygrid_exists = true; return true; } ���������������������������������������������������������������������������������������������������������������������������gri/src/reorder.cc����������������������������������������������������������������������������������0000644�0001750�0001750�00000013706�13147557614�012567� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include "gr.hh" #include "extern.hh" /* Defined here */ bool reorder_columnsCmd(void); static bool reorder_cols_randomly(); static bool reorder_cols_order(bool ascending, int which, int n); // Following is unsafe, but I know indices are OK inline void swap(GriColumn *A, int a, int b) { if (A->size() > 0) { double *ap = A->begin(); double tmp = *(ap + (a)); *(ap + (a)) = *(ap + (b)); *(ap + (b)) = tmp; } } /* * `reorder columns randomly|{ascending in x|y|z}|{descending in x|y|z}' */ bool reorder_columnsCmd() { unsigned int n; bool ascending; switch (_nword) { case 3: if (word_is(2, "randomly")) { return reorder_cols_randomly(); } else { err("Third word must be `randomly', if only 3 words"); demonstrate_command_usage(); return false; } case 5: if (word_is(2, "ascending")) { ascending = true; } else if (word_is(2, "descending")) { ascending = false; } else { err("Third word must be `ascending' or `descending'"); demonstrate_command_usage(); return false; } if (!word_is(3, "in")) { err("Fourth word must be `in'"); demonstrate_command_usage(); return false; } n = _colX.size(); /* presume no x means no cols */ if (word_is(4, "x")) { reorder_cols_order(ascending, 0, n); } else if (word_is(4, "y")) { reorder_cols_order(ascending, 1, n); } else if (word_is(4, "z")) { reorder_cols_order(ascending, 2, n); } else { err("Fifth word must be `x', `y', or `z'"); demonstrate_command_usage(); return false; } if (n < 1) { warning("No x column exists, so ignoring `reorder' command"); return true; } break; /* not reached */ default: NUMBER_WORDS_ERROR; return false; } return false; /* not reached */ } static bool reorder_cols_randomly() { int i, inew, n; n = _colX.size(); /* presume no x means no cols */ if (n < 1) { warning("No x column exists, so ignoring `reorder' command"); return true; } // Seed, then do a few random numbers #if defined(HAVE_DRAND48) srand48(getpid()); #else srand(getpid()); #endif for (i = 0; i < n; i++) { #if defined(HAVE_DRAND48) // range is 0 to 1, but do modulus in case inew = int(drand48() * n) % n; #else inew = int(rand() % n); #endif swap(&_colX, i, inew); swap(&_colY, i, inew); swap(&_colZ, i, inew); swap(&_colU, i, inew); swap(&_colV, i, inew); swap(&_colWEIGHT, i, inew); } return true; } /* `reorder columns ascending|descending in x|y|z' */ /* Use bubble-sort (slow, but easy for me to code) */ /* Also, this code could be made a lot more terse */ static bool reorder_cols_order(bool ascending, int which, int n) { int i, inew; switch (which) { case 0: /* by x */ if (_colX.size() < 1) { warning("No x column exists, so cannot `reorder' by it"); return true; } if (ascending) { for (i = 0; i < n; i++) { for (inew = i; inew < n; inew++) { if (_colX[i] > _colX[inew]) { swap(&_colX, i, inew); swap(&_colY, i, inew); swap(&_colZ, i, inew); swap(&_colU, i, inew); swap(&_colV, i, inew); swap(&_colWEIGHT, i, inew); } } } } else { /* descending */ for (i = n - 1; i >= 0; i--) { for (inew = i; inew >= 0; inew--) { if (_colX[i] > _colX[inew]) { swap(&_colX, i, inew); swap(&_colY, i, inew); swap(&_colZ, i, inew); swap(&_colU, i, inew); swap(&_colV, i, inew); swap(&_colWEIGHT, i, inew); } } } } break; case 1: /* by y */ if (_colY.size() < 1) { warning("No y column exists, so cannot `reorder' by it"); return true; } if (ascending) { for (i = 0; i < n; i++) { for (inew = i; inew < n; inew++) { if (_colY[i] > _colY[inew]) { swap(&_colX, i, inew); swap(&_colY, i, inew); swap(&_colZ, i, inew); swap(&_colU, i, inew); swap(&_colV, i, inew); swap(&_colWEIGHT, i, inew); } } } } else { /* descending */ for (i = n - 1; i >= 0; i--) { for (inew = i; inew >= 0; inew--) { if (_colY[i] > _colY[inew]) { swap(&_colX, i, inew); swap(&_colY, i, inew); swap(&_colZ, i, inew); swap(&_colU, i, inew); swap(&_colV, i, inew); swap(&_colWEIGHT, i, inew); } } } } break; case 2: /* by z */ if (_colZ.size() < 1) { warning("No z column exists, so cannot `reorder' by it"); return true; } if (ascending) { for (i = 0; i < n; i++) { for (inew = i; inew < n; inew++) { if (_colZ[i] > _colZ[inew]) { swap(&_colX, i, inew); swap(&_colY, i, inew); swap(&_colZ, i, inew); swap(&_colU, i, inew); swap(&_colV, i, inew); swap(&_colWEIGHT, i, inew); } } } } else { /* descending */ for (i = n - 1; i >= 0; i--) { for (inew = i; inew >= 0; inew--) { if (_colZ[i] > _colZ[inew]) { swap(&_colX, i, inew); swap(&_colY, i, inew); swap(&_colZ, i, inew); swap(&_colU, i, inew); swap(&_colV, i, inew); swap(&_colWEIGHT, i, inew); } } } } break; default: return false; /* not reached */ } return true; } ����������������������������������������������������������gri/src/files.hh������������������������������������������������������������������������������������0000644�0001750�0001750�00000002370�13147557614�012234� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // define some filenames #if !defined(_files_hh_) #define _files_hh_ #if !defined(HAVE_TMPNAM) #define GRI_TMP_FILE "TMP.GRI" #endif #if defined(VMS) #define GRIRC_FILE "GRI$MACROS:GRI.RC" #define GRI_COMMANDS_FILE "GRI.CMD" #else #define GRIRC_FILE ".grirc" #define GRI_COMMANDS_FILE "gri.cmd" #endif #if defined(HAVE_LIBNETCDF) #include #endif #endif // _files_hh_ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/popen.cc������������������������������������������������������������������������������������0000644�0001750�0001750�00000012510�13147557614�012236� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include "gr.hh" #if defined(VMS) #include #include FILE *popen(); int pclose(); globalvalue CLI$M_NOWAIT; void p_describe(); /* a non-unix function */ static struct dsc$descriptor *set_dsc_cst(); static int create_mbx(); #define mailbox_size (512) #define mailbox_byte_quota (3*mailbox_size) #define mailbox_protection_mask (0x0000F000) struct popen_cell { FILE *fp; char *mbx_name; short mbx_chan; long pid; long completed; long comp_status; struct popen_cell *next; struct popen_cell *prev; }; static struct popen_cell *popen_list = NULL; static struct popen_cell * find_popen_cell(FILE * fp) { struct popen_cell *l; for (l = popen_list; l != NULL; l = l->next) if (l->fp == fp) return (l); return (NULL); } void p_describe(FILE * fp) { struct popen_cell *cell; if (!(cell = find_popen_cell(fp))) { printf("File pointer is not from popen, or it has been closed\n"); return; } printf("FILE *fp = %08X\n", cell->fp); printf("char *mbx_name = %s\n", cell->mbx_name); printf("short mbx_chan = %d\n", cell->mbx_chan); printf("long pid = %08X\n", cell->pid); printf("long completed = %d\n", cell->completed); printf("long comp_status = %d\n", cell->comp_status); printf("struct popen_cell *next = %08X\n", cell->next); printf("struct popen_cell *prev = %08X\n", cell->prev); } static void proc_exit_ast(struct popen_cell * cell) { cell->completed = 1; } static void pclose_cleanup(struct popen_cell * cell) { sys$dassgn(cell->mbx_chan); free(cell->mbx_name); if (!cell->completed) sys$delprc(&cell->pid, 0); memset(cell, 0, sizeof(struct popen_cell)); free(cell); } static void pclose_delq(struct popen_cell * cell) { if (cell->prev) { cell->prev->next = cell->next; if (cell->next) cell->next->prev = cell->prev; } else { popen_list = cell->next; if (cell->next) cell->next->prev = NULL; } } static void popen_push(struct popen_cell * cell) { if (popen_list) popen_list->prev = cell; cell->prev = NULL; cell->next = popen_list; popen_list = cell; } int pclose(FILE * fp) { int i; struct popen_cell *cell; i = fclose(fp); if (cell = find_popen_cell(fp)) { pclose_delq(cell); pclose_cleanup(cell); } return (i); } FILE * popen(char *command, char *mode) { char * temp; struct popen_cell *cell; int readp, n, mask, ret; char * name; char * prompt; char *in; char * out; struct dsc$descriptor comm_d, in_d, out_d, name_d, prompt_d; if (strcmp(mode, "r") == 0) readp = 1; else if (strcmp(mode, "w") == 0) readp = 0; else return (NULL); temp = mktemp("POPEN_MB_XXXXXXXXXX"); n = strlen(temp); get_storage(cell, 1, (struct popen_cell)); get_storage(cell->mbx_name, n + 1, char); strcpy(cell->mbx_name, temp); if ((cell->mbx_chan = create_mbx(cell->mbx_name)) < 0) { cell->completed = 1; pclose_cleanup(cell); return (NULL); } if (readp) { in = "NL:"; out = cell->mbx_name; } else { in = cell->mbx_name; out = "NL:"; } name = 0; prompt = 0; mask = CLI$M_NOWAIT; cell->completed = 0; ret = lib$spawn((command) ? set_dsc_cst(&comm_d, command) : 0, (in) ? set_dsc_cst(&in_d, in) : 0, (out) ? set_dsc_cst(&out_d, out) : 0, &mask, (name) ? set_dsc_cst(&name_d, name) : 0, &cell->pid, &cell->comp_status, 0, /* event flag */ proc_exit_ast, cell, (prompt) ? set_dsc_cst(&prompt_d, prompt) : 0, 0 /* cli */ ); if (ret != SS$_NORMAL) { cell->completed = 1; pclose_cleanup(cell); return (NULL); } if (!(cell->fp = fopen(cell->mbx_name, mode))) { pclose_cleanup(cell); return (NULL); } popen_push(cell); return (cell->fp); } static struct dsc$descriptor * set_dsc_cst(struct dsc$descriptor * x, char *buff) { (*x).dsc$w_length = strlen(buff); (*x).dsc$a_pointer = buff; (*x).dsc$b_class = DSC$K_CLASS_S; (*x).dsc$b_dtype = DSC$K_DTYPE_T; return (x); } static int create_mbx(char *name) { short chan; int prmflg, maxmsg, bufquo, promsk, acmode, iflag, retval; struct dsc$descriptor lognam; prmflg = 0; maxmsg = mailbox_size; bufquo = mailbox_byte_quota; promsk = mailbox_protection_mask; acmode = 0; set_dsc_cst(&lognam, name); retval = sys$crembx(prmflg, &chan, maxmsg, bufquo, promsk, acmode, &lognam); if (retval != SS$_NORMAL) return (-1); return (chan); } #endif /* VMS */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/gri-mode.el���������������������������������������������������������������������������������0000644�0001750�0001750�00000627230�13147557614�012646� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;; gri-mode.el - major mode for Gri, a scientific graphics programming language ;; Copyright (C) 1994-2009 Peter S. Galbraith ;; Author: Peter S. Galbraith ;; Created: 14 Jan 1994 ;; Version: 2.71 (14 Oct 2013) ;; Keywords: gri, emacs, XEmacs, graphics. ;;; This file is not part of GNU Emacs. ;; This package is free software; you can redistribute it and/or modify it ;; under the terms of the GNU General Public License version 2 or later as ;; published by the Free Software Foundation. ;; This package is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;; ---------------------------------------------------------------------------- ;;; Commentary: ;; This major mode for GNU emacs provides support for editing Gri files. ;; Gri is a graphics plotting language that produces beautiful postscript ;; output suitable for publications. Gri is written by Dan Kelley, ;; Dalhousie University. General info about Gri is available at ;; ;; http://gri.sourceforge.net ;; Full documentation on the installation and use of gri-mode.el is ;; provided in the Gri manual, included in source form in gri's source tar ;; file, in Info and HTML form in binary packages, and on-line at ;; ;; http://gri.sourceforge.net/gridoc/html/Emacs.html ;; Features of gri-mode include: ;; ;; Automatic indentation for block structures, line continuations, ;; and comments. ;; Parenthesis matching support. ;; Gri command completion (using abbreviations in your gri buffer) ;; Displays help and info-manual about the gri command on the current line. ;; Hide user commands at the beginning of gri buffers (similar to Outline ;; mode) ;; Run gri from within emacs. ;; Display (possibly compressed) postscript file associated with gri file. ;;; Installation -- Follow these 3 steps: ;; ;; 0- Configuring Emacs to load your extra .el files ;; (Debian package and Red Hat Powertools package users can skip this, ;; as it's done for them.) ;; ;; Extra .el files like gri-mode.el that are not part of Emacs should be ;; stored in a directory where Emacs will find them when you ask it to ;; load them. The files should therefore be found in Emacs' `load-path'. ;; To see the directory list currently in the load-path, do ;; ;; C-h v load-path ;; ;; If you have access to system directories, put gri-mode.el in a ;; `site-lisp' directory, such as `/usr/local/share/emacs/site-lisp/' ;; That way all users will have access to the files. ;; ;; If you don't have access to a site-lisp directory (e.g. you have only a ;; user account), then create a directory where your extra .el files will ;; be stored and add it to Emacs' load-path. For example, say you created ;; the directory ~/emacs and stored gri-mode.el there, you would then put ;; this near the top of your ~/.emacs file: ;; ;; (setq load-path (cons "~/emacs" load-path)) ;; ;; 1- Configuring gri-mode to where gri lives on your system: ;; (Debian package and Red Hat Powertools package users can skip this, ;; as it's done for them.) ;; ;; If gri is installed as /usr/local/bin/gri and /usr/local/share/gri/gri.cmd ;; on your system, go to step 2. If not, then you need to set the variable ;; gri*directory-tree. ;; ;; The Emacs variable `gri*directory-tree' is used to configure gri-mode ;; to where Gri is installed on your system. If you have only one version ;; of gri installed on your system, gri-mode expects to find gri.cmd and ;; the gri executable like so: ;; ;; `gri*directory-tree`/gri.cmd ;; and the gri executable in the PATH ;; or ;; `gri*directory-tree`/lib/gri.cmd ;; and the gri executable in the PATH ;; or ;; `gri*directory-tree`/bin/gri ;; `gri*directory-tree`/lib/gri.cmd ;; ;; However, gri-mode was designed to support, and ease the use of, multiple ;; installed versions of gri. To use this feature, you must use the gri ;; version number as a directory name under the `gri*directory-tree` path, ;; like this: ;; ;; `gri*directory-tree`/VERSION/bin/gri ;; `gri*directory-tree`/VERSION/lib/gri.cmd ;; ;; (e.g. /opt/gri/2.040/bin/gri and /opt/gri/2.040/lib/gri.cmd with ;; gri*directory-tree set to "/opt/gri") ;; ;; or without the `lib' and `bin' subdirectories if the executable is ;; found in the PATH named like `gri-VERSION' ;; ;; `gri*directory-tree`/VERSION/gri.cmd ;; gri-VERSION executable in the PATH ;; ;; (e.g. /usr/share/gri/2.1.17/gri.cmd and /usr/bin/gri-2.1.17 with ;; gri*directory-tree set to "/usr/share/gri") ;; ;; Example 1: ;; If you had multiple versions of Gri installed like so: ;; /opt/gri/2.040/bin/gri ;; /opt/gri/2.040/lib/gri.cmd ;; /opt/gri/2.041/bin/gri ;; /opt/gri/2.041/lib/gri.cmd ;; then you'd use: ;; (setq gri*directory-tree "/opt/gri/") ;; ;; Example 2: ;; If you use a Debian GNU/Linux installation like: ;; /usr/bin/gri -> /usr/bin/gri-2.1.17 ;; /usr/share/gri/2.1.17/gri.cmd ;; then you'd use: ;; (setq gri*directory-tree "/usr/share/gri/") ;; Note that since there is no /usr/share/gri/bin/ directory (a similar ;; structure to /opt/gri above), all gri binaries with version number ;; suffixes must exist in the path (e.g. gri-2.1.17) ;; ;; Example 3: ;; If you use a RedHat Powertool installation like: ;; /usr/bin/gri ;; /usr/share/gri/gri.cmd ;; then you'd also use: ;; (setq gri*directory-tree "/usr/share/gri/") ;; but gri-mode would know of only one installed version of gri. ;; ;; You may have more than one tree and make a list of them: ;; (setq gri*directory-tree '("/opt/gri/" "/usr/share/gri/")) ;; ;; 2- Telling emacs to load gri-mode: ;; (Debian package users can skip this, as it's done for them.) ;; ;; To tell emacs to use this mode with .gri files, you can load gri-mode ;; whenever a new emacs session is starting by adding the following line ;; to your ~/.emacs file: ;; ;; (require 'gri-mode) ;; ;; This is a good thing specially when you only start emacs once a week and ;; use it for every file you edit (as you should). ;; If you startup a fresh emacs every time you edit (bad scientist!) ;; then you probably only want to load gri-mode into emacs when you need it. ;; In that case, instead of the `require' statement above, add the following ;; lines to your ~/.emacs file: ;; ;; (autoload 'gri-mode "gri-mode" "Enter Gri-mode." t) ;; (setq auto-mode-alist (cons '("\\.gri$" . gri-mode) auto-mode-alist)) ;; ;; 3- Extra user configuration of gri-mode ;; (all users should do this at some point) ;; ;; At this point, gri-mode should start up when you edit a gri file. You ;; may optionally customize gri-mode by using the Custom interface (see ;; the Help or Gri-Help menu). ;; ;; ---------------------------------------------------------------------------- ;;; Change log: ;; ;; V1.03 14jan94 by Peter Galbraith, rhogee@bathybius.meteo.mcgill.ca ;; Created (based on version 1.02 from Dan Kelley. See later in file.) ;; V1.03a 18jan94 - fixed bug in gri-hide-all ;; improved gri-hide-function to detect beginning of program ;; V1.04 19jan94 - gri-perform renamed gri-run ;; - gri-run is now error-smart (puts cursor on proper line) ;; - add gri-view (C-c v) ;; - move gri-version to C-c C-v ;; - don't indent comment after system line (e.g. used in sed) ;; 26jan94 - bug fix: `Unbalanced Parenthese' on gri-info and gri-help ;; - remove C-C c binding for gri-complete ;; - gri-apropos renamed gri-help-apropos ;; - bound M-q to gri-indent-region ;; - prefixed gri-indent-region indents entire buffer. ;; 31jan94 - Added menus ;; - Added C-C ? ;; - gri-function-skeleton ;; 08feb94 - Added support for hilit19.el ;; 09feb94 - Added gri*hilit-declarations variable ;; 10feb94 - Added gri*view-command and gri*view-landscape-arg variables ;; V1.05 15feb94 - gri-view checks that postscript file exists. ;; - Added gri-narrow-to-function, added to menu as well. ;; 22feb94 - debugged gri-isolate-this-command for lines with comments ;; - Added ERROR message to gri-run. ;; Don't show the shell-output-buffer window if only showing ;; the error message (no set trace on). ;; ** still can't it shell-output-buffer to display ending ** ;; - Added gri-comment-out-region (in menu) ;; - Added gri-uncomment-out-region (in menu) ;; - Added `Info Special Topics' menu ;; 28feb94 - Changed key defs from `C-c letter' to `C-c C-letter' ;; 07Mar94 - Added gri-help and gri-info w/ minibuffer completion. ;; V1.06 23Mar94 - hilit19 for /* comments new for gri V1.069 */ ;; hilit19 enhanced highlighting for hidden commands ;; V1.07 28Mar94 - hilit optionally after carriage return ;; 05Apr94 - Removed gri-system-syntax-file variable ;; - Replaced variable gri-cmd-file by gri*path ;; 07Apr94 - hilit for system <<"EOF" ;; hilit further enhanced on hidden commands ;; Added vars gri*hilit-variables and gri*hilit-rpn-contents ;; V1.08 08Apr94 - Added gri-insert-file-as-comment. ;; 13Apr94 - gri-indentation skips over foreign system code. ;; 14Apr94 - Fixed gri-help, extracting text fell short with numerics. ;; 18Apr94 - Added gri-mosaic-manual ;; 25Apr94 - expand-file-name instead of concat usage. ;; 03May94 - gri*view-after-run added ;; - Improved hilit pattern for `\synonym = system' ;; V1.09 15Jun94 - Deleted key-defs in menus (standard in emacs-19.24) ;; V1.10 07Jul94 - Fixed indentation on continued system lines (else, //) ;; - gri-hide-all would hide second line if no program existed. ;; V1.11 06Sep94 - Added gri-view for gzip'ed files. ;; V1.12 05Oct94 - C-c C-k kills contents of string or variable under cursor ;; if not within an option. ;; (still kills option, when within an option). ;; - Enhanced gri-next-option now bound to C-c C-n ;; - Moved gri-narrow-to-function to C-c M-n ;; - Bound gri-indent-buffer to M-C-v ;; V1.13 03Nov94 - Better gri-view ;; 20Dec94 - Changed WWW gri manual URL ;; - Changed gri-mosaic-manual to gri-WWW-manual ;; gri*mosaic-program to gri*WWW-program ;; - default is now Mosaic. ;; V1.14 17Feb95 - gri-close-statement added. ;; V1.15 17Feb95 - gri-close-statement fixed. ;; V1.16 23May95 - detect gri segmentation fault. ;; V1.17 09Jun95 - new way of calling gri. See gri*directory-tree variable. ;; V1.18 21Jun95 - Added gri-print ;; V1.19 28Jun95 - Added major artificial intelligence to detect bad ;; installation. I had an evening to spare! ;; V1.20 09Nov95 - emacs-19.29 bug on completion fixed. ;; V1.21 01dec95 - gri-version more flexible about gri directory names ;; V1.22 27dec95 - `M-;' still not generic emacs, but `kill-comment' and ;; `M-x comment-region' work correctly. ;; New syntax table -> font-lock won't crash! ;; New functions gri-option-select-mouse gri-kill-option-mouse ;; V1.23 22jan96 - Added gri-command-arguments and auto-mode-alist setup. ;; V1.24 11jun96 - Added new gri-insertion-filter for set-process-filter ;; Added shell-command-switch for Windows (uses "/c"). ;; V1.25 11jul96 RCS 1.1 ;; - Added *single* menu for XEmacs. Now loads under XEmacs. ;; V1.26 24jul96 RCS 1.2 ;; - Fixed XEmacs special-topics info menu. ;; - set-buffer-menubar in XEmacs so that menu disappears after. ;; V1.27 24Aug96 RCS 1.10 ;; - font-lock support. ;; - Added gri*use-hilit19. ;; - Adding gri-local-version (not finished yet). ;; V1.28 25Oct96 RCS 1.11 - Bug in gri-kill-option ;; V1.29 11Nov96 RCS 1.12 ;; - gri-set-local-version added. ;; - gri-version renamed to gri-set-version. ;; V1.30 31Dec96 RCS 1.13 - Repeat single-line output from gri-run after view ;; V1.31 11Feb97 RCS 1.14 - Better fontification of multi-line system commands. ;; V1.32 03Jun97 RCS 1.15 - `Running gri done' message. ;; V1.33 20Oct97 RCS 1.16 - Fixed font-lock for Emacs-20 ;; V1.34 21Oct97 RCS 1.17 - Fixed menu definition conditional for Emacs-20 ;; V1.35 01Dec97 RCS 1.18 - Emacs-20 outline-minor-mode invisibility. ;; V2.00 10Jul98 RCS 1.21 - gri*path removed. Allow list in gri*directory-tree. ;; V2.01 27Jul98 RCS 1.23 - skipped over a version in gri*directory-tree ;; V2.02 21Aug98 RCS 1.24 - changed gri*WWW-manual ;; V2.03 15Oct98 RCS 1.27 - added # comments; better gri-local-version control. ;; V2.04 10Jan98 RCS 1.29 - only # comments! ;; - added gri-convert-comments ;; - added gri-convert-comments-with-prompt ;; V2.05 27Jan98 RCS 1.30 - Fixed completion when case-different matches exist ;; V2.06 14May99 RCS 1.31 - Fixed `\.var. = system' detected as system line ;; V2.07 30Nov99 RCS 1.32 - Fixed gri info special topics that have changed ;; V2.08 30Nov99 RCS 1.33 - Default gri*view-command is now gv. ;; V2.09 19Dec99 RCS 1.34 - Fixed gri-info-function for xemacs20 ;; - Switch to easy-menu and added gv scale selection ;; - add gri-fontify-buffer ;; V2.10 20Dec99 RCS 1.35 - Added first XEmacs toolbar button. ;; V2.11 21Dec99 - XEmacs gv scale selection uses radio buttons ;; V2.12 19Jan00 RCS 1.36 - XEmacs-21 doesn't have variable lpr-command ;; V2.13 19Jan00 RCS 1.37 - XEmacs-21 fixes: no toolbar in -nw; no show-all ;; V2.14 29Mar00 RCS 1.38 ;; - Made gri*directory-tree default to new /usr/local/share/gri location ;; - Made RedHat setup work (/usr/bin/gri & /usr/share/gri/gri.cmd) ;; V2.15 09Apr00 RCS 1.39 - add `www' prefix to gri*WWW-page URL. ;; V2.16 13Apr00 RCS 1.40 - gri-do-run won't move to gri.cmd on error. ;; V2.17 18Apr00 RCS 1.41 - Made gri-expand-versions use -directory_default ;; in case gri*directory-tree is not set correctly. ;; V2.18 19Apr00 RCS 1.42 - ;; Removed underlines from ~/.gri-syntax file, using semicolon as separator. ;; Fixed all functions such that completions buffer now shows real names and ;; you can click on one to ener it. ;; V2.19 14May00 RCS 1.43 ;; - Use customize; update install docs; use radio buttons for gv-scale in ;; Emacs too; ;; - Fix gri-build-command-alist broken since whitespace removed in gri-syntax ;; V2.20 14May00 RCS 1.44 ;; - gri-help accepts argument (in prep for command list menu) ;; V2.21 16May00 RCS 1.45 ;; - buggy gri-match-list-to-string caused wrong completions string ;; V2.22 17May00 RCS 1.46 ;; - Added the Gri command list menubar. ;; - gri-apropos alias and bug fix for new syntax file format. ;; V2.23 18May00 RCS 1.47 ;; - eval Gri command list menubar only when gri-cmd-file is set correctly ;; - Gri info file can have .info extension now. ;; V2.24 18May00 RCS 1.48 ;; - tweaks for XEmacs (easymenu entries need `t' at end; ;; call add-submenu in gri-mode) ;; V2.25 19May00 RCS 1.49 - Removed RCS Id line to avoid confusion. ;; V2.26 19May00 RCS 1.50 ;; - gri-info-function changed to lookup `Index of Commands' instead of raw ;; list of nodes. ;; V2.27 30May00 RCS 1.51 - default web page changed to: ;; http://www.phys.ocean.dal.ca/~kelley/gri/index.html ;; V2.28 21Jun00 RCS 1.53 - Added gri*run-settings ;; - Bettered some customize entries. ;; V2.29 18Jul00 RCS 1.54 - default web page changed to: ;; http://gri.sourceforge.net/gridoc/html/index.html ;; V2.30 03Aug00 RCS 1.55 - default web page changed to: ;; "http://gri.sourceforge.net/gridoc/html/index.html" (fixes bug) ;; V2.31 03Aug00 RCS 1.56 - `gri-help pwd' was broken (improper regexp) ;; V2.32 28Aug00 RCS 1.57 ;; - Added buffer-local variable gri-command-postarguments ;; and functions gri-set-command-postarguments and ;; gri-unset-command-postarguments. ;; V2.33 29Aug00 RCS 1.58 - gri-hide-all skips over initial commands ;; V2.34 25Sep00 RCS 1.59 - allows spaces after new command brackets ;; Closes SF Bug #115307 ;; V2.35 09Jan01 RCS 1.60 - gri-mode-is-Emacs20 -> gri-mode-is-Emacs2X ;; for Emacs-21 now out in beta. ;; V2.36 07Feb01 RCS 1.61 - add ~.grirc to auto-mode-alist ;; V2.37 15Feb01 RCS 1.62 - modify syntax table for strings with embedded " ;; V2.38 20Feb01 RCS 1.63 - add display of defaults after completion (>= 2.6.0) ;; V2.39 20Feb01 RCS 1.64 - add imenu support. ;; V2.40 20Feb01 RCS 1.65 - add gri-idle-display-defaults. ;; V2.41 20Feb01 RCS 1.66 - gri-idle-display-defaults set outside of X too. ;; V2.42 21Feb01 RCS 1.67 - move idle timer startup into gri-mode proper. ;; V2.43 11Apr01 RCS 1.68 - gri-common-in-list: fix bug introduced in ;; completion of "set color" when compared to "set colorname" ;; V2.44 01May01 RCS 1.69 - XEmacs has IMenu after all. ;; V2.45 03May01 RCS 1.70 - Fix byte-compiled gri-mode's imenu from ;; imenu-progress-message macro definition (can't rely on variable ;; defined here for loading of imenu during byte-compilation). ;; (Closes SF Bug #421076) ;; V2.46 10May01 RCS 1.71 - gri-initialize-version: wrong scope for version var ;; imenu--create-gri-index: fix for few variables and synonym cases. ;; V2.47 10May01 RCS 1.72 - locally set resize-mini-windows to nil when ;; running shell--command to run gri. ;; V2.48 01Jun01 RCS 1.73 - Add emacs21 icons for gri-info and gri-view ;; V2.49 06Jun01 RCS 1.74 - "Error at FILE:LINE" now instead of "detected at" ;; V2.50 13Jul01 RCS 1.75 - Add support for completion of builtin variables. ;; gri-build-expansion-regex: detects if at end of ..var[point] ;; gri-add-variables: new function. ;; gri-perform-completion: tweak fo delete only to gri-complete-begin-point ;; V2.51 14Jul01 RCS 1.76 - Fix support for completion of builtin variables. ;; gri-lookat-syntax-file: add ARG = 3 to skip over variables. ;; gri-build-command-alist: skip over variables in syntax buffer. ;; gri-menubar-cmds-build: (gri-lookat-syntax-file 3) ;; gri-build-expansion-regex: stop at \.synonym. ;; gri-perform-completion: needed to regexp-quote the search string ;; V2.52 15Jul01 RCS 1.77 - Add set/unset-command-postarguments to Perf menubar ;; V2.53 17Jul01 RCS 1.78 - Tweak Perform menubar order. ;; V2.54 18Jul01 RCS 1.79 - Change toolbar icons to look nicer. ;; V2.55 18Jul01 RCS 1.80 - Add gri-syntax-default-this-builtin used by idle ;; timer. ;; V2.56 18Jul01 RCS 1.81 - Fontify defined builtins distinctively ;; V2.57 18Jul01 RCS 1.82 - Tweak the new local .variable. regexp for font-lock ;; V2.58 24Jul01 RCS 1.83 - Typo fix. ;; V2.59 24Jan02 RCS 1.85 - Support gv -watch option. When using gri-run, ;; an existing gv process will be stopped during figure regeneration, and ;; therafter continued. gv will then redisplay automatically. ;; V2.60 25Jan02 RCS 1.87 - Fix support for gv -watch option in Emacs20. ;; Sending (signal-process ID 'SIGCONT) doesn't change the process status ;; from 'stop, even though the process did start up again. I need to do: ;; (continue-process PROCESS) to change the status. Bug in emacs20? ;; V2.61 09May02 RCS 1.88 - Add support for 'gv -noantialias' option. ;; V2.62 21Jun02 RCS 1.89 - Make gri*view-command more customizible, with menu. ;; V2.63 31Jul02 RCS 1.90 - ;; gri-validate-version: new function, see if specified version is available. ;; gri-validate-cmd-file: new function, see if gri-cmd-file as set ik okay. ;; gri-what-version: REMOVED function. Not very useful anyway. ;; V2.64 02Apr2003 - Remove old hilit19 code. Obsolete. ;; V2.65 09Jun2003 - Added Help menu entry to gri History. ;; V2.66 17Aug2004 - Eric Nodwell ;; keybindings similar to phyton-mode to (un)comment regions. ;; V2.67 16Dec2004 ;; Adapt to new texinfo's "Index of Commands" which includes a line offset ;; number. ;; V2.68 01mar2005 ;; gri-view: Adapt to new gv options. (Closes: #296692) ;; V2.69 28may2008 ;; current-menubar: test if bound first. Guess this applied to XEmacs and ;; now this code is being run in Emacs. ;; V2.70 05dec2009 ;; gri-font-lock-system-commands is broken since Emacs v22. Use simple ;; regexp instead. ;; V2.71 14Oct2013 ;; http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=680701 ;; ---------------------------------------------------------------------------- ;;; Code: ;; The following variable may be edited to suit your site: (defgroup gri nil "Gri - Scientific graphics language" :group 'languages) (defcustom gri*directory-tree "/usr/local/share/gri" "Root of the gri directory tree. Root of the gri directory tree holding versions of gri library files. This is either a string, or a list of strings. In the following file layout, gri*directory-tree should be set to \"/usr/share/gri\" /usr/bin/gri-2.10.1 /usr/share/gri/2.10.1/gri.cmd In the following file layout, gri*directory-tree should be set to \"/opt/gri\" /opt/gri/2.1.17/bin/gri /opt/gri/2.1.17/lib/gri.cmd If you had both layouts, you'd use: (setq gri*directory-tree '(\"/opt/gri/\" \"/usr/lib/gri\")) Notes: 1 - The lib/ directory is optional. 2 - The bin/ directory may exist to hold the gri binary. If it doesn't exist, gri-mode will assume that the gri command suffixed with the version number exists in the path (e.g. /usr/bin/gri-2.1.17). This variable must be set correctly for gri-mode to function properly, and for the `gri-set-version' command to switch between gri versions. See the gri-mode.el file itself for more information." :group 'gri :type '(choice (directory) (repeat directory))) (defcustom gri-idle-display-defaults (fboundp 'run-with-idle-timer) "*t means to display function defaults under point when Emacs is idle." :group 'gri :type 'boolean) (defcustom gri-menubar-cmds-action 'Info "Default action to do on listed Gri command in Cmds menu-bar menu. This can be set to one of Info, Help or Insert." :group 'gri ;;; :type '(restricted-sexp :match-alternatives ('Info 'Help 'Insert) :type '(choice (const :tag "Info" Info) (const :tag "Help" Help) (const :tag "Insert" Insert))) (defcustom gri*run-settings nil "List of optional parameters to pass to gri when running it. This list makes the startup values used in the menubar pull-down menu." :group 'gri :type '(set (const "-debug") (const "-nowarn_offpage") (const "-no_bounding_box") (const "-publication") (const "-trace"))) (defcustom gri*use-imenu (fboundp 'imenu-add-to-menubar) "*Use imenu package for gri-mode? If you do not wish this behaviour, reset it in your .emacs file like so: (setq gri*use-imenu nil)" :group 'gri :type 'boolean) (defcustom gri*view-after-run t "When true, the graph will be displayed after compilation. See also variable gri*view-command to set what viewer to use. If you do not wish this behaviour, reset it in your .emacs file like so: (setq gri*view-after-run nil)" :group 'gri :type 'boolean) (defcustom gri*view-command 'gv "Command used by gri-view to display postscript file. Reset this in your .emacs file (but not in your gri-mode-hook) like so: (setq gri*view-command \"ghostview -magstep -1\") ;for small screens or (setq gri*view-command \"gv -media letter\") Note: If you use gv as a viewer, use the gri*view-scale variable to set the default scale; don't use the gv -scale option in this variable." :group 'gri :type '(choice (const :tag "gv" gv) (const :tag "gv (old version)" gv-old) (const :tag "gnome-gv" gnome-gv) (const :tag "ggv" ggv) (const :tag "ghostview" ghostview) (const :tag "kghostview" kghostview) (string :tag "User specified command"))) (defcustom gri*view-landscape-arg "-landscape" "Argument used to obtain landscape orientation in gri-view. This argument is passed to the shell along with the command stored in the variable gri*view-command. Reset this in your .emacs file (but not in your gri-mode-hook) like so: (setq gri*view-landscape-arg \"\") where the empty string is used here (as an example) if no landscape argument exists for the command used in gri*view-command. This is only used when gri*view-command is set to a user-specified string. ghostview or gv-old use -landscape, gv uses --orientation=landscape and kghostview and gnome-gv don't support the option." :group 'gri :type 'string) (defcustom gri*view-scale 0 "Default scale argument to use when using gv as gri-view command. You may change this via the menu-bar during an editing session." :group 'gri ;; :type 'integer) :type '(choice (const :tag "0.1" -5) (const :tag "0.125" -4) (const :tag "0.25" -3) (const :tag "0.5" -2) (const :tag "0.707" -1) (const :tag "1" 0) (const :tag "1.414" 1) (const :tag "2" 2) (const :tag "4" 3) (const :tag "8" 4) (const :tag "10" 5))) (make-variable-buffer-local 'gri*view-scale) (defcustom gri*view-watch t "When true, use -watch option with gv to check the document periodically. If changes are detected gv will automatically display the newer version of the file." :group 'gri :type 'boolean) (make-variable-buffer-local 'gri*view-watch) (defcustom gri*view-noantialias nil "When true, use -noantialias option with gv. The current version of 'gv' has known rendering bugs using -antialias, so try setting this if parts of a figure don't show up on the screen." :group 'gri :type 'boolean) (make-variable-buffer-local 'gri*view-noantialias) (defcustom gri*WWW-program nil "Program name for World-Wide-Web browser, used by command gri-WWW-manual. If set to nil, gri-mode will use the Emacs' browse-url package to deal with the browser request. If set to a string, gri-mode will start it as a sub-process. On your system, this could be `netscape'. If so, set this variable in your .emacs file like so: (setq gri*WWW-program \"netscape\")" :group 'gri ;;; :type '(restricted-sexp :match-alternatives (stringp 'nil)) :type '(choice (const :tag "Use browse-url package" nil) (string :tag "Specify a program"))) (defcustom gri*WWW-page "http://gri.sourceforge.net/gridoc/html/index.html" "*Web page or local html index file for the gri manual. This is used by the gri-WWW-manual command. If the sourceforge site is down, try: http://www.phys.ocean.dal.ca/~kelley/gri/index.html On your system, this could be reset to a local html file, e.g. (setq gri*WWW-page \"file:/usr/share/doc/gri-html-doc/html/index.html\") but it defaults to the online gri manual at sourceforge.net: http://gri.sourceforge.net/gridoc/html/index.html See also: variable gri*WWW-program." :group 'gri :type 'string) (defcustom gri-indent-before-return nil "Set to true to indent current line when pressing carriage return. Reset this in your .emacs file like so: (setq gri-indent-before-return t)" :group 'gri :type 'boolean) (defcustom gri*lpr-command (if (boundp 'lpr-command) lpr-command "lpr") "Command used by gri-mode to print PostScript files produced by gri. Set only the command name here. Options are set in gri*print-switches" :group 'gri :type 'string) (defcustom gri*lpr-switches (if (boundp 'lpr-switches) lpr-switches) "Options used to print PostScript files produced by gri. This is usually entered as a list of strings: (setq gri*lpr-switches '(\"-P las_imlsta\" \"-ps\")) but can also be entered simply as a single string: (setq gri*lpr-switches \"-P las_imlsta -ps\")" :group 'gri :type '(repeat string)) (defvar gri-view-process nil "Buffer local variable holding the process object for gri-view, if any.") (make-variable-buffer-local 'gri-view-process) ;; ---------------------------------------------------------------------------- ;; The syntax file looks like: Used by: ;; ------------------- ;; Syntax for gri version 1.063 ;; - gri-complete works from here (all commands) ;; ?set_axes (fragments) ;; -- gri-help-apropos ;; Draw_Ctd (user commands) ;; --- gri-help (backward to see if user command) ;; cd cd [\pathname] ;; close close [\filename] ;; ------------------- ;; (gri-info doesn't look at this file) ;; ;; System gri commands and fragments are inserted when .gri-syntax is created. ;; User commands and fragments are added when *gri-syntax* buffer is created ;; and when gri-mode is invoked (on a new gri buffer) if *gri-syntax* exists. ;; That way, we won't create *gri-syntax* for users who never use it. ;; User commands and fragments can overwrite older user commands AND any ;; fragments (whether gri or not). This provides a mean for users to modify ;; official gri fragments. (if (not (fboundp 'when)) (eval-when-compile (require 'cl))) (defvar gri-mode-is-XEmacs (not (null (save-match-data (string-match "XEmacs\\|Lucid" emacs-version))))) (defvar gri-mode-is-Emacs2X (and (not gri-mode-is-XEmacs) (<= 20 emacs-major-version))) (defvar gri-bin-file "" "Command used to call gri binary.") (defvar gri-cmd-file "" "gri.cmd file used when calling gri command (if gri-bin-cmd not \"gri\") and used for gri-mode syntax.") (defvar gri-sys-command-alist nil "Alist of gri system commands. This list is filled automatically when needed.") (defvar gri-user-command-alist nil "Alist of gri user commands This list is filled automatically when needed.") (defvar gri-version-list nil "Internal list of gri versions available from variable gri*directory-tree") (defvar gri-local-version nil "Local variable for gri version to use on this file. To use this, you insert strings like this at the end of the file: # Local Variables: # gri-local-version: \"2.053\" # End:") (make-variable-buffer-local 'gri-local-version) (defvar gri-command-arguments "" "command arguments to pass to gri when using gri-run, excluding -b -y which are always sent.") (make-variable-buffer-local 'gri-command-arguments) (defvar gri-command-postarguments "" "command arguments to pass to gri after the script file, i.e. file names. Used, for example, to run a gri script that requires data filenames as argument: $ gri script.gri datafile1.dat datafile2.dat In the above example, you'd set gri-command-postarguments to \"datafile1.dat datafile2.dat\". Use `M-x gri-set-command-postarguments' to set this locally for one gri file. This variable is only locally set for a particular file.") (make-variable-buffer-local 'gri-command-postarguments) (defvar gri-idle-timer nil "Holds gri's idle timer when set.") (defvar gri-commands-menu nil) (defvar gri-menubar nil) (defun gri-set-local-version () "Set the version of gri to use on this file only. This adds an emacs local-variable at the end of your file as a gri comment, such that gri-mode will use the proper version of gri the next time you edit the gri file." (interactive) (let* ((table (gri-expand-versions)) (version (and table ;Choose if we have possiblities (table) (completing-read "Gri version number to use: " table nil t nil)))) (cond ((string-equal version "") (error "No version specified. Exiting.")) ((string-equal version "default") (message "Unsetting local-buffer version and using default version of gri") (gri-unset-local-version)) (t (setq gri-local-version version) (save-excursion (goto-char (point-max)) (if (re-search-backward "\\(//\\|#\\) Local Variables:" nil t) (if (re-search-forward "gri-local-version: \"\\(.*\\)\"" nil t) (progn (goto-char (match-beginning 1)) (delete-region (match-beginning 1)(match-end 1)) (insert version)) (end-of-line) (insert "\n# gri-local-version: \"" version "\"")) (goto-char (point-max)) (insert "# Local Variables:\n" "# gri-local-version: \"" version "\"\n" "# End:\n"))))) (gri-initialize-version t))) (defun gri-unset-local-version () "Unset this buffer's local version of gri and use default value instead" (interactive) (setq gri-local-version nil) (save-excursion (save-restriction (widen) (goto-char (point-max)) (when (and (re-search-backward "# Local Variables:" nil t) (re-search-forward "# gri-local-version:" nil t)) (delete-region (progn (beginning-of-line)(point)) (progn (forward-line 1) (point))) (forward-line -1) (if (and (looking-at "# Local Variables:\n") (progn (forward-line 1)(looking-at "# End:"))) (delete-region (progn (end-of-line)(point)) (progn (forward-line -1) (point)))))))) (defun gri-menu-set-command-postarguments () "Set filename arguments to use for this script when running gri This adds an emacs local-variable at the end of your file as a gri comment, locally setting the gri-mode variable `gri-command-postarguments'." (interactive) (let ((args (read-string "Arguments: "))) (gri-set-command-postarguments args))) (defun gri-set-command-postarguments (args) "Set filename arguments to use for this script when running gri This adds an emacs local-variable at the end of your file as a gri comment, locally setting the gri-mode variable `gri-command-postarguments'." (interactive (list (read-string "Arguments: "))) (cond ((string-equal args "") ;; Unset here? Or error? ;;(error "No arguments specified. Exiting.")) (message "Unsetting local-buffer variable.") (gri-unset-command-postarguments)) (t (setq gri-command-postarguments args) (save-excursion (goto-char (point-max)) (if (re-search-backward "\\(//\\|#\\) Local Variables:" nil t) (if (re-search-forward "gri-command-postarguments: \"\\(.*\\)\"" nil t) (progn (goto-char (match-beginning 1)) (delete-region (match-beginning 1)(match-end 1)) (insert args)) (end-of-line) (insert "\n# gri-command-postarguments: \"" args "\"")) (goto-char (point-max)) (insert "# Local Variables:\n" "# gri-command-postarguments: \"" args "\"\n" "# End:\n")))))) (defun gri-unset-command-postarguments () "Unset this buffer's use of post arguments." (interactive) (setq gri-command-postarguments nil) (save-excursion (save-restriction (widen) (goto-char (point-max)) (when (and (re-search-backward "# Local Variables:" nil t) (re-search-forward "# gri-command-postarguments:" nil t)) (delete-region (progn (beginning-of-line)(point)) (progn (forward-line 1) (point))) (forward-line -1) (if (and (looking-at "# Local Variables:\n") (progn (forward-line 1)(looking-at "# End:"))) (delete-region (progn (end-of-line)(point)) (progn (forward-line -1) (point)))))))) (defun gri-initialize-version (tryhard) "Decide which version of gri to use based on ~/.gri-using-version unless local-variable gri-local-version is set, then use that version, and also use the variable gri*directory-tree. Sets variables gri-bin-file and gri-cmd-file. If TRYHARD is set, then try hard if first guess is not valid." (cond (gri-local-version ;; make gri-bin-file and gri-cmd-file local variables (for gri-run) (cond ((gri-validate-version gri-local-version) (make-local-variable 'gri-cmd-file) (make-local-variable 'gri-bin-file) (setq gri-cmd-file (gri-cmd-file-for-version gri-local-version)) (setq gri-bin-file (gri-bin-file-for-version gri-local-version)) (message "Using gri version %s for this file." gri-local-version)) (tryhard (goto-char (point-max)) (or (re-search-backward "^# gri-local-version" nil t) (re-search-backward "^# Local Variables:" nil t)) (read-string (format "Gri version %s was not on the system. Press ENTER to continue. " gri-local-version)) (setq gri-local-version nil) (gri-initialize-version t)))) ((file-readable-p "~/.gri-using-version") (let ((the-buffer (create-file-buffer "~/.gri-using-version")) (version)) (save-excursion (set-buffer the-buffer) (insert-file-contents "~/.gri-using-version") (goto-char (point-min)) (setq version (buffer-substring (point) (progn (end-of-line)(point))))) (kill-buffer the-buffer) (cond ((gri-validate-version version) (setq gri-cmd-file (gri-cmd-file-for-version version)) (setq gri-bin-file (gri-bin-file-for-version version)) (message "Using gri version %s." version)) (tryhard ;; Version from ~/.gri-using-version doesn't exist. (read-string (format "Gri %s requested in ~/.gri-using-version is not on the system. Press ENTER " version)) (if (file-exists-p "~/.gri-using-version") (delete-file "~/.gri-using-version")) (gri-initialize-version t))))) (t ;; Default setting, (~/.gri-using-version file not used) (setq gri-cmd-file (gri-cmd-file-for-version "default")) (setq gri-bin-file (gri-bin-file-for-version "default")) (if (not (and gri-cmd-file (not (string-equal "" gri-cmd-file)) (file-readable-p gri-cmd-file))) (setq gri-cmd-file "" gri-bin-file ""))))) (defun gri-inquire-default () "Ask gri which -default_directory to use to find gri.cmd. Sets gri-cmd-file." (save-excursion (let ((gri-tmp-buffer (get-buffer-create "*gri-tmp-buffer*"))) (set-buffer gri-tmp-buffer) ;; (message "Inquiring to gri about location of gri.cmd file...") (shell-command-on-region 1 1 "gri -directory_default" t) ;;(shell-command-on-region 1 1 "echo ERROR" t) ;;(shell-command-on-region 1 1 "echo /opt/gri/2.017/lib/" t) ;; (message "Inquiring to gri about location of gri.cmd file... Done.") (setq gri-cmd-file (and (not (search-backward "ERROR" nil t)) (expand-file-name "gri.cmd" (buffer-substring 1 (progn (goto-char 1)(end-of-line)(point)))))) (kill-buffer gri-tmp-buffer)) gri-cmd-file)) (defun gri-inquire-default-version () "Ask gri -v to find version number" (save-excursion (let ((gri-tmp-buffer (get-buffer-create "*gri-tmp-buffer*")) answer) (set-buffer gri-tmp-buffer) (shell-command-on-region 1 1 "gri -v" t) (goto-char (point-min)) (if (re-search-forward "gri version \\(.*\\)$" nil t) (setq answer (match-string 1))) (kill-buffer gri-tmp-buffer) answer))) (defun gri-expand-versions-this-directory (directory-tree) "Do gri-expand-versions on a single directory" ;;; This is what needs to be supported: ;; ;; Old style local install: ;; ;; /opt/gri/VERSION/bin/gri ;; /opt/gri/VERSION/lib/gri.cmd ;; ;; New style local install: ;; ;; /usr/local/bin/gri ;; /usr/local/share/gri/gri.cmd ;; ;; Red Hat: ;; ;; /usr/bin/gri ;; /usr/share/gri/gri.cmd ;; ;; Debian: ;; ;; /usr/bin/gri-VERSION ;; /usr/share/gri/VERSION/gri.cmd ;; ;; gri-mode will only let the user pick and switch gri versions for ;; a given buffer with `Old style local install' and `Debian'. ;; (if (or (not (file-readable-p directory-tree)) (not (file-directory-p directory-tree))) nil (let ((file-list (cdr (cdr (directory-files directory-tree)))) ;; The above trickery removes ./ and ../ from the list (dir-list)(vsn-list)(the-file)) (while file-list ;; find directories which have /bin/gri and /lib/gri.cmd files (setq the-file (car file-list)) (setq file-list (cdr file-list)) (cond ((string-match "^lib$" the-file) (cond ;; gri*directory-tree/bin/gri and gri*directory-tree/lib/gri.cmd ;; No version numbers! ((and (file-directory-p (expand-file-name "lib" directory-tree)) (file-exists-p (expand-file-name "bin/gri" directory-tree)) (file-exists-p (expand-file-name "lib/gri.cmd" directory-tree))) (setq dir-list (cons "default" dir-list)) (setq vsn-list (append vsn-list (list (list "default" (expand-file-name "bin/gri" directory-tree) (expand-file-name "lib/gri.cmd" directory-tree)))))) ;; gri*directory-tree/lib/gri.cmd and gri in the PATH ;; No version numbers! ((and (file-directory-p (expand-file-name "lib" directory-tree)) (file-exists-p (expand-file-name "lib/gri.cmd" directory-tree))) (setq dir-list (cons "default" dir-list)) (setq vsn-list (append vsn-list (list (list "default" "gri" (expand-file-name "lib/gri.cmd" directory-tree)))))))) ;; gri*directory-tree/gri.cmd and gri executable in the PATH ;; No version numbers! ((and (string-match "^gri.cmd$" the-file) (file-exists-p (expand-file-name "gri.cmd" directory-tree))) (setq dir-list (cons "default" dir-list)) (setq vsn-list (append vsn-list (list (list "default" "gri" (expand-file-name "gri.cmd" directory-tree)))))) ;; gri*directory-tree/VERSION/bin/gri and ;; gri*directory-tree/VERSION/lib/gri.cmd ((and (file-directory-p (expand-file-name the-file directory-tree)) (file-exists-p (expand-file-name (concat the-file "/lib/gri.cmd") directory-tree)) (file-exists-p (expand-file-name (concat the-file "/bin/gri") directory-tree))) (setq dir-list (cons the-file dir-list)) (setq vsn-list (append vsn-list (list (list the-file (expand-file-name (concat the-file "/bin/gri") directory-tree) (expand-file-name (concat the-file "/lib/gri.cmd") directory-tree)))))) ;; gri*directory-tree/VERSION/gri.cmd ;; gri-VERSION executable in the PATH ((and (file-directory-p (expand-file-name the-file directory-tree)) (file-exists-p (expand-file-name (concat the-file "/gri.cmd") directory-tree))) (setq dir-list (cons the-file dir-list)) (setq vsn-list (append vsn-list (list (list the-file (concat "gri-" the-file) (expand-file-name (concat the-file "/gri.cmd") directory-tree)))))))) (setq gri-version-list vsn-list) (mapcar 'list (nreverse dir-list))))) (defun gri-expand-versions () "Returns a list of gri versions in gri*directory-tree, either a string or list of strings. Sets gri-version-list variable." (let (versions) (cond ((listp gri*directory-tree) (let ((the-list gri*directory-tree) the-tree vsn-list) (setq gri-version-list nil) (while the-list (setq the-tree (car the-list)) (setq the-list (cdr the-list)) (setq versions (append (gri-expand-versions-this-directory the-tree) versions)) (setq vsn-list (append vsn-list gri-version-list))) (setq gri-version-list vsn-list))) ((stringp gri*directory-tree) (setq versions (gri-expand-versions-this-directory gri*directory-tree)))) ;; If list doesn't contain "default", chase gri link or -directory_default ;; Can't chase gri link unless I do `which gri` or `whereis gri` (if (member '("default") versions) versions ;Okay, we're done... (let ((the-list gri-version-list) (default-version (gri-inquire-default-version))) (while the-list (if (string-equal (car (car the-list)) default-version) (progn (setq versions (cons '("default") versions)) (setq gri-version-list (append gri-version-list (list (cons "default" (cdr (car the-list)))))) (setq the-list nil))) (setq the-list (cdr the-list))) (if versions versions ;; Not done yet, ask -directory_default (let ((default-version (gri-inquire-default))) (setq versions "default") (setq gri-version-list (append gri-version-list (list (list "default" "gri" default-version)))) versions)))))) (defun gri-bin-file-for-version (version) (if (not gri-version-list) (gri-expand-versions)) (let ((the-list gri-version-list) answer) (while the-list (if (string-equal version (car (car the-list))) (progn (setq answer (elt (car the-list) 1)) (setq the-list nil))) (setq the-list (cdr the-list))) answer)) (defun gri-cmd-file-for-version (version) (if (not gri-version-list) (gri-expand-versions)) (let ((the-list gri-version-list) answer) (while the-list (if (string-equal version (car (car the-list))) (progn (setq answer (elt (car the-list) 2)) (setq the-list nil))) (setq the-list (cdr the-list))) answer)) (defun gri-validate-version (version) "Check that this VERSION of gri is available on the system." (if (not gri-version-list) (gri-expand-versions)) (let ((cmd-file (gri-cmd-file-for-version version)) (bin-file (gri-bin-file-for-version version))) (and cmd-file bin-file (file-executable-p bin-file) (file-readable-p cmd-file)))) (defun gri-validate-cmd-file (&optional pass) "Maybe sure gri is ready to run, or report fatal error." (cond ((and gri-cmd-file (not (string-equal "" gri-cmd-file)) (file-readable-p gri-cmd-file)) t) ; All is well ((not pass) ;; Try to recover (gri-initialize-version t) (gri-validate-cmd-file 2)) ((equal pass 2) ;; Try to recover resetting list of known versions (setq gri-version-list nil) (gri-initialize-version t) (gri-validate-cmd-file 3)) ((equal pass 3) ;; Already Tried to recover (error "Cannot find gri on the system.")))) (defun gri-set-version () "Change the version of gri used in gri-mode. If you answer with an empty string, the default version of gri will always be used (even after it gets upgraded on your system). If you choose another version, gri-mode will remember between emacs session by writing it to the file ~/.gri-using-version. See also gri-set-local-version" ;; Sets up variable gri-bin-file and gri-cmd-file ;; Sets up (or deletes) ~/.gri-using-version ;; Deletes syntax buffer if it existed (so that it will be rebuilt next time). (interactive) (if (and (boundp 'gri-local-version) gri-local-version (y-or-n-p "Unset locally-set Gri version and proceed? ")) (gri-unset-local-version)) (if (and (boundp 'gri-local-version) gri-local-version) () ;Still local; We are done. (let* ((table (gri-expand-versions)) (version (and table ;Choose if we have possiblities (table) (completing-read "Gri version number to use: [default] " table nil 0 nil)))) (cond ((and version ;If we have a version number (not (string-equal version ""))) (setq gri-cmd-file (gri-cmd-file-for-version version)) (setq gri-bin-file (gri-bin-file-for-version version)) (if (local-variable-p 'gri-cmd-file) (set-default 'gri-cmd-file gri-cmd-file)) (if (local-variable-p 'gri-bin-file) (set-default 'gri-bin-file gri-bin-file)) ;; Write ~/.gri-using-version (let ((the-buffer (create-file-buffer "~/.gri-using-version"))) (save-excursion (set-buffer the-buffer) (erase-buffer) (insert version) (write-file "~/.gri-using-version") (kill-buffer the-buffer))) (message "Using Gri version %s" version)) (t ;;Else set to default value (with or without /lib appended) (if (file-exists-p "~/.gri-using-version") (delete-file "~/.gri-using-version")) (setq gri-bin-file (gri-bin-file-for-version "default")) (setq gri-cmd-file (gri-cmd-file-for-version "default")) (message "Using Gri default version"))) ;; Now delete syntax buffer if it exists, and the syntax file. (if (get-buffer "*gri-syntax*") (kill-buffer "*gri-syntax*")) (if (file-exists-p "~/.gri-syntax") (delete-file "~/.gri-syntax"))))) (defun gri-build-syntax (local-cmd-file) "Called when gri-syntax-file is not found. Creates ~/.gri-syntax which contains all commands found in gri.cmd, including some code fragments." ;; assumes (possibly local) gri-cmd-file variable is passed as arg. (if (not (file-readable-p local-cmd-file)) (error "%s not found. Check gri*directory-tree in gri-mode.el" local-cmd-file)) (let ((cmd-buffer (get-buffer-create "*gri-cmd-file*")) (syn-buffer (get-buffer-create "*gri-syntax-file*")) (version "(unknown)")) (save-excursion (set-buffer cmd-buffer) (insert-file-contents local-cmd-file) (if (re-search-forward "(version \\([.0-9]*\\))" nil t) (setq version (buffer-substring (match-beginning 1)(match-end 1)))) (message "Building gri version %s syntax..." version) (save-excursion (set-buffer syn-buffer) (insert " Syntax for gri version " version " (created by gri-mode.el)\n" " Based on: " (file-chase-links local-cmd-file) "\n" "-\n--\n---\n")) (gri-add-commands-from-current-buffer t syn-buffer) (gri-add-variables syn-buffer) (set-buffer syn-buffer) (write-file "~/.gri-syntax")) (kill-buffer syn-buffer) (kill-buffer cmd-buffer))) (defun gri-add-variables (syn-buffer) "Add gri variables in current buffer to syntax file. ARG is gri-syntax buffer to add to." (let ((the-list)) (save-excursion (goto-char (point-min)) (while (re-search-forward "^# @variable \\([^ ]*\\) +\\([^@]+\\)\\( @unit \\([^ ]+\\)\\)?\\( @default \\(.*\\)\\)?$" nil t) ;;;# @variable ..fontsize.. size of font @unit point @default 12 (let ((the-variable (match-string 1)) (the-def (cond ((match-string 3) (concat (match-string 1) " (" (match-string 2) ". Default is " (match-string 6) " " (match-string 4) ".)")) ((match-string 5) (concat (match-string 1) " (" (match-string 2) ". Default is " (match-string 6) ".)")) (t (concat (match-string 1) " (" (match-string 2) ".)"))))) (setq the-list (cons (list the-variable the-def) the-list)))) (set-buffer syn-buffer) (setq buffer-read-only nil) (goto-char (point-min)) (re-search-forward "^---$" nil t) (while the-list (let ((variable-pair (car the-list))) (insert "\n" (car (cdr variable-pair)) ";" (car variable-pair)) (setq the-list (cdr the-list)))) (set-buffer-modified-p nil) (setq buffer-read-only t)))) (defun gri-add-commands-from-current-buffer (system-flag syn-buffer) "Add gri commands in current buffer to syntax file. If ARG1 is true, then this is the gri.cmd buffer for gri system commands. ARG2 is gri-syntax buffer." (save-excursion (let ((cmd-buffer (current-buffer))) (set-buffer syn-buffer) (setq buffer-read-only nil) (set-buffer cmd-buffer) (goto-char (point-min)) (makunbound 'gri-user-command-alist) ;force later update of commands (while (re-search-forward "^`\\(.*\\)'$" nil t) (let ((the-command (buffer-substring (match-beginning 1) (match-end 1))) (the-name)(the-default)) (if (string-equal "?" (substring the-command 0 1)) ;; A fragment of gri code to extract (progn (re-search-forward "^{" nil t) (let ((the-fragment (buffer-substring (point) (progn (re-search-forward "^}" nil t) (backward-char 2)(point))))) (set-buffer syn-buffer) (goto-char (point-min)) ;; (setq the-command ;; (psg-replace-within-string the-command " " "_")) (if (and (not system-flag) ;; do no checks for gri.cmd (re-search-forward (concat "^" the-command ";") nil t)) (progn (message "Overwriting syntax for %s" the-command) (delete-region (progn (beginning-of-line) (point)) (progn (forward-char 1) (re-search-forward "^[^ ]" nil t) (backward-char 2)(point)))) (re-search-forward "^-$" nil t) (insert "\n")) (insert the-command ";" the-fragment) (goto-char (point-max)) (set-buffer cmd-buffer))) ;; An ordinary gri command ;; Extract default value if any... (if system-flag (save-excursion (let ((help-limit (progn (beginning-of-line)(point)))) (forward-line -1) (while (and (looking-at "^#\\*") (= 0 (forward-line -1)))) (forward-line 1) (when (re-search-forward "@default +\\([^@\n]+\\) ?" help-limit t) (setq the-default (match-string 1)) (beginning-of-line) (if (re-search-forward "@unit +\\([a-zA-Z0-9.]+\\) ?" (save-excursion (end-of-line)(point)) t) (setq the-default (concat the-default (buffer-substring-no-properties (match-beginning 1) (match-end 1))))) (if (re-search-forward "@variable +\\([a-zA-Z0-9_.]+\\)" (save-excursion (end-of-line)(point)) t) (setq the-default (concat the-default " in variable " (buffer-substring-no-properties (match-beginning 1) (match-end 1))))))))) (set-buffer syn-buffer) (goto-char (point-max)) (insert the-command) (gri-create-cmd-name nil) (setq the-name (buffer-substring (progn (beginning-of-line)(point)) (progn (end-of-line)(point)))) (if system-flag (progn ; Don't check if defined twice (if the-default (insert "(default is " the-default ")")) (insert ";" the-command "\n")) ;; User command--check if command already exists (delete-region (progn (beginning-of-line)(point)) (progn (end-of-line)(point))) (if (re-search-backward (concat "^" the-name " ") nil t) (if (not (re-search-forward "^---\n" nil t)) (message "Cannot overwrite command: %s" the-name) ;; same named user command existed --- overwrite it. (message "Overwriting command: %s" the-name) (re-search-backward (concat "^" the-name " ") nil t) (delete-region (progn (beginning-of-line)(point)) (progn (end-of-line)(point))) (insert the-name ";" the-command)) ;; didn't previously exist -- write it. (re-search-backward "^---\n" nil t) (forward-line -1)(end-of-line) (insert "\n" the-name ";" the-command))) (set-buffer cmd-buffer) (re-search-forward "^}" nil t)))) (set-buffer syn-buffer) (set-buffer-modified-p nil) (setq buffer-read-only t) (set-buffer cmd-buffer)))) (defun gri-create-cmd-name (underscore-flag) "Edits full gri syntax line to leave gri command name. If ARG is true, then put underscores between command words. Gri command name may be longer than that used by gri parser, because this will take words that follow variables (and the gri parser won't check these). Assumes line is last in buffer, and has no leading whitespace." (beginning-of-line) (while (search-forward " " nil t) ;; trim whitesppace (delete-backward-char 1) (beginning-of-line)) (while (re-search-forward "[{|\"\.\\[]" nil t) (backward-char 1) ;; puts point on found character (let ((the-match (buffer-substring (match-beginning 0)(match-end 0))) (the-start (point)) (the-find (point))) (cond ((or (string-equal the-match "{") (string-equal the-match "[")) (goto-char (scan-sexps (point) 1))) ;; faster than forward-sexp 1? ((string-equal the-match "|") (skip-chars-backward " \t") ;; place start-deletion before prior option (search-backward " " nil t) ;; skipping immediate spaces, find start (forward-char 1) ;; move over first character (setq the-start (point)) ;; set the start-deletion (goto-char the-find) ;; now go back to delete trailing option (forward-char 1) ;; move right after | character (skip-chars-forward "\t ") ;; and skip over spaces (re-search-forward "[ {[]\\|$" nil t) (if (or (string-equal "{" (buffer-substring (match-beginning 0) (match-end 0))) (string-equal "[" (buffer-substring (match-beginning 0) (match-end 0)))) (backward-char 1))) ;; don't delete the bracket ((string-equal the-match "\"") (forward-char 1) (search-forward "\"" nil t)) (t ;;case \. (forward-char 1) (re-search-forward "[ {[]\\|$" nil t) (if (or (string-equal "{" (buffer-substring (match-beginning 0) (match-end 0))) (string-equal "[" (buffer-substring (match-beginning 0) (match-end 0)))) (backward-char 1)))) ;; skip before a bracket (skip-chars-forward " \t") (delete-region the-start (point)) (if (looking-at "|") ;; add a dummy option, deleted next iteration (progn (save-excursion (insert "dum")))))) (end-of-line)(insert " ")(backward-char 1) ;; at least one space at end (while (char-equal 32 (char-after (point))) ;; delete all spaces at end (delete-char 1) (backward-char 1)) (if underscore-flag (progn (beginning-of-line) ;;(perform-replace " " "_" nil nil nil) (while (search-forward " " nil t) (delete-backward-char 1)(insert "_"))))) (defun gri-isolate-this-command (underscore-flag) "(gri-mode) returns multi-line command as single string. The command is trimmed and edited to remove any variables, but is not verified. You can end up with: draw label at cm If ARG is true, then put underscores between command words." (if (gri-empty-line) (error "This is an empty line")) (let ((tmp-buffer (get-buffer-create "*gri-tmp-command*")) (the-string)) (save-excursion (set-buffer tmp-buffer) (erase-buffer)) (save-excursion (beginning-of-line) (while (progn (save-excursion (and (= 0 (forward-line -1)) (gri-continuation-line)))) (forward-line -1)) (while (and (gri-continuation-line) (progn (save-excursion (= 0 (forward-line 1))))) (setq the-string (buffer-substring (progn (skip-chars-forward " \t") (point)) (progn (end-of-line) (skip-chars-backward "\\ \t")(point)))) (save-excursion (set-buffer tmp-buffer) (insert the-string " ")) (forward-line 1)) (setq the-string (buffer-substring (progn (skip-chars-forward " \t") (point)) (progn (if (re-search-forward "\\(#\\|//\\)" (progn (save-excursion (end-of-line) (point))) t) (skip-chars-backward "#/ \t") (end-of-line) (skip-chars-backward "#/ \t")) (point)))) (set-buffer tmp-buffer) (insert the-string) ;; multi-line command now in single line (beginning-of-line) (gri-create-cmd-name underscore-flag) (setq the-string (buffer-string))) (kill-buffer tmp-buffer) the-string)) (defun gri-syntax-this-command () "Returns syntax for multi-line gri command on point. Returns error messages if they occur. Used for gri-help-this-command, to find what command to look for in gri.cmd. Used for gri-display-syntax." (save-excursion (let ((the-command (gri-isolate-this-command nil))) ;; the-command could be like draw_label_at_cm ;; check in syntax if a command name (gri-lookat-syntax-file 0) (let ((the-start (point))) (while (and (not (re-search-forward (concat "^" the-command "\\(;\\|(\\)") nil t)) (progn (setq the-command (gri-shorten-guess-command the-command " ")) the-command))) (if (= (point) the-start) (error "Sorry, cannot find such a gri command") (if (string-equal "?" (substring the-command 0 1)) (beginning-of-line)) ;; We'll return the whole line for fragments ;; Skip over default description (forward-char -1) (if (looking-at "(") (re-search-forward ");" nil t) (forward-char 1)) (buffer-substring (point) (progn (end-of-line)(point)))))))) (defun gri-syntax-default-this-command () "Returns default settings for multi-line gri command on point. Return: nil if the command is not found 0 if there is no default setting to display else return the string Used for gri-display-default-syntax." (save-excursion (let ((the-command (gri-isolate-this-command nil))) (gri-lookat-syntax-file 2) (let ((the-start (point))) (while (and (not (re-search-forward (concat "^" the-command "\\(;\\|(\\)") nil t)) (progn (setq the-command (gri-shorten-guess-command the-command " ")) the-command))) (if (= (point) the-start) nil (forward-char -1) (if (not (looking-at "(")) 0 (forward-char 1) (concat the-command ": " (buffer-substring (point) (progn (re-search-forward ");" nil t) (forward-char -2) (point)))))))))) (defun gri-syntax-default-this-builtin () "Returns default settings for builtin variable under point. Return: nil if not on a variable 0 if there is no default setting to display else return the string Used for gri-idle-function." (save-excursion (if (not (progn (if (re-search-backward "[ \t]" (save-excursion (beginning-of-line) (point)) 1) (forward-char 1)) (looking-at "\\(\\\\\\|\\.\\)[^ \n]+"))) nil (let ((the-builtin (match-string-no-properties 0))) (gri-lookat-syntax-file 2) (if (not (re-search-forward (concat "^" (regexp-quote the-builtin) " (\\(.*\\));") nil t)) 0 (concat the-builtin ": " (match-string-no-properties 1))))))) (defun gri-idle-function () "Run whenever Emacs is idle to display function defaults." (if (eq major-mode 'gri-mode) (let ((default-string (gri-syntax-default-this-builtin))) (if (stringp default-string) (message "%s" default-string) (let ((default-string (gri-syntax-default-this-command))) (if (stringp default-string) (message "%s" default-string))))))) (defun gri-prompt-for-command (user-flag) "Prompt user for gri command name, providing minibuffer completion. Allow user commands if ARG is t." (if (or (not (boundp 'gri-sys-command-alist)) ;Need to build both lists (not gri-sys-command-alist)) (gri-build-command-alist t) (if (not (boundp 'gri-user-command-alist)) ;Need only re-build user list (gri-build-command-alist nil))) ;;(completing-read "gri command: " gri-command-alist 'gri-sysp 0 nil ;; completion-ignore-case value to differentiate system from user commands? (if user-flag (if (string-equal "18" (substring emacs-version 0 2)) (completing-read "gri user or system command: " (append gri-sys-command-alist gri-user-command-alist) nil 0 nil) (completing-read "gri user or system command: " (append gri-sys-command-alist gri-user-command-alist) nil 0 nil 'gri-hist-alist)) (if (string-equal "18" (substring emacs-version 0 2)) (completing-read "gri system command: " gri-sys-command-alist nil 0 nil) (completing-read "gri system command: " gri-sys-command-alist nil 0 nil 'gri-hist-alist)))) ;;(defun gri-sysp (element) ;; "Test whether system command" ;; (not (cdr element))) (defun gri-build-command-alist (system-flag) "Build gri-user-command-alist (and gri-sys-command-alist if ARG is t). The lists are built from the gri syntax file. It should only be called when the alists are not bound (not existant)." ; Could be done using an obarray and `intern' to create it, but you ; can't concatenate obarrays, so this is a problem for user commands. ; elisp info doesn't say if completing-read is more efficient with alists ; or obarrays. (gri-lookat-syntax-file 1) (setq gri-user-command-alist nil) ;Making sure always starts empty (while (not (looking-at "---")) (setq gri-user-command-alist (nconc gri-user-command-alist (list (cons ;;;(psg-replace-within-string (buffer-substring-no-properties (point)(progn (search-forward ";") (backward-char 1)(point))) ;;;"_" " ") nil)))) ;Last could be true if we could use it. (forward-line 1)) (if system-flag (progn (message "building list of gri commands...") (setq gri-sys-command-alist nil) (forward-line 1) (when (looking-at "^\\(\.\\|\\\)") ; skip over variables (re-search-forward "^[^\.\\]" nil t) (beginning-of-line)) (while (< (point) (point-max)) (setq gri-sys-command-alist (nconc gri-sys-command-alist (list (cons ;;;(psg-replace-within-string (buffer-substring-no-properties (point)(progn (re-search-forward ";\\|(") (backward-char 1)(point))) ;;; "_" " ") nil)))) (forward-line 1))))) ;;(defun gri-help () ;; "Displays help (in *help* buffer) about a prompted gri command. ;;The help text is taken from gri.cmd (a gri system file) and may differ ;;from the gri info file (displayed by gri-info). Help is also displayed ;;about user commands from ~/.grirc or from the current gri file. ;; ;;BUGS: Can't find help on hidden user commands." ;; (interactive) ;; (let ((the-command (regexp-quote ;;;(psg-replace-within-string ;; (gri-prompt-for-command t) ;; ;;;" " "_") ;; ))) ;; (if (string-equal "" the-command) ;; (message "No command to look-up.") ;; (save-excursion ;lookup syntax in syntax file ;; (gri-lookat-syntax-file 1) ;; (if (re-search-forward (concat "^" the-command ";") nil t) ;; (gri-help-function (buffer-substring (point) ;; (progn (end-of-line)(point)))) ;; (message "Sorry, can't seem to find help for %s" the-command)))))) (defun gri-help (&optional command) "Displays help (in *help* buffer) about a prompted gri command. The help text is taken from gri.cmd (a gri system file) and may differ from the gri info file (displayed by gri-info). Help is also displayed about user commands from ~/.grirc or from the current gri file. BUGS: Can't find help on hidden user commands." (interactive "P") (let* ((the-command (regexp-quote (or command (gri-prompt-for-command t))))) (if (string-equal "" the-command) (message "No command to look-up.") (save-excursion ;lookup syntax in syntax file (gri-lookat-syntax-file 1) (if (not (re-search-forward (concat "^" the-command "\\(;\\|(\\)") nil t)) (message "Sorry, can't seem to find help for %s" the-command) ;; Skip over default description (forward-char -1) (if (looking-at "(") (re-search-forward ");" nil t) (forward-char 1)) (gri-help-function (buffer-substring (point) (progn (end-of-line)(point))))))))) (defun gri-help-this-command () "Displays help (in *help* buffer) about gri command on point. The help text is taken from gri.cmd (a gri system file) and may differ from the gri info file (display by gri-info-this-command). Help is also displayed about user commands from ~/.grirc or from the current gri file. The gri command may span many line, e.g. draw x axis \ at ..ymargin.. \ {rpn ..xmargin.. .2 -} cm will work. BUGS: Can't find help on hidden user commands." (interactive) (gri-help-function (gri-syntax-this-command))) (defun gri-help-function (the-command) "Actual work for gri-help and gri-help-this-command" (gri-validate-cmd-file) (save-excursion (let ((gri-tmp-buffer (get-buffer-create "*gri-tmp-buffer*")) (user-flag)) ;; We've gotten this far; valid command. But gri or user command? (save-excursion (gri-lookat-syntax-file 2) (if (search-backward (concat " " the-command ";") nil t) (setq user-flag t))) (if user-flag ;; user-command -- look in current buffer, else in .grirc (save-excursion (goto-char (point-min)) (if (search-forward (concat "`" the-command "'") nil t) ;;in buffer (gri-extract-help-text the-command t) (error "no") (if (file-readable-p "~/.grirc") (progn (set-buffer gri-tmp-buffer) ;; look in .grirc (insert-file-contents "~/.grirc") (if (re-search-forward (concat "^`" (regexp-quote the-command) "'") nil t) (gri-extract-help-text the-command t) (kill-buffer gri-tmp-buffer) (error "Sorry, can't find user command: %s" the-command))) (kill-buffer gri-tmp-buffer) (error "Sorry, can't find user command: %s" the-command)))) ;; gri system command (set-buffer gri-tmp-buffer) (insert-file-contents gri-cmd-file) (if (not (re-search-forward (concat "^`" (regexp-quote the-command) "'") nil t)) (progn (kill-buffer gri-tmp-buffer) (error "Sorry, can't find help about: %s" the-command))) (gri-extract-help-text the-command nil)) (kill-buffer gri-tmp-buffer)))) (defun gri-extract-help-text (the-command user-flag) "Extract help text after a command. Expecting point on title line. Display message if no help text supplied." (forward-line 1) (if (= 123 (char-after (point))) ;; on on opening bracket already (if user-flag (message "Sorry, no help text for user command: %s" the-command) (message "Sorry, no help text about: %s" the-command)) (if (looking-at "[^a-zA-Z0-9]*$") ;Skip header or C-like comment tring (forward-line 1)) (let ((the-start (point)) (the-text)) (re-search-forward "^{" nil t) (while (and (= 0 (forward-line -1)) (looking-at "[^a-zA-Z0-9]*$"))) (forward-line 1) (setq the-text (buffer-substring the-start (point))) (with-output-to-temp-buffer "*Help*" (princ (gri-format-display-command the-command)) (princ "\n--\n") (princ the-text))))) (defun gri-format-display-command (the-command) "return possible 2-line string for ARG, a gri command syntax string." (if (> (frame-width) (length the-command)) the-command (let ((the-string) (tmp-buffer (get-buffer-create "*gri-format*"))) (save-excursion (set-buffer tmp-buffer) (insert the-command) (backward-char 1) (if (or (char-equal 93 (char-after (point))) ;; [] (char-equal 125 (char-after (point)))) ;; {} (progn (forward-char 1) (goto-char (scan-lists (point) -1 0)) (insert "\n ")) ;; just split at previous whitespace (if (search-backward " " nil t) (insert "\n "))) (setq the-string (buffer-string)) (kill-buffer tmp-buffer)) the-string))) (defun gri-display-syntax () "Displays (in minibuffer) the full syntax of the gri command on point. The gri command may span many line, e.g. draw x axis \ at ..ymargin.. \ {rpn ..xmargin.. .2 -} cm will display draw x axis [at bottom|top|{.y. [cm]} [lower|upper]] in the minibuffer." (interactive) (message "%s" (gri-syntax-this-command))) (defun gri-display-default () "Displays (in minibuffer) the default settings for the gri command on point. Note that only a small subset of commands have such defaults. These are usually command with the keyword \"default\" in their syntax." (interactive) (message "%s" (gri-syntax-default-this-command))) (defvar gri-last-complete-point -1) (defvar gri-last-complete-command "") (defvar gri-last-complete-status 0) (defvar gri-complete-begin-point nil "Gri internal variable to remember point of beginning of completion across multiple invocations.") (defun gri-build-expansion-regex () "Returns regular expression for abbreviated gri command on current line." (save-excursion (let ((expansion-regex nil) (word-count 0) (end-point (progn (end-of-line)(skip-chars-backward " \t") (point)))) (save-excursion (if (progn (if (re-search-backward "[ \t]" (save-excursion (beginning-of-line) (point)) 1) (forward-char 1)) (looking-at "\\(\\\\\\|\\.\\)[^ \n]+")) (progn (setq gri-complete-begin-point (point)) (concat "^" (regexp-quote (match-string-no-properties 0)))) (beginning-of-line) (skip-chars-forward " \t") (setq gri-complete-begin-point (point)) (while (< (point) end-point) ;; Don't go beyond end of line (if (looking-at "[^ \t\n]*") ;; If it is a word... (progn (setq word-count (1+ word-count)) (if (= word-count 1) (setq expansion-regex (concat "^" (buffer-substring-no-properties (match-beginning 0) (match-end 0)))) (setq expansion-regex (concat expansion-regex "[^; ]* " (buffer-substring-no-properties (match-beginning 0) (match-end 0))))) (forward-char (- (match-end 0) (match-beginning 0))) (skip-chars-forward " \t")))) expansion-regex))))) (defun gri-info (&optional command) "Runs info about a prompted gri system command." (interactive "P") (require 'info) (let ((the-command (or command (gri-prompt-for-command nil)))) (if (string-equal "" the-command) (message "No command to look-up.") (gri-info-function the-command)))) (defun gri-info-this-command () "Run info about gri system command at editing point. This works when the edit point is on a valid gri command, but it may also work for uncompleted commands if an info entry exists for that topic. e.g. draw will display info about gri `draw' commands. Note: The search for the command is case-insensitive. Therefore, if you have a user command like `Draw X Axis', gri-info-this-command will display the info page for the gri command `draw x axis'." (interactive) (require 'info) (gri-info-function (gri-isolate-this-command nil))) ;; Delete this when I'm happy with new method. ;; gri-info-function used to read in gri info files and look at all nodes ;; I changed this in RCS 1.50 to get the proper Index of Commands instead. ;; This way, we can get to nodes for alternate spelling. ;;(defun gri-info-function (guess) ;; "Guts for gri-info and gri-info-this-command" ;; (if (not (gri-info-directory)) ;; (error "Sorry, no gri info files!")) ;; (let ((flag t)(loopflag t)(tmp-buffer (get-buffer-create "*info-tmp*"))) ;; (save-excursion ;; (set-buffer tmp-buffer) ;; (cond ;; ((fboundp 'info-insert-file-contents) ;Emacs20 ;; (info-insert-file-contents (concat (gri-info-directory) "gri"))) ;; ((and (fboundp 'Info-insert-file-contents) ;XEmacs20 ;; (fboundp 'Info-suffixed-file)) ;; (Info-insert-file-contents ;; (Info-suffixed-file (concat (gri-info-directory) "gri")) nil)) ;; (t ; old emacs? ;; (insert-file-contents (concat (gri-info-directory) "gri")))) ;; (goto-char (point-min)) ;; (if (re-search-forward ;; (concat "Node: " (regexp-quote guess) "\177") nil t) ;; (setq flag t) ;; (while loopflag ;; flag true until can't shorten or found ;; (setq guess (gri-shorten-guess-command guess " ")) ;; (if guess ;; (if (re-search-forward (concat "Node: " (regexp-quote guess) ;; "\177") nil t) ;; (setq loopflag nil)) ;; found it! ;; (setq loopflag nil) ;; can't shorten no more ;; (setq flag nil))))) ;; failed to find a match ;; (kill-buffer "*info-tmp*") ;; (if flag ;; ;;??Replace with: (Info-find-node "gri" guess) ;; (Info-goto-node (concat "(gri)" guess)) ;; (message "Sorry, can't find this topic in Info.")))) (defun gri-info-function (guess) "Guts for gri-info and gri-info-this-command" ;; (if (not (gri-info-directory)) ;; (error "Sorry, no gri info files!")) (let ((flag)(loopflag t)(node)) (save-excursion (save-window-excursion (let ((Info-history nil)) ;Don't save this move! ;; (Info-find-node "gri" "Index of Commands") (Info-goto-node "(gri)Index of Commands") (goto-char (point-min)) (search-forward "* Menu:" nil t) ;; Search for `guess' ;; and if Didn't find it, shorten the command and try again. (while (and guess loopflag) ; flag true until can't shorten or found (cond ((re-search-forward (concat "^\* " (regexp-quote guess) ":")nil t) ;; Found it this time! (skip-chars-forward " ") (setq node (buffer-substring (point) (progn (search-forward "." (save-excursion (end-of-line)(point))) (forward-char -1) (point)))) (setq flag t) (setq loopflag nil))) ;; exit the loop - found it! (setq guess (gri-shorten-guess-command guess " ")))))) (if flag (Info-goto-node (concat "(gri)" node)) (message "Sorry, can't find this topic in Info.")))) (defun gri-shorten-guess-command (guess separator) "Removes a word (separated by ARG2) from end of ARG1 as a new guess to a gri command" (let ((lastindex nil) (index (string-match separator guess nil))) (if (not index) nil (while index (setq lastindex index) (setq index (string-match separator guess (1+ index)))) (substring guess 0 lastindex)))) (defun gri-complete () "Complete a gri command as much as possible, then indents it. Works one word at a time, e.g. dr (where is actually pressing M-Tab) becomes draw or with many words at a time e.g. dr x a becomes draw x axis [at bottom|top|{.y. [cm]} [lower|upper]] _ How gri-mode names gri commands: The name of a gri command by determined by removing options. This is different than what the gri parser does. In this way, the gri command draw label \"\\string\" [centered|rightjustified] at .x. .y. [cm] \\ [rotated .deg.] is named by gri-mode draw label at Note how the `at' stays in the name because it is not optional. _ Possible Completions: Possible completions are shown in the *completions* buffer, but only if you insist by using gri-complete again. In this way you can use gri-complete word-by-word to abbreviate commands without ever displaying completions, like you would for file completion in emacs or bash. If a completion is ambiguous, but could be exact, invoke gri-complete a second time to complete it. e.g. sh becomes show and informs you that 12 possible completions exists; then show will display these completions in the completions buffer; then show forces completion to a complete but not unique possibility. show .value.|{rpn ...}|\"\\text\" [.value.|{rpn ...}|text [...]] Completions are shown immediately (without invoking gri-complete again) if the completions window is already displayed or if there are 3 possbilities or less. In this case they are displayed in the minibuffer. The *completions* window is deleted after a command is fully completed. gri-complete uses its own *completions* buffer, which is not displayed in the buffer-list to avoid clutter. _ User Commands: User gri commands defined in ~/.grirc or at the beginning of a gri file can also be gri-complete'd. Note that user commands are added from the current buffer whenever `gri-mode' is invoked. They may override previous user commands, but not gri system commands. _ Gri Code Fragments Since gri version 1.063, gri has special commands that begin with a question mark `?'. These special commands have no options, and are composed only of standard gri commands. Their purpose is to provide a short-cut for entering many lines of gri at once (e.g. bits of sample code about contouring grids, or your own preamble which you use at the time to set fonts and line widths). gri-complete acts in a special way with these commands, by replacing the abbreviated name which you are completing by all the lines contained within the gri command. The user is allowed to define new fragments in ~/.grirc, and also to override the gri system fragments. You can therefore fine-tune gri's fragments to your taste. To see the names of all gri fragments, type in a question mark at the beginning of a line in a gri buffer and press M-Tab twice to gri-complete it and display possible choices. The gri commands used to replace them is found in the *gri-syntax* buffer." ;;Sets gri-last-complete-point to point after completion (if matches > 1) ;;Sets gri-last-complete-command to current line (if matches > 1) (interactive) (let ((expansion-regex (gri-build-expansion-regex)) (the-line (buffer-substring (progn (beginning-of-line) (point)) (progn (end-of-line) (point))))) (if (eq expansion-regex nil) (progn (message "No gri command no expand.") (setq gri-last-complete-status 0)) (if (and (= 2 gri-last-complete-status) ; try to match exactly (= (point) gri-last-complete-point) (string-equal the-line gri-last-complete-command)) (gri-perform-completion (concat expansion-regex ";") t) (if (and (= 1 gri-last-complete-status) ; show completions (string-equal the-line gri-last-complete-command)) (gri-perform-completion expansion-regex nil) (setq gri-last-complete-status 0) (gri-perform-completion expansion-regex nil))) (if gri-last-complete-status (progn (setq gri-last-complete-point (point)) (setq gri-last-complete-command (buffer-substring (progn (beginning-of-line) (point)) (progn (end-of-line)(point))))))))) (defun gri-perform-completion (expansion-regex exact-flag) "Does the actual completion based on ARG1 regex. Returns number of matches. Second argument t if trying for exact match. If we fail we will display a different message. Sets gri-last-complete-status to 1 if show completions next time to 2 if expand complete match next time (used by gri-complete only, not here) to 0 in other cases." (let ((unique) (match-count 0) (expansion-list)) (save-excursion (gri-lookat-syntax-file 0) (let ((case-fold-search)) (while (re-search-forward expansion-regex nil t) (setq expansion-list (cons (buffer-substring (progn (beginning-of-line) (point)) (progn (re-search-forward ";\\|(") (forward-char -1)(point))) expansion-list)) (forward-line 1) (setq match-count (1+ match-count))))) (cond ((= match-count 0) (if exact-flag (message "Sorry, this does not match *exactly* to any gri command.") (message "Sorry, this does not match to any known gri command.")) (setq gri-last-complete-status 0)) ((= match-count 1) (save-excursion (if (string-equal "?" (substring (car expansion-list) 0 1)) (progn (gri-lookat-syntax-file 0) (re-search-forward (concat "^" (car expansion-list)) nil t) (forward-line 1) (setq unique (buffer-substring (point) (progn (re-search-forward "^[^ \t]" nil t) (backward-char 1)(point))))) (gri-lookat-syntax-file 1) (re-search-forward (concat "^" (regexp-quote (car expansion-list)) "\\(;\\|(\\)") nil t) ;; Skip over default description, displaying it: (forward-char -1) (if (not (looking-at "(")) (forward-char 1) (forward-char 1) (message "%s" (buffer-substring-no-properties (point) (progn (re-search-forward ");" nil t) (forward-char -2) (point)))) (forward-char 2)) (setq unique (buffer-substring (point) (progn (end-of-line)(point)))))) (delete-region gri-complete-begin-point (point)) (let ((the-start (point)) ; indent all inserted lines (the-end (progn (insert unique) (gri-indent-line) (point-marker)))) (goto-char the-start) (gri-indent-line) (while (and (= 0 (forward-line 1)) (< (point) (marker-position the-end))) (gri-indent-line)) (goto-char (marker-position the-end))) (if (and (get-buffer " *Completions*") ;;need this one line for emacs-18 (get-buffer-window (get-buffer " *Completions*"))) (delete-window (get-buffer-window (get-buffer " *Completions*")))) (setq gri-last-complete-status 0)) ((or (= 1 gri-last-complete-status) ;display completions (and (get-buffer " *Completions*") (get-buffer-window (get-buffer " *Completions*")))) (delete-region gri-complete-begin-point (point)) ;; (delete-region (progn (end-of-line) (point)) ;; (progn (beginning-of-line) (point))) (insert (gri-common-in-list expansion-list nil)) (gri-indent-line) (message "%d possible completions" match-count) (with-output-to-temp-buffer " *Completions*" (display-completion-list expansion-list)) (setq gri-last-complete-status 2)) ;Next time, try unique match ((< match-count 4) ; 3 or fewer matches show in minibuffer (delete-region gri-complete-begin-point (point)) ;; (delete-region (point) (progn (beginning-of-line) (point))) (insert (gri-common-in-list expansion-list nil)) (gri-indent-line) (message "(%d) %s" match-count (gri-match-list-to-string expansion-list)) (setq gri-last-complete-status 2)) (t ;complete as much as possible (delete-region gri-complete-begin-point (point)) ;; (delete-region (progn (end-of-line) (point)) ;; (progn (beginning-of-line) (point))) (insert (gri-common-in-list expansion-list nil)) (gri-indent-line) (message "%d possible completions" match-count) (setq gri-last-complete-status 1))) ;show completions next time match-count)) (defadvice choose-completion-string (after gri-mode-choose-completion protect activate) "Perform completion on mouse selected text." (when (string-equal major-mode "gri-mode") (delete-backward-char 1) (gri-complete))) (defun gri-common-in-list (list remove-underscore-flag) "returns STRING with same beginnings in all strings in LIST" (let ((i 1) (work-list list) (match-len (length (car list))) (first-string (car list)) (current-string nil) (match-flag t)) (setq work-list (cdr work-list)) (while work-list (setq current-string (car work-list)) (if (< (length current-string) match-len) (setq match-len (length current-string))) (if current-string ;; nil last time around (progn (while (and (<= i match-len) match-flag) (if (equal (substring first-string 0 i) (substring current-string 0 i)) (setq i (1+ i)) (setq match-flag nil))) (setq match-len (1- i)) (setq match-flag t) (setq i 1))) (setq work-list (cdr work-list))) (if (not remove-underscore-flag) (substring first-string 0 match-len) (psg-replace-within-string (substring first-string 0 match-len) "_" " ")))) (defun psg-replace-within-string (in-string from to) "Replace ARG2 with ARG3 in ARG1. emacs didn't do this!" (save-excursion (let ((newl "") (index 0) (do-more t) (len (length in-string))) (while do-more (setq do-more (string-match from in-string index)) (if (or (not do-more) (>= do-more len)) ;; finish the line (progn (setq newl (concat newl (substring in-string index))) (setq do-more nil)) ;; found another replacement (setq newl (concat newl (substring in-string index do-more) to)) (setq index (1+ do-more)))) newl))) (defun gri-match-list-to-string (list) "returns STRING with all gri commands in list (just the name part)" (let ((work-list (nreverse list)) (the-command) (the-string)) (while work-list (setq the-command (car work-list)) (setq work-list (cdr work-list)) (setq the-string (concat the-command " " the-string))) (substring the-string 0 -3))) (defun gri-debug-insert (string) "Insert a string in a debug buffer." (save-excursion (let ((gri-test-buffer (get-buffer-create "*gri-test-buffer*"))) (set-buffer gri-test-buffer) (insert string "*\n")))) (defun gri-lookat-syntax-file (where) "Place point in syntax-file buffer, creating it if necessary. If ARG is 0, go to `-' to see all commands (gri-complete) If ARG is 1, go to `--' to skip fragments (gri-help-apropos) (gri-help 2) If ARG is 2, go to `---' to see only gri system commands (gri-help 1) If ARG is 3, go to `---' and skip over variables" (gri-validate-cmd-file) (let ((this-buffer (current-buffer)) (local-cmd-file gri-cmd-file) (gri-syntax-buffer (get-buffer-create "*gri-syntax*")) (gri-syntax-file "~/.gri-syntax") rebuilt) (set-buffer gri-syntax-buffer) (setq buffer-read-only nil) (goto-char (point-min)) ;; Load in existing ~/.gri-syntax if haven't done so yet (when (and (file-readable-p gri-syntax-file) (= (point-min) (point-max))) (insert-file-contents gri-syntax-file) (setq rebuilt t)) (when (or ;; Check if existing ~/.gri-syntax is up-to-date wrt gri-cmd-file (not (file-readable-p gri-syntax-file)) (file-newer-than-file-p local-cmd-file gri-syntax-file) (file-newer-than-file-p (file-chase-links local-cmd-file) gri-syntax-file) ;; Check that correct version in use. (not (re-search-forward "Based on: \\(.*\\)" nil t)) (not (string-equal (file-chase-links local-cmd-file) (buffer-substring (match-beginning 1)(match-end 1))))) (erase-buffer) (gri-build-syntax local-cmd-file) ;build ~/.gri-syntax (insert-file-contents gri-syntax-file) (setq rebuilt t)) (goto-char (point-min)) (when rebuilt (goto-char (point-min)) (if (re-search-forward "gri version \\([.0-9]+\\)" nil t) (message "Using syntax for gri version %s" (buffer-substring (match-beginning 1)(match-end 1))) (message "Using syntax for unknown version of gri")) (if (file-readable-p "~/.grirc") (let ((tmp-buffer (get-buffer-create "*gri-tmp-command*"))) (set-buffer tmp-buffer) (insert-file-contents "~/.grirc") (gri-add-commands-from-current-buffer nil gri-syntax-buffer) (set-buffer gri-syntax-buffer) (kill-buffer tmp-buffer))) (set-buffer this-buffer) (gri-add-commands-from-current-buffer nil gri-syntax-buffer) (set-buffer gri-syntax-buffer) (setq mode-line-buffer-identification "*gri-syntax*")) (set-buffer-modified-p nil) (setq buffer-read-only t) (goto-char (point-min)) (if (= 0 where) (re-search-forward "^-\n" nil t) (if (= 1 where) (re-search-forward "^--\n" nil t) (re-search-forward "^---\n" nil t) ; case 2 or 3 (when (= 3 where) (re-search-forward "^[^\\.\\\\]" nil t) (beginning-of-line)))))) ;; { {{ }} } ;; ^^ ^ ;; (goto-char (scan-lists (point) 1 0)) ;; ;; { {{ }} } ;; ^^ ^ ;; (goto-char (scan-lists (point) 1 1)) (defun gri-kill-option-mouse (EVENT) "Kill (delete) a gri command option, variable or string. See `C-h f gri-kill-option' for more help" (interactive "e") (mouse-set-point EVENT) (gri-kill-option)) (defun gri-kill-option () "Kill (delete) a gri command option, variable or string. An option is everything within brackets. This has highest priority. e.g. after command completion, you get something like: draw x axis [at bottom|top|{.y. [cm]} [lower|upper]] put the cursor here and C-c C-k ^ yields: draw x axis [at bottom|top|{.y. } [lower|upper]] then here and press C-c C-k ^ and you get: draw x axis because it delete the innermost bracketed option. If the cursor is not within a bracketed option, and is within a string or on the first character or a variable, then that string or variable is deleted." (interactive) (let ((beg-line (progn (save-excursion (beginning-of-line) (point)))) (here-point (progn (save-excursion (forward-char 1)(point)))) (del-flag nil) (brk-point)) (save-excursion ;Start with bracket options (while (and (not del-flag) (re-search-backward "[{[]" beg-line t)) (setq brk-point (point)) (save-excursion (goto-char (scan-lists (point) 1 0)) (if (>= (point) here-point) (progn (setq del-flag t) (delete-region (point) brk-point) (delete-horizontal-space) (insert " ")))))) (if del-flag (gri-next-option) ; Visit next option ;; Check if on first char of a variable, delete it. (if (string-match "^\\.\\(\\.\\)?[A-z0-1]+\\(\\.\\)?\\." (buffer-substring (point) (progn (save-excursion (end-of-line)(point))))) (progn (delete-char (match-end 0))) ;; Check if within a string, delete it (save-excursion (if (and (re-search-backward "\"" beg-line t) (progn (forward-char 1) (setq brk-point (point)) (re-search-forward "\"" (progn (save-excursion (end-of-line) (point))) t)) (>= (point) here-point)) (delete-region (progn (forward-char -1)(point)) brk-point))))))) (defun gri-old-goto-option () "Go to first bracket on line, else first dot or slash, else don't move" (let ((flag t) (here-point) (end-line (progn (end-of-line)(point)))) (save-excursion (beginning-of-line) (if (not (re-search-forward "[{[]" end-line t)) (if (not (re-search-forward "[\\.]" end-line t)) (setq flag nil) (backward-char 1))) ;; move on dot or slash (if flag (setq here-point (point)))) (if flag (forward-char (- here-point (point)))))) (defun gri-next-option () "Go to next option on line (options first, variables and strings second)" (interactive) (let ((end-line (progn (save-excursion (end-of-line)(point)))) (the-point (point))) ;; first do brackets, then variables or strings (if (or (re-search-forward "[{[|]" end-line t) (progn (beginning-of-line) (re-search-forward "[{[]" end-line t)) (progn (goto-char the-point) (re-search-forward " [\"\\.]" end-line t)) (progn (beginning-of-line) (re-search-forward " [\"\\.]" end-line t))) (progn ;;move backward if on a variable (with a dot) (backward-char 1) (if (not (string-equal (buffer-substring (point) (1+ (point))) ".")) (forward-char 1)))))) (defun gri-option-select-mouse (EVENT) "Select a gri option left by gri-complete. See gri-option-select for help." (interactive "e") (mouse-set-point EVENT) (gri-option-select)) (defun gri-option-select () "Select a gri option left by gri-complete. Narrow in on a particular gri command, given a syntax description left on the line by gri-complete. The cursor location is used to decide which gri command(s) to narrow to. EXAMPLE: If gri-complete is used on the line `dr x a', the result will be a line like draw x axis [at bottom|top|{.y. [cm]} [lower|upper]] This is the Gri way of describing many commands at once. All these commands are described by this syntax description: draw x axis draw x axis at bottom draw x axis at bottom top draw x axis at bottom bottom draw x axis at top draw x axis at top top draw x axis at top bottom draw x axis at .y. cm draw x axis at .y. cm lower draw x axis at .y. cm upper The gri-option-select command provides easy navigation to select one of these commands. The narrowing process is governed by the cursor position. For example, to get the command narrowed down to draw x axis at bottom [lower|upper] place the cursor somewhere in the word `bottom' and invoke gri-option-select. To complete the narrowing process, selecting draw x axis at bottom lower move the cursor to some place in the word `lower' and invoke gri-option-select again. On the other hand, to get draw x axis at bottom you would put the cursor over either the word `lower' or `upper', and invoke gri-kill-option. NOTE: you might want to practice using this example to learn how to do it. If you make a mistake, note that the normal Emacs undo works." (interactive) ;;Algorithm is 1) remove other options within brackets ;; 2) while there are grouping brackets ;; remove options on either side of brackets ;; remove brackets (let ((beg-line (progn (save-excursion (beginning-of-line) (point)))) ;;;(here-point (progn (save-excursion (forward-char 1)(point)))) ) (save-excursion (skip-chars-backward "^ |[]{}") (gri-del-group-opt-backward)) (save-excursion (skip-chars-forward "^ |[][}") (gri-del-group-opt-forward)) (save-excursion (while (< beg-line (gri-return-enclosing-group nil beg-line)) (goto-char (gri-return-enclosing-group nil beg-line)) ;; on a start bracket of a group (save-excursion (goto-char (scan-lists (progn (backward-char 1)(point)) 1 0)) (delete-backward-char 1) ;; delete the closing bracket (gri-del-group-opt-forward)) (delete-char 1) ;; delete the opening bracket (gri-del-group-opt-backward) ;;;(setq here-point (point)) )) (gri-next-option))) (defun gri-del-group-opt-forward () "Called by gri-option-select to delete backward options within brackets e.g. [arg1|arg2]|[[ar3 arg4]|arg5|arg6]|arg8 | ^ | becomes [arg1|arg2]|[arg5|ar6]|arg8 Always starts on first character to delete." (save-excursion (let ((end-point (gri-return-enclosing-group t (progn (save-excursion (end-of-line) (point))))) (here-point (point))) ;; see if followed by |, if so select option after it for deletion (while (and (progn (skip-chars-forward " \t")(looking-at "|")) (> end-point (point))) ;; and still within group (forward-char 1)(skip-chars-forward " \t") (if (looking-at "[{[]") ;; on an opening bracket (goto-char (scan-lists (point) 1 0)) ;; on a simple word--find end (if (re-search-forward "[] |{}[]" end-point t) (backward-char 1) ;; don't delete bracket or sp (goto-char end-point)))) (skip-chars-backward " \t") (if (< end-point (point)) (goto-char end-point)) (delete-region (point) here-point)))) (defun gri-del-group-opt-backward () "Called by gri-option-select to delete backward options within brackets e.g. [arg1|arg2]|[[ar3 arg4]| arg5|arg6]|arg8 | ^ | becomes [arg1|arg2]|[arg5|ar6]|arg8 Always starts on first character to keep." (save-excursion (let ((beg-point (gri-return-enclosing-group nil (progn (save-excursion (beginning-of-line)(point))))) (here-point (point))) ;; see if preceeded by |, if so select option before it for deletion (while (progn (save-excursion (and (progn (skip-chars-backward " \t")(backward-char 1) (looking-at "|")) ;; preceeded by | (< beg-point (point))))) ;; and still within group (skip-chars-backward " \t")(backward-char 1) ;; on the | (skip-chars-backward " \t")(backward-char 1) ;; on the previous word (if (looking-at "}\\|]") ;; on a closing bracket (progn (forward-char 1)(goto-char (scan-lists (point) -1 0))) (if (re-search-backward "[] |{}[]" beg-point t) ;; on a simple word (forward-char 1) ;; on first char (goto-char beg-point)(forward-char 1)))) (skip-chars-forward " \t") (if (> beg-point (point)) (progn (goto-char beg-point) (forward-char 1))) (delete-region (point) here-point)))) (defun gri-return-enclosing-group (end_flag boundary) "Return as a point either the beginning (ARG1 nil) or end (ARG1 t) of the first enclosing group, either curly or square brakets. [ ] ^ ^ The boundaries are the points not to be exceeded (e.g. end-of-line for ARG1 t, beginning-of-line for ARG1 nil). Return that boundary if no containing group within that boundary." (save-excursion (let ((the-point) (here-point (point))) (if end_flag (progn (while (and (re-search-forward "[]}]" boundary t) (< here-point ;; while group doesn't enclose cursor (progn (save-excursion (goto-char (scan-lists (point) -1 0)) (backward-char 1) (setq the-point (point)) the-point))))) ;; return either end of group or boundary (if (and the-point ;; found at least one group (> here-point the-point)) ;; and it encloses us (point) ;; then return end of group boundary)) ;; else return boundary ;; end_flag is nil (while (and (re-search-backward "[{[]" boundary t) (> here-point ;; while group doesn't enclose cursor (progn (save-excursion (goto-char (scan-lists (point) 1 0)) (setq the-point (point)) the-point))))) ;; return either beginning of group or boundary (if (and the-point ;; found at least one group (< here-point the-point)) ;; and it encloses us (point) ;; then return end of group boundary))))) ;; else return boundary (defun gri-old-del-group-opt-forward () "Called by gri-option-select to delete forward options within brackets e.g. [arg1|arg2|[ar3 arg4]|{arg5 arg6}]|arg8 ^ becomes [arg1]|arg8 Assumes there is always a space between separate options, e.g. [.word1. .word2.] [.word4.] ^ " (let ((end-line (progn (save-excursion (end-of-line) (point)))) (brk-point nil)) (save-excursion ;; see if followed by |, if so delete options after (if (and (re-search-forward "[]}| ]" end-line t) (char-equal 124 (char-after (progn (backward-char 1)(point))))) (progn (setq brk-point (point)) ;; then go to whitespace, skipping groups ;; but don't go past group's closing br (while (and (not (char-equal 93 (char-after (point)))) ;;close-sq (not (char-equal 125 (char-after (point)))) ;;close-cur (not (char-equal 32 (char-after (point)))) ;;space (re-search-forward "[]} {[]" end-line t)) (if (or (char-equal 123 (char-after (progn ;;open-cur (backward-char 1)(point)))) (char-equal 91 (char-after (point)))) ;;open-sq ;; following is why I need a space between options! (goto-char (scan-lists (point) 1 0)))) (if (or (not (char-after (point))) ;;at eol (and (not (char-equal 32 (char-after (point)))) (not (char-equal 125 (char-after (point)))) (not (char-equal 93 (char-after (point)))))) (delete-region (progn (end-of-line)(point)) brk-point) (delete-region (point) brk-point))))))) (defvar Info-directory-list) (defvar Info-directory) (defun gri-info-directory () "Returns nil or gri info file path In emacs 19, path is from Info-default-directory-list and gri info file may be compressed, with suffix .Z .z or .gz In emacs 18, path is Info-directory and cannot be compressed." (require 'info) (if (boundp 'Info-directory-list) (progn (let ((work-list Info-directory-list) (notfound t) (info-directory nil)) (while (and notfound (car work-list)) (if (or (file-readable-p (concat (car work-list) "gri")) (file-readable-p (concat (car work-list) "gri.Z")) (file-readable-p (concat (car work-list) "gri.z")) (file-readable-p (concat (car work-list) "gri.gz")) (file-readable-p (concat (car work-list) "gri.info")) (file-readable-p (concat (car work-list) "gri.info.Z")) (file-readable-p (concat (car work-list) "gri.info.gz"))) (progn (setq info-directory (car work-list)) (setq notfound nil)) ;; In XEmacs, the directories don't have a trailing slash: (if (or (file-readable-p (concat (car work-list) "/gri")) (file-readable-p (concat (car work-list) "/gri.Z")) (file-readable-p (concat (car work-list) "/gri.z")) (file-readable-p (concat (car work-list) "/gri.gz")) (file-readable-p (concat (car work-list) "/gri.info")) (file-readable-p (concat (car work-list) "/gri.info.Z")) (file-readable-p (concat (car work-list) "/gri.info.gz"))) (progn (setq info-directory (concat (car work-list) "/")) (setq notfound nil)) (setq work-list (cdr work-list))))) info-directory)) (if (file-readable-p (concat Info-directory "gri")) Info-directory nil))) (defun gri-help-apropos (keyword) "Displays all gri commands containing keyword argument in *help* buffer. Code fragment abbreviations (e.g. ?set axes) are not included at present time. The keyword is actually a regular expression; while this could be a simple string, you could also list *all* gri commands with gri-help-apropos . which matches any character." (interactive "sgri apropos: ") (save-excursion (gri-lookat-syntax-file 1) (if (re-search-forward keyword nil t) (with-output-to-temp-buffer "*Help*" (princ "List of gri commands containing: ") (princ keyword) (princ "\n\n") (beginning-of-line) (princ (gri-format-display-command (buffer-substring (progn (re-search-forward "\\(;\\|(\\)") ;; Skip over default description (forward-char -1) (if (looking-at "(") (re-search-forward ");" nil t) (forward-char 1)) (point)) (progn (end-of-line) (point))))) (forward-line 1) (while (re-search-forward keyword nil t) (beginning-of-line) (princ "\n") (princ (gri-format-display-command (buffer-substring (progn (search-forward ";") (point)) (progn (end-of-line) (point))))) (forward-line 1)) (print-help-return-message)) (message "Nothing suitable")))) (defalias 'gri-apropos 'gri-help-apropos) (defun gri-show-function (&optional show-all) "Uncover function on current line, hidden by gri-hide commands. If prefixed, show all functions in current buffer (this may easier than typing in C-c M-S)." (interactive "P") (let ((modified (buffer-modified-p))) (if show-all (gri-show-all) (show-entry) (set-buffer-modified-p modified)))) (defun gri-show-all () "Uncover all functions in current buffer, hidden by gri-hide commands." (interactive) (let ((modified (buffer-modified-p))) (if (fboundp 'show-all) (show-all)) (set-buffer-modified-p modified))) (defun gri-hide-function (&optional hide-all) "Hide function under point, similarly to outline-mode. If prefixed, hide all functions in current buffer. BUGS: Will get confused if you have a string which looks like a function title in your function's help text (i.e. a line which begins with a ` character and ends with a ' character." (interactive "P") (if hide-all (gri-hide-all) (let ((the-begin) (the-end) (modified (buffer-modified-p))) (save-excursion (if (not (re-search-forward "^}" nil t)) (error "Sorry, can't find the end of the function to hide.") (setq the-end (point))) (if (not (re-search-backward "^`.*'$" nil t)) (error "Sorry, can't find the beginning of the function to hide.") (setq the-begin (point)))) (hide-region-body the-begin the-end) (set-buffer-modified-p modified)))) (defun gri-hide-all (&optional quiet) "Hide all functions in current buffer, similarly to outline-mode. Optional argument t (prefix) will make it quiet about error. This should be used if you call this function in your gri-mode-hook such that it won't complain when you load a gri file which contains no locally defined gri functions. BUGS: Will get confused if you have a string which looks like a function title in your function's help text (i.e. a line which begins with a ` character and ends with a ' character.)" (interactive "P") (save-excursion (goto-char (point-min)) (re-search-forward "^`[^']*'$" nil t) (beginning-of-line) (let ((the-start (point))(the-end) (modified (buffer-modified-p))) ;; Find the end of the last new command (while (and (re-search-forward "^`[^']*'$" nil t) (re-search-forward "^}$" nil t))) (if (= (point) the-start) (if (not quiet) (message "Sorry, can't find any functions to hide.")) (forward-line 1) (setq the-end (point)) (hide-region-body the-start the-end) (set-buffer-modified-p modified))))) (defvar gri-arg-hist nil) (defun gri-command-arguments (arg-string) "Set the extra arguments sent to the gri process. Usually used to send debugging flags." (interactive (list (read-string "Gri arguments: "))) ;;(interactive ;; (list (completing-read "Gri arguments: " nil nil nil nil gri-arg-hist))) (setq gri-command-arguments arg-string) (message "gri-run will use arguments: -b -y %s" gri-command-arguments)) (defun gri-do-run (the-command inhibit-gri-view) "Do actual work for gri-run and gri-run-new." (if (buffer-modified-p) (save-buffer)) (let ((resize-mini-windows nil)) (when (and gri-view-process gri*view-watch (eq (process-status gri-view-process) 'run)) ;; If using gri-view with -watch option, stop that process now to ;; prevent it from updating while we regenerate the postscript file. (signal-process (process-id gri-view-process) 'SIGSTOP) (stop-process gri-view-process)) (cond ((string-equal "" gri-command-arguments) (message "%s %s %s %s (on newly saved file)" the-command (gri-run-setting-string) (file-name-nondirectory buffer-file-name) gri-command-postarguments) (shell-command (concat the-command (gri-run-setting-string) buffer-file-name " " gri-command-postarguments))) (t (message "%s %s %s %s %s (on newly saved file)" the-command gri-command-arguments (gri-run-setting-string) (file-name-nondirectory buffer-file-name) gri-command-postarguments) (shell-command (concat the-command gri-command-arguments " " (gri-run-setting-string) (file-name-nondirectory buffer-file-name) " " gri-command-postarguments))))) (message "Running gri done.") (cond ((not (get-buffer "*Shell Command Output*")) (cond ((and gri-view-process gri*view-watch (eq (process-status gri-view-process) 'stop)) (signal-process (process-id gri-view-process) 'SIGCONT) ;; In Emacs20, the status doesn't change from 'stop, so do this: (continue-process gri-view-process)) ((and gri*view-after-run (not inhibit-gri-view)) (gri-view))) (message "Gri command completed with no output.")) (t ;; There is a shell ouput buffer... (let ((display-buffer-p)(msg)(eline)(efile)) (save-excursion (set-buffer "*Shell Command Output*") (goto-char (point-min)) (if (re-search-forward "^Segmentation fault" nil t) (setq msg "Segmentation Fault while running gri!")) ;;FATAL error: gr.m:2352: can't use negative y (0.00000) with LOG (if (re-search-forward "^\\(ERROR:\\|FATAL error:\\).*$" nil t) (setq msg (buffer-substring (match-beginning 0)(match-end 0)))) (if (re-search-forward "^PROPER USAGE:" nil t) (setq display-buffer-p t)) (if (re-search-forward "^ Bad command:" nil t) (setq display-buffer-p t)) ;;Error detected at /home/rhogee/new/paper/enlarged_map.gri:42 (if (re-search-forward "Error\\( detected\\)? at \\([^:]+\\):\\([0-9]+\\)" nil t) (setq efile (buffer-substring (match-beginning 2)(match-end 2)) eline (string-to-int (buffer-substring (match-beginning 3)(match-end 3))))) (goto-char (point-min)) (set-window-point (get-buffer-window (current-buffer)) (point-max))) ;This won't work !!! (cond (efile ;Have both msg and line info (cond ((not (string-match "gri.cmd$" efile)) (find-file efile) (goto-line eline))) (if display-buffer-p (display-buffer "*Shell Command Output*")) (if msg (error msg))) (msg (if display-buffer-p (display-buffer "*Shell Command Output*")) (error msg)) (display-buffer-p (display-buffer "*Shell Command Output*")) (t ;Clean execution (let ((lines (save-excursion (if (not (get-buffer "*Shell Command Output*")) 0 (set-buffer "*Shell Command Output*") (if (= (buffer-size) 0) 0 (count-lines (point-min) (point-max))))))) (cond ((and gri-view-process gri*view-watch (eq (process-status gri-view-process) 'stop)) (signal-process (process-id gri-view-process) 'SIGCONT) ;; In Emacs20, the status doesn't change from 'stop, so do this: (continue-process gri-view-process)) ((and gri*view-after-run (not inhibit-gri-view)) (gri-view))) ;; If there was only one line of output from Gri, we should ;; repeat it here. (cond ((= lines 0) (message "Gri command completed with no output.") (kill-buffer "*Shell Command Output*")) ((= lines 1) (message "%s" (save-excursion (set-buffer "*Shell Command Output*") (goto-char (point-min)) (buffer-substring (point) (progn (end-of-line)(point)))))))))))))) (defun gri-run (&optional inhibit-gri-view) "Save buffer to a file, then run Gri on it, creating a PostScript file called *.ps where * is the basename of the gri command-file. (If the buffer/file name does not end in `.gri', the PostScript file name is the full buffer name, with suffix `.ps' added. After its successfull completion, gri-run will invoke gri-view if the variable gri*view-after-run is set to true. If gri-run ends in error, it will try to place the edit point on the source line which contains the error. If an optional prefix argument is supplied to gri-run, gri-view will not be run. If using \"gv\" and the \"-watch\" option, the gv process will be stopped during the time gri-run regenerates the menu, and continued thereafter and gv will redisplay the figure (instead of gri-mode starting up a new gv process)." (interactive "P") (gri-validate-cmd-file) (if (string-equal gri-bin-file "gri") ; Use shell default version (gri-do-run (concat "gri -b -y ") inhibit-gri-view) (gri-do-run (concat gri-bin-file " -directory " (file-name-directory gri-cmd-file) " -y -b ") inhibit-gri-view))) (defun gri-view (&optional filename) "Run X-windows viewer in lower shell on existing .ps file for the gri buffer using landscape mode if `set page lansdscape' is found in gri buffer. A gzip'ed postscript file can also be viewed without overwriting the file. Reset variables gri*view-command and gri*view-landscape-arg in your .emacs file to control what commands are sent to the shell to display the postscript file. Default values are: (setq gri*view-command \"gv\") (setq gri*view-landscape-arg \"-landscape\") The default viewer is \"gv\" because is has options that gri-mode knows about, such as -watch and -scale. Default values for these options are selectable from gri-customize, and buffer-local settings can be made from the menubar. See also the gri-run command, which calls gri-view automatically after successfully executing your gri buffer if the variable gri*view-after-run is set to true. If using \"gv\" and the \"-watch\" option, the gv process will be stopped during the time gri-run regenerates the menu, and continued thereafter and gv will redisplay the figure (instead of gri-mode starting up a new gv process)." ;;; Asynchronyous output goes to *shell-command* buffer. ;;; Return windows to original state because that buffer is usually empty ;;; (if no error occurred) and will probably be empty on error by the time ;;; the function finishes, because it's asynchronious. (interactive) (let ((psfile (or filename (concat (filename-sans-gri-suffix buffer-file-name) ".ps"))) (shell-command-switch (or (and (boundp 'shell-command-switch) shell-command-switch) "-c")) (command (cond ((and (symbolp gri*view-command) (equal 'gv-old gri*view-command)) "gv") ((symbolp gri*view-command) (symbol-name gri*view-command)) (t gri*view-command))) (landscape) (scale) (watch) (noantialias)) (if (not (file-readable-p psfile)) (if (not (file-readable-p (concat psfile ".gz"))) (error "%s not found or not readable" psfile) ;;Found gzipped version of file (setq psfile (concat psfile ".gz")))) (cond ((and (symbolp gri*view-command) (equal 'gv gri*view-command)) (setq landscape (save-excursion (goto-char (point-min)) (if (re-search-forward "^[ \t]*set[ ]+page[ ]+landscape" nil t) "--orientation=landscape" "--orientation=portrait"))) (setq scale (format "--scale=%s" (int-to-string gri*view-scale))) (setq watch (if gri*view-watch "--watch" "--nowatch")) (setq noantialias (if gri*view-noantialias "--noantialias" "--antialias"))) ((and (symbolp gri*view-command) (equal 'gv-old gri*view-command)) (setq landscape (save-excursion (goto-char (point-min)) (if (re-search-forward "^[ \t]*set[ ]+page[ ]+landscape" nil t) "-landscape" "-portrait"))) (setq scale (format "-scale %s" (int-to-string gri*view-scale))) (setq watch (if gri*view-watch "-watch" "-nowatch")) (setq noantialias (if gri*view-noantialias "-noantialias" "-antialias"))) ((not (symbolp gri*view-command)) (setq landscape (save-excursion (goto-char (point-min)) (if (re-search-forward "^[ \t]*set[ ]+page[ ]+landscape" nil t) gri*view-landscape-arg nil))))) (cond ((equal command "gv") (message "%s %s %s %s %s %s" command landscape watch scale noantialias psfile) (setq gri-view-process (start-process "gri-view" nil command landscape watch scale noantialias psfile))) (landscape (message "%s %s %s" command landscape psfile) (setq gri-view-process (start-process "gri-view" nil command landscape psfile))) (t (message "%s %s" command psfile) (setq gri-view-process (start-process "gri-view" nil command psfile)))) ;;(setq mode-line-process '(":%s")) ;;(set-process-sentinel gri-view-process 'shell-command-sentinel) (set-process-filter gri-view-process 'gri-insertion-filter))) (defun gri-insertion-filter (gri-view-process string) (message "gri-view: %s" string)) (defun gri-indent-buffer () "Indent the entire gri buffer. Won't indent hidden user commands." (interactive) (save-excursion (goto-char (point-min)) (skip-chars-forward "\n") (gri-indent-line) (while (= 0 (forward-line 1)) (gri-indent-line)))) (defun gri-indent-region (from to &optional entire-buffer-flag) "Indent the region. Prefix arg means indent entire buffer. e.g. ESC 1 ESC q will indent the entire buffer." (interactive "r\nP") (save-excursion (if entire-buffer-flag (gri-indent-buffer) (save-restriction (narrow-to-region from to) (goto-char (point-min)) (skip-chars-forward "\n") (narrow-to-region (point) (point-max)) (gri-indent-line) (while (= 0 (forward-line 1)) (gri-indent-line))))) (gri-indent-line)) (defun gri-convert-comments () "Convert Gri // and /* */ comments to # style in current buffer. You could add this function to an gri-mode-hook such that it runs automatically to convert all your old gri files. To do this add the following to your ~/.emacs file: (add-hook 'gri-mode-hook ' gri-convert-comments) See also gri-convert-comments-with-prompt." (interactive) (save-excursion (goto-char (point-min)) (while (search-forward "//" nil t) (if (gri-system-line) (end-of-line) (delete-backward-char 2) (insert "#"))) (goto-char (point-min)) (while (search-forward "/*" nil t) (if (gri-system-line) (end-of-line) (delete-backward-char 2) (insert "#") (let ((start (point))) (if (re-search-forward "*/" nil t) (save-restriction (delete-backward-char 2) (narrow-to-region start (point)) (goto-char start) (while (= 0 (forward-line 1)) (insert "#"))))))))) (defun gri-convert-comments-with-prompt () "A function to put in a gri-mode-hook to convert your files to # comments. You could add this function to an gri-mode-hook such that it runs automatically to convert all your old gri files after prompting you to do the conversion. To do this add the following to your ~/.emacs file: (add-hook 'gri-mode-hook ' gri-convert-comments-with-prompt) See also gri-convert-comments." (interactive) (save-excursion (goto-char (point-min)) (let ((found)) (while (and (not found) (re-search-forward "//\\|/\*" nil t)) (if (not (gri-system-line)) (setq found t))) (if (and found (y-or-n-p "Convert old comment lines? ")) (gri-convert-comments))))) (defun gri-comment-out-region (from to) "Comment out the region between point and mark. You can remove these comments using gri-uncomment-out-region." (interactive "r") (save-excursion (save-restriction (narrow-to-region from to) (goto-char (point-min)) (let ((overwrite-mode nil)) (insert "#") (while (and (= 0 (forward-line 1)) (not (= (point) (point-max)))) (insert "#")))))) (defun gri-uncomment-out-region (from to) "Remove Comments at beginning of lines in the region between point and mark." (interactive "r") (save-excursion (save-restriction (narrow-to-region from to) (goto-char (point-min)) (if (looking-at "//") (delete-char 2)) (if (looking-at "#") (delete-char 1)) (while (= 0 (forward-line 1)) (if (looking-at "//") (delete-char 2)) (if (looking-at "#") (delete-char 1)))))) (defun gri*date-function () "Adapted from objective-C-mode. Add name, author and date on current line." (let* ((u (- 63 (length (user-full-name)) (length (gri*date))))) (insert "# ") (if (not (string-equal (user-full-name) "")) (progn (setq u (- u 1)) (insert (user-full-name) " "))) (insert-char 32 u) (insert (gri*date)))) (defun gri*date () "Return the current date in an EB Signal standard form. Code from objective-C-mode." (concat (substring (current-time-string) -4 nil) "-" (gri*month (substring (current-time-string) 4 7)) "-" (gri*day (substring (current-time-string) 8 10)))) (defun gri*day (aString) (let ((a (car (cdr (assoc aString '((" 1" "01") (" 2" "02") (" 3" "03") (" 4" "04") (" 5" "05") (" 6" "06") (" 7" "07") (" 8" "08") (" 9" "09"))))))) (if (null a) aString a))) (defun gri*month (aString) (let ((a (car (cdr (assoc aString '(("JAN" "01") ("FEB" "02") ("MAR" "03") ("APR" "04") ("MAY" "05") ("JUN" "06") ("JUL" "07") ("AUG" "08") ("SEP" "09") ("OCT" "10") ("NOV" "11") ("DEC" "12") )))))) (if (null a) aString a))) (defun gri-function-skeleton () "Build a routine skeleton prompting for name." (interactive) (let ((the-name (read-string "gri function name: "))) (if (string-equal the-name "") (error "No name given.")) (goto-char (point-min)) (insert "\n") (backward-char 1) (insert "`" the-name "'\n") (insert "------------------------------------") (insert "----------------------------------\n\n") (insert "------------------------------------") (insert "----------------------------------\n") (insert "{\n") (gri*date-function) (gri-indent-line) (insert "\n") (gri-indent-line) (insert "\n}") (previous-line 5))) (defun gri-fontify-buffer () "Fontify buffer with font-lock" (interactive) (cond ((featurep 'font-lock) (font-lock-fontify-buffer)) ((load "font-lock" t t) (font-lock-fontify-buffer)) (t (message "font-lock is not available.")))) (defun gri-return () "Carriage return in Gri-mode with optional highlighting and indentation. If variable gri-indent-before-return is t, current line is indented before newline is created." (interactive) (if gri-indent-before-return (gri-indent-line)) ;; FIXME: I could also use font-lock on region to get continued system lines ;; fontified okay. (newline) (gri-indent-line)) ;;; -- font-lock stuff (defvar gri-mode-system-face 'gri-mode-system-face "Face to use for gri-mode system commands.") (defun gri-font-lock-setup () (when (featurep 'font-lock) (cond (gri-mode-is-XEmacs ;; XEmacs: (make-face 'gri-mode-system-face) (set-face-foreground 'gri-mode-system-face "red" 'global nil 'append)) (gri-mode-is-Emacs2X (copy-face 'font-lock-warning-face 'gri-mode-system-face)))) (make-local-variable 'font-lock-defaults) (setq font-lock-defaults '(gri-font-lock-keywords nil ;;; Keywords only? No, let it do syntax via table. nil ;;; case-fold? nil ;;; Local syntax table. nil ;;; Use `backward-paragraph' ? No ;;;(font-lock-comment-start-regexp . "%") ;;;(font-lock-mark-block-function . mark-paragraph))) ))) (defconst gri-font-lock-keywords nil "Default expressions to fontify in gri-mode.") ;; (make-regexp ;; '("break" "else" "else if" "end if" "end while" "if" "quit" "return" "rpn" ;; "while")) ;; Take the list of builtins from gri.cmd, and run ;; perl -ne 'chop;{print "\"$_\"\n"}' ;; to get the list of strings. Then: ;; ;; (regexp-opt ;; '( ;; "..R2.." ;; "..coeff0.." ;; "..coeff0_sig.." ;; "..coeff1.." ;; "..coeff1_sig.." ;; "..num_col_data.." ;; "..num_col_data_missing.." ;; "..arrowsize.." ;; "..batch.." ;; "..debug.." ;; "..fontsize.." ;; "..graylevel.." ;; "..linewidth.." ;; "..linewidthaxis.." ;; "..linewidthsymbol.." ;; "..missingvalue.." ;; "..symbolsize.." ;; "..superuser.." ;; "..trace.." ;; "..tic_direction.." ;; "..tic_size.." ;; "..xmargin.." ;; "..xsize.." ;; "..ymargin.." ;; "..ysize.." ;; "..red.." ;; "..blue.." ;; "..green.." ;; "..exit_status.." ;; "..xleft.." ;; "..xright.." ;; "..ybottom.." ;; "..ytop.." ;; "..use_default_for_query.." ;; "..words_in_dataline.." ;; "..eof.." ;; "..landscape.." ;; "..publication.." ;; "..xlast.." ;; "..ylast.." ;; "..image_width.." ;; "..image_height..")) ;; ;; (regexp-opt ;; '( ;; "\.missingvalue." ;; "\.return_value." ;; "\.version." ;; "\.pid." ;; "\.wd." ;; "\.time." ;; "\.user." ;; "\.host." ;; "\.system." ;; "\.home." ;; "\.lib_dir." ;; "\.command_file." ;; "\.readfrom_file." ;; "\.ps_file." ;; "\.path_data." ;; "\.path_commands.")) (setq gri-font-lock-keywords '((gri-font-lock-match-functions (0 font-lock-function-name-face) (1 font-lock-comment-face nil t) (2 font-lock-function-name-face nil t) (3 font-lock-function-name-face nil t)) ;; gri-font-lock-system-commands is broken since Emacs v22. ;; (gri-font-lock-system-commands ;; (0 font-lock-function-name-face nil t) ;; (1 font-lock-keyword-face nil t) ;; (2 gri-mode-system-face prepend t)) ;; Use simple regexp instead: ("\\(system\\)\\(.*\\)" (1 font-lock-keyword-face nil t) (2 gri-mode-system-face prepend t)) ;;("\\(break\\|e\\(lse\\( if\\)?\\|nd \\(if\\|while\\)\\)\\|if\\|quit\\|r\\(eturn\\|pn\\)\\|while\\)\\b" ("\\(quit\\|return\\|if\\|else\\( if\\)?\\|end \\(if\\|while\\)\\|break\\|while\\|rpn\\)\\b" . font-lock-keyword-face) ("\\\\[^ ]+[ ]+[\\+\\*/^-]?= " . font-lock-function-name-face) ("\\.[^ .]+\\.[ ]+[\\+\\*/^-]?= " . font-lock-function-name-face) ("\\.\\.\\(\\(R2\\|arrowsize\\|b\\(atch\\|lue\\)\\|coeff\\([01]_sig\\|[01]\\)\\|debug\\|e\\(of\\|xit_status\\)\\|fontsize\\|gr\\(aylevel\\|een\\)\\|image_\\(height\\|width\\)\\|l\\(andscape\\|inewidth\\(axis\\|symbol\\)?\\)\\|missingvalue\\|num_col_data\\(_missing\\)?\\|publication\\|red\\|s\\(uperuser\\|ymbolsize\\)\\|t\\(ic_\\(direction\\|size\\)\\|race\\)\\|use_default_for_query\\|words_in_dataline\\|x\\(l\\(\\(as\\|ef\\)t\\)\\|margin\\|right\\|size\\)\\|y\\(bottom\\|last\\|margin\\|size\\|top\\)\\)\\.\\.\\)" ;; " \\(\\.\\.[A-z][^ .\n\C-m]*\\.\\.\\)" (0 font-lock-type-face)) ; builtin ..variables.. ("\\\\\\.\\(\\(command_file\\|ho\\(me\\|st\\)\\|lib_dir\\|missingvalue\\|p\\(ath_\\(commands\\|data\\)\\|id\\|s_file\\)\\|re\\(\\(adfrom_fil\\|turn_valu\\)e\\)\\|system\\|time\\|user\\|version\\|wd\\)\\.\\)" (0 font-lock-type-face)) ; builtin \.synonyms. ("\\(\\\\[^ }\C-m\n]+\\)" (1 font-lock-variable-name-face)) ; \.synonyns. ("\\(\\b\\.[A-z][^ .\n\C-m]*\\.\\b\\)" (1 font-lock-variable-name-face)) ; user .variables. )) ;; V1.28 Stats on gsl-map.gri ;; 0.0202 gri-font-lock-match-functions ;; 0.0831 gri-font-lock-system-commands ;; 0.1074 "\\(quit\\|return\\|if\\|else\\( if\\)?..." ;; 0.0156 "\\\\[^ ]+[ ]+[\\+\\*/^-]?= " ;; 0.0141 "\\.[^ .]+\\.[ ]+[\\+\\*/^-]?= " ;; 0.0447 " \\(\\.\\.[A-z][^ .$]*\\.\\.\\)" ;; 0.0535 " \\(\\.[A-z][^ .$]*\\.\\)" ;; 0.2701 " \\(\\\\[^ $]+\\)" ;; Surprising that optimized regexp is slower... ;; 0.2695 "\\(break\\|e\\(lse\\(\\| if\\)\\|nd \\(if\\|while\\) (defun gri-font-lock-system-commands (limit) "Match gri system commands. Return: match 0 as the declaration. match 1 as the system keyword. match 2 as the command text." ;; Prior imcomplete multi-line system command? (if (not (and gri-mode-is-XEmacs (equal (point) (save-excursion (end-of-line)(point))))) ;;XEmacs finished last continued system command on eol - don't redo it! (let ((start-point (point)) (start-line (progn (beginning-of-line)(point))) (last-step-ok)) (while (and (setq last-step-ok (= 0 (forward-line -1))) (progn (end-of-line) (eq (preceding-char) ?\\)))) (if last-step-ok (forward-line 1)) (if (or (= (point) start-line) (not (looking-at "\\(^\\|\C-m\\)[ \t]*\\(\\\\[^ ]+[ ]+=[ ]+\\)?\\(system\\)" ))) (goto-char start-point)))) ;;;FIXME: XEmacs infinite loop: ;;; - Is it because of the move above? ;;; - Or because it's font-lock moves to end of match-data 0? (if (re-search-forward "\\bsystem\\b" limit t) (let ((sys-b (match-beginning 0)) (sys-e (match-end 0)) decl-b decl-e com-b com-e) ;; goto bol to see if commented out (re-search-backward "^\\|\C-m" (point-min) t) (if (not (looking-at "\\(^\\|\C-m\\)[ \t]*\\(\\\\[^ ]+[ ]+=[ ]+\\)?\\(system\\)")) ;; ^^^^^^^^^^^^^^^^^^^^^^^^opt synonym (progn ; It was commented out or otherwise (goto-char sys-e) ; invalid (store-match-data (list nil nil)) t) (setq decl-b (match-beginning 2)) (setq decl-e (match-end 2)) ;; <@-Z_a-z~" ";.,!?"))) (cond ((zerop (length name)) nil) ((file-exists-p name) name)))) (defvar gri*WWW-process nil) (defun gri-WWW-manual () "Start world-wide-web browser displaying gri manual. The page visited is set in the variable gri-WWW-page, which may be reset on your site. The main site (always up to date) is: http://gri.sourceforge.net/gridoc/html/index.html or http://www.phys.ocean.dal.ca/~kelley/gri/index.html The browser used by determined by the variable gri*WWW-program. Any output (errors?) is put in the buffer `gri-WWW-manual'." (interactive) (cond (gri*WWW-program (message "Starting process. See buffer gri-WWW-manual about errors.") (setq gri*WWW-process (start-process "gri-WWW" "gri-WWW-manual" gri*WWW-program gri*WWW-page))) (t (if (not (featurep 'browse-url)) (load "browse-url" t t)) (if (not (featurep 'browse-url)) (message "Sorry, you don't have browse-url on your system. Set variable gri*WWW-program") (funcall browse-url-browser-function gri*WWW-page))))) (setq completion-ignored-extensions (cons ".ps" completion-ignored-extensions)) (defun gri-close-statement () "Insert a matching closing statement for open, if or while" (interactive) (let* ((the-statement)(the-string)(depth 1) (fullpattern "^[ \t]*\\(open \\|if \\|while \\|end if\\|end while\\|close \\)") (pattern fullpattern)) (save-excursion (while (and (not (equal depth 0)) (re-search-backward pattern nil t)) (setq the-statement (buffer-substring (match-beginning 1)(match-end 1))) (cond ((equal the-statement "end if") (setq depth (1+ depth)) (setq pattern "^[ \t]*\\(if \\)")) ((equal the-statement "end while") (setq depth (1+ depth)) (setq pattern "^[ \t]*\\(while \\)")) ((equal the-statement "close ") (setq depth (1+ depth)) (goto-char (match-end 1)) (re-search-forward "[^ \t\n]+" nil t) (setq pattern (concat "^[ \t]*\\(open \\)" (buffer-substring (match-beginning 0)(match-end 0))))) ((equal the-statement "if ") (setq depth (1- depth)) (setq pattern fullpattern) (setq the-string "end if")) ((equal the-statement "while ") (setq depth (1- depth)) (setq pattern fullpattern) (setq the-string "end while")) ((equal the-statement "open ") (setq depth (1- depth)) (setq pattern fullpattern) (goto-char (match-end 1)) (re-search-forward "[^ \t\n]+" nil t) (setq the-string (concat "close " (buffer-substring (match-beginning 0)(match-end 0)))) (beginning-of-line))))) (if (not (equal depth 0)) (error "Sorry. Could not find an unbalanced statement to close.") (if (not (string-match "[^ \t]" (buffer-substring (point) (save-excursion (beginning-of-line)(point))))) (insert the-string) (end-of-line) (insert "\n" the-string)) (let ((gri-indent-before-return t)) (gri-return))))) (defun gri-print () "Print the postscript file associated with the current gri file." (interactive) (let ((the-option (or (and (stringp gri*lpr-switches) gri*lpr-switches) (car gri*lpr-switches))) (rest (and (listp gri*lpr-switches) (cdr gri*lpr-switches)))) (while rest (setq the-option (concat the-option " " (car rest))) (setq rest (cdr rest))) (let ((psfile (concat (filename-sans-gri-suffix buffer-file-name) ".ps")) (the-command)) (if (not (file-readable-p psfile)) (if (not (file-readable-p (concat psfile ".gz"))) (error "%s not found or not readable" psfile) ;;Found gzipped version of file (setq the-command (concat "gunzip -c " psfile ".gz | " gri*lpr-command " " the-option))) ;;Found postscript file (setq the-command (concat gri*lpr-command " " the-option " " psfile))) (shell-command the-command) (if (get-buffer "*Shell Command Output*");;need this for emacs-18 (save-excursion (set-buffer "*Shell Command Output*") (if (= (point-min)(point-max)) (message "Done: %s" the-command)))) (message "Done: %s" the-command)))) (defun gri-customize () (interactive) (customize-group "gri")) ;; ---The following by Dan E. Kelley (with modifications by Peter Galbraith) ;; V1.01 24Jan91 by Dan Kelley, kelley@cs.dal.ca ;; Created. Used matlab.el as a guide. ;; ;; V1.02 29jan93 by Dan Kelley, kelley@open.dal.ca ;; Change indent level to 2. ;; ;; V1.03 11nov93 by Peter Galbraith, rhogee@bathybius.meteo.mcgill.ca ;; fixed: auto-mode on .gri extension ;; fixed: gri-comment didn't recognise existing comment after command ;; fixed: gri-indent-line didn't recognise existing comment after command ;; fixed: gri-indent-line when previous line is a continued line: ;; - removed abbrev mode ;; - added fill mode with \ at end of lines ;; - increase indent if first continuation ;; - keep same indent as prev line if 2nd or more continuation ;; - then indent next un-continued line same as base line ;; of continuated line, e.g. ;; draw label "\string" at {rpn ..xmargin.. .2 +} \ ;; {rpn ..ymargin.. .5 -} ;; draw ... ^ user modified indentation ;; ^ proper indentation regardless of continuated line ;; based on base line of continuated line (draw label ...) (defconst gri-comment-column 32 "*The goal comment column in Gri-mode buffers.") (defconst gri-new-command-help-indent-level 0 "*The indentation in help lines for new commands.") (defvar gri-indent-level 4 "Number of spaces to indent in gri-mode.") (defvar gri-mode-syntax-table nil "Syntax table used in Gri-mode buffers.") (defvar gri-hist-alist nil "History list for gri-help and gri-info") (if gri-mode-syntax-table () ;;; New syntax-table by PSG -- December 1995 (setq gri-mode-syntax-table (make-syntax-table)) ;; Support # style comments (modify-syntax-entry ?# "<" gri-mode-syntax-table) (modify-syntax-entry ?\n "> " gri-mode-syntax-table) ;; Give CR the same syntax as newline, for selective-display (modify-syntax-entry ?\^m "> b" gri-mode-syntax-table) ;;(modify-syntax-entry ?_ "_" gri-mode-syntax-table) (modify-syntax-entry ?_ "w" gri-mode-syntax-table) (modify-syntax-entry ?. "w" gri-mode-syntax-table) ;;(modify-syntax-entry ?\\ "_" gri-mode-syntax-table) ;; For strings like: "a string with an embedded \" character" (modify-syntax-entry ?\\ "\\" gri-mode-syntax-table) (modify-syntax-entry ?+ "." gri-mode-syntax-table) (modify-syntax-entry ?- "." gri-mode-syntax-table) (modify-syntax-entry ?= "." gri-mode-syntax-table) (modify-syntax-entry ?< "." gri-mode-syntax-table) (modify-syntax-entry ?> "." gri-mode-syntax-table) (modify-syntax-entry ?& "." gri-mode-syntax-table) (modify-syntax-entry ?| "." gri-mode-syntax-table)) ;; Abbrev Table (defvar gri-mode-abbrev-table nil "Abbrev table used in gri-mode buffers.") (define-abbrev-table 'gri-mode-abbrev-table ()) ;; Mode Map (defvar gri-mode-map () "Keymap used in gri-mode.") (if gri-mode-map () (setq gri-mode-map (make-sparse-keymap)) (define-key gri-mode-map "\r" 'gri-return) (define-key gri-mode-map "\M-\C-v" 'gri-indent-buffer) (define-key gri-mode-map "\M-\C-\\" 'gri-indent-region) (define-key gri-mode-map "\M-q" 'gri-indent-region) (define-key gri-mode-map "\t" 'gri-indent-line) (define-key gri-mode-map "\M-;" 'gri-comment) (define-key gri-mode-map "\C-c\C-f" 'gri-function-skeleton) (define-key gri-mode-map [?\C-\S-l] 'gri-fontify-buffer) (define-key gri-mode-map "\M-\r" 'newline) (define-key gri-mode-map "\C-c]" 'gri-close-statement) (define-key gri-mode-map "\C-c\M-h" 'gri-hide-function) (define-key gri-mode-map "\C-c\M-H" 'gri-hide-all) (define-key gri-mode-map "\C-c\M-s" 'gri-show-function) (define-key gri-mode-map "\C-c\M-S" 'gri-show-all) (define-key gri-mode-map "\C-c\M-n" 'gri-narrow-to-function) (define-key gri-mode-map "\C-c\C-x" 'gri-insert-file-as-comment) (define-key gri-mode-map "\C-c\C-v" 'gri-view) (define-key gri-mode-map "\C-c\C-r" 'gri-run) (define-key gri-mode-map "\C-c\C-p" 'gri-print) (define-key gri-mode-map "\C-c\M-v" 'gri-set-version) (define-key gri-mode-map "\C-c\C-a" 'gri-help-apropos) (define-key gri-mode-map "\C-c\C-n" 'gri-next-option) (define-key gri-mode-map "\C-c\C-k" 'gri-kill-option) (define-key gri-mode-map "\C-c\C-o" 'gri-option-select) (define-key gri-mode-map "\C-c\C-d" 'gri-display-syntax) (define-key gri-mode-map "\C-c\C-w" 'gri-WWW-manual) (define-key gri-mode-map "\C-c\C-i" 'gri-info-this-command) (define-key gri-mode-map "\C-c\C-h" 'gri-help-this-command) (define-key gri-mode-map "\C-c\M-i" 'gri-info) (define-key gri-mode-map "\C-c\M-h" 'gri-help) (define-key gri-mode-map "\C-c#" 'gri-comment-out-region) (define-key gri-mode-map "\C-u\C-c#" 'gri-uncomment-out-region) (define-key gri-mode-map "\M-\t" 'gri-complete) (define-key gri-mode-map "\C-c?" 'describe-mode) (cond ((string-match "XEmacs\\|Lucid" emacs-version) (define-key gri-mode-map [(shift button1)] 'gri-option-select-mouse) (define-key gri-mode-map [(shift button2)] 'gri-kill-option-mouse)) (window-system ;; Note [S-down-mouse-1] because of emacs-19.30 !!! ;; It has a font-selection function there, so [S-mouse-1] won't work. (define-key gri-mode-map [S-down-mouse-1] 'gri-option-select-mouse) (define-key gri-mode-map [S-mouse-2] 'gri-kill-option-mouse)))) ;;; Menus - in emacs 19 only... ;;; From XEmacs-19.14 NEWS: ;;; Here is an example of a menubar definition: ;;; ;;; (defvar default-menubar ;;; '(("File" ["Open File..." find-file t] ;;; ["Save Buffer" save-buffer t] ;;; ["Save Buffer As..." write-file t] ;;; ["Revert Buffer" revert-buffer t] ;;; "-----" ;;; ["Print Buffer" lpr-buffer t] ;;; "-----" ;;; ["Delete Frame" delete-frame t] ;;; ["Kill Buffer..." kill-buffer t] ;;; ["Exit Emacs" save-buffers-kill-emacs t] ;;; ) ;;; ("Edit" ["Undo" advertised-undo t] ;;; ["Cut" kill-primary-selection t] ;;; ["Copy" copy-primary-selection t] ;;; ["Paste" yank-clipboard-selection t] ;;; ["Clear" delete-primary-selection t] ;;; ) ;;; ...)) (let ((topics '(("while" "(gri)While") ("if" "(gri)If Statements") ("localSynonyms" "(gri)Local Synonyms") ("synonyms" "(gri)About Synonyms") ("builtInVariables" "(gri)Built-in Variables") ("variables" "(gri)About Variables") ("rpn" "(gri)rpn Mathematics") ("columns" "(gri)Manipulation of Columns etc") ("conceptIndex" "(gri)Concept Index") ("history" "(gri)History")))) (while topics (let* ((topic (car topics)) value menu name) (setq topics (cdr topics)) (setq value (nth 0 topic) menu (nth 1 topic)) (setq name (intern (concat "gri-info-" value))) (fset name (list 'lambda () (list 'interactive) (list 'require ''info) (list 'Info-goto-node menu)))) ;; In latex.el, Per even builds the menu at this stage! )) (cond ((fboundp 'easy-menu-define) (easy-menu-define gri-mode-menu4 gri-mode-map "Menu keymap for gri-mode." '("Gri-Help" ["Help about current command" gri-help-this-command t] ["Help about any command" gri-help t] ["Info about current command" gri-info-this-command t] ["Info about any command" gri-info t] ("InfoTopics" ;;; Old way! ;;; ["While Statements" (lambda () ;;; (interactive)(require 'info) ;;; (Info-goto-node "(gri)While")) t] ["Concept Index" gri-info-conceptIndex t] ["Manipulating Columns" gri-info-columns t] ["Reverse Polish Math (rpn stuff)" gri-info-rpn t] ["About Variables" gri-info-variables t] ["Built-in Variables" gri-info-builtInVariables t] ["About Synonyms" gri-info-synonyms t] ["Local Synonyms" gri-info-localSynonyms t] ["If Statements" gri-info-if t] ["While Statements" gri-info-while t] ["History" gri-info-history t] ) ["Gri Manual on WWW" gri-WWW-manual t] ["Display syntax for current command" gri-display-syntax t] ["List gri commands containing string" gri-help-apropos t] ;; ["Customize Gri" (list 'lambda () (interactive)(customize-group "gri")) t] ["Customize Gri" (customize-group "gri") t] )) (easy-menu-define gri-mode-menu3 gri-mode-map "Menu keymap for gri-mode." '("Hide" ["Hide this gri function" gri-hide-function t] ["Hide all gri functions" gri-hide-all t] ["Show this gri function" gri-show-function t] ["Show all gri functions" gri-show-all t] ["Restrict editing to function" gri-narrow-to-function t] ["Remove function restriction" widen t] )) (load "executable" t t) ; executable-find not autoloaded in emacs20 (easy-menu-define gri-mode-menu2 gri-mode-map "Menu keymap for gri-mode." '("Perform" ["Save, Run and View gri" gri-run t] ("Run Settings" "Global run-time options" ["-publication" (gri-run-setting-toggle "-publication") :style toggle :selected (member "-publication" gri*run-settings)] ["-trace" (gri-run-setting-toggle "-trace") :style toggle :selected (member "-trace" gri*run-settings)] ["-nowarn_offpage" (gri-run-setting-toggle "-nowarn_offpage") :style toggle :selected (member "-nowarn_offpage" gri*run-settings)] ["-debug" (gri-run-setting-toggle "-debug") :style toggle :selected (member "-debug" gri*run-settings)] ["-no_bounding_box" (gri-run-setting-toggle "-no_bounding_box") :style toggle :selected (member "-no_bounding_box" gri*run-settings)] ;; -superuser ? ["Display graph after compilation" (setq gri*view-after-run (not gri*view-after-run)) :style toggle :selected gri*view-after-run] ["Set gri version to use" gri-set-version t] "Local run-time options" ["Set gri version for this file" gri-set-local-version t] ["set filename arguments" (gri-menu-set-command-postarguments) :visible (not gri-command-postarguments)] ["clear filename arguments" (gri-unset-command-postarguments) :visible gri-command-postarguments] ) ["View existing PostScript" gri-view t] ("Postscript viewer" ["gv" (setq gri*view-command 'gv) :style radio :selected (equal gri*view-command 'gv) :active (and (fboundp 'executable-find)(executable-find "gv"))] ["gv (old version)" (setq gri*view-command 'gv-old) :style radio :selected (equal gri*view-command 'gv-old) :active (and (fboundp 'executable-find)(executable-find "gv"))] ["ggv" (setq gri*view-command 'ggv) :style radio :selected (equal gri*view-command 'ggv) :active (and (fboundp 'executable-find)(executable-find "ggv"))] ["gnome-gv" (setq gri*view-command 'gnome-gv) :style radio :selected (equal gri*view-command 'gnome-gv) :active (and (fboundp 'executable-find)(executable-find "gnome-gv"))] ["ghostview" (setq gri*view-command 'ghostview) :style radio :selected (equal gri*view-command 'ghostview) :active (and (fboundp 'executable-find)(executable-find "ghostview"))] ["kghostview" (setq gri*view-command 'kghostview) :style radio :selected (equal gri*view-command 'kghostview) :active (and (fboundp 'executable-find)(executable-find "kghostview"))] ) ("gv settings" "Run-Time Options" ["-watch" (if gri*view-watch (setq gri*view-watch nil) (setq gri*view-watch t)) :style toggle :selected gri*view-watch] ["-noantialias" (if gri*view-noantialias (setq gri*view-noantialias nil) (setq gri*view-noantialias t)) :style toggle :selected gri*view-noantialias] "Scale Selection" ["0.1" ;;FIXME: simply this code! ;;Try (setq gri*view-scale -5) (list 'lambda () (interactive)(setq gri*view-scale -5)) :style radio :selected (equal gri*view-scale -5)] ["0.125" (list 'lambda () (interactive)(setq gri*view-scale -4)) :style radio :selected (equal gri*view-scale -4)] ["0.25" (list 'lambda () (interactive)(setq gri*view-scale -3)) :style radio :selected (equal gri*view-scale -3)] ["0.5" (list 'lambda () (interactive)(setq gri*view-scale -2)) :style radio :selected (equal gri*view-scale -2)] ["0.707" (list 'lambda () (interactive)(setq gri*view-scale -1)) :style radio :selected (equal gri*view-scale -1)] ["1" (list 'lambda () (interactive)(setq gri*view-scale 0)) :style radio :selected (equal gri*view-scale 0)] ["1.414" (list 'lambda () (interactive)(setq gri*view-scale 1)) :style radio :selected (equal gri*view-scale 1)] ["2" (list 'lambda () (interactive)(setq gri*view-scale 2)) :style radio :selected (equal gri*view-scale 2)] ["4" (list 'lambda () (interactive)(setq gri*view-scale 3)) :style radio :selected (equal gri*view-scale 3)] ["8" (list 'lambda () (interactive)(setq gri*view-scale 4)) :style radio :selected (equal gri*view-scale 4)] ["10" (list 'lambda () (interactive)(setq gri*view-scale 5)) :style radio :selected (equal gri*view-scale 5)]) ["Print existing PostScript" gri-print t] )) (easy-menu-define gri-mode-menu1 gri-mode-map "Menu keymap for gri-mode." '("Format" ["Complete gri command" gri-complete t] ["Select option under point" gri-option-select t] ["Kill option under point" gri-kill-option t] ["Add Comment to current line" gri-comment t] ["Insert file head as a comment" gri-insert-file-as-comment t] ["Indent current line" gri-indent-line t] ["Indent selected region" gri-indent-region t] ["Indent entire buffer" gri-indent-buffer t] ["Comment-out region" gri-comment-out-region t] ["Uncomment-out region" gri-uncomment-out-region t] ["Create function skeleton" gri-function-skeleton t] ["Fontify buffer" gri-fontify-buffer t] )))) (defun gri-run-setting-toggle (item) "If ITEM is selected, unselect it. Else select it." (interactive "P") (if (not (member item gri*run-settings)) (setq gri*run-settings (cons item gri*run-settings)) (let ((work-list gri*run-settings) (new-list)) (while work-list (let ((entry (car work-list))) (if (not (equal item entry)) (setq new-list (cons entry new-list)))) (setq work-list (cdr work-list))) (setq gri*run-settings new-list)))) (defun gri-run-setting-string () "Return a string of gri*run-settings elements" (if (not gri*run-settings) "" (let ((work-list gri*run-settings) (new-list)) (while work-list (let ((entry (car work-list))) (setq new-list (concat entry " " new-list))) (setq work-list (cdr work-list))) new-list))) ;;;---------------------------------------------------------------- ;;; Automatic generation of a menubar menu listing all Gri commands. ;;; (gri-easy-menu-build) to regenerate it. (defun gri-menubar-cmds-action (command) (interactive) (cond ((equal gri-menubar-cmds-action 'Info) (gri-info command)) ((equal gri-menubar-cmds-action 'Help) (gri-help command)) ((equal gri-menubar-cmds-action 'Insert) (let ((string)) (save-excursion (cond ;;; This is in here for possible future use, but I'm not ;;; adding code fragments to the command list for now. ((string-equal "?" (substring command 0 1)) (gri-lookat-syntax-file 0) (re-search-forward (concat "^" command "\\(;\\|(\\)") nil t) (forward-line 1) (setq string (buffer-substring (point) (progn (re-search-forward "^[^ \t]" nil t) (backward-char 1)(point))))) (t (gri-lookat-syntax-file 1) (re-search-forward (concat "^" command "\\(;\\|(\\)") nil t) ;; Skip over default description (forward-char -1) (if (looking-at "(") (re-search-forward ");" nil t) (forward-char 1)) (setq string (buffer-substring (point) (progn (end-of-line)(point))))))) (insert string))))) (defun gri-menubar-cmds-build () "Creates a buffer from ~/.gri-syntax to evaluate and define a menu map" (save-excursion (gri-lookat-syntax-file 3) ;; Get list of known commands (let ((syntax-entries (buffer-substring (point)(point-max))) (gri-tmp-buffer (get-buffer-create "*gri-tmp-buffer*"))) (set-buffer gri-tmp-buffer) (insert syntax-entries) (delete-backward-char 1) (goto-char (point-min)) ;; Strip out syntax defs (while (re-search-forward "\\(;\\|(\\)" nil t) (forward-char -1) (delete-region (point) (progn (end-of-line)(point)))) ;;Transform every command into a line like: ;; ["cd" (list (gri-menubar-cmds-action "cd")) t] (goto-char (point-min))(insert "\n")(goto-char (point-min)) (while (= 0 (forward-line 1)) (let ((command (buffer-substring (point)(progn (end-of-line)(point))))) (beginning-of-line) (insert "[\"") (end-of-line) (insert "\" (list (gri-menubar-cmds-action \"" command "\")) t]"))) ;; insert proper bracing to block out submenus (gri-easy-menu-keyword-split) ;; Split the generated easymenu entries dedending on frame height (gri-easy-menu-size-split) ;; insert easy-menu-define preamble (goto-char (point-min)) (insert "(easy-menu-define gri-commands-menu gri-mode-map \"Commands for Gri.\" '(\"Cmds\" [\"Display Info\" (list (setq gri-menubar-cmds-action 'Info)) :style radio :selected (equal gri-menubar-cmds-action 'Info)] [\"Display Help\" (list (setq gri-menubar-cmds-action 'Help)) :style radio :selected (equal gri-menubar-cmds-action 'Help)] [\"Insert commands\" (list (setq gri-menubar-cmds-action 'Insert)) :style radio :selected (equal gri-menubar-cmds-action 'Insert)] \"-\"") ;; insert closing braces (goto-char (point-max)) (insert "))") (eval-buffer nil nil) (kill-buffer gri-tmp-buffer)))) ;;; Functions to split the easymenu into smaller segments. ;;; As it turns out, this was _more_ work than the rest combined! (defvar gri-cmds-submenu-keywords '("convert" "create" "draw" "draw curve" "draw image" "draw label" "draw line" "draw symbol" "filter" "new" "read" "read image" "resize" "set" "set contour" "set font" "set image" "set line" "set x" "set y" "show" "write") "List of Gri command keywords used to fraction menu into submenus") (defun gri-easy-menu-keyword-split () "Insert proper bracing to block out submenus using gri-cmds-submenu-keywords" (let ((case-fold-search) (entry-list gri-cmds-submenu-keywords) (entry)) (while entry-list (goto-char (point-min)) (setq entry (car entry-list)) (search-forward (concat "[\"" entry) nil t) (beginning-of-line) (insert "(\"" entry "\"\n") (goto-char (point-max)) (search-backward (concat "[\"" entry) nil t) (end-of-line) (insert "\n)") (setq entry-list (cdr entry-list))))) (defun gri-easy-menu-size-split () "Split the generated easymenu entries dedending on frame height" (goto-char (point-min)) (re-search-forward "^\\[" nil t) (beginning-of-line) (let* ((menu-count (gri-easy-menu-count-entries)) (frame-lines (cond ((< 60 (frame-height)) ;Big frames (- (frame-height) 17)) ((< 40 (frame-height)) ;Med frames (- (frame-height) 10)) (t (- (frame-height) 6)))) ;Smaller frames (split-number) (split-count)) (if (>= frame-lines menu-count) nil ; No split at all ;; Figure out in many pieces we want the menu to be (setq split-number (/ menu-count frame-lines)) (if (not (= 0 (% menu-count frame-lines))) (setq split-number (1+ split-number))) ;; Figure out many entries in each (setq split-count (/ menu-count split-number)) (if (not (= 0 (% menu-count split-number))) (setq split-count (1+ split-count))) ;; (message "Menu lines: %d Frame lines: %d Split: %d Each: %d" ;; menu-count frame-lines split-number split-count) ;; Do the actual splitting (goto-char (point-min)) (re-search-forward "^\\[" nil t) (beginning-of-line) (while (gri-easy-menu-split-here split-count))))) (defun gri-easy-menu-split-here (size) "Do an actual split at this point in the menu" (let ((title (format "\"%s - %s ...\"" (gri-easy-menu-commandname-at 0) (gri-easy-menu-commandname-at size))) (status)) (beginning-of-line) (insert "(" title "\n") (setq status (gri-forward-sexp size)) (insert ")") (if (not status) nil (forward-line 1) t))) (defun gri-easy-menu-commandname-at (count) "Return name of Gri command COUNT-1 lines down" (save-excursion (beginning-of-line) (if (not (= 0 count)) (progn (gri-forward-sexp count) (forward-sexp -1))) (forward-char 2) (buffer-substring (point) (progn (search-forward "\"" nil t)(forward-char -1)(point))))) (defun gri-easy-menu-count-entries () "Return the number of easymenu sexps from point to end of buffer." (let ((count 1)) (while (gri-forward-sexp 1) (setq count (1+ count))) count)) (defun gri-forward-sexp (count) "Advance by ARG sexp, and returns nil if error occurs or at EOF, t otherwise. By error, I mean un improperly balanced sexp." (when (condition-case nil (goto-char (or (scan-sexps (point) count) (point-max))) (error)) (if (= (point)(point-max)) nil t))) ;;; End of easymenu commands generation. ;;;------------------------------------- ;;;------------- ;;; imenu stuff ;; (Comments from gre-mode) ;; Instead of setting the variable imenu-create-index-function to ;; imenu--create-gri-index, I could set the following REGEXP variable: ;; ;; (setq imenu-generic-expression ;; '((nil "^cmd \\([^(]+\\)" 1) ;; ("Variables" "^\\($[a-zA-Z_]+\\) [+-/*]?=" 1))) ;; ;; and make a simple `imenu-prev-index-position-function' to move backwards ;; to these regexps. (See gri-imenu-prev-index-position-function below). (if (fboundp 'imenu) ;Make sure it's auto-loaded (eval-when-compile (require 'imenu))) (if (and (= emacs-major-version 20) (<= emacs-minor-version 2)) (defun imenu-add-to-menubar (name) "Adds an `imenu' entry to the menu bar for the current buffer. NAME is a string used to name the menu bar item. See the command `imenu' for more information." (interactive "sImenu menu item name: ") (if (or (and (equal imenu-create-index-function 'imenu-default-create-index-function) imenu-generic-expression) (fboundp imenu-create-index-function)) (let ((newmap (make-sparse-keymap)) (menu-bar (lookup-key (current-local-map) [menu-bar]))) (define-key newmap [menu-bar] (append (make-sparse-keymap) menu-bar)) (define-key newmap [menu-bar index] (cons name (nconc (make-sparse-keymap "Imenu") (make-sparse-keymap)))) (use-local-map (append newmap (current-local-map))) (add-hook 'menu-bar-update-hook 'imenu-update-menubar)) (error "The mode `%s' does not support Imenu" mode-name)))) (defun gri-imenu-prev-index-position-function () (re-search-backward "\\(^`\\(.*\\)'$\\)\\|\\(^[ \t]*\\(\\\\[a-zA-Z0-9_]+\\)\\|\\(\\.\\.?[a-zA-Z0-9_]\\.\\.?\\) *=\\)" nil t)) (defvar gri-imenu-counter nil "gri-mode internal variable for imenu support") (defun imenu--create-gri-index () (save-match-data (save-excursion (let ((index-alist '()) (index-var-alist '()) (index-syn-alist '()) (prev-pos) (imenu-scanning-message "Scanning gri functions, variables and synonyms (%3d%%)")) (setq gri-imenu-counter -99) ;IDs menu entries starting at -100 (goto-char (point-max)) (imenu-progress-message prev-pos 0 t) (while (gri-imenu-prev-index-position-function) (imenu-progress-message prev-pos nil t) (let ((marker (make-marker))) (set-marker marker (point)) (cond ((match-beginning 2) ;function (push (cons (match-string-no-properties 2) marker) index-alist)) ((match-beginning 4) ;synonym (push (cons (match-string-no-properties 4) marker) index-syn-alist)) (t ;variable (push (cons (match-string-no-properties 5) marker) index-var-alist))))) (imenu-progress-message prev-pos 100 t) (cond ((and index-var-alist (elt index-var-alist 5)) (push (cons "Variables" ;;Or this: (sort index-var-alist 'gri-imenu-label-cmp)) index-var-alist) index-alist)) (index-var-alist (setq index-alist (append index-var-alist index-alist)))) (cond ((and index-syn-alist (elt index-syn-alist 5)) (push (cons "Synonyms" index-syn-alist) index-alist)) (index-syn-alist (setq index-alist (append index-syn-alist index-alist)))) index-alist)))) (defun gri-imenu-label-cmp (el1 el2) "Predicate to compare labels in lists." (string< (car el1) (car el2))) ;;; end of imenu stuff ;;;------------- ;;(defvar gri::toolbar-run-icon ;; (if (featurep 'toolbar) ;; (toolbar-make-button-list "/home/rhogee/gri.xpm" "Run Gri"))) ;; XEmacs toolbar (cond ((featurep 'toolbar) (defvar gri::toolbar-run-icon (toolbar-make-button-list "/* XPM */ static char *magick[] = { /* columns rows colors chars-per-pixel */ \"32 32 4 1\", \" c #f9fbff\", \". c #d6dae4\", \"X c #97999e\", \"o c #343434\", /* pixels */ \" \", \" \", \" \", \" Xooooooooooooooooooooooooo. \", \" XX......................XX \", \" XX......................XX \", \" XX......................XX \", \" XX......................XX \", \" XX......................XX \", \" XoX......................XX \", \" oX......................XX \", \" XX......................XX \", \" XX......................XX \", \" XX.....ooooX........o...XX \", \" .oX .X X . oo........oX..XX \", \" .oX..o......o........X...XX \", \" XX.o....................XX \", \" XX.o....................XX \", \" XXXo.........XXX..X.XX..XX \", \" XXXo.........XXo..oXoo..XX \", \" .oX.o.....X.....o.....o..XX \", \" .oXXo.....ooo...o....Xo..XX \", \" XX.oX.....Xo...o....Xo..XX \", \" XX.Xo.... Xo...o....Xo..XX \", \" XX..oooXXXXX..XXXX..XXX.XX \", \" XX....XXXXXX..XXXX..XX..XX \", \" .ooXXXXXXXXXXXXXXXXXXXXXXoX \", \" .ooXXXXoXXXXXoXXXXXooXXXXoX \", \" \", \" \", \" \", \" \" };") "Run Gri") (defvar gri-mode-toolbar (append initial-toolbar-spec '([gri::toolbar-run-icon gri-run t "Run Gri"])) "XEmacs toolbar for gri"))) ;; Emacs-21 tool-bar (cond ((featurep 'tool-bar) (defun gri-mode-toolbar-make-button (image) "From idlw-toolbar.el" (list 'image :type 'xpm :data image)) (defvar gri::toolbar-run-icon (gri-mode-toolbar-make-button "/* XPM */ static char * gri24x24_xpm[] = { /* columns rows colors chars-per-pixel */ \"24 24 5 1\", \" c None\", \". c black\", \"X c white\", \"o c grey90\", \"O c #010101\", /* pixels */ \" . . . . \", \" ...................... \", \"..XXXX..XXXXXXXXXXXXXX..\", \" .XXXX..XXXXXXXXXXXXXX. \", \" .XXX.oo.XXXXXXXXXXXXX. \", \" .XX.oooo.XXXXXXX..XXX. \", \" .X.oooooo.XXXXXX..XXX. \", \" ...oooooo.XXXX..oo.XX. \", \" ...ooooooo.XX.ooooo... \", \" .oooooooooo..oooooo... \", \" .oooooooooo..oooooooo. \", \" .oooooooooooooooooooo. \", \"..oooooooooooooooooooo..\", \" .ooooO...Oooooooooooo. \", \" .oooO.ooo.ooooooo.ooo. \", \" .oooOoooooooooooooooo. \", \" .ooOOooooooooO.ooOooo. \", \" .ooO.ooo.O.o.OoooOooo. \", \" .oooOoooo.oooOoooOooo. \", \" .oooO.oooOoooOoooOooo. \", \" .ooooO...OoooOoooOooo. \", \" .oooooooooooooooooooo. \", \"........................\", \" . . . . \" };") "The run gri icon.") (defvar gri::toolbar-view-icon (gri-mode-toolbar-make-button "/* XPM */ static char * gri_gv24x24_xpm[] = { /* columns rows colors chars-per-pixel */ \"24 24 4 1\", \" c None\", \". c black\", \"X c white\", \"o c grey90\", /* pixels */ \" . . . . \", \" ...................... \", \"..XXXX..XXXXXXXXXXXXXX..\", \" .XXXX..XXXXXXXXXXXXXX. \", \" .XXX.oo.XXXXXXXXXXXXX. \", \" .XX.oooo.XXXXXXX..XXX. \", \" .X.oooooo.XXXXXX..XXX. \", \" ...oooooo.XXXX..oo.XX. \", \" ...ooooooo.XX.ooooo... \", \" .oooooooooo..oooooo... \", \" .oooooooooo..oooooooo. \", \" .oooooooooooooooooooo. \", \"..oooooooooooooooooooo..\", \" .oooooooooooooooooooo. \", \" .oooooooooooooooooooo. \", \" .oooooooooooooooooooo. \", \" .oooooo..oo.ooo.ooooo. \", \" .ooooo.oo.o.ooo.ooooo. \", \" .ooooo.oo.oo.o.oooooo. \", \" .oooooo...oo...oooooo. \", \" .oooooooo.ooo.ooooooo. \", \" .ooooo.oo.ooooooooooo. \", \"........oo..............\", \" . .. . . \" };") "The gri view icon.") (defvar gri::toolbar-info-icon (gri-mode-toolbar-make-button "/* XPM */ static char * gri_info24x24_xpm[] = { /* columns rows colors chars-per-pixel */ \"24 24 5 1\", \" c None\", \". c black\", \"X c white\", \"o c grey90\", \"O c #010101\", /* pixels */ \" . . . . \", \" ...................... \", \"..XXXX..XXXXXXXXXXXXXX..\", \" .XXXX..XXXXXXXXXXXXXX. \", \" .XXX.oo.XXXXXXXXXXXXX. \", \" .XX.oooo.XXXXXXX..XXX. \", \" .X.oooooo.XXXXXX..XXX. \", \" ...oooooo.XXXX..oo.XX. \", \" ...ooooooo.XX.ooooo... \", \" .oooooooooo..oooooo... \", \" .oooooooooo..oooooooo. \", \" .oooooooooooooooooooo. \", \"..oooooooooooooooooooo..\", \" .ooo.oooooo...ooooooo. \", \" .ooo.oooooo.ooooooooo. \", \" .oooooooooo.ooooooooo. \", \" .ooo.o.oooo..oooooooo. \", \" .ooo.o.OO.o.oo....ooo. \", \" .ooo.o.oo.o.oo.oo.ooo. \", \" .ooo.o.oo.o.oo.oo.ooo. \", \" .ooo.o.oo.o.oo....ooo. \", \" .oooooooooooooooooooo. \", \"........................\", \" . . . . \" };") "The gri Info icon.") ;; (define-key global-map [tool-bar gri-run] ;; '(menu-item "Run Gri" gri-run ;; :image gri::toolbar-run-icon)))) (defvar gri::toolbar '([gri::toolbar-run-icon gri-run t "Run gri on this file"] [gri::toolbar-view-icon gri-view t "View PostScript file"] [gri::toolbar-info-icon gri-info-this-command t "Lookup Info about command under cursor"])) (mapcar (lambda (x) (let* ((icon (aref x 0)) (func (aref x 1)) ;;(show (aref x 2)) (help (aref x 3)) (key (vector 'tool-bar func)) (def (list 'menu-item "a" func :image (symbol-value icon) :help help))) (define-key gri-mode-map key def))) (reverse gri::toolbar)) )) ;; Gri Mode (defun gri-mode () "Major mode for editing and running Gri files. V2.68 (c) 01 March 2005 -- Peter Galbraith COMMANDS AND DEFAULT KEY BINDINGS: gri-mode Enter Gri major mode. Running Gri; viewing output: gri-run C-c C-r Run gri on this file, and view result. gri-view C-c C-v Run ghostview on the existing .ps file. gri-print C-c C-p Print gri .ps file. To insert and edit full syntax: gri-complete M-Tab Complete abbreviated gri command. gri-next-option C-c C-n Goto to next option, string or variable. gri-kill-option C-c C-k Deletes gri syntax within brackets. gri-option-select C-c C-o Selects gri optional syntax. gri-close-statement C-c ] Closes a gri statement (if, while, open) To obtain help or find commands: gri-help-apropos C-c C-a Display commands containing keyword. gri-display-syntax C-c C-d Display syntax for command on point. gri-help-this-command C-c C-h Help about user/system command on point. gri-help C-c M-h Help about prompted-for command. gri-info-this-command C-c C-i Info about system command on point. gri-info C-c M-i Info about prompted-for command. gri-WWW-manual C-c C-w World Wide Web gri manual. gri-set-version C-c M-v Displays version numbers of databases. describe-mode C-c ? Displays help about gri mode. Indenting/formatting gri code: gri-function-skeleton C-c C-f Add skeleton for a new function. gri-narrow-to-function C-c M-n Narrow editing region to function. (C-x n w Widens editing region back to normal) gri-comment M-; Add comment to current line. gri-insert-file-as-comment C-c C-x Insert filename under point as a comment. gri-indent-line Tab Indent line for structure. gri-indent-region M-q Indent all lines between point and mark. gri-indent-buffer M-C-v Indent all lines in buffer. gri-comment-out-region C-c# To avoid running a block of code. gri-uncomment-out-region C-uC-c# To undo comments. gri-return RET Handle return with indenting. To use multiple versions of Gri installed on the system gri-set-local-version Set version of gri for this file only. gri-unset-local-version Unset and use default value instead. gri-set-version Change version of gri used in gri-mode. To convert comment styles gri-convert-comments Convert Gri // and /* */ comments to # gri-convert-comments-with-prompt A function to put in a gri-mode-hook. To use outline-minor-mode to hide gri functions: gri-hide-function C-c M-h Hides the gri function under point. gri-hide-all C-c M-H Hides all gri functions in buffer. ESC 1 C-c M-h (ESC 1 prefixes a true argument) gri-show-function C-c M-s Shows the gri function on current line. gri-show-all C-c M-S Shows all gri functions in buffer. ESC 1 C-c M-s Misc debugging commands: gri-command-arguments Tell gri-run about extra arguments to use -- VARIABLES: gri*directory-tree New path to gri installation with versions. gri*view-after-run t or nil, view ps file after gri-run if t. gri*view-command String for shell command used by gri-view. gri*view-landscape-arg String for landscape argument in gri-view. gri*lpr-command Command used to print PostScript files. gri*lpr-switches print command switches to use gri*use-imenu Use imenu package? gri*WWW-program String for local WWW browser program. gri*WWW-page Page to use by browser fill-column Column used in auto-fill (default=70). gri-comment-column Goal column for on-line comments. gri-indent-before-return If true, indent current line on gri-indent-level Level to indent blocks. gri-new-command-help-indent-level Level to indent help in new commands. ACCESSING: To add automatic support put something like the following in your .emacs file: (autoload 'gri-mode \"gri-mode\" \"Enter Gri-mode.\" t) (setq auto-mode-alist (cons '(\"\\\\.gri$\" . gri-mode) auto-mode-alist)) If gri is installed in a non-standard place, then you'll need something like: (setq gri*directory-tree \"/home/opt/gri/\") ;Path to our gri installation See C-h v gri*directory-tree to find out more. And optionally, customize the mode in your .emacs file: (setq gri*lpr-switches \"-P laser\") ; Select a printer (setq gri*view-command \"ghostview -magstep -1\") ;for small screens (setq gri*view-after-run nil) ;Don't call gri-view after gri-run. (setq gri*WWW-program \"xmosaic\") ;Our local WWW browser program (setq gri-indent-before-return t) ;Indent current line on (setq gri-mode-hook ;Hook gets invoked after gri-mode '(lambda () (gri-hide-all t) ;Hide gri functions on C-x C-f file.gri (setq fill-column 74))) ;Set fill column for gri buffers SEE ALSO: help about gri-complete (C-h f gri-complete) KNOWN BUGS: gri-help-this-command Can't find help on hidden user commands. gri-complete *completions* buffer lies: you can't use the mouse to make a selection. Completions relies on entire line, not just up to the editing point. gri-show-all, gri-hide-all May get confused if you have a string which looks like a function title in your function's help text (i.e. a line which begins with a ` character and ends with a ' character. PLANNED ADDITIONS: Fix bugs! Make gri-complete able to complete to options. Add mouse support to make selection in *completions* buffer. Add mouse support to select and kill options." (interactive) (kill-all-local-variables) (use-local-map gri-mode-map) (setq major-mode 'gri-mode) (setq mode-name "gri") (set-syntax-table gri-mode-syntax-table) ;; Paragraph definitions (make-local-variable 'paragraph-start) (setq paragraph-start (concat "^$\\|" page-delimiter)) (make-local-variable 'paragraph-separate) (setq paragraph-separate paragraph-start) (make-local-variable 'paragraph-ignore-fill-prefix) (setq paragraph-ignore-fill-prefix t) ;; Indentation (make-local-variable 'indent-line-function) (setq indent-line-function 'gri-indent-line) ;; Comments (make-local-variable 'comment-start-skip) ;Need this for font-lock... (setq comment-start-skip "\\(^\\|\\s-\\);?#+ *") ;;From perl-mode ;(setq comment-start-skip "\\(#\\) *") (make-local-variable 'comment-start) (make-local-variable 'comment-end) (setq comment-start "#" comment-end "") (make-local-variable 'comment-column) (setq comment-column 'gri-comment-column) (make-local-variable 'fill-column) (setq fill-column default-fill-column) ;; (make-local-variable 'auto-fill-hook) ;; (setq auto-fill-hook ;; '(lambda () ;; (insert "\\\n"))) (cond (gri*use-imenu (require 'imenu) (setq imenu-create-index-function 'imenu--create-gri-index) ;;;Instead of setting `imenu-create-index-function', I could set (for gre): ;; (setq imenu-prev-index-position-function ;; 'gri-imenu-prev-index-position-function) ;; (setq imenu-generic-expression ;; '((nil "^cmd \\([^(]+\\)" 1) ;; ("Variables" "^\\($[a-zA-Z_]+\\) [+-/*]?=" 1))) (if (or window-system (fboundp 'tmm-menubar)) (imenu-add-to-menubar "Imenu")))) (gri-font-lock-setup) ;; Local version (make-local-variable 'gri-local-version) ;; Gri-mode's own completion mechanisms (make-local-variable 'gri-last-complete-point) (setq gri-last-complete-point -1) (make-local-variable 'gri-last-complete-command) (setq gri-last-complete-command "") (make-local-variable 'gri-last-complete-status) (setq gri-last-complete-status 0) (make-local-variable 'require-final-newline) (setq require-final-newline t) ;; Outlininng ;;(require 'outline) this is not provided in emacs 18.59 (if (not (fboundp 'hide-body)) (load "outline" t t)) (make-local-variable 'outline-regexp) (cond ((> emacs-major-version 19) (make-local-variable 'line-move-ignore-invisible) (setq line-move-ignore-invisible t) (if (fboundp 'add-to-invisibility-spec) (progn (add-to-invisibility-spec '(hs . t)) ;;hs invisible (add-to-invisibility-spec '(outline . t)))) (setq outline-regexp "^`.*'\n")) (t (setq selective-display t selective-display-ellipses t) (setq outline-regexp "^`.*'[\n\^M]"))) (gri-show-all) ; show all before adding commands ;; Adds this buffer's local commands to gri-syntax (if (get-buffer "*gri-syntax*") (save-excursion (goto-char (point-min)) (gri-add-commands-from-current-buffer nil (get-buffer "*gri-syntax*")))) (and (boundp 'gri-menubar) gri-menubar (fboundp 'add-submenu) ;Insurance for emacs (if (boundp 'current-menubar) (set-buffer-menubar (copy-sequence current-menubar))) (add-submenu nil gri-menubar)) (and (boundp 'gri-mode-menu1) gri-mode-menu1 (fboundp 'add-submenu) ;Insurance for emacs (if (boundp 'current-menubar) (set-buffer-menubar (copy-sequence current-menubar))) (if (and (boundp 'gri-commands-menu) gri-commands-menu) (add-submenu nil gri-commands-menu)) (add-submenu nil gri-mode-menu1) (add-submenu nil gri-mode-menu2) (add-submenu nil gri-mode-menu3) (add-submenu nil gri-mode-menu4)) (if (and (featurep 'toolbar) (console-on-window-system-p)) (set-specifier default-toolbar (cons (current-buffer) gri-mode-toolbar))) ;; FIXME: See other FIXME comments above about installing multiple menus. ;; Figure Out what version of gri to use, where to call it (hack-local-variables) (gri-initialize-version nil) ;Try to set gri version without errors (cond ((and gri-idle-display-defaults gri-cmd-file (file-exists-p gri-cmd-file) (not gri-idle-timer)) ;; Initiate timer (setq gri-idle-timer (run-with-idle-timer 2 t 'gri-idle-function))) ((and (not gri-idle-display-defaults) gri-idle-timer) ;; Cancel timer (cancel-timer gri-idle-timer) (setq gri-idle-timer nil))) (if (and (or (not (boundp 'gri-commands-menu)) (not gri-commands-menu)) ;; Maybe I should redo it all the time in case frame size was changed? (not (equal gri-cmd-file ""))) (gri-menubar-cmds-build)) (run-hooks 'gri-mode-hook)) (defun gri-determine-local-version () (save-excursion (goto-char (point-max)) (if (and (re-search-backward "\\(//\\|#\\) Local Variables:" nil t) (re-search-forward "\\(//\\|#\\) gri-local-version: \"\\(.*\\)\"" nil t)) (buffer-substring (match-beginning 1) (match-end 1))))) (defun gri-comment () "Add a comment to the following line, or format if one already exists." (interactive) (cond ((gri-empty-line) (gri-indent-line) (insert "# ")) ((gri-comment-line-only) (save-excursion (beginning-of-line) (delete-horizontal-space) (indent-to (gri-calc-indent)))) ((gri-comment-line-after-command) (save-excursion (beginning-of-line) (if (re-search-forward "//" (save-excursion (end-of-line)(point)) t) (backward-char 2)) (if (re-search-forward "#" (save-excursion (end-of-line)(point)) t) (backward-char 1)) (re-search-backward "[^ \t]" (save-excursion (beginning-of-line)(point)) t) (forward-char) (delete-horizontal-space) (if (< (current-column) gri-comment-column) (indent-to gri-comment-column) (insert " ")))) (t (end-of-line) (re-search-backward "[^ \t^]" 0 t) (forward-char) (delete-horizontal-space) (if (< (current-column) gri-comment-column) (indent-to gri-comment-column) (insert " ")) (insert "# ")))) (defun gri-indent-line () "Indent a line and its comments in Gri-mode. gri `system' commands do not get their comments indented, since the // string is legal within a system command. e.g. system sed -e \"s/'N//g;s/'W//g;\" gpsfile > gps.tmp to remove 'N and 'W strings from a lat-lon file. `system any-command <<\"EOF\"' lines are treated specially. If the editing point is on the first column, then gri-indent-line will indent the line and skip over the text before the ending EOF. This means that gri-indent-buffer and gri-indent-region will skip over system scripts." (interactive) (save-excursion (beginning-of-line) (delete-horizontal-space) (indent-to (gri-calc-indent)) (if (and (not (gri-system-line)) (gri-comment-line-after-command)) (gri-comment))) (if (looking-at "^[ \t]*system[^$]*<<\"EOF\"") (re-search-forward "^[ \t]*EOF" nil t)) (skip-chars-forward " \t")) (defun gri-system-line () "Returns t if current line is, or is continued from, a system command" (save-excursion (beginning-of-line) (while (save-excursion (and (= 0 (forward-line -1)) (gri-continuation-line))) (forward-line -1)) (looking-at "[ \t]*\\(\\\\[^ ]+[ ]+=[ ]+\\)?system"))) (defun gri-line-type () "Display type of current line. Used in debugging." (interactive) (cond ((gri-empty-line) (message "gri-line-type: empty-line")) ((gri-new-command-name-line) (message "gri-line-type: new-command-name-line")) ((gri-new-command-syntax-start-line) (message "gri-line-type: new-command-syntax-start-line")) ((gri-new-command-syntax-end-line) (message "gri-line-type: new-command-syntax-end-line")) ((gri-comment-line) (message "gri-line-type: comment-line")) ((gri-continuation-line) (message "gri-line-type: continuation-line")) ((gri-block-beg-end-line) (message "gri-line-type: block-beg-end-line")) ((gri-block-beg-line) (message "gri-line-type: block-beg-line")) ((gri-block-end-line) (message "gri-line-type: block-end-line")) (t (message "gri-line-type: other")))) (defvar gri-last-indent-type "unknown" "String to tell line type.") (defun gri-indent-type () "Display type of current or previous nonempty line. Used in debugging." (interactive) (message (concat "gri-ident-type: " gri-last-indent-type))) (defun gri-fill-region (from to) "Fill the region of comments." (interactive "r") (message "gri-fill-region not implemented yet.")) (defun gri-calc-indent () "Return the appropriate indentation for this line as an int." (let ((indent 0)(here-point (point))) (save-excursion (while (and (= 0 (forward-line -1)) (gri-empty-line))) (cond ((= here-point (point))) ;; we din't move, so beginning of file. ((gri-continuation-line) ;; has \ at the end of line ;; PSG -- if first continued line then increase indentation, ;; if continued from yet another continued line, then don't. (setq gri-last-indent-type "continuation") (save-excursion (if (or (= -1 (forward-line -1)) (not (gri-continuation-line))) (setq indent (+ indent (* 1 gri-indent-level)))))) (t ;; PSG -- not a continuation line, but could be the end of a ;; continuation, so move up until it's previous line is not a ;; continuation line (start of command) to base indentation. (while (and (save-excursion (and (= 0 (forward-line -1)) (gri-continuation-line))) (= 0 (forward-line -1)))) (cond ((gri-new-command-name-line) (setq gri-last-indent-type "new-command-name") (setq indent gri-new-command-help-indent-level)) ((gri-new-command-syntax-start-line) (setq gri-last-indent-type "new-command-syntax-start") (setq indent gri-indent-level)) ((gri-new-command-syntax-end-line) (setq gri-last-indent-type "new-command-syntax-end") (setq indent (- indent gri-indent-level))) ((gri-comment-line) (setq gri-last-indent-type "comment")) ((gri-block-beg-end-line) (setq gri-last-indent-type "block begin-end")) ((gri-block-beg-line) (setq gri-last-indent-type "block begin") (setq indent gri-indent-level)) (t (setq gri-last-indent-type "other"))))) (setq indent (+ indent (current-indentation)))) (if (and (gri-block-end-line) (not (gri-system-line))) (setq indent (- indent gri-indent-level))) (if (gri-new-command-syntax-start-line) (setq indent 0)) (if (gri-new-command-syntax-end-line) (setq indent 0)) (if (< indent 0) (setq indent 0)) indent)) (defun gri-empty-line () "Returns t if current line is empty." (save-excursion (beginning-of-line) (looking-at "^[ \t]*$"))) (defun gri-new-command-name-line () "Returns t if current line is a Gri new-command-name line; that is, if it begins with ` and ends with '." (and (save-excursion (beginning-of-line) (skip-chars-forward " \t") (looking-at "`")) (save-excursion (end-of-line) (backward-char) (looking-at "'")))) (defun gri-new-command-syntax-start-line () "Returns t if current line is a left brace, indicating the start of syntax for a new Gri command." (save-excursion (beginning-of-line) (skip-chars-forward " \t") (looking-at "{ *\n"))) (defun gri-new-command-syntax-end-line () "Returns t if current line is a right brace, indicating the end of syntax for a new Gri command." (save-excursion (beginning-of-line) (skip-chars-forward " \t") (looking-at "} *\n"))) (defun gri-comment-line () "Returns t if current line is a Gri comment line." (save-excursion (beginning-of-line) (skip-chars-forward " \t") (looking-at "\\(//\\|#\\)"))) (defun gri-comment-line-only () "Returns t if current line is only a Gri comment line" (save-excursion (beginning-of-line) (looking-at "[ \t]*\\(//\\|#\\)"))) (defun gri-comment-line-after-command () "Returns t if current line contains a Gri comment after a command line" (save-excursion (beginning-of-line) (looking-at ".+\\(//\\|#\\).*$"))) (defun gri-continuation-line () "Returns t if current line ends in \\." (save-excursion (beginning-of-line) (re-search-forward "\\\\$" (gri-eoln-point) t))) (defun gri-eoln-point () "Returns point for end-of-line in Gri-mode." (save-excursion (end-of-line) (point))) (defconst gri-block-beg-kw "\\(if\\|else\\|else if\\|while\\)" "Regular expression for keywords which begin blocks in Gri-mode.") (defconst gri-block-end-kw "\\(\\end if\\|else\\|end while\\)" "Regular expression for keywords which end blocks.") (defun gri-block-beg-line () "Returns t if line contains beginning of Gri block." (save-excursion (beginning-of-line) (skip-chars-forward " \t") (looking-at gri-block-beg-kw))) (defun gri-block-end-line () "Returns t if line contains end of Gri block." (save-excursion (beginning-of-line) (skip-chars-forward " \t") (looking-at gri-block-end-kw))) (defun gri-block-beg-end-line () "Returns t if line contains matching block begin-end in Gri-mode." (save-excursion (beginning-of-line) (looking-at (concat "\\([^[//]\n]*[ \t]\\)?" gri-block-beg-kw "." "\\([^[//]\n]*[ \t]\\)?" gri-block-end-kw)))) (defun gri-comment-on-line () "Returns t if current line contains a comment." (save-excursion (beginning-of-line) (looking-at "[^\n]*\\(//\\|#\\)"))) (defun gri-in-comment () "Returns t if point is in a comment." (save-excursion (and (/= (point) (point-max)) (forward-char)) (re-search-backward "\\(//\\|#\\)" (save-excursion (beginning-of-line) (point)) t))) (defun filename-sans-gri-suffix (name) "Return FILENAME sans .gri suffix. If FILENAME does not end in `.gri', return FILENAME." (substring name 0 (or (string-match ".gri\$" name) (length name)))) ;; Setup auto-mode-alist (if (not (assoc '"\\.gri$" auto-mode-alist)) (setq auto-mode-alist (cons '("\\.gri\\'" . gri-mode) auto-mode-alist))) (if (not (assoc '"\\.grirc$" auto-mode-alist)) (setq auto-mode-alist (cons '("\\.grirc\\'" . gri-mode) auto-mode-alist))) (provide 'gri-mode) ;;; gri-mode.el ends here ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/G_string.cc���������������������������������������������������������������������������������0000644�0001750�0001750�00000014352�13147557614�012677� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #if 0 // Maybe keep for later! #include #include //##include #include "types.hh" #include "G_string.hh" // Read line from file. If there is a newline character at the // end of the line in the file, keep it. Otherwise, tack one on. // // RETURN true if got to EOF bool G_string::line_from_FILE(FILE *fp) { printf("line_from_FILE %s:%d\n",__FILE__,__LINE__); assign(""); if (feof(fp)) { printf("line_from_FILE %s:%d. HEY, eof at start!\n",__FILE__,__LINE__); return true; } char c[2]; c[1] = '\0'; do { c[0] = getc(fp); append(c); if (c[0] == '\n') break; } while (!feof(fp)); printf("line_from_FILE %s:%d. done loop. Got '%s'\n",__FILE__,__LINE__,c_str()); if (feof(fp)) { printf("line_from_FILE %s:%d. had eof so tacking newline\n",__FILE__,__LINE__); append("\n"); // tack newline on } return false; } //OLD** #if 0 //OLD** // Read word from file, enlarging if neccessary. Leave newline if //OLD** // found, but if hit eof do not insert extra newline. //OLD** // CHANGE 28AUG95: DO //OLD** // NOT KEEP NEWLINE; PUT IT BACK INTO FILE SO 'READ WORD' CAN FLUSH COMMENTS //OLD** // AND EXTRA JUNK AT EOL ... PROVISIONAL CHANGE. //OLD** // RETURN true if hit EOF //OLD** //OLD** bool G_string::word_from_FILE(FILE *fp) //OLD** { //OLD** if (feof(fp)) { //OLD** value[0] = '\0'; //OLD** return true; //OLD** } //OLD** unsigned int i = 0; //OLD** // Flush any existing whitespace //OLD** value[i] = getc(fp); //OLD** if (feof(fp)) { //OLD** value[0] = '\0'; //OLD** return true; //OLD** } //OLD** while (isspace(value[i])) { //OLD** value[i] = getc(fp); //OLD** if (feof(fp)) { //OLD** value[i] = '\0'; //OLD** return true; //OLD** } //OLD** } //OLD** i++; //OLD** do { //OLD** value[i] = getc(fp); //OLD** if (i >= capacity - 1) { // Get more space if required //OLD** capacity += capacity; //OLD** char *more_space = new char[capacity]; //OLD** if (!more_space) OUT_OF_MEMORY; //OLD** for (unsigned int j = 0; j <= i; j++) //OLD** more_space[j] = value[j]; //OLD** delete [] value; //OLD** value = more_space; //OLD** } //OLD** if (value[i] == '\n') { //OLD** ungetc(value[i], fp); //OLD** break; //OLD** } //OLD** if (isspace(value[i])) //OLD** break; //OLD** i++; //OLD** } while (!feof(fp)); //OLD** if (feof(fp)) //OLD** i--; //OLD** value[i] = '\0'; //OLD** return false; //OLD** } //OLD** #endif #if 0 void G_string::sed(const char *cmd) // Assume, *WITHOUT CHECKING*, that cmd is of one of the forms // s/A/B/ where 'A' and 'B' are strings // s:A:B: or any other 'stop-char', as in sed unix command // Also, require B to be a shorter string than A. (easily fixed) { switch (cmd[0]) { case 's': { int len_cmd = strlen(cmd); int len_value = strlen(value); char *copy = new char[1 + strlen(value)]; char stop = cmd[1]; char *A = new char [1 + len_cmd]; char *B = new char [1 + len_cmd]; int lenA = 0; int iA; for (iA = 2; iA < len_cmd; iA++) { if (cmd[iA] == stop) break; A[lenA++] = cmd[iA]; } A[lenA] = '\0'; int lenB = 0; int iB; for (iB = iA + 1; iB < len_cmd; iB++) { if (cmd[iB] == stop) break; B[lenB++] = cmd[iB]; } B[lenB] = '\0'; Require2(lenB <= lenA, gr_Error("sed requires lenB <= lenA\n")); int iCOPY = 0; for (int iVALUE = 0; iVALUE < len_value; iVALUE++) { for (iA = 0; iA < lenA; iA++) { if (iVALUE + iA > len_value - 1) { break; } if (value[iVALUE + iA] != A[iA]) { break; } } if (iA == lenA) { for (iB = 0; iB < lenB; iB++) { copy[iCOPY++] = B[iB++]; } iVALUE += lenA - 1; } else { copy[iCOPY++] = value[iVALUE]; } } copy[iCOPY] = '\0'; delete [] A; delete [] B; strcpy(value, copy); delete [] copy; break; } default: gr_Error("G_string's sed() command can only do 's' commands"); } } #endif #if 0 void G_string::draw(double xcm, double ycm, gr_textStyle s, double angle) const { gr_show_at(value, xcm, ycm, s, angle); // Figure bounding box double width, ascent, descent; gr_stringwidth(value, &width, &ascent, &descent); #if 0 printf("\n`%s' xcm=%.1f ycm=%.1f width=%.1f ascent=%.1f descent=%.1f angle=%.1f\n", value, xcm,ycm,width,ascent, descent, angle); #endif double tmpx[4], tmpy[4]; // 0123 from lower-left anticlockwise switch (s) { case TEXT_LJUST: gr_rotate_xy( 0.0, -descent, angle, tmpx + 0, tmpy + 0); gr_rotate_xy( width, -descent, angle, tmpx + 1, tmpy + 1); gr_rotate_xy( width, ascent, angle, tmpx + 2, tmpy + 2); gr_rotate_xy( 0.0, ascent, angle, tmpx + 3, tmpy + 3); break; case TEXT_RJUST: gr_rotate_xy( -width, -descent, angle, tmpx + 0, tmpy + 0); gr_rotate_xy( 0.0, -descent, angle, tmpx + 1, tmpy + 1); gr_rotate_xy( 0.0, ascent, angle, tmpx + 2, tmpy + 2); gr_rotate_xy( -width, ascent, angle, tmpx + 3, tmpy + 3); break; case TEXT_CENTERED: gr_rotate_xy(-width/2, -descent, angle, tmpx + 0, tmpy + 0); gr_rotate_xy( width/2, -descent, angle, tmpx + 1, tmpy + 1); gr_rotate_xy( width/2, ascent, angle, tmpx + 2, tmpy + 2); gr_rotate_xy(-width/2, ascent, angle, tmpx + 3, tmpy + 3); break; } tmpx[0] += xcm, tmpy[0] += ycm; tmpx[1] += xcm, tmpy[1] += ycm; tmpx[2] += xcm, tmpy[2] += ycm; tmpx[3] += xcm, tmpy[3] += ycm; rectangle box(vector_min(tmpx, 4), vector_min(tmpy, 4), vector_max(tmpx, 4), vector_max(tmpy, 4)); bounding_box_update(box); } #endif #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/template.cc���������������������������������������������������������������������������������0000644�0001750�0001750�00000006363�13147557614�012741� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // Instantiate templates. // NB. This code may need changing as compilers evolve :-( #define _PUT_STATIC_DATA_MEMBERS_HERE #include #include // part of STL #include // part of STL #include #include "gr.hh" #include "defaults.hh" #include "private.hh" #include "types.hh" #include "gr_coll.hh" #include "GriColor.hh" #include "GMatrix.hh" #include "GriState.hh" #include "Synonym.hh" #include "Variable.hh" #if defined(USING_CXX_REPO) template void sort(vector::iterator, vector::iterator); #else // DEC c++ compiler #if defined(__DECCXX) //#pragma define_template void reverse(vector::iterator, vector::iterator); //#pragma define_template void sort(vector::iterator, vector::iterator); #pragma define_template vector #pragma define_template vector #pragma define_template vector #pragma define_template vector #pragma define_template vector #pragma define_template vector #pragma define_template vector #pragma define_template vector #pragma define_template vector #pragma define_template vector #pragma define_template vector #pragma define_template vector #pragma define_template vector #pragma define_template GriMatrix #pragma define_template GriMatrix #endif // DEC compiler // GNU c++ compiler #if defined(__GNUC__) #if __GNUC__ >= 3 // avoid deficiency in old compilers //void std::reverse(std::vector::iterator, std::vector::iterator); //void std::sort(std::vector::iterator, std::vector::iterator); #else template void std::reverse(std::vector::iterator, std::vector::iterator); template void std::sort(std::vector::iterator, std::vector::iterator); #endif template class std::vector; template class std::vector; template class std::vector; template class std::vector; template class std::vector; template class std::vector; template class std::vector; template class std::vector; template class std::vector; template class std::vector; template class std::vector; template class std::vector; template class std::vector; template class std::vector; template class GriMatrix; template class GriMatrix; #endif #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/endup.cc������������������������������������������������������������������������������������0000644�0001750�0001750�00000002123�13147557614�012227� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include "gr.hh" #include "extern.hh" #include "private.hh" #include "superus.hh" void end_up() { #if 0 // inaccurate anyhow! if (_chatty > 0) { display_unused_var(); display_unused_syn(); } #endif gr_set_clip_ps_off(); close_data_files(); gr_end("!"); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/src/macro.hh������������������������������������������������������������������������������������0000644�0001750�0001750�00000011626�13147557614�012237� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Gri - A language for scientific graphics programming Copyright (C) 2008 Daniel Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // Macros to save time #if !defined(_macro_hh_) #define _macro_hh_ #define BETWEEN(l,r,m) ( (l)<(r) ? (m)<=(r)&&(l)<=(m) : (r)<=(m)&&(m)<=(l) ) #define strEQ(s1, s2) (!strcmp((s1), (s2))) #define strNE(s1, s2) ( strcmp((s1), (s2))) #define SMALLER_ONE(a, b) ((a) < (b) ? (a) : (b)) #define LARGER_ONE(a, b) ((a) > (b) ? (a) : (b)) #define GRI_ABS(x) ((x) < 0.0 ? (-(x)) : (x)) // If 'condition' is false, perform action (typically warning). #define SUGGEST(condition, action_if_not) { \ if (!(condition)) { \ action_if_not; \ } \ } // If 'condition' is untrue, perform action (typically err) and return false #define Require(condition, action_if_not) { \ if (!(condition)) { \ action_if_not; \ return false; \ } \ } // If 'condition' is untrue, perform action (typically error) and return void #define Require2(condition, action_if_not) { \ if (!(condition)) { \ action_if_not; \ return; \ } \ } #define ShowStr(x) { \ gr_textput ((x)); \ } // Variable assignment macros, which replaces existing values. #define PUT_VAR(name, value) { \ if (!put_var(name , double(value), true)) \ fatal_err ("Can't store value of \\", name, "\\"); \ } // Establish return code #define RETURN_VALUE(s) { \ if (!put_syn("\\.return_value.", (s), true)) OUT_OF_MEMORY; \ } // Copy string 'c' into string 'n', first deleting old storage for 'n' #define COPY_STRING(n, c) { \ if(strlen((n)) < strlen((c))) { \ delete [] (n); \ (n) = new char[1 + strlen(c)]; \ if (!(n)) OUT_OF_MEMORY; \ } \ strcpy((n), (c)); \ } // Pretty-print debug info #if defined (__GNUC__) #define DEBUG_MESSAGE(s) { \ printf("%*s%s", _function_indent, " ", (s)); \ } #define DEBUG_FUNCTION_ENTRY { \ printf("%*s<%s> # %s:%d\n",_function_indent, " ", __FUNCTION__,__FILE__,__LINE__); \ _function_indent += 4; \ } #define DEBUG_FUNCTION_EXIT { \ if (_function_indent > 3) { \ _function_indent -= 4; \ } \ printf("%*s # %s:%d\n", _function_indent, " ", __FUNCTION__,__FILE__,__LINE__); \ } #else #define DEBUG_MESSAGE(s) { \ printf("%*s%s", _function_indent, " ", (s)); \ } #define DEBUG_FUNCTION_ENTRY { \ printf("%*s<%s> # %s:%d\n",_function_indent, " ", "unknown-function-name", __FILE__,__LINE__); \ _function_indent += 4; \ } #define DEBUG_FUNCTION_EXIT { \ if (_function_indent > 3) { \ _function_indent -= 4; \ } \ printf("%*s # %s:%d\n", _function_indent, " ", "unknown-function-name", __FILE__, __LINE__); \ } #endif // Optional printing. BUG: only works for GCC #if defined(__GNUC__) #if __GNUC__ >= 3 #define gri_debug_printf(debug_level, format, ...) {\ if (_debugFlag>=(debug_level)) {\ printf("DEBUG [%s:%d] ",__FILE__,__LINE__);\ printf((format),## __VA_ARGS__);\ }\ } #else // Older Gcc versions had a different syntax #define gri_debug_printf(debug_level, format, args...) {\ if (_debugFlag>=(debug_level)) {\ printf("DEBUG [%s:%d] ",__FILE__,__LINE__);\ printf((format),## args);\ }\ } #endif #endif #endif ����������������������������������������������������������������������������������������������������������gri/grilogo.gif�������������������������������������������������������������������������������������0000644�0001750�0001750�00000000531�13147557614�012150� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89aO�&�ð�����ÿÿÿ!þ0 Image generated by Ghostscript (device=ppmraw) �,����O�&��þŒyÀí£dªNPíÌ\]ÚQ(…æ9’—ž® Áö¸ß›Ô*–ë¸û-V"(“HÚÑ—T‚¢PÏ´•fջ̰ܿ•‡©f¯”,Vn»OLZ=-çt<ü׿Ö7·‡èuçÇVH“Hø‡²¶ã˜%isxF¹h99XÉÈÒé‰ ™QŠZòr#'úª©Š4êf V¹”‹{ÊJñû•kûÚë{yŸ–*j|ì:F턬8Û˜<û–½þl|Fݽ3&¢L^WwþÜ.dméì®ÇÞÉ ¿h<º¯œ­G¾j¼7Ð$^ù ²3T(`¨R9-{‡¬^Ey ��;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/NEWS��������������������������������������������������������������������������������������������0000644�0001750�0001750�00000000115�13147557614�010514� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������For information about changes to Gri, please see the manual in doc/gri.texi. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/UpdateVersion�����������������������������������������������������������������������������������0000755�0001750�0001750�00000004214�13147557614�012537� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/perl # Script run to update version number in all relevant files require "getopts.pl"; &Getopts('hv:'); sub get_current_version_number() { $version = `awk '(/VERSION =/) {print \$3}' Makefile.in`; chop($version); } sub usage () { get_current_version_number(); print "UpdateVersion: Script run to update version number in all relevant files USAGE: For example, to update all files to Version 2.6.0: ./UpdateVersion -v 2.6.0 Then erase all .bak after looking at diffs. Eventually, I'll trust it and will remove the .bak file creation. Options: -v VERSION -h : display this message. ToDo: Handle release date in version.cc Put prior version in comments in version.cc. NOTE: present version number is $version\n"; } die "This script is disabled, pending updates. (For example, some files are moved, and others are not manually updated anymore.)"; exit usage() if ($opt_h || ! $opt_v || ($opt_v == "")); die "CVSROOT not defined" if (! defined($ENV{'CVSROOT'})); die "CVSROOT not pointing to cvs.gri.sourceforge.net" if (! $ENV{'CVSROOT'} =~ /cvs.gri.sourceforge.net/); $CVSmsg = " is read-only. Are you sure the file is checked out for edit? Do: # cvs edit Makefile.in gri.spec gri.cmd version.cc doc/gri.texim "; die "Makefile.in $CVSmsg" if (! -w "Makefile.in"); die "gri.cmd $CVSmsg" if (! -w "gri.cmd"); die "version.cc $CVSmsg" if (! -w "version.cc"); die "doc/gri.texim $CVSmsg" if (! -w "doc/gri.texim"); # Get current version number get_current_version_number(); die "Version is up-to-date" if ($opt_v eq $version); $regexp = $version; $regexp =~ s/\./\\./g; `perl -pi.bak -e 's/(version $regexp)$/(version $opt_v)/' gri.cmd` `perl -pi.bak -e 's/VERSION = $regexp/VERSION = $opt_v/' Makefile.in` `perl -pi.bak -e 's/%define griversion $regexp/%define griversion $opt_v/g' gri.spec` `perl -pi.bak -e 's/\@set GRI-VERSION $regexp/\@set GRI-VERSION $opt_v/`; `perl -pi.bak -e 's/_gri_number\\[\\] = "$regexp"/_gri_number[] = "$opt_v"/' version.cc`; print "CAUTION: Dan modified this script 2002-nov-23 because it was too aggressive (doing global changes in the files), but it has NOT been tested yet !!\n"; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/aclocal.m4��������������������������������������������������������������������������������������0000644�0001750�0001750�00000122235�13147560113�011651� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# generated automatically by aclocal 1.15 -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.15], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.15])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/THANKS������������������������������������������������������������������������������������������0000644�0001750�0001750�00000001440�13147557614�010732� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Developing Gri was made easier by suggestions and bug reports from many users, among whom are: Ivo Alxneit, Karin Bryan, Sara Bennett, Luke Blaikie, Dave Brickman, Clyde Clements, Pierre Flament, Peter Galbraith, Dave Hebert, Alejandro López-Valencia, Kawamura Masao, Steve Matheson, Ed Nather, Carl Osterwisch, Richard Andrew Miles Outerbridge, Brian May, Jinyu Sheng, Toru Suzuki, Keith Thompson, David Trueman, and George White. The Gri manual provides a fuller list, and the fact that it grows monthly is a testament to the power of the open-source movement. Throughout Gri development, Peter Galbraith has been a steady collaborator, supporter, and advisor. Gri would not exist without him. All of these, and many users with whom I've interacted over the years, I thank warmly. -- Dan Kelley ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/gri.spec����������������������������������������������������������������������������������������0000644�0001750�0001750�00000046730�13147557614�011467� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Summary: A language for scientific illustration %define griversion 2.12.26 Name: gri Version: %{griversion} Release: 1 Copyright: distributable Group: Applications/Engineering License: GPLv3+ Source: http://ftp1.sourceforge.net/gri/gri-%{griversion}.tgz URL: http://gri.sourceforge.net Packager: Dan E. Kelley #Icon: grilogo.gif BuildRoot: /var/tmp/%{name}-root %description Gri is a language for scientific graphics programming. It is a command-driven application, as opposed to a click/point application. It is analogous to latex, and shares the property that extensive power is the reward for tolerating a modest learning curve. Gri output is in industry-standard PostScript, suitable for incorporation in documents prepared by various text processors. Gri can make x-y graphs, contour-graphs, and image graphs. In addition to high-level capabilities, it has enough low-level capabilities to allow users to achieve a high degree of customization. Precise control is extended to all aspects of drawing, including line-widths, colors, and fonts. Text includes a subset of the tex language, so that it is easy to incorporate Greek letters and mathematical symbols in labels. The following is a terse yet working Gri program. If it is stored in a file called 'example.gri', and executed with the unix command 'gri example', it will create a postscript file called 'example.ps' with a linegraph connecting data points in the file called `file.dat'. open file.dat # open a file with columnar data read columns x * y # read first column as x and third as y draw curve # draw line through data (autoscaled axes) %prep %setup -q %build %configure --enable-linux_redhat make DESTDIR=$RPM_BUILD_ROOT libdir=$RPM_BUILD_ROOT/usr/share/gri strip src/gri %install # remove docinst if it is there from a previous build rm -rf docinst (cd doc ; make CARD_DIR=.. install-refcards) (cd doc ; make DESTDIR=$RPM_BUILD_ROOT HTML_DIR=../docinst/html EXAMPLES_DIR=../docinst/examples html-install) (cd docinst/html; ln -sf index.html gri1.html) cp -f README-linux-redhat README || : (cd src ; make install DESTDIR=$RPM_BUILD_ROOT) (cd doc ; make install-data-local DESTDIR=$RPM_BUILD_ROOT) %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) %doc README copyright.txt refcard.ps cmdrefcard.ps %doc docinst/html /usr/bin/gri /usr/bin/gri_unpage /usr/bin/gri_merge /usr/share/gri /usr/share/man/man1/gri.* /usr/share/man/man1/gri_unpage.* /usr/share/man/man1/gri_merge.* /usr/share/info/gri.info* /usr/share/emacs/site-lisp/gri-mode.el %post # add a gri entry to /usr/share/info/dir if [ "$1" = 1 ] then if ! grep -i gri /usr/share/info/dir > /dev/null then /sbin/install-info --dir-file="/usr/share/info/dir" /usr/share/info/gri.info.gz # chmod a+r /usr/share/info/dir fi fi %postun # remove instances of gri in /usr/share/info/dir if [ "$1" = 0 ]; then if grep -i "gri" /usr/share/info/dir > /dev/null then /sbin/install-info --dir-file="/usr/share/info/dir" --remove /usr/share/info/gri.info.gz # grep -vi "gri" /usr/share/info/dir > /usr/info/share/dir.tmp # mv /usr/share/info/dir.tmp /usr/share/info/dir # chmod a+r /usr/share/info/dir fi fi %changelog * (date) release 2.12.26 - Fix various Debian bugs * 2008-jul-17 release 2.12.19 - Fix SourceForge bug 2977816 (Fedora licensing issue) - Fix SourceForge bug 3266884 (error in docs for strlen). * 2008-sep-08 release 2.12.18 - Improve security of temporary-file handling. - Fix SourceForge bug 1985862 (SVG output had axis linewidth equal to curve line width). * 2008-may-29 release 2.12.17 - Add history and editing of commands in interactive mode - Fix SourceForge bug 1913577 (superscripts did not end correctly, if preceded by a {} block) - Fix SourceForge bug #1761562 (y axis name is upside down, for log axis with decreasing values) * Fri Jul 20 18:25:47 ADT 2007 - release 2.12.16 - Fix Debian bug #130802 (postscript problem in landscape mode, refreshed in gv viewer) - Fix Debian bug #434010 ('set page landscape' requires 'set page size' first, but it should really default to something reasonable instead) * Sun Apr 15 11:00:00 AST 2007 - Fix SourceForge bug #1700978 (html concept index mostly broken) - Fix SourceForge bug 1698924 (box plots show missing data) - Fix Debian bug 417217 (will not compile in GCC 4.3) - Fix SourceForge bug 1698116 (poorly-positioned name of RHS y-axis) * Mon Jan 8 15:17:49 AST 2007 - Fix SourceForge bug 1630768 (segfault with clipped images) * Mon Nov 6 14:23:03 ADT 2006 -Fix SourceForge bug 1591475 (to compile in Solaris CC) -Fix SourceForge bug 1591062 (to compile in OpenBSD) -Add Century font * Sat Jul 15 10:31:00 AST 2006 -Fix SourceForge bug #1523033 (malloc warning) -Fix SourceForge bug #1523032 ('create columns from function' fails if existing local 'tmp' directory) -Fix SourceForge bug #1491105 ('set x axis labels' had no effect for log axes; same for y axis) * Sat Mar 25 23:14:04 AST 2006 -Fix SourceForge bug #1449546 (x/y axis limits not correctly inferred from 'set x/ grid'). -Fix SourceForge bug #1285180 (NaN was mishandled in recent versions). -Port to FreeBSD. (Thanks to Christopher Illies and Roman Neuhauser for helping.) * Mon Jan 16 2006 Add -private and -no_private commandline options * Tue May 11 2005 Fix SourceForge bug 1196613 (user-supplied x-axis labels can run offscale) Fix SourceForge bug 1198341 (x-axis labels sometimes rotated) * Tue May 10 2005 Fix SourceForge bug 1199280 (malloc warning for RPN assignment) * Mon May 5 2005 Fix SourceForge bug 1196115 (gri_merge and gri_unpage mis-installed) * Mon Mar 2 2005 Fix SourceForge bug 1153209 (Emacs mode incompatible with new version of 'gv' * Wed Jan 12 2005 Fix SourceForge bug 1101172 ('gri -help' incorrectly stated meaning of last argument(s)) * Sat Jan 8 2005 Fix SourceForge bug 835711 ('draw gri logo' fails) * Sat Jan 8 2005 Fix SourceForge bug 875881 (failed compilation with gcc 2.95.3) * Sat Jan 8 2005 Fix SourceForge bug 867515 (problem with junk in images) * Fri Jan 7 2005 - Fix SourceForge bug 1094087 (failed gcc-4.0 AMD64 compilation; solution provided by Andreas Jochens, a Debian user) * Mon Jan 3 2005 - Fix SourceForge bug 1094087 ('set path to' gave incorrect results) * Sun Dec 19 2004 - Fix SourceForge bug 1085788 ('image *=' gave incorrect results) * Mon Dec 13 2004 - Fix SourceForge bug 1084123 (Fink packaging put info files in wrong place) * Mon Aug 30 2004 - Fix SourceForge bug 1019141 ('draw arc' ignores the present pen color) * Sun Jul 25 2004 - Fix SourceForge bug 997741 (PostScript-clipped images broken if y-axis decreases) * Thu Jun 24 2004 - fix SF bug 978822 (doc error on 'set path to') * Sun Jun 13 2004 - add 'set transparency' * Thu Apr 15 2004 - fix SF bug 932203 (misplaced labels caused by 'set x axis labels') * Tue Apr 6 2004 - fix SF bug 930259 ('draw arc' had an extra line [thanks for fix by Wolfgang Voegeli]) * Fri Apr 2 2004 - fix SF bug 928277 ('draw polygon' should take 'cm' and 'pt' units) * Mon Mar 29 2004 - fix SF bug 923719 ('draw curve overlying' ignored effect of 'set dash') * Thu Mar 11 2004 - fix SF bug 914125 (all offpage points reported to have been drawn by 'draw curve') * Thu Jan 15 2004 - fix SF bug 877613 ('help' broken; cannot use temporary files) - fix SF bug 875881 ('draw image' broken with GCC 2.95) - fix SF bug 867515 ('convert grid to image' error) * Sun Jan 11 2004 - fix SF bug 874483 ('dash' properties ignored by 'save state') * Thu Jan 8 2004 - fix SF bug 873245 (inaccurate warnings on slow operations) * Wed Jan 7 2004 - fix SF bug 871477 by making 'set missing value none' the default * Wed Sep 3 2003 - RELEASE as version 2.12.7 - switch to automake-1.7 from automake-1.6 * Mon Sep 1 2003 - RELEASE as version 2.12.6 * Sat Aug 30 2003 - add 'age' RPN function, for testing file ages * Sat Jul 19 2003 - fix Sourceforge bug 773850 (bbox increased by 'draw symbol' even if (rectangular) postscript clipping is on) * Thu Jun 27 2003 - add 'age' RPN operator * Tue Jun 24 2003 - fix Sourceforge bug 760130 (solaris cannot compile with Ctl-l in Makefile) * Sat Jun 14 2003 - fix Sourceforge bug 750561 (make rebuilt HTML docs even if up-to-date) * Sun Jun 7 2003 - fix Sourceforge bug 743134 (bounding box not limited by 'set clip postscript') * Sat May 31 2003 - alter some target names to match the Automake Makefiles. * Sat May 03 2003 (fix by Kawamura Masao) - fix several typos on filenames, plus a compilation error hidden behind a precompilation flag * Tue Apr 15 2003 (fix by Peter Galbraith) - fix Sourceforge bug 720607 (emacs mode couldn't find html docs in redhat) * Sun Apr 06 2003 Dan Kelley - fix SourceForge bug 696073 (incorrect handling of \$() syntax) * Sat Apr 05 2003 Dan Kelley - fix SourceForge bug 715884 (mixup on quoted strings) * Sat Mar 29 2003 Dan Kelley - fix SourceForge bug 711354 (program name wrong in PostScript Creator: comment) - fix SourceForge bug 706202 (Page orientation hint missing in Postscript) * Thu Mar 01 2003 Dan Kelley - +++ VERSION 2.12.3 +++ - fix SourceForge bug 685919 (cannot understand '.eps' file extension) * Fri Feb 7 2003 Dan Kelley - +++ VERSION 2.12.2 +++ * Tue Jan 28 2003 Dan Kelley - fix SourceForge bug 675304 (segfault on 'read image pgm') * Sat Jan 25 2003 Dan Kelley - fix SourceForge bug 647234 (will not compile on Mac OS X 10.1.5) * Mon Jan 20 2003 Dan Kelley - fix SourceForge bug 671022 (error on 'flip image x|y') * Sat Jan 18 2003 Dan Kelley - fix SourceForge bug 669603 ('skip backward .n.' did not work) * Tue Jan 14 2003 Dan Kelley - fix SourceForge bug 667754 ('read image pgm' segfaults on memory) * Wed Jan 8 2003 Dan Kelley - fix SourceForge bug 664388 ('read image pgm' broken) * Sun Dec 15 2002 Dan Kelley - fix SourceForge bug 654129 (ignores ~/.grirc file) - fix SourceForge bug 654127 (configure scripts are broken) * Sat Dec 7 2002 Dan Kelley - fix SourceForge bug 649132 (LDFLAGS not used in Makefile.in) - fix SourceForge bug 649134 (tweak gcc optimization) - fix SourceForge bug 649136 (examples 8 and 9 out-dated) - fix SourceForge bug 641406 (RPN too aggressive on missing values) * Wed Sep 25 2002 Dan Kelley - Version 2.12.1 - fix SourceForge bug 613075 (sin, cos, tan problem in RPN) * Sun Sep 15 2002 Dan Kelley - Version 2.12.0 - add 'sed' RPN operator - add 'skewness' RPN operator - add 'kurtosis' RPN operator - fix SourceForge bug 606303 (web pages were not valid html) - fix SourceForge bug 593958 (should ignore 'missingvalue' if it occurs within an intermediate result of an RPN calculation) - fix SourceForge bug 600395 (won't compile with recently released version (3.2) of GCC compiler) - fix SourceForge bug 600233 (segfaults if some RPN operators are used on too-small stack) * Sun Jun 16 2002 Dan Kelley - Add 'hex2dec' and 'dec2hex' rpn operators. * Wed Jun 5 2002 Dan Kelley - Add 'sed' rpn operator. * Sat Jun 1 2002 Dan Kelley - Version 2.10.1 - Fix Sourceforge bug 562911 (won't build with gcc-3.0) - Fix Sourceforge bug 562558 ('draw title' confusion with log axes) - Fix Sourceforge bug 562014 (won't build if popt library is unavailable) - Fix SourceForge bug 558463 (in HTML docs, the ``press'' margin tag was misdirected) - Fix SourceForge bug 562017 (parser fails with DOS end-of-line) - Fix SourceForge bug 562017 ('new page' postscript error in gv viewer) * Tue May 07 2002 Dan Kelley - Version 2.10.0 * Sat Apr 20 2002 Dan Kelley - Fix Sourceforge bug 546109 (bounding box wrong if postscript clipping used) * Mon Mar 18 2002 Dan Kelley - Permit 'draw label' coordinates in pt * Sat Mar 16 2002 Dan Kelley - Fix Sourceforge bug 508657 (missing backslash in drawing undefined synonyms) - Fix Sourceforge bug 482120 ('regress' ignores data weights) * Tue Mar 12 2002 Dan Kelley - Permit 'draw box' to have coordinates in pt, as well as cm. - Permit 'draw symbol' to have coordinates in pt, as well as cm. - Permit 'draw line from' to have coordinates in pt, as well as cm. * Wed Feb 27 2002 Dan Kelley - Fix Sourceforge bug 523450 (log axes detect non-positive values too late) * Thu Feb 21 2002 Dan Kelley - Fix Sourceforge bug 521045 (install problem, function prototype problem) * Thu Feb 07 2002 Dan Kelley - Fix Sourceforge bug 513002 (minor error in documentation of 'set clip'). * Mon Jan 28 2002 Dan Kelley - Fix Sourceforge bug 509592 (doc HTML indices misordered). * Sat Jan 26 2002 Dan Kelley - Fix SourceForge bug 506523 (map axes give wrong minutes in negative regions). * Fri Jan 25 2002 Dan Kelley - Fix SourceForge bug 508088 (grimode: gv should update, not be relaunched). - Make RPM install/uninstall run silently. * Wed Jan 23 2002 Dan Kelley - Fix SourceForge bug 506490 ('-v' commandline option gave wrong number) * Wed Jan 02 2002 Dan Kelley - add `set clip to curve' * Thu Dec 13 2001 Dan Kelley - Release as gri-2.8.5 on SourceForge.Net site. - Fix SourceForge bug 492472 ('inf' rpn operator caused segfault) * Thu Oct 04 2001 Dan Kelley - Release as gri-2.8.4 on SourceForge.Net site. - Fix SourceForge bug 467973 (`gri -version' gave wrong version number, breaking the Emacs Gri mode.) - Fix SourceForge bug 468401 (`draw grid' disobeys pencolor) * Mon Oct 01 2001 Dan Kelley - Release as gri-2.8.3 on SourceForge.Net site. - Fix SourceForge bug 462243 (endian problem in Rasterfile images, plus a reading problem in PGM images). * Mon Sep 10 2001 Dan Kelley - Release as gri-2.8.2 on SourceForge.Net site. - Really Fix SourceForge bug 454557 (wouldn't compile with the pre-release version 3.0.1 of the GNU c++ compiler). This closes SourceForge bug 111093. * Thu Sep 06 2001 Dan Kelley - Release as gri-2.8.1 on SourceForge.Net site. - Fix SourceForge bug 450465 (`create columns from function' was broken). - Fix SourceForge bug 454557 (wouldn't compile with the pre-release version 3.0.1 of the GNU c++ compiler; closes: sourceforge bug 111093) * Tue Jul 24 2001 Dan Kelley - Bump up version number to 2.8.0 * Mon Jul 23 2001 Dan Kelley - Release as gri-2.8.0 on SourceForge.Net site. - Add `unlink' command as a unix-familiar way to delete files. - Add `set page size' command to clip to a given page size. - Add `substr' RPN operator to permit extraction of sub-strings. - Add `default' for the `set x name' and the `set y name' commands. - Add Perl-like ability to put underscores in numerical constants (`.v. = 1_000' and `.v. = 1000' are completely equivalent). - In Emacs mode, change so that it completes builtin variables and synonyms as well as commands. - In Emacs mode, add "idle-timer help" to display defaults for builtin variables under cursor. - In Emacs mode, make fontification of builtin variables apply only if spelled correctly. - To Makefile, add `make source-arch-indep' target in sources. This will build a source tar file in which all the architecture-independent material (documentation in HTML, postscript and Info formats) is pre-made. This makes it easier to install gri on a host that doesn't have TeX and ImageMagick installed. - Move gri-html-doc and gri-ps-doc documentation files to the /usr/share/doc/gri directory - Ensure that package compiles with Standards-Version: 3.5.5 without changes. * Thu Apr 19 2001 Dan Kelley - Rename this file as gri.spec, without the version number embedded in the filename. Upgrade to version number 2.6.1. Change url to point to sourceforge site (but leave ftp as it is, for now anyway). * Tue Jan 30 2001 Dan Kelley - Changing to e.g. /usr/share/info instead of /usr/info. Same for manpages. I know, I should be using the fancy macros that are defined in /usr/lib/rpm, but these seemed contradictory, with respect to where things are in my Redhat 7.0 setup ... and I had a hard time figuring out how to use these macros anyway, so I just gave up and hard-wired them in, using the new directories as used in Redhat 7.0, as opposed to the (different) directories in all the other Redhat versions I've had. Someday I'll switch to using macros, but it means changing both this spec-file and various Makefiles, and I need to be sure that changes to the Makefiles don't hurt the distributions for Debian linux, for solaris, etc. * Thu Jun 1 2000 Dan Kelley - Triv changes here; code changes are to read compressed files, and manual improvements. * Fri May 12 2000 Dan Kelley - Compress info files for linux-redhat. * Thu May 11 2000 Peter S Galbraith - Change info files to .info file extension. - Tweaked install-info rules. I hope they work. * Sat Apr 01 2000 Dan Kelley - Fix spec-file error in the install-info command. However, to my great frustration, this is still broken or install-info is broken) since the command doesn't install an entry for gri. After hand-editing to insert a Gri entry, I uncovered another bug, and so I have added a chmod of /usr/info/dir file so folks other than root can use info. - Update the version number in gri.cmd to match the number compiled into gri. - Update the startup message from the old form to the new form. - Call this release 3 to match Tim Powers' convention (although I think it should be called release 1, when it works!) * Fri Mar 31 2000 Dan Kelley - applied Tim Powers' patches directly to the sources, updating them so that the patches Tim had made in this spec file are no longer needed. Note: I didn't apply Tim's patch to the documentation, since visual inspection indicated that I had already repaired the errors he found (each of which which involved my having used an incorrect name for the example gif files.) - renamed Tim's spec file from gri.spec to gri-2.4.3.spec since otherwise I'd get too confused as versions develop. * Fri Mar 31 2000 Tim Powers - changed group * Thu Mar 30 2000 Tim Powers - started changelog on Dan Kelley's origional spec file - quiet setup - patched Makefile so that the install goes a bit smoother since we use BuildRoots - changed post and postun sections so that they operate on /usr/info/dir instead of /etc/info-dir - streamlined files list so that man/info pages are picked up even if RPM doesn't want to gzip them - bzipped source to conserve space - added clean section ����������������������������������������gri/copyright.txt�����������������������������������������������������������������������������������0000644�0001750�0001750�00000000035�13147557614�012567� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(c) 1991-2017 Dan E. Kelley. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/check.pl����������������������������������������������������������������������������������������0000755�0001750�0001750�00000010250�13147557614�011433� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/perl use Date::Manip; # For more on how Date::Manip works, see for example # http://theoryx5.uwinnipeg.ca/CPAN/data/DateManip/Manip.html # or other CPAN sites. sub indicate_age($$) { my $before = $_[0]; my $item = $_[1]; $age = &DateCalc(&ParseDate("now"), $before); $s = 0; # prevent warning ($y, $mo, $w, $d, $h, $min, $s) = split(/:/, "$age"); # print "<$age> [age]\n"; # print "<$y> [year]\n"; $future = 0 if ("$y" eq "-0"); $future = 1 if ("$y" eq "+0"); # print "NEW \n" if $new; if ($future) { print "\t... $item is from $y years, $mo months, $w weeks, $d days into the future\n"; } else { if ($y > 0) { print "\t... $item was last updated $y years and $mo months ago\n"; } elsif ($mo > 0) { print "\t... $item was last updated $mo months and $w weeks ago\n"; } elsif ($w > 0) { print "\t... $item was last updated $w weeks ago\n"; } else { print "\t... $item was last updated $d days ago\n"; } } } $version_makefile = "?"; print "Check 1: do the version numbers match?\n"; sub version_mismatch() { print "\t... No!\n"; print " Version is $version_makefile in the Makefile file.\n"; print " Version is $version_doc in the doc/gri.texi file.\n"; print " Version is $version_spec in the gri.spec file.\n"; print " Version is $version_cmd in the gri.cmd file.\n"; return " ... this error was detected"; } open(MAKEFILE, "Makefile") or die "Cannot open Makefile"; $version_makefile = "?.?.?"; while() { if (/^VERSION = (.*)/) { $version_makefile = $1; close (MAKEFILE); last; } } open(DOC, "doc/gri.texi") or die "Cannot open doc/gri.texi"; $version_doc = "?.?.?"; while() { if (/^\@set GRI-VERSION (.*)/) { $version_doc = $1; close (DOC); last; } } die version_mismatch() if $version_makefile ne $version_doc; print "\t... Makefile and doc/gri.texi match\n"; open(SPEC, "gri.spec") or die "Cannot open gri.spec"; $version_spec = "?.?.?"; while() { if (/^\%define griversion (.*)/) { $version_spec = "$1"; close (SPEC); last; } } die version_mismatch() if $version_spec ne $version_makefile; print "\t... gri.spec also matches\n"; open(CMD, "gri.cmd") or die "Cannot open gri.cmd"; $version_cmd = "?.?.?"; $_ = ; close(CMD); chop; s/.*version //; s/\)//; $version_cmd = $_; die version_mismatch() if $version_cmd ne $version_makefile; print "\t... gri.cmd also matches\n"; #### #### #### #### #### #### #### #### #### print "Check 2: have various dated files been updated recently?\n"; # ChangeLog open(CHANGELOG, "changelog") or die "Can't open changelog file"; $_ = ; close(CHANGELOG); @_ = split; $date_changelog = &ParseDate($_[0]); indicate_age($date_changelog, " ChangeLog"); # gri.spec open(SPEC, "gri.spec") or die "Can't open gri.spec"; while() { next if !/^%changelog/; $_ = ; close(SPEC); @_ = split; $date_spec = &ParseDate("$_[1] $_[2] $_[3] $_[4]"); last; } indicate_age($date_spec, " gri.spec"); # debian/changelog open(DEBIAN_CHANGELOG, "debian/changelog") or die "Can't open debian/changelog"; #print "DEBUG. Now examine debian/changelog file.\n"; #print "BUG: need to examine WHOLE file and find MOST RECENT date!\n"; #print "\n"; #print "For reference, the present date is $now\n"; $latest = &ParseDate("1971"); # pre-history, basically while() { if (/ \-\- (.*) <(.*)> (.*), (.*)/) { $date_debian_changelog = &ParseDate($4); #print "the sequence '$4' parses to $date_debian_changelog\n"; #print "latest $latest $date_debian_changelog\n"; $latest = $date_debian_changelog if (&Date_Cmp($date_debian_changelog, $latest) > 0); } } $date_debian_changelog = $latest; indicate_age($date_debian_changelog, "debian/changelog"); # doc/gri.texi open (DOC, "doc/gri.texi") or die "Cannot open doc/gri.texi"; $latest = &ParseDate("1971"); # pre-history, basically while() { if (/\@subsubsection\s*Version\s*(.*)\s*\[(.*)\]\s*$/) { #print; $date_doc = $2; $latest = $date_doc if (&Date_Cmp($date_doc, $latest) > 0); #printf "$date_doc [date_doc] $latest [latest]\n"; } } $date_doc = $latest; indicate_age($date_doc, " doc/gri.texi"); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/depcomp�����������������������������������������������������������������������������������������0000755�0001750�0001750�00000027533�13147557614�011407� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # depcomp - compile a program generating dependencies as side-effects # Copyright 1999, 2000 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # `libtool' can also be set to `yes' or `no'. if test -z "$depfile"; then base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'` dir=`echo "$object" | sed 's,/.*$,/,'` if test "$dir" = "$object"; then dir= fi # FIXME: should be _deps on DOS. depfile="$dir.deps/$base" fi tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. This file always lives in the current directory. # Also, the AIX compiler puts `$object:' at the start of each line; # $object doesn't have directory information. stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` tmpdepfile="$stripped.u" outname="$stripped.o" if test "$libtool" = yes; then "$@" -Wc,-M else "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1="$dir.libs/$base.lo.d" tmpdepfile2="$dir.libs/$base.d" "$@" -Wc,-MD else tmpdepfile1="$dir$base.o.d" tmpdepfile2="$dir$base.d" "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi if test -f "$tmpdepfile1"; then tmpdepfile="$tmpdepfile1" else tmpdepfile="$tmpdepfile2" fi if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a space and a tab in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. We will use -o /dev/null later, # however we can't do the remplacement now because # `-o $object' might simply not be used IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M "$@" -o /dev/null $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # X makedepend shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes ;; esac case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; -*) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix="`echo $object | sed 's/^.*\././'`" touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. "$@" || exit $? IFS=" " for arg do case "$arg" in "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/compile�����������������������������������������������������������������������������������������0000755�0001750�0001750�00000016245�13147560122�011372� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2012-10-14.11; # UTC # Copyright (C) 1999-2014 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/COPYING�����������������������������������������������������������������������������������������0000644�0001750�0001750�00000104513�13147557614�011057� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/configure.ac������������������������������������������������������������������������������������0000644�0001750�0001750�00000034172�13147557614�012315� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������AC_PREREQ(2.50) AC_INIT(gri, 2.12.26) AC_CONFIG_SRCDIR(src/gri.cc) AM_INIT_AUTOMAKE AC_CANONICAL_HOST AC_PROG_RANLIB AC_PROG_INSTALL AC_PROG_MAKE_SET PROGS="gri" AC_SUBST(PROGS) dnl checks for programs. AC_PROG_CC AC_PROG_CXX AC_PROG_CXXCPP AC_LANG_CPLUSPLUS dnl See if uses string::remove or string::erase AC_DEFUN([CHECK_OLD_STRING], AC_MSG_CHECKING(for old C++ subroutine called string::remove) AC_CACHE_VAL(gri_cv_have_old_string, [ AC_TRY_COMPILE([ #define _POSIX_SOURCE 1 #include ], [ string s("hi"); s.remove(0,1); ], gri_cv_have_old_string=yes, gri_cv_have_old_string=no)]) AC_MSG_RESULT($gri_cv_have_old_string) if test $gri_cv_have_old_string = yes ; then AC_DEFINE(HAVE_OLD_STRING) fi )dnl dnl CHECK_OLD_STRING define(GCC_TWEAK1, AC_MSG_CHECKING(for gcc compiler) [AC_BEFORE([$0], [AC_COMPILE_CHECK])AC_BEFORE([$0], [AC_TEST_PROGRAM])AC_BEFORE([$0], [AC_HEADER_EGREP])AC_BEFORE([$0], [AC_TEST_CPP])AC_EGREP_CPP(yes, [#if defined(__GNUC__) yes #endif ], GCC=yes, GCC=no) if test $GCC = yes; then EXTRA_CFLAGS_TEMPLATE="$AM_CFLAGS -Wall" AM_CXXFLAGS="$AM_CXXFLAGS -Wall" AC_SUBST(AM_CXXFLAGS) AC_SUBST(EXTRA_CFLAGS_TEMPLATE) fi AC_MSG_RESULT($GCC) ])dnl dnl GCC_TWEAK1 define(GCC_TWEAK2, AC_MSG_CHECKING(for C++ compiler with new headers as of August 2002) [AC_BEFORE([$0], [AC_COMPILE_CHECK])AC_BEFORE([$0], [AC_TEST_PROGRAM])AC_BEFORE([$0], [AC_HEADER_EGREP])AC_BEFORE([$0], [AC_TEST_CPP])AC_EGREP_CPP(yes, [#if defined(__GNUC__) #if __GNUC__ >= 3 yes #endif #endif ], Cplusplusnew=yes, Cplusplusnew=no) if test $Cplusplusnew = yes; then AM_CXXFLAGS="$AM_CXXFLAGS -DCPLUSPLUSNEW" # AM_CXXFLAGS="$AM_CXXFLAGS -fno-strength-reduce" AC_SUBST(AM_CXXFLAGS) fi AC_MSG_RESULT($Cplusplusnew) ])dnl dnl GCC_TWEAK2 dnl Note: prior to 2.9.x, we used to have dnl EXTRA_CFLAGS="$EXTRA_CFLAGS -Wall -fno-implicit-templates" dnl above. But now, this seems not to be needed, at least dnl on intel (linux), with g++-2.96 and g++-3.0 dnl On DEC computers, with cxx compiler, need something special AC_DEFUN([DEK_IS_DECCXX], AC_MSG_CHECKING(for DEC cxx compiler) AC_CACHE_VAL(gri_cv_is_deccxx, [ AC_BEFORE([$0], [AC_COMPILE_CHECK])AC_BEFORE([$0], [AC_TEST_PROGRAM])AC_BEFORE([$0], [AC_HEADER_EGREP])AC_BEFORE([$0], [AC_TEST_CPP])AC_EGREP_CPP(yes, [#ifdef __DECCXX yes #endif ], gri_cv_is_deccxx=yes, gri_cv_is_deccxx=no)]) AC_MSG_RESULT($gri_cv_is_deccxx) if test $gri_cv_is_deccxx = yes; then AM_CXXFLAGS="$AM_CXXFLAGS -D_ANSI_C_SOURCE" AC_SUBST(AM_CXXFLAGS) fi )dnl dnl DEK_IS_DECCXX AC_DEFUN([DEK_IS_APPLE_OSX], AC_MSG_CHECKING(for for apple computer assumed running OSX) AC_CACHE_VAL(gri_cv_os_is_apple_osx, [ AC_BEFORE([$0], [AC_COMPILE_CHECK])AC_BEFORE([$0], [AC_TEST_PROGRAM])AC_BEFORE([$0], [AC_HEADER_EGREP])AC_BEFORE([$0], [AC_TEST_CPP])AC_EGREP_CPP(yes, [#if defined(__APPLE__) && defined(__GNUC__) yes #endif ], gri_cv_os_is_apple_osx=yes, gri_cv_os_is_apple_osx=no)]) AC_MSG_RESULT($gri_cv_os_is_apple_osx) if test $gri_cv_os_is_apple_osx = yes; then AM_CXXFLAGS="$AM_CXXFLAGS -O0" AC_DEFINE(OS_IS_APPLE_OSX) fi )dnl dnl dnl DEK_IS_APPLE_OSX AC_DEFUN([IS_THIS_AN_ALPHA_SYSTEM], AC_MSG_CHECKING(for DEC alpha computer) AC_CACHE_VAL(gri_cv_is_dec_alpha, [ AC_BEFORE([$0], [AC_COMPILE_CHECK])AC_BEFORE([$0], [AC_TEST_PROGRAM])AC_BEFORE([$0], [AC_HEADER_EGREP])AC_BEFORE([$0], [AC_TEST_CPP])AC_EGREP_CPP(yes, [#ifdef __alpha__ yes #endif ], gri_cv_is_dek_alpha=yes, gri_cv_is_dec_alpha=no)]) AC_MSG_RESULT($gri_cv_is_dec_alpha) if test $gri_cv_is_dec_alpha = yes; then AC_DEFINE(IS_DEC_ALPHA) fi )dnl dnl IS_THIS_AN_ALPHA_SYSTEM AC_DEFUN([IS_THIS_A_BEOS_SYSTEM], AC_MSG_CHECKING(for BeOS environment) AC_CACHE_VAL(gri_cv_is_beos, [ AC_BEFORE([$0], [AC_COMPILE_CHECK])AC_BEFORE([$0], [AC_TEST_PROGRAM])AC_BEFORE([$0], [AC_HEADER_EGREP])AC_BEFORE([$0], [AC_TEST_CPP])AC_EGREP_CPP(yes, [#ifdef __BEOS__ yes #endif ], gri_cv_is_beos=yes, gri_cv_is_beos=no)]) AC_MSG_RESULT($gri_cv_is_beos) if test $gri_cv_is_beos = yes; then AC_DEFINE(OS_IS_BEOS) fi )dnl dnl IS_THIS_A_BEOS_SYSTEM dnl See if FreeBSD computer AC_DEFUN([DEK_IS_FREEBSD], AC_MSG_CHECKING(for FreeBSD system) AC_CACHE_VAL(gri_cv_is_freebsd, [ AC_BEFORE([$0], [AC_COMPILE_CHECK])AC_BEFORE([$0], [AC_TEST_PROGRAM])AC_BEFORE([$0], [AC_HEADER_EGREP])AC_BEFORE([$0], [AC_TEST_CPP])AC_EGREP_CPP(yes, [#ifdef __FreeBSD__ yes #endif ], gri_cv_is_freebsd=yes, gri_cv_is_freebsd=no)]) AC_MSG_RESULT($gri_cv_is_freebsd) if test $gri_cv_is_freebsd = yes; then AC_DEFINE(IS_FREEBSD) fi )dnl dnl DEK_IS_FREEBSD dnl See if OpenBSD computer AC_DEFUN([DEK_IS_OPENBSD], AC_MSG_CHECKING(for OPENBSD system) AC_CACHE_VAL(gri_cv_is_openbsd, [ AC_BEFORE([$0], [AC_COMPILE_CHECK])AC_BEFORE([$0], [AC_TEST_PROGRAM])AC_BEFORE([$0], [AC_HEADER_EGREP])AC_BEFORE([$0], [AC_TEST_CPP])AC_EGREP_CPP(yes, [#ifdef __OpenBSD__ yes #endif ], gri_cv_is_openbsd=yes, gri_cv_is_openbsd=no)]) AC_MSG_RESULT($gri_cv_is_openbsd) if test $gri_cv_is_openbsd = yes; then AC_DEFINE(IS_OPENBSD) fi )dnl dnl DEK_IS_OPENBSD dnl See if HPUX system AC_DEFUN([IS_THIS_AN_HPUX_SYSTEM], AC_MSG_CHECKING(for HPUX environment) AC_CACHE_VAL(gri_cv_is_hpux, [ AC_BEFORE([$0], [AC_COMPILE_CHECK])AC_BEFORE([$0], [AC_TEST_PROGRAM])AC_BEFORE([$0], [AC_HEADER_EGREP])AC_BEFORE([$0], [AC_TEST_CPP])AC_EGREP_CPP(yes, [#ifdef hpux yes #endif ], gri_cv_is_hpux=yes, gri_cv_is_hpux=no)]) AC_MSG_RESULT($gri_cv_is_hpux) if test $gri_cv_is_hpux = yes; then AC_DEFINE(OS_IS_HPUX) fi )dnl dnl IS_THIS_AN_HPUX_SYSTEM dnl See if NetBSD computer AC_DEFUN([DEK_IS_NETBSD], AC_MSG_CHECKING(for NetBSD system) AC_CACHE_VAL(gri_cv_is_netbsd, [ AC_BEFORE([$0], [AC_COMPILE_CHECK])AC_BEFORE([$0], [AC_TEST_PROGRAM])AC_BEFORE([$0], [AC_HEADER_EGREP])AC_BEFORE([$0], [AC_TEST_CPP])AC_EGREP_CPP(yes, [#ifdef __NetBSD__ yes #endif ], gri_cv_is_netbsd=yes, gri_cv_is_netbsd=no)]) AC_MSG_RESULT($gri_cv_is_netbsd) if test $gri_cv_is_netbsd = yes; then AC_DEFINE(IS_NETBSD) fi )dnl dnl DEK_IS_NETBSD dnl See if SUN computer AC_DEFUN([DEK_IS_SUN], AC_MSG_CHECKING(for for Sun Microsystems computer) AC_CACHE_VAL(gri_cv_is_sun, [ AC_BEFORE([$0], [AC_COMPILE_CHECK])AC_BEFORE([$0], [AC_TEST_PROGRAM])AC_BEFORE([$0], [AC_HEADER_EGREP])AC_BEFORE([$0], [AC_TEST_CPP])AC_EGREP_CPP(yes, [#ifdef sun yes #endif ], gri_cv_is_sun=yes, gri_cv_is_sun=no)]) AC_MSG_RESULT($gri_cv_is_sun) if test $gri_cv_is_sun = yes; then AC_DEFINE(IS_SUN) fi )dnl dnl DEK_IS_SUN dnl See if IBM AIX with IBM compiler. Note dnl that an IBM running GNU compiler won't dnl fall into this category. AC_DEFUN([DEK_IS_AIX_WITH_IBM], AC_MSG_CHECKING(for for IBM AIX computer with IBM compiler) AC_CACHE_VAL(gri_cv_is_aix_with_ibm, [ AC_BEFORE([$0], [AC_COMPILE_CHECK])AC_BEFORE([$0], [AC_TEST_PROGRAM])AC_BEFORE([$0], [AC_HEADER_EGREP])AC_BEFORE([$0], [AC_TEST_CPP])AC_EGREP_CPP(yes, [#ifdef __IBMCPP__ yes #endif ], gri_cv_is_aix_with_ibm=yes, gri_cv_is_aix_with_ibm=no)]) AC_MSG_RESULT($gri_cv_is_aix_with_ibm) if test $gri_cv_is_aix_with_ibm = yes; then AC_DEFINE(IS_AIX_WITH_IBM) fi )dnl dnl DEK_IS_AIX_WITH_IBM dnl See if mingw32 AC_DEFUN([DEK_IS_MINGW32], AC_MSG_CHECKING(for for mingw32 system) AC_CACHE_VAL(gri_cv_is_mingw32, [ AC_BEFORE([$0], [AC_COMPILE_CHECK])AC_BEFORE([$0], [AC_TEST_PROGRAM])AC_BEFORE([$0], [AC_HEADER_EGREP])AC_BEFORE([$0], [AC_TEST_CPP])AC_EGREP_CPP(yes, [#ifdef __MINGW32__ yes #endif ], gri_cv_is_mingw32=yes, gri_cv_is_mingw32=no)]) AC_MSG_RESULT($gri_cv_is_mingw32) if test $gri_cv_is_mingw32 = yes; then AC_DEFINE(IS_MINGW32) fi )dnl dnl DEK_IS_MINGW32 dnl Determine endian type. NOTE: I have [[ and ]] in the test code. I couldn't dnl find anything in the docs that told me to do that, but it was the only dnl I could find to make the code, created in "configure", to have the dnl required brackets. I tried the quoting macros as described in the docs dnl but couldn't get it working. AC_DEFUN([GRI_DETERMINE_ENDIAN], AC_MSG_CHECKING(to see whether this machine is big endian or little endian) AC_CACHE_VAL(gri_cv_endian_type, [ AC_LANG_C AC_TRY_RUN([ int main () { /* Figure out endian-ness, from Harbison & Steele */ union { long l; char c[[sizeof (long)]]; } u; u.l = 1; exit(u.c[[sizeof (long) - 1]] == (char)1); }], gri_cv_endian_type=little, gri_cv_endian_type=big, gri_cv_endian_type=unknown)]) AC_LANG_CPLUSPLUS AC_MSG_RESULT($gri_cv_endian_type) if test $gri_cv_endian_type = big; then AC_DEFINE(GRI_IS_BIG_ENDIAN, 1) else AC_DEFINE(GRI_IS_BIG_ENDIAN, 0) fi )dnl dnl GRI_DETERMINE_ENDIAN AC_CHECK_HEADERS(unistd.h) dnl Check for netcdf library. It might be in one of several places, dnl so check several locations, reporting the location if found. define(CHECK_FOR_NETCDF, [ AC_MSG_CHECKING(for netcdf library) for d in /opt/netcdf /usr/local /usr; do if test -f $d/include/netcdf.h; then AM_CXXFLAGS="$AM_CXXFLAGS -I$d/include" EXTRA_CFLAGS_TEMPLATE="$EXTRA_CFLAGS_TEMPLATE -I$d/include" DEFS="$DEFS -I$d/include" LIBS="$LIBS -L$d/lib -lnetcdf" if test $gri_cv_is_sun = yes ; then LIBS="$LIBS -lnsl" fi AC_DEFINE(HAVE_LIBNETCDF) AC_MSG_RESULT(yes, in $d/include/netcdf.h and $d/lib/libnetcdf.a) fi done AC_MSG_RESULT(done) ])dnl dnl CHECK_FOR_NETCDF dnl use this?? dnl AC_SUBST(EXTRA_CXXFLAGS) #AC_SUBST(EXTRA_OBJS) dnl AC_SUBST(EXTRA_LIBS) dnl Check for Imgemagick's convert, needed to make PNG files in HTML manual AC_CHECK_PROG(HAVE_CONVERT, convert, "yes", "no") if test $HAVE_CONVERT = "no" ; then echo " **WARNING: Cannot make proper HTML manual without Imagemagick." echo " **WARNING: It is needed to make PNG images from PostScript files." echo " **WARNING: Expect broken image links in the manual!" fi dnl AC_MSG_CHECKING(for ImageMagick's convert) dnl define(CHECK_FOR_CONVERT, [ dnl if test -f /usr/bin/convert ; then dnl HAVE_CONVERT="yes" dnl echo "yes" dnl else dnl HAVE_CONVERT="no" dnl echo "no. Cannot make HTML manual without it" dnl fi dnl AC_SUBST(HAVE_CONVERT)dnl dnl ])dnl dnl dnl dnl CHECK_FOR_CONVERT dnl checks for UNIX variants that set `DEFS' dnl checks for header files dnl stdarg.h, stdlib.h AC_HEADER_STDC dnl Check whether system has libpopt online. For dnl now, this check value is not used; later on dnl I should skip the compilation of my local dnl popt if there is a version online. AC_CHECK_LIB(popt, poptReadConfigFile, AM_CONDITIONAL(OS_HAS_POPT, test 1=1), AM_CONDITIONAL(OS_HAS_POPT, test 0=1)) dnl check for readline library AC_CHECK_LIB(readline, readline, [], []) dnl checks for typedefs AC_TYPE_PID_T dnl checks for functions dnl AC_CHECK_FUNCS(isnan isinf acosh getcwd getenv popen drand48 mkstemp tmpnam tempname gethostname access lstat strerror) AC_CHECK_FUNCS(isnan isinf acosh getcwd popen mkstemp tmpnam tempnam gethostname access lstat stat strerror) dnl The next lines are because configure fails in c++, to find these things. dnl I first noticed this on 2002-Dec-15. A discussion thread on the topic, dnl valid at that date, is dnl http://mail.gnu.org/pipermail/bug-autoconf/2001-September/001036.html dnl and I patterned my solution loosely on advice I found thre. AC_CHECK_DECL(getenv, [AC_DEFINE(HAVE_GETENV)]) AC_CHECK_DECL(drand48, [AC_DEFINE(HAVE_DRAND48)]) dnl checks for structure members dnl checks for compiler characteristics dnl checks for operating system services dnl other checks for UNIX variants dnl See if the user did "configure --enable-OSX" AC_ARG_ENABLE(OSX, [ --enable-OSX Build for OSX], [case "${enableval}" in yes) OSX=true ;; no) OSX=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-OSX) ;; esac],[debug=false]) AM_CONDITIONAL(OS_IS_APPLE_OSX, test x$OSX = xtrue) dnl See if the user did "configure --enable-OSX_BUNDLE" AC_ARG_ENABLE(OSX_BUNDLE, [ --enable-OSX_BUNDLE Build for an OSX BUNDLE], [case "${enableval}" in yes) OSX_BUNDLE=true ;; no) OSX_BUNDLE=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-OSX_BUNDLE) ;; esac],[debug=false]) AM_CONDITIONAL(OS_IS_OSX_BUNDLE, test x$OSX_BUNDLE = xtrue) dnl See if the user did "configure --enable-FreeBSD" AC_ARG_ENABLE(FreeBSD, [ --enable-FreeBSD Build for FreeBSD], [case "${enableval}" in yes) FreeBSD=true ;; no) FreeBSD=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-FreeBSD) ;; esac],[debug=false]) AM_CONDITIONAL(OS_IS_FREEBSD, test x$FreeBSD = xtrue) dnl See if the user did "configure --enable-FINK" AC_ARG_ENABLE(FINK, [ --enable-FINK Build for FINK], [case "${enableval}" in yes) FINK=true ;; no) FINK=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-FINK) ;; esac],[debug=false]) AM_CONDITIONAL(OS_IS_FINK, test x$FINK = xtrue) dnl See if the user did "configure --enable-linux_redhat" AC_ARG_ENABLE(linux_redhat, [ --enable-linux_redhat Build for Linux/redhat OS], [case "${enableval}" in yes) linux_redhat=true ;; no) linux_redhat=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-linux_redhat) ;; esac],[debug=false]) AM_CONDITIONAL(OS_IS_LINUX_REDHAT, test x$linux_redhat = xtrue) dnl use as e.g. dnl if OS_IS_LINUX_REDHAT dnl NAME = Dan dnl else dnl NAME = nad dnl endif dnl myname = $(NAME) dnl dnl dan: dnl @echo "myname is $(myname)" dnl See if the user did "configure --enable-linux_debian" AC_ARG_ENABLE(linux_debian, [ --enable-linux_debian Build for Linux/debian OS], [case "${enableval}" in yes) linux_debian=true ;; no) linux_debian=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-linux_debian) ;; esac],[debug=false]) AM_CONDITIONAL(OS_IS_LINUX_DEBIAN, test x$linux_debian = xtrue) dnl See if the user did "configure --enable-solaris" AC_ARG_ENABLE(solaris, [ --enable-solaris Build for Solaris OS], [case "${enableval}" in yes) solaris=true ;; no) solaris=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-solaris) ;; esac],[debug=false]) AM_CONDITIONAL(OS_IS_SOLARIS, test x$solaris = xtrue) AC_CONFIG_FILES([Makefile debian/Makefile doc/Makefile doc/examples/Makefile doc/tst_suite/Makefile doc/resources/Makefile doc/screenshots/Makefile src/Makefile src/popt/Makefile]) AC_OUTPUT ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/fink/�������������������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�13147557614�010747� 5����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/fink/README�������������������������������������������������������������������������������������0000644�0001750�0001750�00000001503�13147557614�011626� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������BUILDING A LOCAL GRI FOR FINK ----------------------------- 1. Ensure that Gri compiles without errors and without warnings: cd ~/src/gri make cd doc make 2. Create the tarball, install it, and note the md5sum. cd ~/src/gri make dist sudo mv gri-2.12.10.tar.gz /sw/src/gri-2.12.10.tgz md5sum /sw/src/gri-2.12.10.tgz 3. Deposit files in correct places for build cd ~/src/gri/fink emacs gri.fink # adjust the md5sum to match that from step 2 fink validate gri.info sudo cp gri.info /sw/fink/dists/local/main/finkinfo/ 4. Build it, install it, test it cd /sw/fink/dists/local/main/finkinfo fink delete gri fink rebuild gri fink install gri fink validate /sw/fink/debs/gri_2.12.10-1_darwin-powerpc.deb REFERENCES * http://fink.sourceforge.net/doc/quick-start-pkg/example.php?phpLang=en ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/fink/gri.info�����������������������������������������������������������������������������������0000644�0001750�0001750�00000002213�13147557614�012403� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Package: gri Version: 2.12.11 Revision: 1 BuildDepends: imagemagick, tetex Depends: Source: mirror:sourceforge:%n/%n-%v.tgz Source-MD5: cbe103a32375ae73bb507aa0c66484fa DocFiles: README doc/*html InfoDocs: gri.info gri.info-1 gri.info-2 gri.info-3 Description: Scientific graphics language ConfigureParams: --enable-FINK --infodir='${prefix}/share/info' DescDetail: << Gri is a language for scientific graphics programming. The word "language" is important: Gri is command-driven, not point/click. Some users consider Gri similar to LaTeX, since both provide extensive power as a reward for tolerating a learning curve. Gri can make x-y graphs, contour graphs, and image graphs, in PostScript and (someday) SVG formats. Control is provided over all aspects of drawing, e.g. line widths, colors, and fonts. A TeX-like syntax provides common mathematical symbols. Folks who write thousand-line Gri scripts usually start with something as simple as the following, which produces an auto-scaled graph. open file.dat read columns x y draw curve << GCC: 3.3 License: GPL Maintainer: Dan Kelley Homepage: http://gri.sourceforge.net �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri/DISCUSSION-error-levels�������������������������������������������������������������������������0000644�0001750�0001750�00000001441�13147557614�014045� 0����������������������������������������������������������������������������������������������������ustar �psg�����������������������������psg��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������This file is intended for the developers to discuss plans for error-level handling. When/if this is implemented in Gri, the present file will be removed from the CVS tree. Basic idea: have 3 levels of error tolerance, set by a commandline flag perhaps of the following form: -error_tolerance ERROR_LEVEL where ERROR_LEVEL = 0: stop executation if _any_ error is encountered ERROR_LEVEL = 1: stop executation if one or more level-1 errors is encountered ERROR_LEVEL = 2: stop executation if one or more level-2 errors is encountered, or if one or more level-1 errors is encountered LEVEL 0 ERROR LIST: - add items to this list - LEVEL 1 ERROR LIST: - add items to this list - LEVEL 2 ERROR LIST: - add items to this list - �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������