gri-2.12.23/000777 000767 000024 00000000000 11607310072 013075 5ustar00kelleystaff000000 000000 gri-2.12.23/aclocal.m4000644 000767 000024 00000076150 11605066211 014743 0ustar00kelleystaff000000 000000 # generated automatically by aclocal 1.10 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006 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_if(m4_PACKAGE_VERSION, [2.61],, [m4_fatal([this file was generated for autoconf 2.61. You have another version of autoconf. If you want to use that, you should regenerate the build system entirely.], [63])]) # Copyright (C) 2002, 2003, 2005, 2006 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.10' 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.10], [], [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 AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.10])dnl _AM_AUTOCONF_VERSION(m4_PACKAGE_VERSION)]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005 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], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006 # 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. # serial 8 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$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 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, 2000, 2001, 2002, 2003, 2004, 2005, 2006 # 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. # serial 9 # 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", "GCJ", or "OBJC". # 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 ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" 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'. 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 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 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in 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 ;; none) break ;; esac # 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. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} 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 sub/conftest.${OBJEXT-o} 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, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 # 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. #serial 3 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [for mf in $CONFIG_FILES; 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 10q "$mf" | grep '^#.*generated by automake' > /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"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //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' -e 's/\$U/'"$U"'/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, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006 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. # serial 12 # 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. # 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.60])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], [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], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [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) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. 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)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES(OBJC)], [define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) ]) # 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_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $1 | $1:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005 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 install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 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. # serial 2 # 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, 2002, 2003, 2005 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. # serial 3 # 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 done .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 # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi 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, 1999, 2000, 2001, 2003, 2004, 2005 # 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. # serial 5 # 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 supports --run. # If it does, 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 test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005, 2006 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_MKDIR_P # --------------- # Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, dnl while keeping a definition of mkdir_p for backward compatibility. dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of dnl Makefile.ins that do not define MKDIR_P, so we do our own dnl adjustment using top_builddir (which is defined more often than dnl MKDIR_P). AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl case $mkdir_p in [[\\/$]]* | ?:[[\\/]]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005 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. # serial 3 # _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], [AC_FOREACH([_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])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # 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. # serial 4 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # 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 ( 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 rm -f conftest.file 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 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)]) # Copyright (C) 2001, 2003, 2005 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 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 outputing VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 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. # serial 2 # _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. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. 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-2.12.23/AUTHORS000644 000767 000024 00000000310 11310756313 014136 0ustar00kelleystaff000000 000000 Dan 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-2.12.23/ChangeLog000644 000767 000024 00000033264 11310756313 014656 0ustar00kelleystaff000000 000000 2008-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-2.12.23/config.guess000755 000767 000024 00000127637 11354643364 015445 0ustar00kelleystaff000000 000000 #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 # Free Software Foundation, Inc. timestamp='2009-12-30' # 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 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., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, 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 Per Bothner. Please send patches (context # diff format) to and include a ChangeLog # entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # 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 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 (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 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 # 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 tupples: *-*-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 ;; *: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'` exit ;; 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:*:[456]) 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:*:*) case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 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-gnu`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/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix 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="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${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-gnu else echo ${UNAME_MACHINE}-unknown-linux-gnueabi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; i*86:Linux:*:*) LIBC=gnu eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu 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-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu 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-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu 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 ;; 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 case $UNAME_PROCESSOR in i386) eval $set_cc_for_build 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 UNAME_PROCESSOR="x86_64" fi fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac 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 ;; 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 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 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-2.12.23/config.sub000755 000767 000024 00000103445 11354643364 015077 0ustar00kelleystaff000000 000000 #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 # Free Software Foundation, Inc. timestamp='2010-01-22' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # 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 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., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, 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. # Please send patches to . Submit a context # diff and a properly formatted GNU ChangeLog entry. # # 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 (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 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-dietlibc | linux-newlib* | 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/'` ;; *) 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*) 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 \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | 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 \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nios | nios2 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | 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 | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | ubicom32 \ | v850 | v850e \ | we32k \ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | picochip) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-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-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | 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-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ | 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-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | 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-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile-* | tilegx-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ | 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 ;; 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) 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'm not sure what "Sysv32" means. Should this be sysv3.2? 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 ;; mingw32) basic_machine=i386-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-/'` ;; mvs) basic_machine=i370-ibm os=-mvs ;; 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 ;; 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) basic_machine=powerpc-unknown ;; ppc-*) 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) 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 ;; 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 ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; # This must be matched before tile*. tilegx*) basic_machine=tilegx-unknown os=-linux-gnu ;; tile*) basic_machine=tile-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 ;; 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* \ | -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* \ | -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* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-newlib* | -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 ;; -kaos*) os=-kaos ;; -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 ;; # 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 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) 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-2.12.23/configure000755 000767 000024 00000645677 11605066213 015034 0ustar00kelleystaff000000 000000 #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for gri 2.12.23. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006 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=: # Zsh 3.x and 4.x performs 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 # PATH needs CR # 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 # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false 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.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. 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 echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. 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 # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs 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 : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs 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_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell autoconf@gnu.org about your system, echo including any error possibly output before this echo message } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. 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" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # 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 } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi 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 fi echo >conf$$.file 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 -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' 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=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # 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 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, 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= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='gri' PACKAGE_TARNAME='gri' PACKAGE_VERSION='2.12.23' PACKAGE_STRING='gri 2.12.23' PACKAGE_BUGREPORT='' 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='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datarootdir datadir sysconfdir sharedstatedir localstatedir includedir oldincludedir docdir infodir htmldir dvidir pdfdir psdir libdir localedir mandir DEFS ECHO_C ECHO_N ECHO_T LIBS build_alias host_alias target_alias INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA am__isrc CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar build build_cpu build_vendor build_os host host_cpu host_vendor host_os RANLIB PROGS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP GREP EGREP AM_CXXFLAGS EXTRA_CFLAGS_TEMPLATE HAVE_CONVERT OS_HAS_POPT_TRUE OS_HAS_POPT_FALSE OS_IS_APPLE_OSX_TRUE OS_IS_APPLE_OSX_FALSE OS_IS_OSX_BUNDLE_TRUE OS_IS_OSX_BUNDLE_FALSE OS_IS_FREEBSD_TRUE OS_IS_FREEBSD_FALSE OS_IS_FINK_TRUE OS_IS_FINK_FALSE OS_IS_LINUX_REDHAT_TRUE OS_IS_LINUX_REDHAT_FALSE OS_IS_LINUX_DEBIAN_TRUE OS_IS_LINUX_DEBIAN_FALSE OS_IS_SOLARIS_TRUE OS_IS_SOLARIS_FALSE LIBOBJS LTLIBOBJS' ac_subst_files='' 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 # 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' 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=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_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=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_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=\$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 ;; -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_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=\$ac_optarg ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=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 ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && 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'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute directory names. 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 do eval ac_val=\$$ac_var case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } 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 echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 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 .` || { echo "$as_me: error: Working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # 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 -- "$0" || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X"$0" | 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 .." { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } 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.23 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] --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.23:";; esac cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --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 C/C++/Objective 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. _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" || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`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 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.23 generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 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 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.23, which was generated by GNU Autoconf 2.61. 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=. 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=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$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 ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export 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 cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX 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_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_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 cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" 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'; { (exit 1); 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 # 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 # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then set x "$CONFIG_SITE" elif test "x$prefix" != xNONE; then set x "$prefix/share/config.site" "$prefix/etc/config.site" else set x "$ac_default_prefix/share/config.site" \ "$ac_default_prefix/etc/config.site" fi shift for ac_site_file do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" 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. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 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,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 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 { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`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. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } 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 am__api_version='1.10' 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 { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } 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. { echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$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 ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done IFS=$as_save_IFS 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 { echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$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' { echo "$as_me:$LINENO: checking whether build environment is sane" >&5 echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6; } # Just in case sleep 1 echo timestamp > conftest.file # 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 ( 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 rm -f conftest.file 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". { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&5 echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&2;} { (exit 1); exit 1; }; } fi test "$2" = conftest.file ) then # Ok. : else { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! Check your system clock" >&5 echo "$as_me: error: newly created file is older than distributed files! Check your system clock" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } 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 $. echo might interpret backslashes. # By default was `s,x,x', remove it if useless. cat <<\_ACEOF >conftest.sed s/[\\$]/&&/g;s/;s,x,x,$// _ACEOF program_transform_name=`echo $program_transform_name | sed -f conftest.sed` rm -f conftest.sed # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi { echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5 echo $ECHO_N "checking for a thread-safe mkdir -p... $ECHO_C" >&6; } if test -z "$MKDIR_P"; then if test "${ac_cv_path_mkdir+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$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 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. test -d ./--version && rmdir ./--version MKDIR_P="$ac_install_sh -d" fi fi { echo "$as_me:$LINENO: result: $MKDIR_P" >&5 echo "${ECHO_T}$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac 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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_AWK+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $AWK" >&5 echo "${ECHO_T}$AWK" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$AWK" && break done { echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&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 { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } SET_MAKE= else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 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 { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} { (exit 1); exit 1; }; } 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.23' 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"} install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} # 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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $STRIP" >&5 echo "${ECHO_T}$STRIP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 echo "${ECHO_T}$ac_ct_STRIP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&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" # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. AMTAR=${AMTAR-"${am_missing_run}tar"} am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} { (exit 1); exit 1; }; } { echo "$as_me:$LINENO: checking build system type" >&5 echo $ECHO_N "checking build system type... $ECHO_C" >&6; } if test "${ac_cv_build+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 && { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 echo "$as_me: error: cannot guess build type; you must specify one" >&2;} { (exit 1); exit 1; }; } ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: result: $ac_cv_build" >&5 echo "${ECHO_T}$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 echo "$as_me: error: invalid value of canonical build" >&2;} { (exit 1); exit 1; }; };; 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 { echo "$as_me:$LINENO: checking host system type" >&5 echo $ECHO_N "checking host system type... $ECHO_C" >&6; } if test "${ac_cv_host+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { echo "$as_me:$LINENO: result: $ac_cv_host" >&5 echo "${ECHO_T}$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 echo "$as_me: error: invalid value of canonical host" >&2;} { (exit 1); exit 1; }; };; 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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $RANLIB" >&5 echo "${ECHO_T}$RANLIB" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 echo "${ECHO_T}$ac_ct_RANLIB" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi # 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. { echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$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 ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done IFS=$as_save_IFS 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 { echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$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' { echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&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 { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } SET_MAKE= else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$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" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO: checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out 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. { echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # # List of possible output files, starting from the most likely. # The algorithm is not robust to junk in `.', hence go to wildcards (a.*) # only as a last resort. b.out is created by i960 compilers. ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' # # The IRIX 6 linker writes into existing files which may not be # executable, retaining their permissions. Remove them first so a # subsequent execution test works. ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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 | *.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 { echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6; } if test -z "$ac_file"; then echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6; } { echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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 | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext { echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT { echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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 ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 { echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$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 { echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* 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" 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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) { echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6; } ;; xno) { echo "$as_me:$LINENO: result: unsupported" >&5 echo "${ECHO_T}unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; esac 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 done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi { echo "$as_me:$LINENO: result: $_am_result" >&5 echo "${ECHO_T}$_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='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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'. 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 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 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in 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 ;; none) break ;; esac # 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. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} 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 sub/conftest.${OBJEXT-o} 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 { echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 echo "${ECHO_T}$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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $CXX" >&5 echo "${ECHO_T}$CXX" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 echo "${ECHO_T}$ac_ct_CXX" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. echo "$as_me:$LINENO: checking for C++ compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; } if test "${ac_cv_cxx_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 { echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; } GXX=`test $ac_compiler_gnu = yes && echo yes` ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; } if test "${ac_cv_prog_cxx_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CXXFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 { echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 echo "${ECHO_T}$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= { echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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'. 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 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 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in 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 ;; none) break ;; esac # 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. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} 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 sub/conftest.${OBJEXT-o} 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 { echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 echo "${ECHO_T}$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 { echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6; } if test -z "$CXXCPP"; then if test "${ac_cv_prog_CXXCPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f 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 { echo "$as_me:$LINENO: result: $CXXCPP" >&5 echo "${ECHO_T}$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } 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 { echo "$as_me:$LINENO: checking for old C++ subroutine called string::remove" >&5 echo $ECHO_N "checking for old C++ subroutine called string::remove... $ECHO_C" >&6; } if test "${gri_cv_have_old_string+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _POSIX_SOURCE 1 #include int main () { string s("hi"); s.remove(0,1); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then gri_cv_have_old_string=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 gri_cv_have_old_string=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $gri_cv_have_old_string" >&5 echo "${ECHO_T}$gri_cv_have_old_string" >&6; } if test $gri_cv_have_old_string = yes ; then cat >>confdefs.h <<\_ACEOF #define HAVE_OLD_STRING 1 _ACEOF fi { echo "$as_me:$LINENO: checking for gcc compiler" >&5 echo $ECHO_N "checking for gcc compiler... $ECHO_C" >&6; } { echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Extract the first word of "grep ggrep" to use in msg output if test -z "$GREP"; then set dummy grep ggrep; ac_prog_name=$2 if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else 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" { test -f "$ac_path_GREP" && $as_test_x "$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 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" 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 ac_count=`expr $ac_count + 1` 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 fi GREP="$ac_cv_path_GREP" if test -z "$GREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 echo "${ECHO_T}$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else # Extract the first word of "egrep" to use in msg output if test -z "$EGREP"; then set dummy egrep; ac_prog_name=$2 if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else 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" { test -f "$ac_path_EGREP" && $as_test_x "$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 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" 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 ac_count=`expr $ac_count + 1` 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 fi EGREP="$ac_cv_path_EGREP" if test -z "$EGREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 -r conftest* if test $GCC = yes; then EXTRA_CFLAGS_TEMPLATE="$AM_CFLAGS -Wall" AM_CXXFLAGS="$AM_CXXFLAGS -Wall" fi { echo "$as_me:$LINENO: result: $GCC" >&5 echo "${ECHO_T}$GCC" >&6; } { echo "$as_me:$LINENO: checking for C++ compiler with new headers as of August 2002" >&5 echo $ECHO_N "checking for C++ compiler with new headers as of August 2002... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 -r conftest* if test $Cplusplusnew = yes; then AM_CXXFLAGS="$AM_CXXFLAGS -DCPLUSPLUSNEW" AM_CXXFLAGS="$AM_CXXFLAGS -fno-strength-reduce" fi { echo "$as_me:$LINENO: result: $Cplusplusnew" >&5 echo "${ECHO_T}$Cplusplusnew" >&6; } { echo "$as_me:$LINENO: checking for DEC cxx compiler" >&5 echo $ECHO_N "checking for DEC cxx compiler... $ECHO_C" >&6; } if test "${gri_cv_is_deccxx+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 -r conftest* fi { echo "$as_me:$LINENO: result: $gri_cv_is_deccxx" >&5 echo "${ECHO_T}$gri_cv_is_deccxx" >&6; } if test $gri_cv_is_deccxx = yes; then AM_CXXFLAGS="$AM_CXXFLAGS -D_ANSI_C_SOURCE" fi { echo "$as_me:$LINENO: checking for DEC alpha computer" >&5 echo $ECHO_N "checking for DEC alpha computer... $ECHO_C" >&6; } if test "${gri_cv_is_dec_alpha+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 -r conftest* fi { echo "$as_me:$LINENO: result: $gri_cv_is_dec_alpha" >&5 echo "${ECHO_T}$gri_cv_is_dec_alpha" >&6; } if test $gri_cv_is_dec_alpha = yes; then cat >>confdefs.h <<\_ACEOF #define IS_DEC_ALPHA 1 _ACEOF fi { echo "$as_me:$LINENO: checking for BeOS environment" >&5 echo $ECHO_N "checking for BeOS environment... $ECHO_C" >&6; } if test "${gri_cv_is_beos+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 -r conftest* fi { echo "$as_me:$LINENO: result: $gri_cv_is_beos" >&5 echo "${ECHO_T}$gri_cv_is_beos" >&6; } if test $gri_cv_is_beos = yes; then cat >>confdefs.h <<\_ACEOF #define OS_IS_BEOS 1 _ACEOF fi { echo "$as_me:$LINENO: checking for FreeBSD system" >&5 echo $ECHO_N "checking for FreeBSD system... $ECHO_C" >&6; } if test "${gri_cv_is_freebsd+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 -r conftest* fi { echo "$as_me:$LINENO: result: $gri_cv_is_freebsd" >&5 echo "${ECHO_T}$gri_cv_is_freebsd" >&6; } if test $gri_cv_is_freebsd = yes; then cat >>confdefs.h <<\_ACEOF #define IS_FREEBSD 1 _ACEOF fi { echo "$as_me:$LINENO: checking for OPENBSD system" >&5 echo $ECHO_N "checking for OPENBSD system... $ECHO_C" >&6; } if test "${gri_cv_is_openbsd+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 -r conftest* fi { echo "$as_me:$LINENO: result: $gri_cv_is_openbsd" >&5 echo "${ECHO_T}$gri_cv_is_openbsd" >&6; } if test $gri_cv_is_openbsd = yes; then cat >>confdefs.h <<\_ACEOF #define IS_OPENBSD 1 _ACEOF fi { echo "$as_me:$LINENO: checking for HPUX environment" >&5 echo $ECHO_N "checking for HPUX environment... $ECHO_C" >&6; } if test "${gri_cv_is_hpux+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 -r conftest* fi { echo "$as_me:$LINENO: result: $gri_cv_is_hpux" >&5 echo "${ECHO_T}$gri_cv_is_hpux" >&6; } if test $gri_cv_is_hpux = yes; then cat >>confdefs.h <<\_ACEOF #define OS_IS_HPUX 1 _ACEOF fi { echo "$as_me:$LINENO: checking for NetBSD system" >&5 echo $ECHO_N "checking for NetBSD system... $ECHO_C" >&6; } if test "${gri_cv_is_netbsd+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 -r conftest* fi { echo "$as_me:$LINENO: result: $gri_cv_is_netbsd" >&5 echo "${ECHO_T}$gri_cv_is_netbsd" >&6; } if test $gri_cv_is_netbsd = yes; then cat >>confdefs.h <<\_ACEOF #define IS_NETBSD 1 _ACEOF fi { echo "$as_me:$LINENO: checking for for Sun Microsystems computer" >&5 echo $ECHO_N "checking for for Sun Microsystems computer... $ECHO_C" >&6; } if test "${gri_cv_is_sun+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 -r conftest* fi { echo "$as_me:$LINENO: result: $gri_cv_is_sun" >&5 echo "${ECHO_T}$gri_cv_is_sun" >&6; } if test $gri_cv_is_sun = yes; then cat >>confdefs.h <<\_ACEOF #define IS_SUN 1 _ACEOF fi { echo "$as_me:$LINENO: checking for for IBM AIX computer with IBM compiler" >&5 echo $ECHO_N "checking for for IBM AIX computer with IBM compiler... $ECHO_C" >&6; } if test "${gri_cv_is_aix_with_ibm+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 -r conftest* fi { echo "$as_me:$LINENO: result: $gri_cv_is_aix_with_ibm" >&5 echo "${ECHO_T}$gri_cv_is_aix_with_ibm" >&6; } if test $gri_cv_is_aix_with_ibm = yes; then cat >>confdefs.h <<\_ACEOF #define IS_AIX_WITH_IBM 1 _ACEOF fi { echo "$as_me:$LINENO: checking for for mingw32 system" >&5 echo $ECHO_N "checking for for mingw32 system... $ECHO_C" >&6; } if test "${gri_cv_is_mingw32+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 -r conftest* fi { echo "$as_me:$LINENO: result: $gri_cv_is_mingw32" >&5 echo "${ECHO_T}$gri_cv_is_mingw32" >&6; } if test $gri_cv_is_mingw32 = yes; then cat >>confdefs.h <<\_ACEOF #define IS_MINGW32 1 _ACEOF fi { echo "$as_me:$LINENO: checking to see whether this machine is big endian or little endian" >&5 echo $ECHO_N "checking to see whether this machine is big endian or little endian... $ECHO_C" >&6; } if test "${gri_cv_endian_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then gri_cv_endian_type=little else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) gri_cv_endian_type=big fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext 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 { echo "$as_me:$LINENO: result: $gri_cv_endian_type" >&5 echo "${ECHO_T}$gri_cv_endian_type" >&6; } if test $gri_cv_endian_type = big; then cat >>confdefs.h <<\_ACEOF #define GRI_IS_BIG_ENDIAN 1 _ACEOF else cat >>confdefs.h <<\_ACEOF #define GRI_IS_BIG_ENDIAN 0 _ACEOF fi { echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 -r conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 -r 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF 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=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking for netcdf library" >&5 echo $ECHO_N "checking for netcdf library... $ECHO_C" >&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 cat >>confdefs.h <<\_ACEOF #define HAVE_LIBNETCDF 1 _ACEOF { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } fi done { echo "$as_me:$LINENO: result: done" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_HAVE_CONVERT+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_HAVE_CONVERT=""yes"" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $HAVE_CONVERT" >&5 echo "${ECHO_T}$HAVE_CONVERT" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 -r conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 -r 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi { echo "$as_me:$LINENO: checking for poptReadConfigFile in -lpopt" >&5 echo $ECHO_N "checking for poptReadConfigFile in -lpopt... $ECHO_C" >&6; } if test "${ac_cv_lib_popt_poptReadConfigFile+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpopt $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_popt_poptReadConfigFile=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_popt_poptReadConfigFile=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_popt_poptReadConfigFile" >&5 echo "${ECHO_T}$ac_cv_lib_popt_poptReadConfigFile" >&6; } if test $ac_cv_lib_popt_poptReadConfigFile = yes; 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 { echo "$as_me:$LINENO: checking for readline in -lreadline" >&5 echo $ECHO_N "checking for readline in -lreadline... $ECHO_C" >&6; } if test "${ac_cv_lib_readline_readline+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lreadline $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_readline_readline=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_readline_readline=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_readline_readline" >&5 echo "${ECHO_T}$ac_cv_lib_readline_readline" >&6; } if test $ac_cv_lib_readline_readline = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBREADLINE 1 _ACEOF LIBS="-lreadline $LIBS" fi { echo "$as_me:$LINENO: checking for pid_t" >&5 echo $ECHO_N "checking for pid_t... $ECHO_C" >&6; } if test "${ac_cv_type_pid_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef pid_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_pid_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_pid_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 echo "${ECHO_T}$ac_cv_type_pid_t" >&6; } if test $ac_cv_type_pid_t = yes; 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=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking whether getenv is declared" >&5 echo $ECHO_N "checking whether getenv is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_getenv+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { #ifndef getenv (void) getenv; #endif ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_getenv=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_getenv=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_getenv" >&5 echo "${ECHO_T}$ac_cv_have_decl_getenv" >&6; } if test $ac_cv_have_decl_getenv = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_GETENV 1 _ACEOF fi { echo "$as_me:$LINENO: checking whether drand48 is declared" >&5 echo $ECHO_N "checking whether drand48 is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_drand48+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { #ifndef drand48 (void) drand48; #endif ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_drand48=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_drand48=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_drand48" >&5 echo "${ECHO_T}$ac_cv_have_decl_drand48" >&6; } if test $ac_cv_have_decl_drand48 = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_DRAND48 1 _ACEOF 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 ;; *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for --enable-OSX" >&5 echo "$as_me: error: bad value ${enableval} for --enable-OSX" >&2;} { (exit 1); exit 1; }; } ;; 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 ;; *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for --enable-OSX_BUNDLE" >&5 echo "$as_me: error: bad value ${enableval} for --enable-OSX_BUNDLE" >&2;} { (exit 1); exit 1; }; } ;; 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 ;; *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for --enable-FreeBSD" >&5 echo "$as_me: error: bad value ${enableval} for --enable-FreeBSD" >&2;} { (exit 1); exit 1; }; } ;; 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 ;; *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for --enable-FINK" >&5 echo "$as_me: error: bad value ${enableval} for --enable-FINK" >&2;} { (exit 1); exit 1; }; } ;; 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 ;; *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for --enable-linux_redhat" >&5 echo "$as_me: error: bad value ${enableval} for --enable-linux_redhat" >&2;} { (exit 1); exit 1; }; } ;; 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 ;; *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for --enable-linux_debian" >&5 echo "$as_me: error: bad value ${enableval} for --enable-linux_debian" >&2;} { (exit 1); exit 1; }; } ;; 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 ;; *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for --enable-solaris" >&5 echo "$as_me: error: bad value ${enableval} for --enable-solaris" >&2;} { (exit 1); exit 1; }; } ;; 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_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_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 test "x$cache_file" != "x/dev/null" && { echo "$as_me:$LINENO: updating cache $cache_file" >&5 echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 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=' 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= 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=`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. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${OS_HAS_POPT_TRUE}" && test -z "${OS_HAS_POPT_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"OS_HAS_POPT\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"OS_HAS_POPT\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${OS_HAS_POPT_TRUE}" && test -z "${OS_HAS_POPT_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"OS_HAS_POPT\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"OS_HAS_POPT\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${OS_IS_APPLE_OSX_TRUE}" && test -z "${OS_IS_APPLE_OSX_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"OS_IS_APPLE_OSX\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"OS_IS_APPLE_OSX\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${OS_IS_OSX_BUNDLE_TRUE}" && test -z "${OS_IS_OSX_BUNDLE_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"OS_IS_OSX_BUNDLE\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"OS_IS_OSX_BUNDLE\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${OS_IS_FREEBSD_TRUE}" && test -z "${OS_IS_FREEBSD_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"OS_IS_FREEBSD\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"OS_IS_FREEBSD\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${OS_IS_FINK_TRUE}" && test -z "${OS_IS_FINK_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"OS_IS_FINK\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"OS_IS_FINK\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${OS_IS_LINUX_REDHAT_TRUE}" && test -z "${OS_IS_LINUX_REDHAT_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"OS_IS_LINUX_REDHAT\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"OS_IS_LINUX_REDHAT\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${OS_IS_LINUX_DEBIAN_TRUE}" && test -z "${OS_IS_LINUX_DEBIAN_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"OS_IS_LINUX_DEBIAN\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"OS_IS_LINUX_DEBIAN\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${OS_IS_SOLARIS_TRUE}" && test -z "${OS_IS_SOLARIS_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"OS_IS_SOLARIS\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"OS_IS_SOLARIS\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $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} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## 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=: # Zsh 3.x and 4.x performs 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 # PATH needs CR # 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 # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false 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.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. 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 echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. 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 # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. 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" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # 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 } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi 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 fi echo >conf$$.file 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 -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' 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=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # 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 # 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.23, which was generated by GNU Autoconf 2.61. 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 cat >>$CONFIG_STATUS <<_ACEOF # Files that config.status was made for. config_files="$ac_config_files" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit -q, --quiet 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 ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ gri config.status 2.12.23 configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2006 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' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. 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=$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 ) echo "$ac_cs_version"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) 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. -*) { echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$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 if \$ac_cs_recheck; then echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 CONFIG_SHELL=$SHELL export CONFIG_SHELL exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # 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" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; 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= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # # Set up the sed scripts for CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "$CONFIG_FILES"; then _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF SHELL!$SHELL$ac_delim PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim PACKAGE_NAME!$PACKAGE_NAME$ac_delim PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim PACKAGE_STRING!$PACKAGE_STRING$ac_delim PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim exec_prefix!$exec_prefix$ac_delim prefix!$prefix$ac_delim program_transform_name!$program_transform_name$ac_delim bindir!$bindir$ac_delim sbindir!$sbindir$ac_delim libexecdir!$libexecdir$ac_delim datarootdir!$datarootdir$ac_delim datadir!$datadir$ac_delim sysconfdir!$sysconfdir$ac_delim sharedstatedir!$sharedstatedir$ac_delim localstatedir!$localstatedir$ac_delim includedir!$includedir$ac_delim oldincludedir!$oldincludedir$ac_delim docdir!$docdir$ac_delim infodir!$infodir$ac_delim htmldir!$htmldir$ac_delim dvidir!$dvidir$ac_delim pdfdir!$pdfdir$ac_delim psdir!$psdir$ac_delim libdir!$libdir$ac_delim localedir!$localedir$ac_delim mandir!$mandir$ac_delim DEFS!$DEFS$ac_delim ECHO_C!$ECHO_C$ac_delim ECHO_N!$ECHO_N$ac_delim ECHO_T!$ECHO_T$ac_delim LIBS!$LIBS$ac_delim build_alias!$build_alias$ac_delim host_alias!$host_alias$ac_delim target_alias!$target_alias$ac_delim INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim INSTALL_DATA!$INSTALL_DATA$ac_delim am__isrc!$am__isrc$ac_delim CYGPATH_W!$CYGPATH_W$ac_delim PACKAGE!$PACKAGE$ac_delim VERSION!$VERSION$ac_delim ACLOCAL!$ACLOCAL$ac_delim AUTOCONF!$AUTOCONF$ac_delim AUTOMAKE!$AUTOMAKE$ac_delim AUTOHEADER!$AUTOHEADER$ac_delim MAKEINFO!$MAKEINFO$ac_delim install_sh!$install_sh$ac_delim STRIP!$STRIP$ac_delim INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim mkdir_p!$mkdir_p$ac_delim AWK!$AWK$ac_delim SET_MAKE!$SET_MAKE$ac_delim am__leading_dot!$am__leading_dot$ac_delim AMTAR!$AMTAR$ac_delim am__tar!$am__tar$ac_delim am__untar!$am__untar$ac_delim build!$build$ac_delim build_cpu!$build_cpu$ac_delim build_vendor!$build_vendor$ac_delim build_os!$build_os$ac_delim host!$host$ac_delim host_cpu!$host_cpu$ac_delim host_vendor!$host_vendor$ac_delim host_os!$host_os$ac_delim RANLIB!$RANLIB$ac_delim PROGS!$PROGS$ac_delim CC!$CC$ac_delim CFLAGS!$CFLAGS$ac_delim LDFLAGS!$LDFLAGS$ac_delim CPPFLAGS!$CPPFLAGS$ac_delim ac_ct_CC!$ac_ct_CC$ac_delim EXEEXT!$EXEEXT$ac_delim OBJEXT!$OBJEXT$ac_delim DEPDIR!$DEPDIR$ac_delim am__include!$am__include$ac_delim am__quote!$am__quote$ac_delim AMDEP_TRUE!$AMDEP_TRUE$ac_delim AMDEP_FALSE!$AMDEP_FALSE$ac_delim AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim CCDEPMODE!$CCDEPMODE$ac_delim am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim CXX!$CXX$ac_delim CXXFLAGS!$CXXFLAGS$ac_delim ac_ct_CXX!$ac_ct_CXX$ac_delim CXXDEPMODE!$CXXDEPMODE$ac_delim am__fastdepCXX_TRUE!$am__fastdepCXX_TRUE$ac_delim am__fastdepCXX_FALSE!$am__fastdepCXX_FALSE$ac_delim CXXCPP!$CXXCPP$ac_delim GREP!$GREP$ac_delim EGREP!$EGREP$ac_delim AM_CXXFLAGS!$AM_CXXFLAGS$ac_delim EXTRA_CFLAGS_TEMPLATE!$EXTRA_CFLAGS_TEMPLATE$ac_delim HAVE_CONVERT!$HAVE_CONVERT$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF CEOF$ac_eof _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF OS_HAS_POPT_TRUE!$OS_HAS_POPT_TRUE$ac_delim OS_HAS_POPT_FALSE!$OS_HAS_POPT_FALSE$ac_delim OS_IS_APPLE_OSX_TRUE!$OS_IS_APPLE_OSX_TRUE$ac_delim OS_IS_APPLE_OSX_FALSE!$OS_IS_APPLE_OSX_FALSE$ac_delim OS_IS_OSX_BUNDLE_TRUE!$OS_IS_OSX_BUNDLE_TRUE$ac_delim OS_IS_OSX_BUNDLE_FALSE!$OS_IS_OSX_BUNDLE_FALSE$ac_delim OS_IS_FREEBSD_TRUE!$OS_IS_FREEBSD_TRUE$ac_delim OS_IS_FREEBSD_FALSE!$OS_IS_FREEBSD_FALSE$ac_delim OS_IS_FINK_TRUE!$OS_IS_FINK_TRUE$ac_delim OS_IS_FINK_FALSE!$OS_IS_FINK_FALSE$ac_delim OS_IS_LINUX_REDHAT_TRUE!$OS_IS_LINUX_REDHAT_TRUE$ac_delim OS_IS_LINUX_REDHAT_FALSE!$OS_IS_LINUX_REDHAT_FALSE$ac_delim OS_IS_LINUX_DEBIAN_TRUE!$OS_IS_LINUX_DEBIAN_TRUE$ac_delim OS_IS_LINUX_DEBIAN_FALSE!$OS_IS_LINUX_DEBIAN_FALSE$ac_delim OS_IS_SOLARIS_TRUE!$OS_IS_SOLARIS_TRUE$ac_delim OS_IS_SOLARIS_FALSE!$OS_IS_SOLARIS_FALSE$ac_delim LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 18; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b end _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF :end s/|#_!!_#|//g CEOF$ac_eof _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ 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[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF fi # test -n "$CONFIG_FILES" for ac_tag in :F $CONFIG_FILES :C $CONFIG_COMMANDS do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 echo "$as_me: error: Invalid tag $ac_tag." >&2;} { (exit 1); exit 1; }; };; :[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="$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 || { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac ac_file_inputs="$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 "`IFS=: echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} fi case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin";; 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 || 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" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`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 || 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" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`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 # 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= case `sed -n '/datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p ' $ac_file_inputs` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF 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 sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s&@configure_input@&$configure_input&;t t s&@top_builddir@&$ac_top_builddir_sub&;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 " $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 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 "$tmp/stdin" case $ac_file in -) cat "$tmp/out"; rm -f "$tmp/out";; *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; esac ;; :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; 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 10q "$mf" | grep '^#.*generated by automake' > /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 || 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"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //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' -e 's/\$U/'"$U"'/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 || 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 case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`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 || 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" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # 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 || { (exit 1); exit 1; } fi gri-2.12.23/configure.ac000644 000767 000024 00000034171 11605066021 015365 0ustar00kelleystaff000000 000000 AC_PREREQ(2.50) AC_INIT(gri, 2.12.23) 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-2.12.23/COPYING000644 000767 000024 00000104513 11310756313 014133 0ustar00kelleystaff000000 000000 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-2.12.23/copyright.txt000644 000767 000024 00000000035 11310756313 015643 0ustar00kelleystaff000000 000000 (c) 1991-2009 Dan E. Kelley. gri-2.12.23/debian/000777 000767 000024 00000000000 11607310073 014320 5ustar00kelleystaff000000 000000 gri-2.12.23/depcomp000755 000767 000024 00000027533 11310756313 014463 0ustar00kelleystaff000000 000000 #! /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-2.12.23/doc/000777 000767 000024 00000000000 11607310072 013642 5ustar00kelleystaff000000 000000 gri-2.12.23/gri.spec000644 000767 000024 00000046717 11310756313 014550 0ustar00kelleystaff000000 000000 Summary: A language for scientific illustration %define griversion 2.12.20 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.20 - in development * 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-2.12.23/grilogo.gif000644 000767 000024 00000000531 11310756313 015224 0ustar00kelleystaff000000 000000 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-2.12.23/INSTALL000644 000767 000024 00000001746 11403701436 014134 0ustar00kelleystaff000000 000000 If 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-2.12.23/install-sh000755 000767 000024 00000011243 11310756313 015101 0ustar00kelleystaff000000 000000 #!/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-2.12.23/license.txt000644 000767 000024 00000001260 11310756313 015256 0ustar00kelleystaff000000 000000 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-2.12.23/Makefile.am000644 000767 000024 00000000450 11403217224 015123 0ustar00kelleystaff000000 000000 ## 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-2.12.23/Makefile.in000644 000767 000024 00000044402 11605066212 015144 0ustar00kelleystaff000000 000000 # Makefile.in generated by automake 1.10 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(top_srcdir)/configure AUTHORS COPYING \ ChangeLog INSTALL NEWS THANKS config.guess config.sub depcomp \ install-sh missing mkinstalldirs texinfo.tex 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) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-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 uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print VPATH = @srcdir@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CXXFLAGS = @AM_CXXFLAGS@ 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_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@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ # gri: Makefile.am srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ 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: @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \ cd $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile .PRECIOUS: 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) cd $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) # 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. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; 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; \ (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" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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 || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ distdir) \ || exit 1; \ fi; \ done -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -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__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__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) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && cd $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(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 $(am__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: @cd $(distuninstallcheck_dir) \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-exec-am: install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive 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: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am am--refresh check check-am clean clean-generic \ ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ dist-shar dist-tarZ 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-recursive uninstall uninstall-am # 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-2.12.23/missing000755 000767 000024 00000024036 11310756313 014500 0ustar00kelleystaff000000 000000 #! /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-2.12.23/mkinstalldirs000755 000767 000024 00000003704 11310756313 015706 0ustar00kelleystaff000000 000000 #! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # 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-2.12.23/NEWS000644 000767 000024 00000000115 11310756313 013570 0ustar00kelleystaff000000 000000 For information about changes to Gri, please see the manual in doc/gri.texi. gri-2.12.23/README000644 000767 000024 00000003547 11353143221 013760 0ustar00kelleystaff000000 000000 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 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. A less common case is to have received Gri from the CVS server. This is the method used by co-developers or packagers, and also by folks who are testing pre-release versions. In this case, you need to type aclocal autoconf automake 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-2010 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-2010 Peter S. Galbraith Gri and gri-mode.el are distributed under GPLv3 license or later; see COPYING. gri-2.12.23/README-linux-redhat000644 000767 000024 00000002670 11310756313 016363 0ustar00kelleystaff000000 000000 What 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-2.12.23/README-SunOS5000644 000767 000024 00000002731 11310756313 015051 0ustar00kelleystaff000000 000000 Compiling 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-2.12.23/src/000777 000767 000024 00000000000 11607310072 013664 5ustar00kelleystaff000000 000000 gri-2.12.23/texinfo.tex000644 000767 000024 00000661766 11310756313 015320 0ustar00kelleystaff000000 000000 % 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{2003-05-04.08} % % Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 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 2, 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 texinfo.tex file; see the file COPYING. If not, write % to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, % Boston, MA 02111-1307, USA. % % In other words, you are welcome to use, share and improve this program. % You are forbidden to forbid anyone else to use, share and improve % what you give them. Help stamp out software-hoarding! % % Please try the latest version of texinfo.tex before submitting bug % reports; you can get the latest version from: % ftp://ftp.gnu.org/gnu/texinfo/texinfo.tex % (and all GNU mirrors, see http://www.gnu.org/order/ftp.html) % ftp://tug.org/tex/texinfo.tex % (and all CTAN mirrors, see http://www.ctan.org), % and /home/gd/gnu/doc/texinfo.tex on the GNU machines. % % The GNU Texinfo home page is http://www.gnu.org/software/texinfo. % % The texinfo.tex in any given Texinfo 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. \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} \message{Basics,} \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\ptexgtr=> \let\ptexhat=^ \let\ptexi=\i \let\ptexindent=\indent \let\ptexlbrace=\{ \let\ptexless=< \let\ptexplus=+ \let\ptexrbrace=\} \let\ptexslash=\/ \let\ptexstar=\* \let\ptext=\t % If this character appears in an error message or help string, it % starts a new line in the output. \newlinechar = `^^J % 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\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\putwordDeftypevar\undefined\gdef\putwordDeftypevar{Variable}\fi \ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi \ifx\putwordDeftypefun\undefined\gdef\putwordDeftypefun{Function}\fi % In some macros, we cannot use the `\? notation---the left quote is % in some cases the escape char. \chardef\colonChar = `\: \chardef\commaChar = `\, \chardef\dotChar = `\. \chardef\equalChar = `\= \chardef\exclamChar= `\! \chardef\questChar = `\? \chardef\semiChar = `\; \chardef\spaceChar = `\ % \chardef\underChar = `\_ % Ignore a token. % \def\gobble#1{} % True if #1 is the empty string, i.e., called like `\ifempty{}'. % \def\ifempty#1{\ifemptyx #1\emptymarkA\emptymarkB}% \def\ifemptyx#1#2\emptymarkB{\ifx #1\emptymarkA}% % Hyphenation fixes. \hyphenation{ap-pen-dix} \hyphenation{eshell} \hyphenation{mini-buf-fer mini-buf-fers} \hyphenation{time-stamp} \hyphenation{white-space} % Margin to add to right of even pages, to left of odd pages. \newdimen\bindingoffset \newdimen\normaloffset \newdimen\pagewidth \newdimen\pageheight % 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\undefined\else % etex gives us more logging \tracingscantokens1 \tracingifs1 \tracinggroups1 \tracingnesting2 \tracingassigns1 \fi \tracingcommands3 % 3 gives us more in etex \errorcontextlines\maxdimen }% % 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} % For @cropmarks command. % 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 % 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). \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% \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. % \escapechar = `\\ % use backslash in output files. \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. \shipout\vbox{% % Do this early so pdf references go to the beginning of the page. \ifpdfmakepagedest \pdfmkdest{\the\pageno} \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 \oddfootingxxx.) % The \baselineskip=24pt in plain's \makefootline has no effect. \vskip 2\baselineskip \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 \normalturnoffactive \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 \unvbox#1 \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#1{% \let\next = #1% \begingroup \obeylines \futurelet\temp\parseargx } % If the next token is an obeyed space (from an @example environment or % the like), remove it and recurse. Otherwise, we're done. \def\parseargx{% % \obeyedspace is defined far below, after the definition of \sepspaces. \ifx\obeyedspace\temp \expandafter\parseargdiscardspace \else \expandafter\parseargline \fi } % Remove a single space (as the delimiter token to the macro call). {\obeyspaces % \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} {\obeylines % \gdef\parseargline#1^^M{% \endgroup % End of the group started in \parsearg. % % First remove any @c comment, then any @comment. % Result of each macro is put in \toks0. \argremovec #1\c\relax % \expandafter\argremovecomment \the\toks0 \comment\relax % % % Call the caller's macro, saved as \next in \parsearg. \expandafter\next\expandafter{\the\toks0}% }% } % Since all \c{,omment} does is throw away the argument, we can let TeX % do that for us. The \relax here is matched by the \relax in the call % in \parseargline; it could be more or less anything, its purpose is % just to delimit the argument to the \c. \def\argremovec#1\c#2\relax{\toks0 = {#1}} \def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} % \argremovec{,omment} might leave us with trailing spaces, though; e.g., % @end itemize @c foo % will have two active spaces as part of the argument with the % `itemize'. Here we remove all active spaces from #1, and assign the % result to \toks0. % % This loses if there are any *other* active characters besides spaces % in the argument -- _ ^ +, for example -- since they get expanded. % Fortunately, Texinfo does not define any such commands. (If it ever % does, the catcode of the characters in questionwill have to be changed % here.) But this means we cannot call \removeactivespaces as part of % \argremovec{,omment}, since @c uses \parsearg, and thus the argument % that \parsearg gets might well have any character at all in it. % \def\removeactivespaces#1{% \begingroup \ignoreactivespaces \edef\temp{#1}% \global\toks0 = \expandafter{\temp}% \endgroup } % Change the active space to expand to nothing. % \begingroup \obeyspaces \gdef\ignoreactivespaces{\obeyspaces\let =\empty} \endgroup \def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} %% These are used to keep @begin/@end levels from running away %% Call \inENV within environments (after a \begingroup) \newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} \def\ENVcheck{% \ifENV\errmessage{Still within an environment; press RETURN to continue} \endgroup\fi} % This is not perfect, but it should reduce lossage % @begin foo is the same as @foo, for now. \newhelp\EMsimple{Press RETURN to continue.} \outer\def\begin{\parsearg\beginxxx} \def\beginxxx #1{% \expandafter\ifx\csname #1\endcsname\relax {\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else \csname #1\endcsname\fi} % @end foo executes the definition of \Efoo. % \def\end{\parsearg\endxxx} \def\endxxx #1{% \removeactivespaces{#1}% \edef\endthing{\the\toks0}% % \expandafter\ifx\csname E\endthing\endcsname\relax \expandafter\ifx\csname \endthing\endcsname\relax % There's no \foo, i.e., no ``environment'' foo. \errhelp = \EMsimple \errmessage{Undefined command `@end \endthing'}% \else \unmatchedenderror\endthing \fi \else % Everything's ok; the right environment has been started. \csname E\endthing\endcsname \fi } % There is an environment #1, but it hasn't been started. Give an error. % \def\unmatchedenderror#1{% \errhelp = \EMsimple \errmessage{This `@end #1' doesn't have a matching `@#1'}% } % Define the control sequence \E#1 to give an unmatched @end error. % \def\defineunmatchedend#1{% \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% } %% Simple single-character @ commands % @@ prints an @ % Kludge this until the fonts are right (grr). \def\@{{\tt\char64}} % This is turned off because it was never documented % and you can use @w{...} around a quote to suppress ligatures. %% Define @` and @' to be the same as ` and ' %% but suppressing ligatures. %\def\`{{`}} %\def\'{{'}} % Used to generate quoted braces. \def\mylbrace {{\tt\char123}} \def\myrbrace {{\tt\char125}} \let\{=\mylbrace \let\}=\myrbrace \begingroup % Definitions to produce \{ and \} commands for indices, % and @{ and @} for the aux file. \catcode`\{ = \other \catcode`\} = \other \catcode`\[ = 1 \catcode`\] = 2 \catcode`\! = 0 \catcode`\\ = \other !gdef!lbracecmd[\{]% !gdef!rbracecmd[\}]% !gdef!lbraceatcmd[@{]% !gdef!rbraceatcmd[@}]% !endgroup % Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent % Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. \let\, = \c \let\dotaccent = \. \def\ringaccent#1{{\accent23 #1}} \let\tieaccent = \t \let\ubaraccent = \b \let\udotaccent = \d % Other special characters: @questiondown @exclamdown % Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. \def\questiondown{?`} \def\exclamdown{!`} % Dotless i and dotless j, used for accents. \def\imacro{i} \def\jmacro{j} \def\dotless#1{% \def\temp{#1}% \ifx\temp\imacro \ptexi \else\ifx\temp\jmacro \j \else \errmessage{@dotless can be used only with i or j}% \fi\fi } % 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\*{\hfil\break\hbox{}\ignorespaces} % @/ allows a line break. \let\/=\allowbreak % @. is an end-of-sentence period. \def\.{.\spacefactor=3000 } % @! is an end-of-sentence bang. \def\!{!\spacefactor=3000 } % @? is an end-of-sentence query. \def\?{?\spacefactor=3000 } % @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} % \def\group{\begingroup \ifnum\catcode13=\active \else \errhelp = \groupinvalidhelp \errmessage{@group invalid in context where filling is enabled}% \fi % % The \vtop we start below 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. (See p.82 of % the TeXbook.) Thus, space below is not quite equal to space % above. But it's pretty close. \def\Egroup{% \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 \copy\groupbox \endgroup % End the \group. }% % \setbox\groupbox = \vtop\bgroup % We have to put a strut on the last line in case the @group is in % the midst of an example, rather than completely enclosing it. % Otherwise, the interline space between the last line of the group % and the first line afterwards is too small. But we can't put the % strut in \Egroup, since there it would be on a line by itself. % Hence this just inserts a strut at the beginning of each line. \everypar = {\strut}% % % Since we have a strut on every line, we don't need any of TeX's % normal interline spacing. \offinterlineskip % % OK, but now we have to do something about blank % lines in the input in @example-like environments, which normally % just turn into \lisppar, which will insert no space now that we've % turned off the interline space. Simplest is to make them be an % empty paragraph. \ifx\par\lisppar \edef\par{\leavevmode \par}% % % Reset ^^M's definition to new definition of \par. \obeylines \fi % % 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 } % % 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 \def\need{\parsearg\needx} % Old definition--didn't work. %\def\needx #1{\par % %% This method tries to make TeX break the page naturally %% if the depth of the box does not fit. %{\baselineskip=0pt% %\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak %\prevdepth=-1000pt %}} \def\needx#1{% % 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 \let\br = \par % @dots{} output an ellipsis using the current font. % We do .5em per period so that it has the same spacing in a typewriter % font as three actual period characters. % \def\dots{% \leavevmode \hbox to 1.5em{% \hskip 0pt plus 0.25fil minus 0.25fil .\hss.\hss.% \hskip 0pt plus 0.5fil minus 0.5fil }% } % @enddots{} is an end-of-sentence ellipsis. % \def\enddots{% \leavevmode \hbox to 2em{% \hskip 0pt plus 0.25fil minus 0.25fil .\hss.\hss.\hss.% \hskip 0pt plus 0.5fil minus 0.5fil }% \spacefactor=3000 } % @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. \def\exdent{\parsearg\exdentyyy} \def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} % This defn is used inside nofill environments such as @example. \def\nofillexdent{\parsearg\nofillexdentyyy} \def\nofillexdentyyy #1{{\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'. % \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 } % @include file insert text of that file as input. % Allow normal characters that we make active in the argument (a file name). \def\include{\begingroup \catcode`\\=\other \catcode`~=\other \catcode`^=\other \catcode`_=\other \catcode`|=\other \catcode`<=\other \catcode`>=\other \catcode`+=\other \parsearg\includezzz} % Restore active chars for included file. \def\includezzz#1{\endgroup\begingroup % Read the included file in a group so nested @include's work. \def\thisfile{#1}% \let\value=\expandablevalue \input\thisfile \endgroup} \def\thisfile{} % @center line % outputs that line, centered. % \def\center{\parsearg\docenter} \def\docenter#1{{% \ifhmode \hfil\break \fi \advance\hsize by -\leftskip \advance\hsize by -\rightskip \line{\hfil \ignorespaces#1\unskip \hfil}% \ifhmode \break \fi }} % @sp n outputs n lines of vertical space \def\sp{\parsearg\spxxx} \def\spxxx #1{\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} % \def\paragraphindent{\parsearg\doparagraphindent} \def\doparagraphindent#1{% \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. \def\exampleindent{\parsearg\doexampleindent} \def\doexampleindent#1{% \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 indentat 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} \newdimen\currentparindent % \def\insertword{insert} % \def\firstparagraphindent{\parsearg\dofirstparagraphindent} \def\dofirstparagraphindent#1{% \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{% \global\let\indent=\ptexindent \global\everypar = {}% }% \global\everypar = {% \kern-\parindent \global\let\indent=\ptexindent \global\everypar = {}% }% }% % @asis just yields its argument. Used with @table, for example. % \def\asis#1{#1} % @math outputs its argument in math mode. % We don't use $'s directly in the definition of \math because we need % to set catcodes according to plain TeX first, to allow for subscripts, % superscripts, special math chars, etc. % \let\implicitmath = $%$ font-lock fix % % One complication: _ usually means subscripts, but it could also mean % an actual _ character, as in @math{@var{some_variable} + 1}. So make % _ within @math be active (mathcode "8000), and distinguish by seeing % if the current family is \slfam, which is what @var uses. % {\catcode\underChar = \active \gdef\mathunderscore{% \catcode\underChar=\active \def_{\ifnum\fam=\slfam \_\else\sb\fi}% }} % % Another complication: we want \\ (and @\) to output a \ character. % FYI, plain.tex uses \\ as a temporary control sequence (why?), but % this is not advertised and we don't care. Texinfo does not % otherwise define @\. % % The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. \def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} % \def\math{% \tex \mathcode`\_="8000 \mathunderscore \let\\ = \mathbackslash \mathactive \implicitmath\finishmath} \def\finishmath#1{#1\implicitmath\Etex} % 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 set the catcodes (such as @item or @section). % { \catcode`^ = \active \catcode`< = \active \catcode`> = \active \catcode`+ = \active \gdef\mathactive{% \let^ = \ptexhat \let< = \ptexless \let> = \ptexgtr \let+ = \ptexplus } } % @bullet and @minus need the same treatment as @math, just above. \def\bullet{\implicitmath\ptexbullet\implicitmath} \def\minus{\implicitmath-\implicitmath} % @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{% \iflinks \readauxfile \fi % \openindices needs to do some work in any case. \openindices \fixbackslash % Turn off hack to swallow `\input texinfo'. \global\let\setfilename=\comment % Ignore extra @setfilename cmds. % % If texinfo.cnf is present on the system, read it. % Useful for site-wide @afourpaper, etc. % Just to be on the safe side, close the input stream before the \input. \openin 1 texinfo.cnf \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi \closein1 \temp % \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 \ifx\pdfoutput\undefined \pdffalse \let\pdfmkdest = \gobble \let\pdfurl = \gobble \let\endlink = \relax \let\linkcolor = \relax \let\pdfmakeoutlines = \relax \else \pdftrue \pdfoutput = 1 \input pdfcolor \def\dopdfimage#1#2#3{% \def\imagewidth{#2}% \def\imageheight{#3}% % without \immediate, 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 \ifx\empty\imagewidth\else width \imagewidth \fi \ifx\empty\imageheight\else height \imageheight \fi \ifnum\pdftexversion<13 #1.pdf% \else {#1.pdf}% \fi \ifnum\pdftexversion < 14 \else \pdfrefximage \pdflastximage \fi} \def\pdfmkdest#1{{\normalturnoffactive \pdfdest name{#1} xyz}} \def\pdfmkpgn#1{#1} \let\linkcolor = \Blue % was Cyan, but that seems light? \def\endlink{\Black\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 by1 \expandafter\xdef\csname#1\endcsname{\the\tempnum}} \def\pdfmakeoutlines{{% \openin 1 \jobname.toc \ifeof 1\else\begingroup \closein 1 % Thanh's hack / proper braces in bookmarks \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace % \def\chapentry ##1##2##3{} \def\secentry ##1##2##3##4{\advancenumber{chap##2}} \def\subsecentry ##1##2##3##4##5{\advancenumber{sec##2.##3}} \def\subsubsecentry ##1##2##3##4##5##6{\advancenumber{subsec##2.##3.##4}} \let\appendixentry = \chapentry \let\unnumbchapentry = \chapentry \let\unnumbsecentry = \secentry \let\unnumbsubsecentry = \subsecentry \let\unnumbsubsubsecentry = \subsubsecentry \input \jobname.toc \def\chapentry ##1##2##3{% \pdfoutline goto name{\pdfmkpgn{##3}}count-\expnumber{chap##2}{##1}} \def\secentry ##1##2##3##4{% \pdfoutline goto name{\pdfmkpgn{##4}}count-\expnumber{sec##2.##3}{##1}} \def\subsecentry ##1##2##3##4##5{% \pdfoutline goto name{\pdfmkpgn{##5}}count-\expnumber{subsec##2.##3.##4}{##1}} \def\subsubsecentry ##1##2##3##4##5##6{% \pdfoutline goto name{\pdfmkpgn{##6}}{##1}} \let\appendixentry = \chapentry \let\unnumbchapentry = \chapentry \let\unnumbsecentry = \secentry \let\unnumbsubsecentry = \subsecentry \let\unnumbsubsubsecentry = \subsubsecentry % % Make special characters normal for writing to the pdf file. % \indexnofonts \let\tt=\relax \turnoffactive \input \jobname.toc \endgroup\fi }} \def\makelinks #1,{% \def\params{#1}\def\E{END}% \ifx\params\E \let\nextmakelinks=\relax \else \let\nextmakelinks=\makelinks \ifnum\lnkcount>0,\fi \picknum{#1}% \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{\the\pgn}}% \linkcolor #1% \advance\lnkcount by 1% \endlink \fi \nextmakelinks } \def\picknum#1{\expandafter\pn#1} \def\pn#1{% \def\p{#1}% \ifx\p\lbrace \let\nextpn=\ppn \else \let\nextpn=\ppnn \def\first{#1} \fi \nextpn } \def\ppn#1{\pgn=#1\gobble} \def\ppnn{\pgn=\first} \def\pdfmklnk#1{\lnkcount=0\makelinks #1,END,} \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} \def\skipspaces#1{\def\PP{#1}\def\D{|}% \ifx\PP\D\let\nextsp\relax \else\let\nextsp\skipspaces \ifx\p\space\else\addtokens{\filename}{\PP}% \advance\filenamelength by 1 \fi \fi \nextsp} \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax} \ifnum\pdftexversion < 14 \let \startlink \pdfannotlink \else \let \startlink \pdfstartlink \fi \def\pdfurl#1{% \begingroup \normalturnoffactive\def\@{@}% \let\value=\expandablevalue \leavevmode\Red \startlink attr{/Border [0 0 0]}% user{/Subtype /Link /A << /S /URI /URI (#1) >>}% % #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| \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}} \linkcolor #1\endlink} \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} \fi % \ifx\pdfoutput \message{fonts,} % Font-change commands. % Texinfo sort of supports the sans serif font style, which plain TeX does not. % So we set up a \sf analogous to plain's \rm, etc. \newfam\sffam \def\sf{\fam=\sffam \tensf} \let\li = \sf % Sometimes we call it \li, not \sf. % We don't need math for this one. \def\ttsl{\tenttsl} % Default leading. \newdimen\textleading \textleading = 13.2pt % 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} % \def\setleading#1{% \normalbaselineskip = #1\relax \normallineskip = \lineskipfactor\normalbaselineskip \normalbaselines \setbox\strutbox =\hbox{% \vrule width0pt height\strutheightpercent\baselineskip depth \strutdepthpercent \baselineskip }% } % Set the font macro #1 to the font named #2, adding on the % specified font prefix (normally `cm'). % #3 is the font's design size, #4 is a scale factor \def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4} % Use cm as the default font prefix. % To specify the font prefix, you must define \fontprefix % before you read in texinfo.tex. \ifx\fontprefix\undefined \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} \newcount\mainmagstep \ifx\bigger\relax % not really supported. \mainmagstep=\magstep1 \setfont\textrm\rmshape{12}{1000} \setfont\texttt\ttshape{12}{1000} \else \mainmagstep=\magstephalf \setfont\textrm\rmshape{10}{\mainmagstep} \setfont\texttt\ttshape{10}{\mainmagstep} \fi % Instead of cmb10, you may want to use cmbx10. % cmbx10 is a prettier font on its own, but cmb10 % looks better when embedded in a line with cmr10 % (in Bob's opinion). \setfont\textbf\bfshape{10}{\mainmagstep} \setfont\textit\itshape{10}{\mainmagstep} \setfont\textsl\slshape{10}{\mainmagstep} \setfont\textsf\sfshape{10}{\mainmagstep} \setfont\textsc\scshape{10}{\mainmagstep} \setfont\textttsl\ttslshape{10}{\mainmagstep} \font\texti=cmmi10 scaled \mainmagstep \font\textsy=cmsy10 scaled \mainmagstep % A few fonts for @defun, etc. \setfont\defbf\bxshape{10}{\magstep1} %was 1314 \setfont\deftt\ttshape{10}{\magstep1} \def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} % Fonts for indices, footnotes, small examples (9pt). \setfont\smallrm\rmshape{9}{1000} \setfont\smalltt\ttshape{9}{1000} \setfont\smallbf\bfshape{10}{900} \setfont\smallit\itshape{9}{1000} \setfont\smallsl\slshape{9}{1000} \setfont\smallsf\sfshape{9}{1000} \setfont\smallsc\scshape{10}{900} \setfont\smallttsl\ttslshape{10}{900} \font\smalli=cmmi9 \font\smallsy=cmsy9 % Fonts for small examples (8pt). \setfont\smallerrm\rmshape{8}{1000} \setfont\smallertt\ttshape{8}{1000} \setfont\smallerbf\bfshape{10}{800} \setfont\smallerit\itshape{8}{1000} \setfont\smallersl\slshape{8}{1000} \setfont\smallersf\sfshape{8}{1000} \setfont\smallersc\scshape{10}{800} \setfont\smallerttsl\ttslshape{10}{800} \font\smalleri=cmmi8 \font\smallersy=cmsy8 % Fonts for title page: \setfont\titlerm\rmbshape{12}{\magstep3} \setfont\titleit\itbshape{10}{\magstep4} \setfont\titlesl\slbshape{10}{\magstep4} \setfont\titlett\ttbshape{12}{\magstep3} \setfont\titlettsl\ttslshape{10}{\magstep4} \setfont\titlesf\sfbshape{17}{\magstep1} \let\titlebf=\titlerm \setfont\titlesc\scbshape{10}{\magstep4} \font\titlei=cmmi12 scaled \magstep3 \font\titlesy=cmsy10 scaled \magstep4 \def\authorrm{\secrm} \def\authortt{\sectt} % Chapter (and unnumbered) fonts (17.28pt). \setfont\chaprm\rmbshape{12}{\magstep2} \setfont\chapit\itbshape{10}{\magstep3} \setfont\chapsl\slbshape{10}{\magstep3} \setfont\chaptt\ttbshape{12}{\magstep2} \setfont\chapttsl\ttslshape{10}{\magstep3} \setfont\chapsf\sfbshape{17}{1000} \let\chapbf=\chaprm \setfont\chapsc\scbshape{10}{\magstep3} \font\chapi=cmmi12 scaled \magstep2 \font\chapsy=cmsy10 scaled \magstep3 % Section fonts (14.4pt). \setfont\secrm\rmbshape{12}{\magstep1} \setfont\secit\itbshape{10}{\magstep2} \setfont\secsl\slbshape{10}{\magstep2} \setfont\sectt\ttbshape{12}{\magstep1} \setfont\secttsl\ttslshape{10}{\magstep2} \setfont\secsf\sfbshape{12}{\magstep1} \let\secbf\secrm \setfont\secsc\scbshape{10}{\magstep2} \font\seci=cmmi12 scaled \magstep1 \font\secsy=cmsy10 scaled \magstep2 % Subsection fonts (13.15pt). \setfont\ssecrm\rmbshape{12}{\magstephalf} \setfont\ssecit\itbshape{10}{1315} \setfont\ssecsl\slbshape{10}{1315} \setfont\ssectt\ttbshape{12}{\magstephalf} \setfont\ssecttsl\ttslshape{10}{1315} \setfont\ssecsf\sfbshape{12}{\magstephalf} \let\ssecbf\ssecrm \setfont\ssecsc\scbshape{10}{\magstep1} \font\sseci=cmmi12 scaled \magstephalf \font\ssecsy=cmsy10 scaled 1315 % The smallcaps and symbol fonts should actually be scaled \magstep1.5, % but that is not a standard magnification. % 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 so that font changes will continue to work % in math mode, where it is the current \fam that is relevant in most % cases, not the current font. Plain TeX does \def\bf{\fam=\bffam % \tenbf}, for example. By redefining \tenbf, we obviate the need to % redefine \bf itself. \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 \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 \resetmathfonts \setleading{25pt}} \def\titlefont#1{{\titlefonts\rm #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 \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 \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 \resetmathfonts \setleading{15pt}} \let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf? \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 \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 \resetmathfonts \setleading{9.5pt}} % 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 \smallerfonts (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 % % I wish we used A4 paper on this side of the Atlantic. % % --karl, 24jan03. % Set up the default fonts, so we can use them for creating boxes. % \textfonts % Define these so they can be easily changed for other fonts. \def\angleleft{$\langle$} \def\angleright{$\rangle$} % Count depth in font-changes, for error checks \newcount\fontdepth \fontdepth=0 % Fonts for short table of contents. \setfont\shortcontrm\rmshape{12}{1000} \setfont\shortcontbf\bxshape{12}{1000} \setfont\shortcontsl\slshape{12}{1000} \setfont\shortconttt\ttshape{12}{1000} %% Add scribe-like font environments, plus @l for inline lisp (usually sans %% serif) and @ii for TeX italic % \smartitalic{ARG} outputs arg in italics, followed by an italic correction % unless the following character is such as not to need one. \def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else \ptexslash\fi\fi\fi} \def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx} \def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx} \let\i=\smartitalic \let\var=\smartslanted \let\dfn=\smartslanted \let\emph=\smartitalic \let\cite=\smartslanted \def\b#1{{\bf #1}} \let\strong=\b % 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\frenchspacing{% \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m } \catcode`@=\other \def\t#1{% {\tt \rawbackslash \frenchspacing #1}% \null } \let\ttfont=\t \def\samp#1{`\tclose{#1}'\null} \setfont\keyrm\rmshape{8}{1000} \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}}}} % The old definition, with no lozenge: %\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} \def\ctrl #1{{\tt \rawbackslash \hat}#1} % @file, @option are the same as @samp. \let\file=\samp \let\option=\samp % @code is a modification of @t, % which makes spaces the same size as normal in the surrounding text. \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 \frenchspacing #1% }% \null } % 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 % \global\def\code{\begingroup \catcode`\-=\active \let-\codedash \catcode`\_=\active \let_\codeunder \codex } % % If we end up with any active - characters when handling the index, % just treat them as a normal -. \global\def\indexbreaks{\catcode`\-=\active \let-\realdash} } \def\realdash{-} \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{}{}{}}% {\_}% } \def\codex #1{\tclose{#1}\endgroup} % @kbd is like @code, except that if the argument is just one @key command, % then @kbd has no effect. % @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). \def\kbdinputstyle{\parsearg\kbdinputstylexxx} \def\kbdinputstylexxx#1{% \def\arg{#1}% \ifx\arg\worddistinct \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% \else\ifx\arg\wordexample \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% \else\ifx\arg\wordcode \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% \else \errhelp = \EMsimple \errmessage{Unknown @kbdinputstyle option `\arg'}% \fi\fi\fi } \def\worddistinct{distinct} \def\wordexample{example} \def\wordcode{code} % Default is `distinct.' \kbdinputstyle distinct \def\xkey{\key} \def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% \ifx\one\xkey\ifx\threex\three \key{#2}% \else{\tclose{\kbdfont\look}}\fi \else{\tclose{\kbdfont\look}}\fi} % For @url, @env, @command quotes seem unnecessary, so use \code. \let\url=\code \let\env=\code \let\command=\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. Perhaps eventually put in % a hypertex \special here. % \def\uref#1{\douref #1,,,\finish} \def\douref#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} % 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 % 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 } % 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} \def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} % @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} % 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 % @acronym downcases the argument and prints in smallcaps. \def\acronym#1{{\smallcaps \lowercase{#1}}} % @pounds{} is a sterling sign. \def\pounds{{\it\$}} % @registeredsymbol - R in a circle. For now, only works in text size; % we'd have to redo the font mechanism to change the \scriptstyle and % \scriptscriptstyle font sizes to make it look right in headings. % Adapted from the plain.tex definition of \copyright. % \def\registeredsymbol{% $^{{\ooalign{\hfil\raise.07ex\hbox{$\scriptstyle\rm R$}\hfil\crcr\Orb}}% }$% } \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 \def\shorttitlepage{\parsearg\shorttitlepagezzz} \def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% \endgroup\page\hbox{}\page} \def\titlepage{\begingroup \parindent=0pt \textfonts \let\subtitlerm=\tenrm \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}% % \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines \let\tt=\authortt}% % % Leave some space at the very top of the page. \vglue\titlepagetopglue % % Now you can print the title using @title. \def\title{\parsearg\titlezzz}% \def\titlezzz##1{\leftline{\titlefonts\rm ##1} % print a rule at the page bottom also. \finishedtitlepagefalse \vskip4pt \hrule height 4pt width \hsize \vskip4pt}% % No rule at page bottom unless we print one at the top with @title. \finishedtitlepagetrue % % Now you can put text using @subtitle. \def\subtitle{\parsearg\subtitlezzz}% \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% % % @author should come last, but may come many times. \def\author{\parsearg\authorzzz}% \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi {\authorfont \leftline{##1}}}% % % 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 \oldpage \let\page = \oldpage \hbox{}}% % \def\page{\oldpage \hbox{}} } \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 } %%% 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\oddheading{\parsearg\oddheadingxxx} \def\everyheading{\parsearg\everyheadingxxx} \def\evenfooting{\parsearg\evenfootingxxx} \def\oddfooting{\parsearg\oddfootingxxx} \def\everyfooting{\parsearg\everyfootingxxx} {\catcode`\@=0 % \gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} \gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% \global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} \gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% \global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}% \gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} \gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% \global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} \gdef\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 -\baselineskip \global\advance\vsize by -\baselineskip } \gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}} % }% unbind the catcode of @. % @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{ \global\evenheadline={\hfil} \global\evenfootline={\hfil} \global\oddheadline={\hfil} \global\oddfootline={\hfil}} \HEADINGSoff % 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\undefined \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\settitlezzz} \def\settitlezzz #1{\gdef\thistitle{#1}} \message{tables,} % Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(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, @vtable, 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\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} \def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz} \def\internalBkitem{\smallbreak \parsearg\kitemzzz} \def\internalBkitemx{\itemxpar \parsearg\kitemzzz} \def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% \itemzzz {#1}} \def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}% \itemzzz {#1}} \def\itemzzz #1{\begingroup % \advance\hsize by -\rightskip \advance\hsize by -\tableindent \setbox0=\hbox{\itemfont{#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 \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. (Unfortunately % we can't prevent a possible page break at the following % \baselineskip glue.) However, if what follows is an environment % such as @example, there will be no \parskip glue; then % the negative vskip we just 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. % (Possibly there are other commands that could be followed by % @example which need the same treatment, but not section titles; or % maybe section titles are the only special case and they should be % penalty 10001...) \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 table}} \def\itemx{\errmessage{@itemx while not in a table}} \def\kitem{\errmessage{@kitem while not in a table}} \def\kitemx{\errmessage{@kitemx while not in a table}} \def\xitem{\errmessage{@xitem while not in a table}} \def\xitemx{\errmessage{@xitemx while not in a table}} % Contains a kludge to get @end[description] to work. \def\description{\tablez{\dontindex}{1}{}{}{}{}} % @table, @ftable, @vtable. \def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} {\obeylines\obeyspaces% \gdef\tablex #1^^M{% \tabley\dontindex#1 \endtabley}} \def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} {\obeylines\obeyspaces% \gdef\ftablex #1^^M{% \tabley\fnitemindex#1 \endtabley \def\Eftable{\endgraf\afterenvbreak\endgroup}% \let\Etable=\relax}} \def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} {\obeylines\obeyspaces% \gdef\vtablex #1^^M{% \tabley\vritemindex#1 \endtabley \def\Evtable{\endgraf\afterenvbreak\endgroup}% \let\Etable=\relax}} \def\dontindex #1{} \def\fnitemindex #1{\doind {fn}{\code{#1}}}% \def\vritemindex #1{\doind {vr}{\code{#1}}}% {\obeyspaces % \gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% \tablez{#1}{#2}{#3}{#4}{#5}{#6}}} \def\tablez #1#2#3#4#5#6{% \aboveenvbreak % \begingroup % \def\Edescription{\Etable}% Necessary kludge. \let\itemindex=#1% \ifnum 0#3>0 \advance \leftskip by #3\mil \fi % \ifnum 0#4>0 \tableindent=#4\mil \fi % \ifnum 0#5>0 \advance \rightskip by #5\mil \fi % \def\itemfont{#2}% \itemmax=\tableindent % \advance \itemmax by -\itemmargin % \advance \leftskip by \tableindent % \exdentamount=\tableindent \parindent = 0pt \parskip = \smallskipamount \ifdim \parskip=0pt \parskip=2pt \fi% \def\Etable{\endgraf\afterenvbreak\endgroup}% \let\item = \internalBitem % \let\itemx = \internalBitemx % \let\kitem = \internalBkitem % \let\kitemx = \internalBkitemx % \let\xitem = \internalBxitem % \let\xitemx = \internalBxitemx % } % This is the counter used by @enumerate, which is really @itemize \newcount \itemno \def\itemize{\parsearg\itemizezzz} \def\itemizezzz #1{% \begingroup % ended by the @end itemize \itemizey {#1}{\Eitemize} } \def\itemizey#1#2{% \aboveenvbreak \itemmax=\itemindent \advance\itemmax by -\itemmargin \advance\leftskip by \itemindent \exdentamount=\itemindent \parindent=0pt \parskip=\smallskipamount \ifdim\parskip=0pt \parskip=2pt \fi \def#2{\endgraf\afterenvbreak\endgroup}% \def\itemcontents{#1}% % @itemize with no arg is equivalent to @itemize @bullet. \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi \let\item=\itemizeitem } % \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'. % \def\enumerate{\parsearg\enumeratezzz} \def\enumeratezzz #1{\enumeratey #1 \endenumeratey} \def\enumeratey #1 #2\endenumeratey{% \begingroup % ended by the @end enumerate % % 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 itemizey, 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 \itemizey{#1.}\Eenumerate\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} % Definition of @item while inside @itemize. \def\itemizeitem{% \advance\itemno by 1 {\let\par=\endgraf \smallbreak}% \ifhmode \errmessage{In hmode at itemizeitem}\fi {\parskip=0in \hskip 0pt \hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% \vadjust{\penalty 1200}}% \flushcr} % @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. % % For those who want to use more than one line's worth of words in % the preamble, break the line within one argument and it % will parse correctly, i.e., % % @multitable {Column 1 template} {Column 2 template} {Column 3 % template} % Not: % @multitable {Column 1 template} {Column 2 template} % {Column 3 template} % 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, @multitable or @end multitable 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 part of the @columnfraction before the decimal point, which % is presumably either 0 or the empty string (but we don't check, we % just throw it away). #2 is the decimal part, which we use as the % percent of \hsize for this column. \def\pickupwholefraction#1.#2 {% \global\advance\colcount by 1 \expandafter\xdef\csname col\the\colcount\endcsname{.#2\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 ... @end multitable definitions: % \def\multitable{\parsearg\dotable} \def\dotable#1{\bgroup \vskip\parskip \let\item=\crcrwithfootnotes % 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 encounter the problem it was intended to solve again. --karl, % nathan@acm.org, 20apr99. \let\tab=&% \let\startfootins=\startsavedfootnote \tolerance=9500 \hbadness=9500 \setmultitablespacing \parskip=\multitableparskip \parindent=\multitableparindent \overfullrule=0pt \global\colcount=0 \def\Emultitable{% \global\setpercentfalse \crcrwithfootnotes\crcr \egroup\egroup }% % % To parse everything between @multitable and @item: \setuptable#1 \endsetuptable % % \everycr will reset column counter, \colcount, at the end of % each line. Every column entry will cause \colcount to advance by one. % The table preamble % looks at the current \colcount to find the correct column width. \everycr{\noalign{% % % \filbreak%% keeps underfull box messages off when table breaks over pages. % 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. \global\colcount=0\relax}}% % % 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\relax \multistrut\vtop{\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\setmultitablespacing{% test to see if user has set \multitablelinespace. % If so, do nothing. If not, give it an appropriate dimension based on % current baselineskip. \ifdim\multitablelinespace=0pt \setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip \global\advance\multitablelinespace by-\ht0 %% strut to put in table in case some entry doesn't have descenders, %% to keep lines equally spaced \let\multistrut = \strut \else %% FIXME: what is \box0 supposed to be? \gdef\multistrut{\vrule height\multitablelinespace depth\dp0 width0pt\relax} \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} % In case 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. Otherwise, the insertion is lost, it never migrates to the % main vertical list. --kasal, 22jan03. % \newbox\savedfootnotes % % \dotable \let's \startfootins to this, so that \dofootnote will call % it instead of starting the insertion right away. \def\startsavedfootnote{% \global\setbox\savedfootnotes = \vbox\bgroup \unvbox\savedfootnotes } \def\crcrwithfootnotes{% \crcr \ifvoid\savedfootnotes \else \noalign{\insert\footins{\box\savedfootnotes}}% \fi } \message{conditionals,} % Prevent errors for section commands. % Used in @ignore and in failing conditionals. \def\ignoresections{% \let\chapter=\relax \let\unnumbered=\relax \let\top=\relax \let\unnumberedsec=\relax \let\unnumberedsection=\relax \let\unnumberedsubsec=\relax \let\unnumberedsubsection=\relax \let\unnumberedsubsubsec=\relax \let\unnumberedsubsubsection=\relax \let\section=\relax \let\subsec=\relax \let\subsubsec=\relax \let\subsection=\relax \let\subsubsection=\relax \let\appendix=\relax \let\appendixsec=\relax \let\appendixsection=\relax \let\appendixsubsec=\relax \let\appendixsubsection=\relax \let\appendixsubsubsec=\relax \let\appendixsubsubsection=\relax \let\contents=\relax \let\smallbook=\relax \let\titlepage=\relax } % Used in nested conditionals, where we have to parse the Texinfo source % and so want to turn off most commands, in case they are used % incorrectly. % % We use \empty instead of \relax for the @def... commands, so that \end % doesn't throw an error. For instance: % @ignore % @deffn ... % @end deffn % @end ignore % % The @end deffn is going to get expanded, because we're trying to allow % nested conditionals. But we don't want to expand the actual @deffn, % since it might be syntactically correct and intended to be ignored. % Since \end checks for \relax, using \empty does not cause an error. % \def\ignoremorecommands{% \let\defcodeindex = \relax \let\defcv = \empty \let\defcvx = \empty \let\Edefcv = \empty \let\deffn = \empty \let\deffnx = \empty \let\Edeffn = \empty \let\defindex = \relax \let\defivar = \empty \let\defivarx = \empty \let\Edefivar = \empty \let\defmac = \empty \let\defmacx = \empty \let\Edefmac = \empty \let\defmethod = \empty \let\defmethodx = \empty \let\Edefmethod = \empty \let\defop = \empty \let\defopx = \empty \let\Edefop = \empty \let\defopt = \empty \let\defoptx = \empty \let\Edefopt = \empty \let\defspec = \empty \let\defspecx = \empty \let\Edefspec = \empty \let\deftp = \empty \let\deftpx = \empty \let\Edeftp = \empty \let\deftypefn = \empty \let\deftypefnx = \empty \let\Edeftypefn = \empty \let\deftypefun = \empty \let\deftypefunx = \empty \let\Edeftypefun = \empty \let\deftypeivar = \empty \let\deftypeivarx = \empty \let\Edeftypeivar = \empty \let\deftypemethod = \empty \let\deftypemethodx = \empty \let\Edeftypemethod = \empty \let\deftypeop = \empty \let\deftypeopx = \empty \let\Edeftypeop = \empty \let\deftypevar = \empty \let\deftypevarx = \empty \let\Edeftypevar = \empty \let\deftypevr = \empty \let\deftypevrx = \empty \let\Edeftypevr = \empty \let\defun = \empty \let\defunx = \empty \let\Edefun = \empty \let\defvar = \empty \let\defvarx = \empty \let\Edefvar = \empty \let\defvr = \empty \let\defvrx = \empty \let\Edefvr = \empty \let\clear = \relax \let\down = \relax \let\evenfooting = \relax \let\evenheading = \relax \let\everyfooting = \relax \let\everyheading = \relax \let\headings = \relax \let\include = \relax \let\item = \relax \let\lowersections = \relax \let\oddfooting = \relax \let\oddheading = \relax \let\printindex = \relax \let\pxref = \relax \let\raisesections = \relax \let\ref = \relax \let\set = \relax \let\setchapternewpage = \relax \let\setchapterstyle = \relax \let\settitle = \relax \let\up = \relax \let\verbatiminclude = \relax \let\xref = \relax } % Ignore @ignore, @ifhtml, @ifinfo, and the like. % \def\direntry{\doignore{direntry}} \def\documentdescriptionword{documentdescription} \def\documentdescription{\doignore{documentdescription}} \def\html{\doignore{html}} \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}} % @dircategory CATEGORY -- specify a category of the dir file % which this file should belong to. Ignore this in TeX. \let\dircategory = \comment % Ignore text until a line `@end #1'. % \def\doignore#1{\begingroup % Don't complain about control sequences we have declared \outer. \ignoresections % % Define a command to swallow text until we reach `@end #1'. % This @ is a catcode 12 token (that is the normal catcode of @ in % this texinfo.tex file). We change the catcode of @ below to match. \long\def\doignoretext##1@end #1{\enddoignore}% % % Make sure that spaces turn into tokens that match what \doignoretext wants. \catcode\spaceChar = 10 % % Ignore braces, too, so mismatched braces don't cause trouble. \catcode`\{ = 9 \catcode`\} = 9 % % We must not have @c interpreted as a control sequence. \catcode`\@ = 12 % \def\ignoreword{#1}% \ifx\ignoreword\documentdescriptionword % The c kludge breaks documentdescription, since % `documentdescription' contains a `c'. Means not everything will % be ignored inside @documentdescription, but oh well... \else % Make the letter c a comment character so that the rest of the line % will be ignored. This way, the document can have (for example) % @c @end ifinfo % and the @end ifinfo will be properly ignored. % (We've just changed @ to catcode 12.) \catcode`\c = 14 \fi % % And now expand the command defined above. \doignoretext } % What we do to finish off ignored text. % \def\enddoignore{\endgroup\ignorespaces}% \newif\ifwarnedobs\warnedobsfalse \def\obstexwarn{% \ifwarnedobs\relax\else % We need to warn folks that they may have trouble with TeX 3.0. % This uses \immediate\write16 rather than \message to get newlines. \immediate\write16{} \immediate\write16{WARNING: for users of Unix TeX 3.0!} \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).} \immediate\write16{If you are running another version of TeX, relax.} \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.} \immediate\write16{ Then upgrade your TeX installation if you can.} \immediate\write16{ (See ftp://ftp.gnu.org/non-gnu/TeX.README.)} \immediate\write16{If you are stuck with version 3.0, run the} \immediate\write16{ script ``tex3patch'' from the Texinfo distribution} \immediate\write16{ to use a workaround.} \immediate\write16{} \global\warnedobstrue \fi } % **In TeX 3.0, setting text in \nullfont hangs tex. For a % workaround (which requires the file ``dummy.tfm'' to be installed), % uncomment the following line: %%%%%\font\nullfont=dummy\let\obstexwarn=\relax % Ignore text, except that we keep track of conditional commands for % purposes of nesting, up to an `@end #1' command. % \def\nestedignore#1{% \obstexwarn % We must actually expand the ignored text to look for the @end % command, so that nested ignore constructs work. Thus, we put the % text into a \vbox and then do nothing with the result. To minimize % the chance of memory overflow, we follow the approach outlined on % page 401 of the TeXbook. % \setbox0 = \vbox\bgroup % Don't complain about control sequences we have declared \outer. \ignoresections % % Define `@end #1' to end the box, which will in turn undefine the % @end command again. \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}% % % We are going to be parsing Texinfo commands. Most cause no % trouble when they are used incorrectly, but some commands do % complicated argument parsing or otherwise get confused, so we % undefine them. % % We can't do anything about stray @-signs, unfortunately; % they'll produce `undefined control sequence' errors. \ignoremorecommands % % Set the current font to be \nullfont, a TeX primitive, and define % all the font commands to also use \nullfont. We don't use % dummy.tfm, as suggested in the TeXbook, because some sites % might not have that installed. Therefore, math mode will still % produce output, but that should be an extremely small amount of % stuff compared to the main input. % \nullfont \let\tenrm=\nullfont \let\tenit=\nullfont \let\tensl=\nullfont \let\tenbf=\nullfont \let\tentt=\nullfont \let\smallcaps=\nullfont \let\tensf=\nullfont % Similarly for index fonts. \let\smallrm=\nullfont \let\smallit=\nullfont \let\smallsl=\nullfont \let\smallbf=\nullfont \let\smalltt=\nullfont \let\smallsc=\nullfont \let\smallsf=\nullfont % Similarly for smallexample fonts. \let\smallerrm=\nullfont \let\smallerit=\nullfont \let\smallersl=\nullfont \let\smallerbf=\nullfont \let\smallertt=\nullfont \let\smallersc=\nullfont \let\smallersf=\nullfont % % Don't complain when characters are missing from the fonts. \tracinglostchars = 0 % % Don't bother to do space factor calculations. \frenchspacing % % Don't report underfull hboxes. \hbadness = 10000 % % Do minimal line-breaking. \pretolerance = 10000 % % Do not execute instructions in @tex. \def\tex{\doignore{tex}}% % Do not execute macro definitions. % `c' is a comment character, so the word `macro' will get cut off. \def\macro{\doignore{ma}}% } % @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. Make sure the catcode of space is correct to avoid % losing inside @example, for instance. % \def\set{\begingroup\catcode` =10 \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. \parsearg\setxxx} \def\setxxx#1{\setyyy#1 \endsetyyy} \def\setyyy#1 #2\endsetyyy{% \def\temp{#2}% \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. \fi \endgroup } % Can't use \xdef to pre-expand #2 and save some time, since \temp or % \next or other control sequences that we've defined might get us into % an infinite loop. Consider `@set foo @cite{bar}'. \def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}} % @clear VAR clears (i.e., unsets) the variable VAR. % \def\clear{\parsearg\clearxxx} \def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax} % @value{foo} gets the text saved in variable foo. { \catcode`\_ = \active % % We might end up with active _ or - characters in the argument if % we're called from @code, as @code{@value{foo-bar_}}. So \let any % such active characters to their normal equivalents. \gdef\value{\begingroup \catcode`\-=\other \catcode`\_=\other \indexbreaks \let_\normalunderscore \valuexxx} } \def\valuexxx#1{\expandablevalue{#1}\endgroup} % We have this subroutine so that we can handle at least some @value's % properly in indexes (we \let\value to this in \indexdummies). Ones % whose names contain - or _ still won't work, but we can't do anything % about that. 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. % \def\ifset{\parsearg\doifset} \def\doifset#1{% \expandafter\ifx\csname SET#1\endcsname\relax \let\next=\ifsetfail \else \let\next=\ifsetsucceed \fi \next } \def\ifsetsucceed{\conditionalsucceed{ifset}} \def\ifsetfail{\nestedignore{ifset}} \defineunmatchedend{ifset} % @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been % defined with @set, or has been undefined with @clear. % \def\ifclear{\parsearg\doifclear} \def\doifclear#1{% \expandafter\ifx\csname SET#1\endcsname\relax \let\next=\ifclearsucceed \else \let\next=\ifclearfail \fi \next } \def\ifclearsucceed{\conditionalsucceed{ifclear}} \def\ifclearfail{\nestedignore{ifclear}} \defineunmatchedend{ifclear} % @iftex, @ifnothtml, @ifnotinfo, @ifnotplaintext always succeed; we % read the text following, through the first @end iftex (etc.). Make % `@end iftex' (etc.) valid only after an @iftex. % \def\iftex{\conditionalsucceed{iftex}} \def\ifnothtml{\conditionalsucceed{ifnothtml}} \def\ifnotinfo{\conditionalsucceed{ifnotinfo}} \def\ifnotplaintext{\conditionalsucceed{ifnotplaintext}} \defineunmatchedend{iftex} \defineunmatchedend{ifnothtml} \defineunmatchedend{ifnotinfo} \defineunmatchedend{ifnotplaintext} % True conditional. Since \set globally defines its variables, we can % just start and end a group (to keep the @end definition undefined at % the outer level). % \def\conditionalsucceed#1{\begingroup \expandafter\def\csname E#1\endcsname{\endgroup}% } % @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 \newindex. {\catcode`\@=11 \gdef\newwrite{\alloc@7\write\chardef\sixt@@n}} % \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 \undefined % 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{% \def\@{@}% change to @@ when we switch to @ as escape char in index files. \def\ {\realbackslash\space }% % Need these in case \tex is in effect and \{ is a \delimiter again. % But can't use \lbracecmd and \rbracecmd because texindex assumes % braces and backslashes are used only as delimiters. \let\{ = \mylbrace \let\} = \myrbrace % % \definedummyword defines \#1 as \realbackslash #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{% \expandafter\def\csname ##1\endcsname{\realbackslash ##1\space}% }% \def\definedummyletter##1{% \expandafter\def\csname ##1\endcsname{\realbackslash ##1}% }% % % Do the redefinitions. \commondummies } % For the aux file, @ is the escape character. So we want to redefine % everything using @ instead of \realbackslash. When everything uses % @, this will be simpler. % \def\atdummies{% \def\@{@@}% \def\ {@ }% \let\{ = \lbraceatcmd \let\} = \rbraceatcmd % % (See comments in \indexdummies.) \def\definedummyword##1{% \expandafter\def\csname ##1\endcsname{@##1\space}% }% \def\definedummyletter##1{% \expandafter\def\csname ##1\endcsname{@##1}% }% % % Do the redefinitions. \commondummies } % Called from \indexdummies and \atdummies. \definedummyword and % \definedummyletter must be defined first. % \def\commondummies{% % \normalturnoffactive % % Control letters and accents. \definedummyletter{_}% \definedummyletter{,}% \definedummyletter{"}% \definedummyletter{`}% \definedummyletter{'}% \definedummyletter{^}% \definedummyletter{~}% \definedummyletter{=}% \definedummyword{u}% \definedummyword{v}% \definedummyword{H}% \definedummyword{dotaccent}% \definedummyword{ringaccent}% \definedummyword{tieaccent}% \definedummyword{ubaraccent}% \definedummyword{udotaccent}% \definedummyword{dotless}% % % Other non-English letters. \definedummyword{AA}% \definedummyword{AE}% \definedummyword{L}% \definedummyword{OE}% \definedummyword{O}% \definedummyword{aa}% \definedummyword{ae}% \definedummyword{l}% \definedummyword{oe}% \definedummyword{o}% \definedummyword{ss}% % % 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}% % % Texinfo font commands. \definedummyword{b}% \definedummyword{i}% \definedummyword{r}% \definedummyword{sc}% \definedummyword{t}% % \definedummyword{TeX}% \definedummyword{acronym}% \definedummyword{cite}% \definedummyword{code}% \definedummyword{command}% \definedummyword{dfn}% \definedummyword{dots}% \definedummyword{emph}% \definedummyword{env}% \definedummyword{file}% \definedummyword{kbd}% \definedummyword{key}% \definedummyword{math}% \definedummyword{option}% \definedummyword{samp}% \definedummyword{strong}% \definedummyword{uref}% \definedummyword{url}% \definedummyword{var}% \definedummyword{w}% % % Assorted special characters. \definedummyword{bullet}% \definedummyword{copyright}% \definedummyword{dots}% \definedummyword{enddots}% \definedummyword{equiv}% \definedummyword{error}% \definedummyword{expansion}% \definedummyword{minus}% \definedummyword{pounds}% \definedummyword{point}% \definedummyword{print}% \definedummyword{result}% % % Handle some cases of @value -- where the variable name does not % contain - or _, and the value does not contain any % (non-fully-expandable) commands. \let\value = \expandablevalue % % Normal spaces, not active ones. \unsepspaces % % No macro expansion. \turnoffmacros } % 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 \ ). {\obeyspaces \gdef\unsepspaces{\obeyspaces\let =\space}} % \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\indexdummytex{TeX} \def\indexdummydots{...} % \def\indexnofonts{% \def\ { }% \def\@{@}% % how to handle braces? \def\_{\normalunderscore}% % \let\,=\asis \let\"=\asis \let\`=\asis \let\'=\asis \let\^=\asis \let\~=\asis \let\==\asis \let\u=\asis \let\v=\asis \let\H=\asis \let\dotaccent=\asis \let\ringaccent=\asis \let\tieaccent=\asis \let\ubaraccent=\asis \let\udotaccent=\asis \let\dotless=\asis % % Other non-English letters. \def\AA{AA}% \def\AE{AE}% \def\L{L}% \def\OE{OE}% \def\O{O}% \def\aa{aa}% \def\ae{ae}% \def\l{l}% \def\oe{oe}% \def\o{o}% \def\ss{ss}% \def\exclamdown{!}% \def\questiondown{?}% % % 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 % % Texinfo font commands. \let\b=\asis \let\i=\asis \let\r=\asis \let\sc=\asis \let\t=\asis % \let\TeX=\indexdummytex \let\acronym=\asis \let\cite=\asis \let\code=\asis \let\command=\asis \let\dfn=\asis \let\dots=\indexdummydots \let\emph=\asis \let\env=\asis \let\file=\asis \let\kbd=\asis \let\key=\asis \let\math=\asis \let\option=\asis \let\samp=\asis \let\strong=\asis \let\uref=\asis \let\url=\asis \let\var=\asis \let\w=\asis } \let\indexbackslash=0 %overridden during \printindex. \let\SETmarginindex=\relax % put index entries in margin (undocumented)? % For \ifx comparisons. \def\emptymacro{\empty} % Most index entries go through here, but \dosubind is the general case. % \def\doind#1#2{\dosubind{#1}{#2}\empty} % 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 defuns, which call us directly. % \def\dosubind#1#2#3{% % Put the index entry in the margin if desired. \ifx\SETmarginindex\relax\else \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}% \fi {% \count255=\lastpenalty {% \indexdummies % Must do this here, since \bf, etc expand at this stage \escapechar=`\\ {% \let\folio = 0% We will expand all macros now EXCEPT \folio. \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now % so it will be output as is; and it will print as backslash. % % The main index entry text. \toks0 = {#2}% % % If third arg is present, precede it with space in sort key. \def\thirdarg{#3}% \ifx\thirdarg\emptymacro \else % If the third (subentry) arg is present, add it to the index % line to write. \toks0 = \expandafter{\the\toks0 \space #3}% \fi % % 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\csname#1indfile\endcsname{% \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}% }% % % 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 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. % \iflinks \ifvmode \skip0 = \lastskip \ifdim\lastskip = 0pt \else \nobreak\vskip-\skip0 \fi \fi % \temp % do the write % \ifvmode \ifdim\skip0 = 0pt \else \nobreak\vskip\skip0 \fi \fi \fi }% }% \penalty\count255 }% } % 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). % \def\printindex{\parsearg\doprintindex} \def\doprintindex#1{\begingroup \dobreak \chapheadingskip{10000}% % \smallfonts \rm \tolerance = 9500 \everypar = {}% don't want the \kern\-parindent from indentation suppression. \indexbreaks % % 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{\rawbackslashxx}% \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. \penalty -300 % % 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}% \vskip .33\baselineskip plus .1\baselineskip % % Do our best not to break after the initial. \nobreak }} % This typesets a paragraph consisting of #1, dot leaders, and then #2 % flush to the right margin. It is used for index and table of contents % entries. The paragraph is indented by \leftskip. % \def\entry#1#2{\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 % % Start a ``paragraph'' for the index entry so the line breaking % parameters we've set above will have an effect. \noindent % % Insert the text of the index entry. TeX will do line-breaking on it. #1% % 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. \def\tempa{{\rm }}% \def\tempb{#2}% \edef\tempc{\tempa}% \edef\tempd{\tempb}% \ifx\tempc\tempd\ \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#2.\ \the\toksA % The page number ends the paragraph. \else \ #2% The page number ends the paragraph. \fi \fi% \par \endgroup} % Like \dotfill except takes at least 1 em. \def\indexdotfill{\cleaders \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \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{% \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. \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 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 this as the name of the chapter. % page headings and footings can use it. @section does likewise. \def\thischapter{} \def\thissection{} \newcount\absseclevel % used to calculate proper heading level \newcount\secbase\secbase=0 % @raise/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 % Choose a numbered-heading macro % #1 is heading level if unmodified by @raisesections or @lowersections % #2 is text for heading \def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \chapterzzz{#2} \or \seczzz{#2} \or \numberedsubseczzz{#2} \or \numberedsubsubseczzz{#2} \else \ifnum \absseclevel<0 \chapterzzz{#2} \else \numberedsubsubseczzz{#2} \fi \fi \suppressfirstparagraphindent } % like \numhead, but chooses appendix heading levels \def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \appendixzzz{#2} \or \appendixsectionzzz{#2} \or \appendixsubseczzz{#2} \or \appendixsubsubseczzz{#2} \else \ifnum \absseclevel<0 \appendixzzz{#2} \else \appendixsubsubseczzz{#2} \fi \fi \suppressfirstparagraphindent } % like \numhead, but chooses numberless heading levels \def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \unnumberedzzz{#2} \or \unnumberedseczzz{#2} \or \unnumberedsubseczzz{#2} \or \unnumberedsubsubseczzz{#2} \else \ifnum \absseclevel<0 \unnumberedzzz{#2} \else \unnumberedsubsubseczzz{#2} \fi \fi \suppressfirstparagraphindent } % @chapter, @appendix, @unnumbered. \def\thischaptername{No Chapter Title} \outer\def\chapter{\parsearg\chapteryyy} \def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz \def\chapterzzz #1{% \secno=0 \subsecno=0 \subsubsecno=0 \global\advance \chapno by 1 \message{\putwordChapter\space \the\chapno}% \chapmacro {#1}{\the\chapno}% \gdef\thissection{#1}% \gdef\thischaptername{#1}% % We don't substitute the actual chapter name into \thischapter % because we don't want its macros evaluated now. \xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}% \writetocentry{chap}{#1}{{\the\chapno}} \donoderef \global\let\section = \numberedsec \global\let\subsection = \numberedsubsec \global\let\subsubsection = \numberedsubsubsec } % we use \chapno to avoid indenting back \def\appendixbox#1{% \setbox0 = \hbox{\putwordAppendix{} \the\chapno}% \hbox to \wd0{#1\hss}} \outer\def\appendix{\parsearg\appendixyyy} \def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz \def\appendixzzz #1{% \secno=0 \subsecno=0 \subsubsecno=0 \global\advance \appendixno by 1 \message{\putwordAppendix\space \appendixletter}% \chapmacro {#1}{\appendixbox{\putwordAppendix{} \appendixletter}}% \gdef\thissection{#1}% \gdef\thischaptername{#1}% \xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}% \writetocentry{appendix}{#1}{{\appendixletter}} \appendixnoderef \global\let\section = \appendixsec \global\let\subsection = \appendixsubsec \global\let\subsubsection = \appendixsubsubsec } % @centerchap is like @unnumbered, but the heading is centered. \outer\def\centerchap{\parsearg\centerchapyyy} \def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}} % @top is like @unnumbered. \outer\def\top{\parsearg\unnumberedyyy} \outer\def\unnumbered{\parsearg\unnumberedyyy} \def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz \def\unnumberedzzz #1{% \secno=0 \subsecno=0 \subsubsecno=0 % % 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)}% % \unnumbchapmacro {#1}% \gdef\thischapter{#1}\gdef\thissection{#1}% \writetocentry{unnumbchap}{#1}{{\the\chapno}} \unnumbnoderef \global\let\section = \unnumberedsec \global\let\subsection = \unnumberedsubsec \global\let\subsubsection = \unnumberedsubsubsec } % Sections. \outer\def\numberedsec{\parsearg\secyyy} \def\secyyy #1{\numhead1{#1}} % normally calls seczzz \def\seczzz #1{% \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % \gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}% \writetocentry{sec}{#1}{{\the\chapno}{\the\secno}} \donoderef \nobreak } \outer\def\appendixsection{\parsearg\appendixsecyyy} \outer\def\appendixsec{\parsearg\appendixsecyyy} \def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz \def\appendixsectionzzz #1{% \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % \gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}% \writetocentry{sec}{#1}{{\appendixletter}{\the\secno}} \appendixnoderef \nobreak } \outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} \def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz \def\unnumberedseczzz #1{% \plainsecheading {#1}\gdef\thissection{#1}% \writetocentry{unnumbsec}{#1}{{\the\chapno}{\the\secno}} \unnumbnoderef \nobreak } % Subsections. \outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} \def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz \def\numberedsubseczzz #1{% \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % \subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}% \writetocentry{subsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}} \donoderef \nobreak } \outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} \def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz \def\appendixsubseczzz #1{% \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % \subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}% \writetocentry{subsec}{#1}{{\appendixletter}{\the\secno}{\the\subsecno}} \appendixnoderef \nobreak } \outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} \def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz \def\unnumberedsubseczzz #1{% \plainsubsecheading {#1}\gdef\thissection{#1}% \writetocentry{unnumbsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}} \unnumbnoderef \nobreak } % Subsubsections. \outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} \def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz \def\numberedsubsubseczzz #1{% \gdef\thissection{#1}\global\advance \subsubsecno by 1 % \subsubsecheading {#1} {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}% \writetocentry{subsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}} \donoderef \nobreak } \outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} \def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz \def\appendixsubsubseczzz #1{% \gdef\thissection{#1}\global\advance \subsubsecno by 1 % \subsubsecheading {#1} {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}% \writetocentry{subsubsec}{#1}{{\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}} \appendixnoderef \nobreak } \outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} \def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz \def\unnumberedsubsubseczzz #1{% \plainsubsubsecheading {#1}\gdef\thissection{#1}% \writetocentry{unnumbsubsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}} \unnumbnoderef \nobreak } % These are variants which are not "outer", so they can appear in @ifinfo. % Actually, they should now be obsolete; ordinary section commands should work. \def\infotop{\parsearg\unnumberedzzz} \def\infounnumbered{\parsearg\unnumberedzzz} \def\infounnumberedsec{\parsearg\unnumberedseczzz} \def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} \def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} \def\infoappendix{\parsearg\appendixzzz} \def\infoappendixsec{\parsearg\appendixseczzz} \def\infoappendixsubsec{\parsearg\appendixsubseczzz} \def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} \def\infochapter{\parsearg\chapterzzz} \def\infosection{\parsearg\sectionzzz} \def\infosubsection{\parsearg\subsectionzzz} \def\infosubsubsection{\parsearg\subsubsectionzzz} % 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. \global\let\section = \numberedsec \global\let\subsection = \numberedsubsec \global\let\subsubsection = \numberedsubsubsec % Define @majorheading, @heading and @subheading % NOTE on use of \vbox for chapter headings, section headings, and such: % 1) We use \vbox rather than the earlier \line to permit % overlong headings to fold. % 2) \hyphenpenalty is set to 10000 because hyphenation in a % heading is obnoxious; this forbids it. % 3) Likewise, headings look best if no \parindent is used, and % if justification is not attempted. Hence \raggedright. \def\majorheading{\parsearg\majorheadingzzz} \def\majorheadingzzz #1{% {\advance\chapheadingskip by 10pt \chapbreak }% {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\penalty 200} \def\chapheading{\parsearg\chapheadingzzz} \def\chapheadingzzz #1{\chapbreak % {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\penalty 200} % @heading, @subheading, @subsubheading. \def\heading{\parsearg\plainsecheading} \def\subheading{\parsearg\plainsubsecheading} \def\subsubheading{\parsearg\plainsubsubsecheading} % 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} \def\setchapterstyle #1 {\csname CHAPF#1\endcsname} %%% Define plain chapter starts, and page on/off switching for it % Parameter controlling skip before chapter headings (if needed) \newskip\chapheadingskip \def\chapbreak{\dobreak \chapheadingskip {-4000}} \def\chappager{\par\vfill\supereject} \def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\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 \def\CHAPFplain{ \global\let\chapmacro=\chfplain \global\let\unnumbchapmacro=\unnchfplain \global\let\centerchapmacro=\centerchfplain} % Plain chapter opening. % #1 is the text, #2 the chapter number or empty if unnumbered. \def\chfplain#1#2{% \pchapsepmacro {% \chapfonts \rm \def\chapnum{#2}% \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}% \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright \hangindent = \wd0 \centerparametersmaybe \unhbox0 #1\par}% }% \nobreak\bigskip % no page break after a chapter title \nobreak } % Plain opening for unnumbered. \def\unnchfplain#1{\chfplain{#1}{}} % @centerchap -- centered and unnumbered. \let\centerparametersmaybe = \relax \def\centerchfplain#1{{% \def\centerparametersmaybe{% \advance\rightskip by 3\rightskip \leftskip = \rightskip \parfillskip = 0pt }% \chfplain{#1}{}% }} \CHAPFplain % The default \def\unnchfopen #1{% \chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\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 {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt \hfill {\rm #1}\hfill}}\bigskip \par\nobreak } \def\CHAPFopen{ \global\let\chapmacro=\chfopen \global\let\unnumbchapmacro=\unnchfopen \global\let\centerchapmacro=\centerchfopen} % Section titles. \newskip\secheadingskip \def\secheadingbreak{\dobreak \secheadingskip {-1000}} \def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}} \def\plainsecheading#1{\sectionheading{sec}{}{#1}} % Subsection titles. \newskip \subsecheadingskip \def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}} \def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}} \def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}} % Subsubsection titles. \let\subsubsecheadingskip = \subsecheadingskip \let\subsubsecheadingbreak = \subsecheadingbreak \def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}} \def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}} % Print any size section title. % % #1 is the section type (sec/subsec/subsubsec), #2 is the section % number (maybe empty), #3 the text. \def\sectionheading#1#2#3{% {% \expandafter\advance\csname #1headingskip\endcsname by \parskip \csname #1headingbreak\endcsname }% {% % Switch to the right set of fonts. \csname #1fonts\endcsname \rm % % Only insert the separating space if we have a section number. \def\secnum{#2}% \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}% % \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright \hangindent = \wd0 % zero if no section number \unhbox0 #3}% }% % Add extra space after the heading -- either a line space or a % paragraph space, whichever is more. (Some people like to set % \parskip to large values for some reason.) Don't allow stretch, though. \nobreak \ifdim\parskip>\normalbaselineskip \kern\parskip \else \kern\normalbaselineskip \fi \nobreak } \message{toc,} % Table of contents. \newwrite\tocfile % Write an entry to the toc file, opening it if necessary. % Called from @chapter, etc. We supply {\folio} at the end of the % argument, which will end up as the last argument to the \...entry macro. % % Usage: \writetocentry{chap}{The Name of The Game}{{\the\chapno}} % 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. % \newif\iftocfileopened \def\writetocentry#1#2#3{% \iftocfileopened\else \immediate\openout\tocfile = \jobname.toc \global\tocfileopenedtrue \fi % \iflinks \toks0 = {#2}% \edef\temp{\write\tocfile{\realbackslash #1entry{\the\toks0}#3{\folio}}}% \temp \fi % % Tell \shipout to create a page destination if we're doing pdf, which % will be the target of the links in the table of contents. We can't % just do it 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 \pdfmakepagedesttrue \fi } \newskip\contentsrightmargin \contentsrightmargin=1in \newcount\savepageno \newcount\lastnegativepageno \lastnegativepageno = -1 % Finish up the main text and 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. \unnumbchapmacro{#1}\def\thischapter{}% \savepageno = \pageno \begingroup % Set up to handle contents files properly. \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 % We can't do this, because then an actual ^ in a section % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97. %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi \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 } % Normal (long) toc. \def\contents{% \startcontents{\putwordTOC}% \openin 1 \jobname.toc \ifeof 1 \else \closein 1 \input \jobname.toc \fi \vfill \eject \contentsalignmacro % in case @setchapternewpage odd is in effect \pdfmakeoutlines \endgroup \lastnegativepageno = \pageno \global\pageno = \savepageno } % And just the chapters. \def\summarycontents{% \startcontents{\putwordShortTOC}% % \let\chapentry = \shortchapentry \let\appendixentry = \shortappendixentry \let\unnumbchapentry = \shortunnumberedentry % 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\secentry ##1##2##3##4{} \def\subsecentry ##1##2##3##4##5{} \def\subsubsecentry ##1##2##3##4##5##6{} \let\unnumbsecentry = \secentry \let\unnumbsubsecentry = \subsecentry \let\unnumbsubsubsecentry = \subsubsecentry \openin 1 \jobname.toc \ifeof 1 \else \closein 1 \input \jobname.toc \fi \vfill \eject \contentsalignmacro % in case @setchapternewpage odd is in effect \endgroup \lastnegativepageno = \pageno \global\pageno = \savepageno } \let\shortcontents = \summarycontents \ifpdf \pdfcatalog{/PageMode /UseOutlines}% \fi % 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, ... % Chapters, in the main contents. \def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}} % % Chapters, in the short toc. % See comments in \dochapentry re vbox and related settings. \def\shortchapentry#1#2#3{% \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#3\egroup}% } % Appendices, in the main contents. \def\appendixentry#1#2#3{% \dochapentry{\appendixbox{\putwordAppendix{} #2}\labelspace#1}{#3}} % % Appendices, in the short toc. \let\shortappendixentry = \shortchapentry % Typeset the label for a chapter or appendix for the short contents. % The arg is, e.g., `Appendix A' for an appendix, or `3' for a chapter. % We could simplify the code here by writing out an \appendixentry % command in the toc file for appendices, instead of using \chapentry % for both, but it doesn't seem worth it. % \newdimen\shortappendixwidth % \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.) \dimen0 = 1em \hbox to \dimen0{#1\hss}% } % Unnumbered chapters. \def\unnumbchapentry#1#2#3{\dochapentry{#1}{#3}} \def\shortunnumberedentry#1#2#3{\tocentry{#1}{\doshortpageno\bgroup#3\egroup}} % Sections. \def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}} \def\unnumbsecentry#1#2#3#4{\dosecentry{#1}{#4}} % Subsections. \def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}} \def\unnumbsubsecentry#1#2#3#4#5{\dosubsecentry{#1}{#5}} % And subsubsections. \def\subsubsecentry#1#2#3#4#5#6{% \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}} \def\unnumbsubsubsecentry#1#2#3#4#5#6{\dosubsubsecentry{#1}{#6}} % This parameter controls the indentation of the various levels. \newdimen\tocindent \tocindent = 3pc % 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} % Final typesetting of a toc entry; we use the same \entry macro as for % the index entries, but we want to suppress hyphenation here. (We % can't do that in the \entry macro, since index entries might consist % of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) \def\tocentry#1#2{\begingroup \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks % Do not use \turnoffactive in these arguments. Since the toc is % typeset in cmr, characters such as _ would come out wrong; we % have to do the usual translation tricks. \entry{#1}{#2}% \endgroup} % 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} \let\subsecentryfonts = \textfonts \let\subsubsecentryfonts = \textfonts \message{environments,} % @foo ... @end foo. % @point{}, @result{}, @expansion{}, @print{}, @equiv{}. % % Since these characters are used in examples, it should be an even number of % \tt widths. Each \tt character is 1en, so two makes it 1em. % \def\point{$\star$} \def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} \def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} \def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} \def\equiv{\leavevmode\lower.1ex\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 \tensf error\kern-1.5pt} % \global\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} % @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 tex @ character. \def\tex{\begingroup \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 \escapechar=`\\ % \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\{=\ptexlbrace \let\+=\tabalign \let\}=\ptexrbrace \let\/=\ptexslash \let\*=\ptexstar \let\t=\ptext % \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% \def\@{@}% \let\Etex=\endgroup} % Define @lisp ... @end lisp. % @lisp does a \begingroup 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} % 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. % {\obeyspaces % \gdef\sepspaces{\obeyspaces\let =\tie}} % Define \obeyedspace to be our active space, whatever it is. This is % for use in \parsearg. {\sepspaces% \global\let\obeyedspace= } % 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, 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 \else \penalty-50 \fi \vskip\envskipamount \fi \fi }} \let\afterenvbreak = \aboveenvbreak % \nonarrowing is a flag. If "set", @lisp etc don't narrow margins. \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 \def\cartouche{% \par % can't be in the midst of a paragraph. \begingroup \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=\comment \vbox\bgroup \baselineskip=0pt\parskip=0pt\lineskip=0pt \carttop \hbox\bgroup \hskip\lskip \vrule\kern3pt \vbox\bgroup \hsize=\cartinner \kern3pt \begingroup \baselineskip=\normbskip \lineskip=\normlskip \parskip=\normpskip \vskip -\parskip \def\Ecartouche{% \endgroup \kern3pt \egroup \kern3pt\vrule \hskip\rskip \egroup \cartbot \egroup \endgroup }} % This macro is called at the beginning of all the @example variants, % inside a group. \def\nonfillstart{% \aboveenvbreak \inENV % This group ends at the end of the body \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 \parindent = 0pt \emergencystretch = 0pt % don't try to avoid overfull boxes % @cartouche defines \nonarrowing to inhibit narrowing % at next level down. \ifx\nonarrowing\relax \advance \leftskip by \lispnarrowing \exdentamount=\lispnarrowing \let\exdent=\nofillexdent \let\nonarrowing=\relax \fi } % Define the \E... control sequence only if we are inside the particular % environment, so the error checking in \end will work. % % To end an @example-like environment, we first end the paragraph (via % \afterenvbreak's vertical glue), and then the group. That way we keep % the zero \parskip that the environments set -- \parskip glue will be % inserted at the beginning of the next paragraph in the document, after % the environment. % \def\nonfillfinish{\afterenvbreak\endgroup} % @lisp: indented, narrowed, typewriter font. \def\lisp{\begingroup \nonfillstart \let\Elisp = \nonfillfinish \tt \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. \gobble % eat return } % @example: Same as @lisp. \def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} % @smallexample and @smalllisp: use smaller fonts. % Originally contributed by Pavel@xerox. \def\smalllisp{\begingroup \def\Esmalllisp{\nonfillfinish\endgroup}% \def\Esmallexample{\nonfillfinish\endgroup}% \smallexamplefonts \lisp } \let\smallexample = \smalllisp % @display: same as @lisp except keep current font. % \def\display{\begingroup \nonfillstart \let\Edisplay = \nonfillfinish \gobble } % % @smalldisplay: @display plus smaller fonts. % \def\smalldisplay{\begingroup \def\Esmalldisplay{\nonfillfinish\endgroup}% \smallexamplefonts \rm \display } % @format: same as @display except don't narrow margins. % \def\format{\begingroup \let\nonarrowing = t \nonfillstart \let\Eformat = \nonfillfinish \gobble } % % @smallformat: @format plus smaller fonts. % \def\smallformat{\begingroup \def\Esmallformat{\nonfillfinish\endgroup}% \smallexamplefonts \rm \format } % @flushleft (same as @format). % \def\flushleft{\begingroup \def\Eflushleft{\nonfillfinish\endgroup}\format} % @flushright. % \def\flushright{\begingroup \let\nonarrowing = t \nonfillstart \let\Eflushright = \nonfillfinish \advance\leftskip by 0pt plus 1fill \gobble } % @quotation does normal linebreaking (hence we can't use \nonfillstart) % and narrows the margins. % \def\quotation{% \begingroup\inENV %This group ends at the end of the @quotation body {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip \parindent=0pt % We have retained a nonzero parskip for the environment, since we're % doing normal filling. So to avoid extra space below the environment... \def\Equotation{\parskip = 0pt \nonfillfinish}% % % @cartouche defines \nonarrowing to inhibit narrowing at next level down. \ifx\nonarrowing\relax \advance\leftskip by \lispnarrowing \advance\rightskip by \lispnarrowing \exdentamount = \lispnarrowing \let\nonarrowing = \relax \fi } % 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\"% } % % [Knuth] p. 380 \def\uncatcodespecials{% \def\do##1{\catcode`##1=12}\dospecials} % % [Knuth] pp. 380,381,391 % Disable Spanish ligatures ?` and !` of \tt font \begingroup \catcode`\`=\active\gdef`{\relax\lq} \endgroup % % 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}% \catcode`\`=\active \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 % \def\starttabbox{\setbox0=\hbox\bgroup} \begingroup \catcode`\^^I=\active \gdef\tabexpand{% \catcode`\^^I=\active \def^^I{\leavevmode\egroup \dimen0=\wd0 % the width so far, or since the previous tab \divide\dimen0 by\tabw \multiply\dimen0 by\tabw % compute previous multiple of \tabw \advance\dimen0 by\tabw % advance to next multiple of \tabw \wd0=\dimen0 \box0 \starttabbox }% } \endgroup \def\setupverbatim{% % Easiest (and conventionally used) font for verbatim \tt \def\par{\leavevmode\egroup\box0\endgraf}% \catcode`\`=\active \tabexpand % 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`\{=12\catcode`\}=12 \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] %% Include LaTeX hack for completeness -- never know %% \begingroup %% \catcode`|=0 \catcode`[=1 %% \catcode`]=2\catcode`\{=12\catcode`\}=12\catcode`\ =\active %% \catcode`\\=12|gdef|doverbatim#1@end verbatim[ %% #1|endgroup|def|Everbatim[]|end[verbatim]] %% |endgroup % \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. \gdef\doverbatim#1^^M#2@end verbatim{#2\end{verbatim}}% \endgroup % \def\verbatim{% \def\Everbatim{\nonfillfinish\endgroup}% \begingroup \nonfillstart \advance\leftskip by -\defbodyindent \begingroup\setupverbatim\doverbatim } % @verbatiminclude FILE - insert text of file in verbatim environment. % % Allow normal characters that we make active in the argument (a file name). \def\verbatiminclude{% \begingroup \catcode`\\=\other \catcode`~=\other \catcode`^=\other \catcode`_=\other \catcode`|=\other \catcode`<=\other \catcode`>=\other \catcode`+=\other \parsearg\doverbatiminclude } \def\setupverbatiminclude{% \begingroup \nonfillstart \advance\leftskip by -\defbodyindent \begingroup\setupverbatim } % \def\doverbatiminclude#1{% % Restore active chars for included file. \endgroup \begingroup \let\value=\expandablevalue \def\thisfile{#1}% \expandafter\expandafter\setupverbatiminclude\input\thisfile \endgroup \nonfillfinish \endgroup } % @copying ... @end copying. % Save the text away for @insertcopying later. Many commands won't be % allowed in this context, but that's ok. % % 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{\begingroup % Define a command to swallow text until we reach `@end copying'. % \ is the escape char in this texinfo.tex file, so it is the % delimiter for the command; @ will be the escape char when we read % it, but that doesn't matter. \long\def\docopying##1\end copying{\gdef\copyingtext{##1}\enddocopying}% % % We must preserve ^^M's in the input file; see \insertcopying below. \catcode`\^^M = \active \docopying } % What we do to finish off the copying text. % \def\enddocopying{\endgroup\ignorespaces} % @insertcopying. Here we must play games with ^^M's. On the one hand, % we need them to delimit commands such as `@end quotation', so they % must be active. On the other hand, we certainly don't want every % end-of-line to be a \par, as would happen with the normal active % definition of ^^M. On the third hand, two ^^M's in a row should still % generate a \par. % % Our approach is to make ^^M insert a space and a penalty1 normally; % then it can also check if \lastpenalty=1. If it does, then manually % do \par. % % This messes up the normal definitions of @c[omment], so we redefine % it. Similarly for @ignore. (These commands are used in the gcc % manual for man page generation.) % % Seems pretty fragile, most line-oriented commands will presumably % fail, but for the limited use of getting the copying text (which % should be quite simple) inserted, we can hope it's ok. % {\catcode`\^^M=\active % \gdef\insertcopying{\begingroup % \parindent = 0pt % looks wrong on title page \def^^M{% \ifnum \lastpenalty=1 % \par % \else % \space \penalty 1 % \fi % }% % % Fix @c[omment] for catcode 13 ^^M's. \def\c##1^^M{\ignorespaces}% \let\comment = \c % % % Don't bother jumping through all the hoops that \doignore does, it % would be very hard since the catcodes are already set. \long\def\ignore##1\end ignore{\ignorespaces}% % \copyingtext % \endgroup}% } \message{defuns,} % @defun etc. % Allow user to change definition object font (\df) internally \def\setdeffont#1 {\csname DEF#1\endcsname} \newskip\defbodyindent \defbodyindent=.4in \newskip\defargsindent \defargsindent=50pt \newskip\deflastargmargin \deflastargmargin=18pt \newcount\parencount % 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 = ) {\activeparens % Now, smart parens don't turn on until &foo (see \amprm) % 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. \global\let(=\lparen \global\let)=\rparen \global\let[=\lbrack \global\let]=\rbrack \gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} % This is used to turn on special parens % but make & act ordinary (given that it's active). \gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr} % Definitions of (, ) and & used in args for functions. % This is the definition of ( outside of all parentheses. \gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested \global\advance\parencount by 1 } % % This is the definition of ( when already inside a level of parens. \gdef\opnested{\char`\(\global\advance\parencount by 1 } % \gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. % also in that case restore the outer-level definition of (. \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi \global\advance \parencount by -1 } % If we encounter &foo, then turn on ()-hacking afterwards \gdef\amprm#1 {{\rm\}\let(=\oprm \let)=\clrm\ } % \gdef\normalparens{\boldbrax\let&=\ampnr} } % End of definition inside \activeparens %% These parens (in \boldbrax) actually are a little bolder than the %% contained text. This is especially needed for [ and ] \def\opnr{{\sf\char`\(}\global\advance\parencount by 1 } \def\clnr{{\sf\char`\)}\global\advance\parencount by -1 } \let\ampnr = \& \def\lbrb{{\bf\char`\[}} \def\rbrb{{\bf\char`\]}} % Active &'s sneak into the index arguments, so make sure it's defined. { \catcode`& = \active \global\let& = \ampnr } % \defname, which formats the name of the @def (not the args). % #1 is the function name. % #2 is the type of definition, such as "Function". % \def\defname#1#2{% % How we'll output the type name. Putting it in brackets helps % distinguish it from the body text that may end up on the next line % just below it. \ifempty{#2}% \def\defnametype{}% \else \def\defnametype{[\rm #2]}% \fi % % Get the values of \leftskip and \rightskip as they were outside the @def... \dimen2=\leftskip \advance\dimen2 by -\defbodyindent % % Figure out values for the paragraph shape. \setbox0=\hbox{\hskip \deflastargmargin{\defnametype}}% \dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line \dimen1=\hsize \advance \dimen1 by -\defargsindent % size for continuations \parshape 2 0in \dimen0 \defargsindent \dimen1 % % Output arg 2 ("Function" or some such) but stuck inside a box of % width 0 so it does not interfere with linebreaking. \noindent % {% Adjust \hsize to exclude the ambient margins, % so that \rightline will obey them. \advance \hsize by -\dimen2 \dimen3 = 0pt % was -1.25pc \rlap{\rightline{\defnametype\kern\dimen3}}% }% % % Allow all lines to be underfull without complaint: \tolerance=10000 \hbadness=10000 \advance\leftskip by -\defbodyindent \exdentamount=\defbodyindent {\df #1}\enskip % output function name % \defunargs will be called next to output the arguments, if any. } % Common pieces to start any @def... % #1 is the \E... control sequence to end the definition (which we define). % #2 is the \...x control sequence (which our caller defines). % #3 is the control sequence to process the header, such as \defunheader. % \def\parsebodycommon#1#2#3{% \begingroup\inENV % 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 want to allow a % break after all. Check for penalty 10002 (inserted by % \defargscommonending) instead of 10000, since the sectioning % commands insert a \penalty10000, and we don't want to allow a break % between a section heading and a defun. \ifnum\lastpenalty=10002 \penalty0 \fi \medbreak % % Define the \E... end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% % \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent } % Common part of the \...x definitions. % \def\defxbodycommon{% % As with \parsebodycommon above, allow line break if we have multiple % x headers in a row. It's not a great place, though. \ifnum\lastpenalty=10000 \penalty1000 \fi % \begingroup\obeylines } % Process body of @defun, @deffn, @defmac, etc. % \def\defparsebody#1#2#3{% \parsebodycommon{#1}{#2}{#3}% \def#2{\defxbodycommon \activeparens \spacesplit#3}% \catcode\equalChar=\active \begingroup\obeylines\activeparens \spacesplit#3% } % #1, #2, #3 are the common arguments (see \parsebodycommon above). % #4, delimited by the space, is the class name. % \def\defmethparsebody#1#2#3#4 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 {\defxbodycommon \activeparens \spacesplit{#3{##1}}}% \begingroup\obeylines\activeparens % The \empty here prevents misinterpretation of a construct such as % @deffn {whatever} {Enharmonic comma} % See comments at \deftpparsebody, although in our case we don't have % to remove the \empty afterwards, since it is empty. \spacesplit{#3{#4}}\empty } % Used for @deftypemethod and @deftypeivar. % #1, #2, #3 are the common arguments (see \defparsebody). % #4, delimited by a space, is the class name. % #5 is the method's return type. % \def\deftypemethparsebody#1#2#3#4 #5 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 ##2 {\defxbodycommon \activeparens \spacesplit{#3{##1}{##2}}}% \begingroup\obeylines\activeparens \spacesplit{#3{#4}{#5}}% } % Used for @deftypeop. The change from \deftypemethparsebody is an % extra argument at the beginning which is the `category', instead of it % being the hardwired string `Method' or `Instance Variable'. We have % to account for this both in the \...x definition and in parsing the % input at hand. Thus also need a control sequence (passed as #5) for % the \E... definition to assign the category name to. % \def\deftypeopparsebody#1#2#3#4#5 #6 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 ##2 ##3 {\def#4{##1}% \defxbodycommon \activeparens \spacesplit{#3{##2}{##3}}}% \begingroup\obeylines\activeparens \spacesplit{#3{#5}{#6}}% } % For @defop. \def\defopparsebody #1#2#3#4#5 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 ##2 {\def#4{##1}% \defxbodycommon \activeparens \spacesplit{#3{##2}}}% \begingroup\obeylines\activeparens \spacesplit{#3{#5}}% } % These parsing functions are similar to the preceding ones % except that they do not make parens into active characters. % These are used for "variables" since they have no arguments. % \def\defvarparsebody #1#2#3{% \parsebodycommon{#1}{#2}{#3}% \def#2{\defxbodycommon \spacesplit#3}% \catcode\equalChar=\active \begingroup\obeylines \spacesplit#3% } % @defopvar. \def\defopvarparsebody #1#2#3#4#5 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 ##2 {\def#4{##1}% \defxbodycommon \spacesplit{#3{##2}}}% \begingroup\obeylines \spacesplit{#3{#5}}% } \def\defvrparsebody#1#2#3#4 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 {\defxbodycommon \spacesplit{#3{##1}}}% \begingroup\obeylines \spacesplit{#3{#4}}% } % This loses on `@deftp {Data Type} {struct termios}' -- it thinks the % type is just `struct', because we lose the braces in `{struct % termios}' when \spacesplit reads its undelimited argument. Sigh. % \let\deftpparsebody=\defvrparsebody % % So, to get around this, we put \empty in with the type name. That % way, TeX won't find exactly `{...}' as an undelimited argument, and % won't strip off the braces. % \def\deftpparsebody #1#2#3#4 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 {\defxbodycommon \spacesplit{#3{##1}}}% \begingroup\obeylines \spacesplit{\parsetpheaderline{#3{#4}}}\empty } % Fine, but then we have to eventually remove the \empty *and* the % braces (if any). That's what this does. % \def\removeemptybraces\empty#1\relax{#1} % After \spacesplit has done its work, this is called -- #1 is the final % thing to call, #2 the type name (which starts with \empty), and #3 % (which might be empty) the arguments. % \def\parsetpheaderline#1#2#3{% #1{\removeemptybraces#2\relax}{#3}% }% % Split up #2 (the rest of the input line) at the first space token. % call #1 with two arguments: % the first is all of #2 before the space token, % the second is all of #2 after that space token. % If #2 contains no space token, all of it is passed as the first arg % and the second is passed as empty. % {\obeylines % \gdef\spacesplit#1#2^^M{\endgroup\spacesplitx{#1}#2 \relax\spacesplitx}% \long\gdef\spacesplitx#1#2 #3#4\spacesplitx{% \ifx\relax #3% #1{#2}{}% \else % #1{#2}{#3#4}% \fi}% } % Define @defun. % This is called to end the arguments processing for all the @def... commands. % \def\defargscommonending{% \interlinepenalty = 10000 \advance\rightskip by 0pt plus 1fil \endgraf \nobreak\vskip -\parskip \penalty 10002 % signal to \parsebodycommon. } % This expands the args and terminates the paragraph they comprise. % \def\defunargs#1{\functionparens \sl % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. % Set the font temporarily and use \font in case \setfont made \tensl a macro. {\tensl\hyphenchar\font=0}% #1% {\tensl\hyphenchar\font=45}% \ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi% \defargscommonending } \def\deftypefunargs #1{% % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. % Use \boldbraxnoamp, not \functionparens, so that & is not special. \boldbraxnoamp \tclose{#1}% avoid \code because of side effects on active chars \defargscommonending } % Do complete processing of one @defun or @defunx line already parsed. % @deffn Command forward-char nchars \def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} \def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% \begingroup\defname {#2}{#1}\defunargs{#3}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @defun == @deffn Function \def\defun{\defparsebody\Edefun\defunx\defunheader} \def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{\putwordDeffunc}% \defunargs {#2}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @deftypefun int foobar (int @var{foo}, float @var{bar}) \def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader} % #1 is the data type. #2 is the name and args. \def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax} % #1 is the data type, #2 the name, #3 the args. \def\deftypefunheaderx #1#2 #3\relax{% \doind {fn}{\code{#2}}% Make entry in function index \begingroup\defname {\defheaderxcond#1\relax$.$#2}{\putwordDeftypefun}% \deftypefunargs {#3}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) \def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} % \defheaderxcond#1\relax$.$ % puts #1 in @code, followed by a space, but does nothing if #1 is null. \def\defheaderxcond#1#2$.${\ifx#1\relax\else\code{#1#2} \fi} % #1 is the classification. #2 is the data type. #3 is the name and args. \def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} % #1 is the classification, #2 the data type, #3 the name, #4 the args. \def\deftypefnheaderx #1#2#3 #4\relax{% \doind {fn}{\code{#3}}% Make entry in function index \begingroup \normalparens % notably, turn off `&' magic, which prevents % at least some C++ text from working \defname {\defheaderxcond#2\relax$.$#3}{#1}% \deftypefunargs {#4}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @defmac == @deffn Macro \def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} \def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{\putwordDefmac}% \defunargs {#2}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @defspec == @deffn Special Form \def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} \def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{\putwordDefspec}% \defunargs {#2}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @defop CATEGORY CLASS OPERATION ARG... % \def\defop #1 {\def\defoptype{#1}% \defopparsebody\Edefop\defopx\defopheader\defoptype} % \def\defopheader#1#2#3{% \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% function index entry \begingroup \defname{#2}{\defoptype\ \putwordon\ #1}% \defunargs{#3}% \endgroup } % @deftypeop CATEGORY CLASS TYPE OPERATION ARG... % \def\deftypeop #1 {\def\deftypeopcategory{#1}% \deftypeopparsebody\Edeftypeop\deftypeopx\deftypeopheader \deftypeopcategory} % % #1 is the class name, #2 the data type, #3 the operation name, #4 the args. \def\deftypeopheader#1#2#3#4{% \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index \begingroup \defname{\defheaderxcond#2\relax$.$#3} {\deftypeopcategory\ \putwordon\ \code{#1}}% \deftypefunargs{#4}% \endgroup } % @deftypemethod CLASS TYPE METHOD ARG... % \def\deftypemethod{% \deftypemethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader} % % #1 is the class name, #2 the data type, #3 the method name, #4 the args. \def\deftypemethodheader#1#2#3#4{% \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index \begingroup \defname{\defheaderxcond#2\relax$.$#3}{\putwordMethodon\ \code{#1}}% \deftypefunargs{#4}% \endgroup } % @deftypeivar CLASS TYPE VARNAME % \def\deftypeivar{% \deftypemethparsebody\Edeftypeivar\deftypeivarx\deftypeivarheader} % % #1 is the class name, #2 the data type, #3 the variable name. \def\deftypeivarheader#1#2#3{% \dosubind{vr}{\code{#3}}{\putwordof\ \code{#1}}% entry in variable index \begingroup \defname{\defheaderxcond#2\relax$.$#3} {\putwordInstanceVariableof\ \code{#1}}% \defvarargs{#3}% \endgroup } % @defmethod == @defop Method % \def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} % % #1 is the class name, #2 the method name, #3 the args. \def\defmethodheader#1#2#3{% \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% entry in function index \begingroup \defname{#2}{\putwordMethodon\ \code{#1}}% \defunargs{#3}% \endgroup } % @defcv {Class Option} foo-class foo-flag \def\defcv #1 {\def\defcvtype{#1}% \defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype} \def\defcvarheader #1#2#3{% \dosubind{vr}{\code{#2}}{\putwordof\ \code{#1}}% variable index entry \begingroup \defname{#2}{\defcvtype\ \putwordof\ #1}% \defvarargs{#3}% \endgroup } % @defivar CLASS VARNAME == @defcv {Instance Variable} CLASS VARNAME % \def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} % \def\defivarheader#1#2#3{% \dosubind{vr}{\code{#2}}{\putwordof\ \code{#1}}% entry in var index \begingroup \defname{#2}{\putwordInstanceVariableof\ #1}% \defvarargs{#3}% \endgroup } % @defvar % First, define the processing that is wanted for arguments of @defvar. % This is actually simple: just print them in roman. % This must expand the args and terminate the paragraph they make up \def\defvarargs #1{\normalparens #1% \defargscommonending } % @defvr Counter foo-count \def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader} \def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% \begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} % @defvar == @defvr Variable \def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader} \def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index \begingroup\defname {#1}{\putwordDefvar}% \defvarargs {#2}\endgroup % } % @defopt == @defvr {User Option} \def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader} \def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index \begingroup\defname {#1}{\putwordDefopt}% \defvarargs {#2}\endgroup % } % @deftypevar int foobar \def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader} % #1 is the data type. #2 is the name, perhaps followed by text that % is actually part of the data type, which should not be put into the index. \def\deftypevarheader #1#2{% \dovarind#2 \relax% Make entry in variables index \begingroup\defname {\defheaderxcond#1\relax$.$#2}{\putwordDeftypevar}% \defargscommonending \endgroup} \def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}} % @deftypevr {Global Flag} int enable \def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} \def\deftypevrheader #1#2#3{\dovarind#3 \relax% \begingroup\defname {\defheaderxcond#2\relax$.$#3}{#1} \defargscommonending \endgroup} % Now define @deftp % Args are printed in bold, a slight difference from @defvar. \def\deftpargs #1{\bf \defvarargs{#1}} % @deftp Class window height width ... \def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} \def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% \begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} % These definitions are used if you use @defunx (etc.) % anywhere other than immediately after a @defun or @defunx. % \def\defcvx#1 {\errmessage{@defcvx in invalid context}} \def\deffnx#1 {\errmessage{@deffnx in invalid context}} \def\defivarx#1 {\errmessage{@defivarx in invalid context}} \def\defmacx#1 {\errmessage{@defmacx in invalid context}} \def\defmethodx#1 {\errmessage{@defmethodx in invalid context}} \def\defoptx #1 {\errmessage{@defoptx in invalid context}} \def\defopx#1 {\errmessage{@defopx in invalid context}} \def\defspecx#1 {\errmessage{@defspecx in invalid context}} \def\deftpx#1 {\errmessage{@deftpx in invalid context}} \def\deftypefnx#1 {\errmessage{@deftypefnx in invalid context}} \def\deftypefunx#1 {\errmessage{@deftypefunx in invalid context}} \def\deftypeivarx#1 {\errmessage{@deftypeivarx in invalid context}} \def\deftypemethodx#1 {\errmessage{@deftypemethodx in invalid context}} \def\deftypeopx#1 {\errmessage{@deftypeopx in invalid context}} \def\deftypevarx#1 {\errmessage{@deftypevarx in invalid context}} \def\deftypevrx#1 {\errmessage{@deftypevrx in invalid context}} \def\defunx#1 {\errmessage{@defunx in invalid context}} \def\defvarx#1 {\errmessage{@defvarx in invalid context}} \def\defvrx#1 {\errmessage{@defvrx in invalid context}} \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\undefined \newwrite\macscribble \def\scanmacro#1{% \begingroup \newlinechar`\^^M % Undo catcode changes of \startcontents and \doprintindex \catcode`\@=0 \catcode`\\=\other \escapechar=`\@ % Append \endinput to make sure that TeX does not see the ending newline. \toks0={#1\endinput}% \immediate\openout\macscribble=\jobname.tmp \immediate\write\macscribble{\the\toks0}% \immediate\closeout\macscribble \let\xeatspaces\eatspaces \input \jobname.tmp \endgroup } \else \def\scanmacro#1{% \begingroup \newlinechar`\^^M % Undo catcode changes of \startcontents and \doprintindex \catcode`\@=0 \catcode`\\=\other \escapechar=`\@ \let\xeatspaces\eatspaces\scantokens{#1\endinput}\endgroup} \fi \newcount\paramno % Count of parameters \newtoks\macname % Macro name \newif\ifrecursive % Is it recursive? \def\macrolist{} % List of all defined macros in the form % \do\macro1\do\macro2... % Utility routines. % Thisdoes \let #1 = #2, except with \csnames. \def\cslet#1#2{% \expandafter\expandafter \expandafter\let \expandafter\expandafter \csname#1\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 \. % 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\macrobodyctxt{% \catcode`\~=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\+=\other \catcode`\{=\other \catcode`\}=\other \catcode`\@=\other \catcode`\^^M=\other \usembodybackslash} \def\macroargctxt{% \catcode`\~=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\+=\other \catcode`\@=\other \catcode`\\=\other} % \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\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% \else \expandafter\parsemargdef \argl;% \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% % Add the macroname to \macrolist \toks0 = \expandafter{\macrolist\do}% \xdef\macrolist{\the\toks0 \expandafter\noexpand\csname\the\macname\endcsname}% \fi \begingroup \macrobodyctxt \ifrecursive \expandafter\parsermacbody \else \expandafter\parsemacbody \fi} \def\unmacro{\parsearg\dounmacro} \def\dounmacro#1{% \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\do\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\do \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}} % 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 be ##N where N is the position in that list. % 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. \def\parsemargdef#1;{\paramno=0\def\paramlist{}% \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,} \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} % These two commands read recursive and nonrecursive macro bodies. % (They're different since rec and nonrec macros end differently.) \long\def\parsemacbody#1@end macro% {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% \long\def\parsermacbody#1@end rmacro% {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% % This defines the macro itself. There are six cases: recursive and % nonrecursive macros of zero, one, 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 % many \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}}% \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 % many \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}% \fi \fi} \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\next=#1\futurelet\nchar\braceorlinexxx} \def\braceorlinexxx{% \ifx\nchar\bgroup\else \expandafter\parsearg \fi \next} % We mant to disable all macros during \shipout so that they are not % expanded by \write. \def\turnoffmacros{\begingroup \def\do##1{\let\noexpand##1=\relax}% \edef\next{\macrolist}\expandafter\endgroup\next} % @alias. % We need some trickery to remove the optional spaces around the equal % sign. Just make them active and then expand them all to nothing. \def\alias{\begingroup\obeyspaces\parsearg\aliasxxx} \def\aliasxxx #1{\aliasyyy#1\relax} \def\aliasyyy #1=#2\relax{\ignoreactivespaces \edef\next{\global\let\expandafter\noexpand\csname#1\endcsname=% \expandafter\noexpand\csname#2\endcsname}% \expandafter\endgroup\next} \message{cross references,} % @xref etc. \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 job is to define \lastnode. \def\node{\ENVcheck\parsearg\nodezzz} \def\nodezzz#1{\nodexxx #1,\finishnodeparse} \def\nodexxx#1,#2\finishnodeparse{\gdef\lastnode{#1}} \let\nwnode=\node \let\lastnode=\relax % The sectioning commands (@chapter, etc.) call these. \def\donoderef{% \ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}% {Ysectionnumberandtype}% \global\let\lastnode=\relax \fi } \def\unnumbnoderef{% \ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}{Ynothing}% \global\let\lastnode=\relax \fi } \def\appendixnoderef{% \ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}% {Yappendixletterandtype}% \global\let\lastnode=\relax \fi } % @anchor{NAME} -- define xref target at arbitrary point. % \newcount\savesfregister \gdef\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} \gdef\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} \gdef\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} % \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an % anchor), namely NAME-title (the corresponding @chapter/etc. name), % NAME-pg (the page number), and NAME-snt (section number and type). % Called from \foonoderef. % % We have to set \indexdummies so commands such as @code in a section % title aren't expanded. It would be nicer not to expand the titles in % the first place, but there's so many layers that that is hard to do. % % Likewise, use \turnoffactive so that punctuation chars such as underscore % and backslash work in node names. % \def\setref#1#2{{% \atdummies \pdfmkdest{#1}% % \turnoffactive \dosetq{#1-title}{Ytitle}% \dosetq{#1-pg}{Ypagenumber}% \dosetq{#1-snt}{#2}% }} % @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,,,,,,,]} \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup \unsepspaces \def\printedmanual{\ignorespaces #5}% \def\printednodename{\ignorespaces #3}% \setbox1=\hbox{\printedmanual}% \setbox0=\hbox{\printednodename}% \ifdim \wd0 = 0pt % No printed node name was explicitly given. \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax % Use the node name inside the square brackets. \def\printednodename{\ignorespaces #1}% \else % Use the actual chapter/section title appear inside % the square brackets. Use the real section title if we have it. \ifdim \wd1 > 0pt % It is in another manual, so we don't have it. \def\printednodename{\ignorespaces #1}% \else \ifhavexrefs % We know the real title if we have the xref values. \def\printednodename{\refx{#1-title}{}}% \else % Otherwise just copy the Info node name. \def\printednodename{\ignorespaces #1}% \fi% \fi \fi \fi % % If we use \unhbox0 and \unhbox1 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. \ifpdf \leavevmode \getfilename{#4}% {\turnoffactive \otherbackslash \ifnum\filenamelength>0 \startlink attr{/Border [0 0 0]}% goto file{\the\filename.pdf} name{#1}% \else \startlink attr{/Border [0 0 0]}% goto name{#1}% \fi }% \linkcolor \fi % \ifdim \wd1 > 0pt \putwordsection{} ``\printednodename'' \putwordin{} \cite{\printedmanual}% \else % _ (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 \otherbackslash % 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 a macro. \xrefprintnodename\printednodename % % But we always want a comma and a space: ,\space % % output the `page 3'. \turnoffactive \otherbackslash \putwordpage\tie\refx{#1-pg}{}% \fi \endlink \endgroup} % 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 not square brackets don't work in some documents. Particularly % one that Bob is working on :). % \def\xrefprintnodename#1{[#1]} % \dosetq is called from \setref to do the actual \write (\iflinks). % \def\dosetq#1#2{% {\let\folio=0% \edef\next{\write\auxfile{\internalsetq{#1}{#2}}}% \iflinks \next \fi }% } % \internalsetq{foo}{page} expands into % CHARACTERS @xrdef{foo}{...expansion of \page...} \def\internalsetq#1#2{@xrdef{#1}{\csname #2\endcsname}} % Things to be expanded by \internalsetq. % \def\Ypagenumber{\folio} \def\Ytitle{\thissection} \def\Ynothing{} \def\Ysectionnumberandtype{% \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\Yappendixletterandtype{% \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 } % 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{\the\inputlineno:\space} \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 X#1\endcsname }% \ifx\thisrefX\relax % If not defined, say something at least. \angleleft un\-de\-fined\angleright \iflinks \ifhavexrefs \message{\linenumber Undefined cross reference `#1'.}% \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. % \def\xrdef#1{\expandafter\gdef\csname X#1\endcsname} % Read the last existing aux file, if any. No error if none exists. \def\readauxfile{\begingroup \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 % % Make the characters 128-255 be printing characters {% \count 1=128 \def\loop{% \catcode\count 1=\other \advance\count 1 by 1 \ifnum \count 1<256 \loop \fi }% }% % % Turn off \ as an escape so we do not lose on % entries which were dumped with control sequences in their names. % For example, @xrdef{$\leq $-fun}{page ...} made by @defun ^^ % Reference to such entries still does not work the way one would wish, % but at least they do not bomb out when the aux file is read in. \catcode`\\=\other % % @ is our escape character in .aux files. \catcode`\{=1 \catcode`\}=2 \catcode`\@=0 % \openin 1 \jobname.aux \ifeof 1 \else \closein 1 \input \jobname.aux \global\havexrefstrue \global\warnedobstrue \fi % Open the new aux file. TeX will close it automatically at exit. \openout\auxfile=\jobname.aux \endgroup} % 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 \let\ptexfootnote=\footnote {\catcode `\@=11 % % Auto-number footnotes. Otherwise like plain. \gdef\footnote{% \let\indent=\ptexindent \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 fail inside footnotes because the tokens are fixed when % the footnote is read. --karl, 16nov96. % % The start of the footnote looks usually like this: \gdef\startfootins{\insert\footins\bgroup} % % ... but this macro is redefined inside @multitable. % \gdef\dofootnote{% \startfootins % 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 \futurelet\next\fo@t } }%end \catcode `\@=11 % @| 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). % \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 }% }% } % 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} % @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 \closein 1 % 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 % % 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\undefined \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 this 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 \nobreak\bigskip % 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 \line\bgroup\hss \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 \hss \egroup \bigbreak \fi % space after the image \endgroup} \message{localization,} % and i18n. % @documentlanguage is usually given very early, just after % @setfilename. If done too late, it may not override everything % properly. Single argument is the language abbreviation. % It would be nice if we could set up a hyphenation file here. % \def\documentlanguage{\parsearg\dodocumentlanguage} \def\dodocumentlanguage#1{% \tex % read txi-??.tex file in plain TeX. % Read the file if it exists. \openin 1 txi-#1.tex \ifeof1 \errhelp = \nolanghelp \errmessage{Cannot read language file txi-#1.tex}% \let\temp = \relax \else \def\temp{\input txi-#1.tex }% \fi \temp \endgroup } \newhelp\nolanghelp{The given language definition file cannot be found or is empty. Maybe you need to install it? In the current directory should work if nowhere else does.} % @documentencoding should change something in TeX eventually, most % likely, but for now just recognize it. \let\documentencoding = \comment % Page size parameters. % \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 so finicky about underfull hboxes, either. \hbadness = 2000 % Following George Bush, just 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 \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{46\baselineskip}{6in}% {\voffset}{.25in}% {\bindingoffset}{36pt}% {11in}{8.5in}% }} % Use @smallbook to reset parameters for 7x9.5 (or so) format. \def\smallbook{{\globaldefs = 1 \parskip = 2pt plus 1pt \textleading = 12pt % \internalpagesizes{7.5in}{5in}% {\voffset}{.25in}% {\bindingoffset}{16pt}% {9.25in}{7in}% % \lispnarrowing = 0.3in \tolerance = 700 \hfuzz = 1pt \contentsrightmargin = 0pt \defbodyindent = .5cm }} % 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{51\baselineskip}{160mm} {\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. % \def\pagesizes{\parsearg\pagesizesxxx} \def\pagesizesxxx#1{\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 \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.} % Define macros to output various characters with catcode for normal text. \catcode`\"=\other \catcode`\~=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\+=\other \catcode`\$=\other \def\normaldoublequote{"} \def\normaltilde{~} \def\normalcaret{^} \def\normalunderscore{_} \def\normalverticalbar{|} \def\normalless{<} \def\normalgreater{>} \def\normalplus{+} \def\normaldollar{$}%$ font-lock fix % This macro is used to make a character print one way in ttfont % where it can probably just be output, 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\_} % 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 % Set up an active definition for =, but don't enable it most of the time. {\catcode`\==\active \global\def={{\tt \char 61}}} \catcode`+=\active \catcode`\_=\active % 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} \catcode`\@=0 % \rawbackslashxx outputs one backslash character in current font, % as in \char`\\. \global\chardef\rawbackslashxx=`\\ % \rawbackslash defines an active \ to do \rawbackslashxx. % \otherbackslash defines an active \ to be a literal `\' character with % catcode other. {\catcode`\\=\active @gdef@rawbackslash{@let\=@rawbackslashxx} @gdef@otherbackslash{@let\=@realbackslash} } % \realbackslash is an actual character `\' with catcode other. {\catcode`\\=\other @gdef@realbackslash{\}} % \normalbackslash outputs one backslash in fixed width font. \def\normalbackslash{{\tt\rawbackslashxx}} \catcode`\\=\active % Used sometimes to turn off (effectively) the active characters % even after parsing them. @def@turnoffactive{% @let"=@normaldoublequote @let\=@realbackslash @let~=@normaltilde @let^=@normalcaret @let_=@normalunderscore @let|=@normalverticalbar @let<=@normalless @let>=@normalgreater @let+=@normalplus @let$=@normaldollar %$ font-lock fix } % Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of % the literal character `\'. (Thus, \ is not expandable when this is in % effect.) % @def@normalturnoffactive{@turnoffactive @let\=@normalbackslash} % 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 back turn 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 look ok in all fonts, so just make them not special. @catcode`@& = @other @catcode`@# = @other @catcode`@% = @other @c Set initial fonts. @textfonts @rm @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: gri-2.12.23/THANKS000644 000767 000024 00000001440 11310756313 014006 0ustar00kelleystaff000000 000000 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-2.12.23/src/assert.cc000644 000767 000024 00000003567 11310756313 015506 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/chopword.cc000644 000767 000024 00000011153 11310756313 016020 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/close.cc000644 000767 000024 00000003373 11310756313 015305 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/CmdFile.hh000644 000767 000024 00000005436 11370545251 015522 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/command.cc000644 000767 000024 00000075171 11354643364 015634 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/command.hh000644 000767 000024 00000003005 11310756313 015620 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/convert.cc000644 000767 000024 00000212672 11403160126 015656 0ustar00kelleystaff000000 000000 /* 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 (!image_range_exists()) { _image0 = _f_min; _image255 = _f_max; } // 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-2.12.23/src/DataFile.hh000644 000767 000024 00000010411 11310756313 015652 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/debug.cc000644 000767 000024 00000003401 11310756313 015256 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/debug.hh000644 000767 000024 00000001676 11310756313 015304 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/defaults.hh000644 000767 000024 00000004344 11310756313 016020 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/delete.cc000644 000767 000024 00000026506 11357067101 015446 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/differ.cc000644 000767 000024 00000015466 11310756313 015445 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/doline.cc000644 000767 000024 00000077537 11310756313 015467 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/draw.cc000644 000767 000024 00000270604 11605063242 015137 0ustar00kelleystaff000000 000000 /* 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; } // If it's color, extract hue/saturation/brightness if (!uses_graylevel) { 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'); } 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) { _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-2.12.23/src/endup.cc000644 000767 000024 00000002123 11310756313 015303 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/errors.hh000644 000767 000024 00000004054 11356363317 015533 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/expect.cc000644 000767 000024 00000011413 11310756313 015462 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/extern.hh000644 000767 000024 00000013617 11357067101 015522 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/file.cc000644 000767 000024 00000021256 11310756313 015117 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/files.hh000644 000767 000024 00000002370 11310756313 015310 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/filter.cc000644 000767 000024 00000016756 11310756313 015476 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/flip.cc000644 000767 000024 00000007725 11310756313 015137 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/G_string.cc000644 000767 000024 00000014352 11310756313 015753 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/G_string.hh000644 000767 000024 00000002405 11310756313 015761 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/GCounter.hh000644 000767 000024 00000002322 11310756313 015731 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/GMatrix.hh000644 000767 000024 00000006272 11310756313 015566 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/gr.cc000644 000767 000024 00000152314 11500152353 014603 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/gr.hh000644 000767 000024 00000035310 11370545516 014625 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/gr_coll.cc000644 000767 000024 00000040711 11354657654 015636 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/gr_coll.hh000644 000767 000024 00000014010 11310756313 015621 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/graxes.cc000644 000767 000024 00000103435 11357067101 015472 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/grcntour.cc000644 000767 000024 00000057072 11310756313 016050 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/gri-mode.el000644 000767 000024 00000627105 11320703435 015721 0ustar00kelleystaff000000 000000 ;; 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.70 (05 Dec 2009) ;; 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. ;; ---------------------------------------------------------------------------- ;;; 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-2.12.23/src/gri.cc000644 000767 000024 00000014240 11357067101 014755 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/gri.cmd-skel000644 000767 000024 00000556146 11605063746 016116 0ustar00kelleystaff000000 000000 # gri - scientific graphic program (version VERSION) # Copyright 2011 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]|[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 `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-2.12.23/src/gri_merge000755 000767 000024 00000014070 11310756313 015553 0ustar00kelleystaff000000 000000 #!/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 { require 'getopts.pl' ; }; 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-2.12.23/src/gri_unpage000755 000767 000024 00000003533 11310756313 015735 0ustar00kelleystaff000000 000000 #!/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 { require 'getopts.pl' ; }; 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-2.12.23/src/GriColor.cc000644 000767 000024 00000011433 11370545506 015722 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/GriColor.hh000644 000767 000024 00000005063 11310756313 015730 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/grimage.cc000644 000767 000024 00000051472 11605063214 015614 0ustar00kelleystaff000000 000000 // 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-2.12.23/src/grinterp.cc000644 000767 000024 00000013403 11310756313 016025 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/GriPath.cc000644 000767 000024 00000034410 11477470652 015547 0ustar00kelleystaff000000 000000 /* 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 (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-2.12.23/src/GriPath.hh000644 000767 000024 00000004142 11310756313 015543 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/GriState.cc000644 000767 000024 00000010631 11310756313 015715 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/GriState.hh000644 000767 000024 00000006632 11310756313 015735 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/GriTimer.hh000644 000767 000024 00000002017 11310756313 015726 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/group.cc000644 000767 000024 00000003116 11310756313 015327 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/grsmooth.cc000644 000767 000024 00000014705 11310756313 016043 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/grstring.cc000644 000767 000024 00000226514 11311462224 016037 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/heal.cc000644 000767 000024 00000012251 11310756313 015104 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/help.cc000644 000767 000024 00000020363 11310756313 015126 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/if.cc000644 000767 000024 00000011603 11310756313 014571 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/ignore.cc000644 000767 000024 00000005020 11310756313 015452 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/image.cc000644 000767 000024 00000013713 11310756313 015261 0ustar00kelleystaff000000 000000 /* 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) ? true : false); } #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-2.12.23/src/image_ex.hh000644 000767 000024 00000003036 11310756313 015764 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/input.cc000644 000767 000024 00000005315 11310756313 015335 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/insert.cc000644 000767 000024 00000005131 11310756313 015476 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/install-sh000755 000767 000024 00000011243 11310756313 015670 0ustar00kelleystaff000000 000000 #!/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-2.12.23/src/interp.cc000644 000767 000024 00000010357 11310756313 015501 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/logo.dat000644 000767 000024 00000005637 11310756313 015330 0ustar00kelleystaff000000 000000 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-2.12.23/src/macro.hh000644 000767 000024 00000011625 11310756313 015312 0ustar00kelleystaff000000 000000 /* 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_h_ #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-2.12.23/src/main.cc000644 000767 000024 00000001641 11310756313 015120 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/Makefile.am000644 000767 000024 00000023362 11310756313 015725 0ustar00kelleystaff000000 000000 ## 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-2.12.23/src/Makefile.dj2000644 000767 000024 00000005553 11310756313 016011 0ustar00kelleystaff000000 000000 # 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-2.12.23/src/Makefile.in000644 000767 000024 00000101330 11605066212 015725 0ustar00kelleystaff000000 000000 # Makefile.in generated by automake 1.10 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in install-sh 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) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = am__installdirs = "$(DESTDIR)$(bindir)" binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) 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 DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(gri_SOURCES) $(nodist_gri_SOURCES) DIST_SOURCES = $(gri_SOURCES) RECURSIVE_TARGETS = all-recursive check-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 uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) VPATH = @srcdir@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CXXFLAGS = @AM_CXXFLAGS@ 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_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@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ # gri: src/Makefile.am srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ 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 \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile .PRECIOUS: 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 install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ else :; fi; \ done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; for p in $$list; do \ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ rm -f "$(DESTDIR)$(bindir)/$$f"; \ done clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) gri$(EXEEXT): $(gri_OBJECTS) $(gri_DEPENDENCIES) @rm -f gri$(EXEEXT) $(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@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(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. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; 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; \ (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" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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 || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-recursive info-am: install-data-am: install-data-local install-dvi: install-dvi-recursive install-exec-am: install-binPROGRAMS install-exec-local install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive 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: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am all-local check check-am clean clean-binPROGRAMS \ clean-generic ctags ctags-recursive 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-recursive uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-local #### 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-2.12.23/src/mask.cc000644 000767 000024 00000005542 11310756313 015133 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/math.cc000644 000767 000024 00000030531 11310756313 015125 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/new.cc000644 000767 000024 00000010663 11310756313 014771 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/open.cc000644 000767 000024 00000020425 11310756313 015136 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/popen.cc000644 000767 000024 00000012510 11310756313 015312 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/popt/000777 000767 000024 00000000000 11607310072 014646 5ustar00kelleystaff000000 000000 gri-2.12.23/src/postscpt.hh000644 000767 000024 00000035765 11310756313 016103 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/private.hh000644 000767 000024 00000033121 11310756313 015656 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/query.cc000644 000767 000024 00000017133 11310756313 015344 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/quit.cc000644 000767 000024 00000002346 11310756313 015161 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/read.cc000644 000767 000024 00000271474 11605046076 015131 0ustar00kelleystaff000000 000000 // 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-2.12.23/src/regress.cc000644 000767 000024 00000017651 11310756313 015656 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/reorder.cc000644 000767 000024 00000013706 11310756313 015643 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/rescale.cc000644 000767 000024 00000002373 11310756313 015615 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/rewind.cc000644 000767 000024 00000003262 11310756313 015465 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/rgb.txt000644 000767 000024 00000044571 11310756313 015211 0ustar00kelleystaff000000 000000 # # 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-2.12.23/src/rpn.cc000644 000767 000024 00000017442 11310756313 015001 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/rpncalc.cc000644 000767 000024 00000171575 11310756313 015634 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/scales.cc000644 000767 000024 00000011642 11310756313 015450 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/set.cc000644 000767 000024 00000345644 11605062663 015012 0ustar00kelleystaff000000 000000 // 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, ll_y_cm, ur_x_cm, ur_y_cm; // points if (_nword == 7) { // user-units 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; } 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]"); } _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 (!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-2.12.23/src/show.cc000644 000767 000024 00000061510 11605045403 015153 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/skip.cc000644 000767 000024 00000011125 11310756313 015140 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/sleep.cc000644 000767 000024 00000002475 11310756313 015312 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/smooth.cc000644 000767 000024 00000015001 11310756313 015500 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/source.cc000644 000767 000024 00000004770 11310756313 015502 0ustar00kelleystaff000000 000000 /* 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-2.12.23/src/startup.cc000644 000767 000024 00000134176 11357067101 015711 0ustar00kelleystaff000000 000000 /* 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 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) { //printf("\t<%s>\n", *argv_leftover); 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 . 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-2.12.23/src/startup.debian����������������������������������������������������������������������000644 �000767 �000024 �00000000522 11310756313 016530� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������ gri - scientific graphic program (version VERSION) Copyright (c) 2004 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-2.12.23/src/startup.msg�������������������������������������������������������������������������000644 �000767 �000024 �00000000542 11605064011 016070� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������ gri - scientific graphic program (version VERSION) Copyright 2011 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-2.12.23/src/startup.redhat����������������������������������������������������������������������000644 �000767 �000024 �00000000527 11605064043 016561� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������ gri - scientific graphic program (version VERSION) Copyright 2011 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-2.12.23/src/state.cc����������������������������������������������������������������������������000644 �000767 �000024 �00000007273 11310756313 015323� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* 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-2.12.23/src/stats.cc����������������������������������������������������������������������������000644 �000767 �000024 �00000005610 11310756313 015332� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* 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-2.12.23/src/storage.cc��������������������������������������������������������������������������000644 �000767 �000024 �00000010605 11311246671 015642� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* 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-2.12.23/src/superus.hh��������������������������������������������������������������������������000644 �000767 �000024 �00000002753 11310756313 015721� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* 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-2.12.23/src/Synonym.hh��������������������������������������������������������������������������000644 �000767 �000024 �00000007656 11310756313 015676� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* 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-2.12.23/src/synonyms.cc�������������������������������������������������������������������������000644 �000767 �000024 �00000071354 11310756313 016103� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* 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-2.12.23/src/tags.hh�����������������������������������������������������������������������������000644 �000767 �000024 �00000032756 11310756313 015157� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* 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_h_) #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-2.12.23/src/template.cc�������������������������������������������������������������������������000644 �000767 �000024 �00000006363 11310756313 016015� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* 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-2.12.23/src/timer.cc����������������������������������������������������������������������������000644 �000767 �000024 �00000003362 11310756313 015316� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* 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-2.12.23/src/types.hh����������������������������������������������������������������������������000644 �000767 �000024 �00000006054 11310756313 015355� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* 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-2.12.23/src/unlink.cc���������������������������������������������������������������������������000644 �000767 �000024 �00000002106 11310756313 015471� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* 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-2.12.23/src/utility.cc��������������������������������������������������������������������������000644 �000767 �000024 �00000173013 11607102617 015703� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* 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) 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-2.12.23/src/variable.cc�������������������������������������������������������������������������000644 �000767 �000024 �00000021771 11310756313 015767� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* 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-2.12.23/src/Variable.hh�������������������������������������������������������������������������000644 �000767 �000024 �00000006267 11310756313 015744� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* 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-2.12.23/src/version.cc��������������������������������������������������������������������������000644 �000767 �000024 �00000002525 11605062465 015670� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* 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[] = "2011-07-07"; char _gri_date[] = "2011"; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri-2.12.23/src/while.cc����������������������������������������������������������������������������000644 �000767 �000024 �00000010115 11310756313 015300� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* 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-2.12.23/src/write.cc����������������������������������������������������������������������������000644 �000767 �000024 �00000031050 11310756313 015323� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* 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-2.12.23/src/popt/findme.c�����������������������������������������������������������������������000644 �000767 �000024 �00000002337 11310756313 016260� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* (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-2.12.23/src/popt/findme.h�����������������������������������������������������������������������000644 �000767 �000024 �00000000406 11310756313 016260� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* (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-2.12.23/src/popt/Makefile.am��������������������������������������������������������������������000644 �000767 �000024 �00000000423 11310756313 016700� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������## 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-2.12.23/src/popt/Makefile.in��������������������������������������������������������������������000644 �000767 �000024 �00000030237 11605066212 016716� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.10 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in 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) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru 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) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libgripopt_a_SOURCES) DIST_SOURCES = $(libgripopt_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) VPATH = @srcdir@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CXXFLAGS = @AM_CXXFLAGS@ 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_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@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ # gri/src/popt/ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ 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 \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/popt/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/popt/Makefile .PRECIOUS: 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 clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libgripopt.a: $(libgripopt_a_OBJECTS) $(libgripopt_a_DEPENDENCIES) -rm -f libgripopt.a $(libgripopt_a_AR) libgripopt.a $(libgripopt_a_OBJECTS) $(libgripopt_a_LIBADD) $(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@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-am info-am: install-data-am: install-dvi: install-dvi-am 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 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 all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags 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 uninstall \ uninstall-am # 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-2.12.23/src/popt/popt.c�������������������������������������������������������������������������000644 �000767 �000024 �00000035465 11310756313 016010� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* (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-2.12.23/src/popt/popt.h�������������������������������������������������������������������������000644 �000767 �000024 �00000010312 11310756313 015775� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* (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-2.12.23/src/popt/poptconfig.c�������������������������������������������������������������������000644 �000767 �000024 �00000006456 11310756313 017174� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* (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-2.12.23/src/popt/popthelp.c���������������������������������������������������������������������000644 �000767 �000024 �00000015372 11310756313 016654� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* (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-2.12.23/src/popt/poptint.h����������������������������������������������������������������������000644 �000767 �000024 �00000002356 11310756313 016521� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* (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-2.12.23/src/popt/poptparse.c��������������������������������������������������������������������000644 �000767 �000024 �00000003474 11310756313 017036� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* (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-2.12.23/src/popt/README�������������������������������������������������������������������������000644 �000767 �000024 �00000001527 11310756313 015532� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������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-2.12.23/doc/._archive-to-html.pl����������������������������������������������������������������000755 �000767 �000024 �00000000342 11310756313 017420� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mac OS X ���� ���2���°������â��������������������������������������ATTRäÖ���â���˜���J������������������˜���J��com.apple.acl.text���!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gri-2.12.23/doc/archive-to-html.pl������������������������������������������������������������������000755 �000767 �000024 �00000002665 11310756313 017215� 0����������������������������������������������������������������������������������������������������ustar�00kelley��������������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/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-2.12.23/doc/._cmdrefcard.tex000644 000767 000024 00000000342 11310756313 016671 0ustar00kelleystaff000000 000000 Mac OS X  2°âATTRäÖ â˜J˜Jcom.apple.acl.text!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write gri-2.12.23/doc/cmdrefcard.tex000644 000767 000024 00000055353 11310756313 016470 0ustar00kelleystaff000000 000000 % 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-2.12.23/doc/examples/000777 000767 000024 00000000000 11607310072 015460 5ustar00kelleystaff000000 000000 gri-2.12.23/doc/._FAQ.html000644 000767 000024 00000000342 11310756313 015352 0ustar00kelleystaff000000 000000 Mac OS X  2°âATTRäÖâ˜J˜Jcom.apple.acl.text!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write gri-2.12.23/doc/FAQ.html000644 000767 000024 00000116506 11310756313 015147 0ustar00kelleystaff000000 000000 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-2.12.23/doc/._gri-manpage-redhat.1000644 000767 000024 00000000342 11310756313 017573 0ustar00kelleystaff000000 000000 Mac OS X  2°âATTRäÖâ˜J˜Jcom.apple.acl.text!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write gri-2.12.23/doc/gri-manpage-redhat.1000644 000767 000024 00000003521 11310756313 017360 0ustar00kelleystaff000000 000000 .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-2.12.23/doc/._gri-manpage-SunOS5.1000644 000767 000024 00000000342 11310756313 017420 0ustar00kelleystaff000000 000000 Mac OS X  2°âATTRäÖâ˜J˜Jcom.apple.acl.text!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write gri-2.12.23/doc/gri-manpage-SunOS5.1000644 000767 000024 00000006047 11310756313 017213 0ustar00kelleystaff000000 000000 .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-2.12.23/doc/._gri-manpage.1000644 000767 000024 00000000342 11310756313 016326 0ustar00kelleystaff000000 000000 Mac OS X  2°âATTRäÖâ˜J˜Jcom.apple.acl.text!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write gri-2.12.23/doc/gri-manpage.1000644 000767 000024 00000005435 11310756313 016121 0ustar00kelleystaff000000 000000 .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-2.12.23/doc/gri.info000644 000767 000024 00000023342 11607300641 015301 0ustar00kelleystaff000000 000000 This is gri.info, produced by makeinfo version 4.8 from gri.texi. INFO-DIR-SECTION Scientific Applications START-INFO-DIR-ENTRY * Gri: (gri). Programming language for scientific illustration END-INFO-DIR-ENTRY  Indirect: gri.info-1: 213 gri.info-2: 299259 gri.info-3: 571148  Tag Table: (Indirect) Node: Top213 Node: Introduction2188 Node: Simple Example7690 Node: Invoking Gri9868 Node: Getting More Control21906 Node: Simple Example Revisited22752 Node: Axis Scaling26725 Node: Log And Linear28461 Node: Length28737 Node: Range29369 Node: Labels29997 Node: Position30242 Node: Fonts31225 Node: Pen Color31669 Ref: pen-color-hexadecimal33008 Node: X-y Plots37188 Node: Linegraphs37478 Node: Scattergraphs40269 Node: Formula Plots43018 Node: Contour Plots45091 Node: Pre-gridded Data45479 Node: Ungridded Data49319 Node: Images51523 Node: Reading and Creating Image Data52469 Node: Image PostScript Output56271 Node: Example Image57184 Node: Examples60835 Node: Box Plots62068 Node: Contouring64003 Node: Grayscale Images68119 Node: Combination71071 Node: Fancy74676 Node: Legend79896 Node: Polygons82682 Node: TS Diagram84407 Node: PDF Diagram86089 Node: Running Means92044 Node: Finite Element Model Mesh95214 Node: Handling Data98400 Node: Handling Headers98908 Node: Ignoring Columns101969 Node: Column Algebra103267 Node: Combining Columns104438 Node: Plotting Several Columns105046 Node: Commands107288 Node: Overview Of Gri Commands107635 Node: Command Syntax109432 Node: List Of Gri Commands110865 Node: Assert114643 Node: Cd115717 Node: Close116216 Node: Convert116465 Node: Convert Columns To Grid116965 Node: Convert Columns To Spline129778 Node: Convert Grid To Columns131336 Node: Convert Grid To Image132233 Node: Convert Image To Grid134956 Node: Create135870 Node: Create Columns From Function136186 Node: Create Image Grayscale136945 Node: Debug137455 Node: Delete138571 Node: Differentiate140042 Node: Draw140815 Node: Draw Arc143887 Node: Draw Arrow144637 Node: Draw Arrows145180 Node: Draw Axes If Needed145704 Node: Draw Axes146012 Node: Draw Border Box147279 Node: Draw Box148237 Node: Draw Circle149714 Node: Draw Contour149988 Node: Draw Curve151915 Node: Draw Essay153300 Node: Draw Gri Logo154011 Node: Draw Grid155051 Node: Draw Image Histogram155273 Node: Draw Image Palette155792 Node: Draw Image158352 Node: Draw Isopycnal158590 Node: Draw Isospice162300 Node: Draw Label Boxed163681 Node: Draw Label Whiteunder164170 Node: Draw Label For Last Curve164676 Node: Draw Label165003 Node: Draw Line From165751 Node: Draw Line Legend166238 Node: Draw Lines167279 Node: Draw Patches167939 Node: Draw Polygon168459 Node: Draw Regression Line168987 Node: Draw Symbol At169693 Node: Draw Symbol Legend171129 Node: Draw Symbol171559 Node: Draw Time Stamp174360 Node: Draw Title175090 Node: Draw Values175299 Node: Draw X Axis176643 Node: Draw X Box Plot177565 Node: Draw Y Axis178829 Node: Draw Y Box Plot179868 Node: Draw Zero Line180527 Node: End Group180962 Node: Expecting181179 Node: Filter181792 Node: Flip184509 Node: Get Env185014 Node: Group186337 Node: Heal186532 Node: Help187950 Node: If188594 Node: Ignore190946 Node: Input191138 Node: Insert192210 Node: Interpolate192949 Node: List193582 Node: Ls193986 Node: Mask194416 Node: New195164 Node: Newpage197001 Node: New Postscript File197394 Node: Open197769 Node: Opening Simple Files198196 Node: Ascii Files198408 Node: Binary Files199854 Node: NetCDF Files201776 Node: Opening Pipes202800 Node: Opening URLs207297 Node: Postscript208159 Node: Pwd209168 Node: Query209350 Node: Quit210607 Node: Read210992 Node: Read Colornames211911 Node: Read Columns212978 Node: Read Grid216984 Node: Read Image Colorscale220875 Node: Read Image Grayscale221770 Node: Read Image Mask223526 Node: Read Image224241 Node: Read From226454 Node: Read Synonym or Variable227431 Node: Read Line229560 Node: Regress229892 Node: Reorder231173 Node: Rescale232070 Node: Resize232714 Node: Return234198 Node: Rewind234459 Node: Rpnfunction234757 Node: Set236162 Node: Set Axes Style240063 Node: Set Arrow Size241528 Node: Set Arrow Type242318 Node: Set Beep243046 Node: Set Bounding Box243323 Node: Set Clip245081 Node: Set Color246800 Node: Set Colorname249196 Node: Set Contour Format249996 Node: Set Contour Label For250725 Node: Set Contour Label Position251046 Node: Set Contour Labels252004 Node: Set Dash252856 Node: Set Environment254214 Node: Set Error Action254647 Node: Set Flag254894 Node: Set Font Color255963 Node: Set Font Encoding256603 Node: Set Font Size257345 Node: Set Font To258275 Node: Set Graylevel259237 Node: Set Grid Missing259946 Node: Set Ignore Initial Newline260974 Node: Set Ignore Error Eof261368 Node: Set Image Colorscale261732 Node: Set Image Grayscale263776 Node: Set Image Missing Value Color266440 Node: Set Image Range267162 Node: Set Input Data Window269396 Node: Set Input Data Separator270524 Node: Set Line Cap271333 Node: Set Line Join272071 Node: Set Line Width272712 Node: Set Missing Value275359 Node: Set Page Size275990 Node: Set Page277047 Node: Set Panel278391 Node: Set Panels278841 Node: Set Path To280059 Node: Set Postscript Filename281712 Node: Set Symbol Size281989 Node: Set Tic Size282433 Node: Set Trace282865 Node: Set Transparency283263 Node: Set U Scale283801 Node: Set V Scale284342 Node: Set X Axis284877 Node: Set X Format288423 Node: Set X Grid289230 Node: Set X Margin289938 Node: Set X Name290710 Node: Set X Size291020 Node: Set X Type291432 Node: Set Y Axis292638 Node: Set Y Format296207 Node: Set Y Grid297016 Node: Set Y Margin297724 Node: Set Y Name298534 Node: Set Y Size298844 Node: Set Y Type299259 Node: Set Z Missing300469 Node: Show300796 Node: Skip303747 Node: Sleep304418 Node: Smooth304967 Node: Source307480 Node: Sprintf307882 Node: State308758 Node: Superuser309529 Node: System310551 Node: Unlink316206 Node: While317154 Node: Write318972 Node: Write Columns319938 Node: Write Contour320167 Node: Write Grid321107 Node: Write Image321571 Node: Programming323271 Node: Defaults324920 Node: Online Help326751 Node: Long Command Lines329393 Node: Variables329714 Node: About Variables330050 Node: User Variables332277 Node: Built-in Variables333951 Node: Synonyms340665 Node: Naming Convention341280 Node: Using Synonyms344693 Node: Generalizing Code345133 Node: Storing OS Output345579 Node: Storing User Responses346641 Node: Storing File Contents347439 Node: Extracting Words From Strings348158 Node: Important Builtin Synonyms349717 Node: Alias Synonyms351525 Node: Local Synonyms353145 Node: If Statements356729 Node: Loops359656 Node: Mathematics359863 Node: rpn Mathematics362815 Node: Stack Operators364783 Node: Rpn Functions365648 Node: Tertiary Operators366167 Node: Binary Operators366600 Node: Unary Operators371261 Ref: age-rpn-operator372148 Node: Solitary Operators381336 Node: Manipulation of Columns etc382867 Node: rpn Examples384350 Node: Text386393 Node: Embedded Synonyms387201 Node: Mathematical Text387850 Node: Non-English Text391858 Node: Adjustment Of Character Position395564 Node: Adding New Commands395978 Node: Purpose396567 Node: Parsing397826 Node: Simple New Command400329 Node: Complicated New Command402606 Node: Changeable Command Arguments405106 Node: The Ampersand Syntax406032 Node: Doubling A Variable407535 Node: Manipulating A Synonym409187 Node: Nesting409710 Node: Using New And Delete410491 Node: Determining Calling Information411613 Node: Implementation of Ampersand Syntax412492 Node: Hints414582 Node: Debugging418132 Node: Error Messages420262 Node: Missing Values422097 Node: Operating System423150 Node: Using OS Inside Gri423501 Node: Using Gri Inside OS428317 Node: Resource File429146 Node: Environment431275 Node: Extras431832 Node: gri_merge432135 Node: gri_unpage434140 Node: Using System Tools434913 Node: Why Use The Environment435564 Node: Grep437810 Node: Sed438198 Node: Awk438765 Node: Perl440550 Node: Discussion Group441614 Node: Emacs Mode442099 Node: About Gri Mode442869 Node: Gri-mode screenshots445113 Node: Screenshot 1445394 Node: Screenshot 2445956 Node: Screenshot 3446542 Node: Screenshot 4447084 Node: Installing gri-mode.el447563 Node: Step 1448951 Node: Step 2450178 Node: Step 3453712 Node: Step 4454932 Node: Major Gri-mode commands455880 Node: Gri command names456668 Node: Possible completions457528 Node: Command abbreviations459116 Node: Variable completion459862 Node: Editing the syntax460684 Node: User commands462757 Node: Gri code fragments463252 Node: Info interface464452 Node: Other features465452 Node: Dealing with many Gri versions466795 Node: Filename arguments when running gri468587 Node: History469891 Node: Stable Stream471097 Node: Version 2.12471622 Node: Version 2.10494574 Node: Version 2.8498292 Node: Version 2.6502042 Node: Version 2.4509593 Node: Version 2.2511010 Node: Unstable Stream512943 Node: Development Version513134 Node: Plans514121 Node: Deprecated Commands516058 Node: Installation516409 Node: Unix-install516638 Node: Archiving Old Versions517038 Node: Linux518479 Node: Precompiled Unix519535 Node: Uncompiled Unix520724 Node: Msdos-install527147 Node: OS2-install529735 Node: Mac-install530146 Node: Beos-install532782 Node: Bugs533029 Node: Known Bugs533306 Node: Reporting Bugs533565 Node: Killing Bugs534898 Node: Debugging Software You Will Need535144 Node: Debugging at a Glance536115 Node: Debugging Example538003 Node: Test Suite546702 Node: Gri in the Press547273 Node: Acknowledgments549607 Node: License550620 Node: Concept Index571148 Node: Index of Commands680342 Node: Index of Builtins694548  End Tag Table gri-2.12.23/doc/gri.info-1000644 000767 000024 00001110373 11607300641 015441 0ustar00kelleystaff000000 000000 This is gri.info, produced by makeinfo version 4.8 from gri.texi. INFO-DIR-SECTION Scientific Applications START-INFO-DIR-ENTRY * Gri: (gri). Programming language for scientific illustration END-INFO-DIR-ENTRY  File: gri.info, Node: Top, Next: Introduction, Prev: (dir), Up: (dir) Gri *** Gri is an extensible plotting language designed for scientists. It can draw x-y plots, contour plots, and image plots, and has rudimentary programming capabilities. It is not mouse driven, nor gui-based; rather, it is an interpreted scriping language. Users regard it as an analogue to the latex document formatting language: users gain considerable power, at the price of a moderate learning curve. This manual describes Gri version 2.12.23 (c) 1991-2011, Dan Kelley Gri is released with the GNU Public License (*Note License::). * Menu: * Introduction:: What Gri is for * Simple Example:: Introductory example * Invoking Gri:: Running/viewing/printing Gri * Getting More Control:: Controlling axes, text, color, etc. * X-y Plots:: Drawing x-y linegraphs/scattergraphs * Contour Plots:: Drawing contour plots * Images:: Drawing black+white or color images * Examples:: Some real-world examples * Handling Data:: Dealing with oddly-configured data * Commands:: All about the many Gri commands * Programming:: How to program in the Gri language * Environment:: Related tools * Emacs Mode:: Editing Gri code inside Emacs * History:: How Gri has changed over time * Installation:: How to install Gri * Bugs:: How to report on bugs * Test Suite:: Series of test programs * Gri in the Press:: Further reading * Acknowledgments:: Many folks have helped me with Gri * License:: Gri is open-source! Three indices * Concept Index:: Detailed index * Index of Commands:: Commands in Gri * Index of Builtins:: Builtin variables  File: gri.info, Node: Introduction, Next: Simple Example, Prev: Top, Up: Top 1 Introduction ************** *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 LaTeX document preparation system. *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. *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 (*Note X-y Plots::), contour plots (*Note Contour Plots::), and image plots (*Note 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. (*Note Getting More Control::), and it is a programming language of moderate power. *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 (`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 `set graylevel 1' or `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 (`set graylevel 0') and draw the curve again, so that the negative part would appear again. *Input/output* in Gri may be interactive or non-interactive. For interactive use, type `gri' at the system commandline prompt. For non-interactive use, with Gri commands in a command-file called `cmd.gri', type `gri cmd.gri'. *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. *Online help:* the Gri command `help' makes Gri list the first words of all known commands, along with a hint for getting further help. To get more information, type `help' followed by a command-name (e.g. `help read'). There is also a tiny bit of information stored online and categorized by topic. Get this by typing for example `help - strings' (*Note Online Help::). *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. *System calls* are an easy and important facet of Gri. It is easy to use operating system commands within Gri (*Note System::; *Note Operating System::; *Note 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 (*Note Open::). *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 `if' statements (*Note If Statements::), `while' loops (*Note While::), facilities for interacting with the user (*Note Query::), and mechanisms for storing numbers in "variables" (*Note Variables::), and text strings in "synonyms" (*Note Synonyms::). The Gri syntax can be augmented easily (*Note Adding New Commands::), and these augmentations can be stored in a startup file (*Note Resource File::), creating personalized versions of Gri. *Manuals:* Gri has an online texinfo manual, a PostScript manual, a WWW manual, a cookbook and several reference cards. It also has several discussion groups (*Note Discussion Group::). *Version Numbering Scheme* When you launch Gri interactively (without naming a commandfile, i.e. by just typing `gri' at the unix prompt), you'll see something like gri - scientific graphic program (version 2.12.23) GPL Copyright 2008 by Dan E. Kelley. Type `help' for an overview of Gri commands, or see the full manual at /usr/share/doc/gri-2.12.23/html/index.html and its text-only version in the 'gri' INFO node. Visit http://gri.sourceforge.net for updates and resources. gri: The last line is a prompt, suggesting that you type in Gri commands. You may type `quit' to get out of gri. The first line gives the version number. You can also get this by running Gri with the command `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.  File: gri.info, Node: Simple Example, Next: Invoking Gri, Prev: Introduction, Up: Top 2 Simple Gri Program and How to Run it ************************************** This chapter introduces Gri with a common example: an x-y graph. The example is discussed in detail later (*Note X-y Plots::). The data files and command files here and throughout the manual should be available to you in a directory `.../gri/examples' on unix machines. 2.1 Gri Command 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 `example1.dat': # 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 The first line is a comment, as are all things following hash symbols (`#'). (An exception to this rule is made within strings contained within the double-quote character `"'. This allows `sed' system commands to work as expected; (*Note System::).) The other lines are Gri command lines; (*Note X-y Plots::) for more explanation. 2.2 Data File ============= The data file `example1.dat' looks like: 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 Note that spaces (or tabs) separate numbers. Any data line may have a comment on it, just as any command line may. 2.3 Running The Command File ============================ Type `gri example1.gri' at the system prompt. Gri will create a PostScript file called `example1.ps'. For details on running Gri see *Note Invoking Gri::. 2.4 Output Graph ================ The output PostScript file is called `example1.ps'. [image src="./examples/example1.png" text="example1.gri "] 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.  File: gri.info, Node: Invoking Gri, Next: Getting More Control, Prev: Simple Example, Up: Top 3 Invoking Gri ************** 3.1 Invoking Gri in a nutshell ============================== First, the short story. In 90 percent of cases, Gri is run as gri myscript where the file `myscript.gri' holds a script (list of Gri commands), and Gri will create a PostScript file called `myscript.ps' with the output. Some folks like to give the `.gri' suffix explicitly, so they would invoke Gri as gri myscript.gri instead. If you'd rather not have `myscript.ps' as the PostScript output file name (let's say you prefer `graph1.ps') you'd do gri -output graph1.ps myscript.gri 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. 3.2 Using Gri to draw things ============================ To draw things, invoke Gri as gri [OPTIONS] [CmdFile [optional_arguments]] where the square brackets indicate that the enclosed items are optional. The `OPTIONS' item may consist of one or more of the following (explained below): [-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] Here, the optional `optional_arguments' are a mechanism to customize the action of the given Gri script from the commandline. After Gri processes standard arguments (e.g. `-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 `argc' (*Note Solitary Operators::) and `argv' (*Note Unary Operators::). For a note on usage within the Emacs gri-mode, see *Note Filename arguments when running gri::. *Details of command-line options* * `-batch' or `-b' Stops Gri from printing out prompts and hints. * `-chatty N' or `-c N' Make Gri print out various informative messages. The numerical value gives a level of chattiness. A value of 1, the default if the `-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: * *0* The bare minimum is printed. Thus invoking Gri as `gri -c 0'... will make it as quiet as can be. * *1 or higher* (the default) The full filenames of the commandfiles are displayed at startup time. `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. `convert grid to image' prints characteristics of image created, including amount of image clipped. `read grid data' reports number of data values it could not read (since they were nonnumeric). `draw symbol' reports number of data points not drawn because they were missing or outside clip region (if one exists). * *2 or higher* `draw contour' prints value of contour being drawn. `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. `show image' reports histograms in intensity bands of 8 units, instead of the default 16 units. * *3 or higher* `show image' reports histograms in intensity bands of 4 units, instead of the default 16 units. * `-debug' or `-d' Sets the built-in variable flag `..debug..' that you can use to isolate blocks of code. * `-directory_default' Reports directory where `gri.cmd' is expected to be found, either in the default location or the one specified by `-directory' commandline option. * `-directory pathname' Specifies the directory where Gri looks for the startup 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 `gri.cmd' in a standard system directory (sometimes, but not always, `/usr/local/share/gri/2.12.23') which was specified during the compilation of the Gri program itself. For more on how Gri looks for `gri.cmd', see the subsection below. * `-no_bounding_box' 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 `epsfbox' macro in `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 `set bounding box' command (*Note Set Bounding Box::). * `-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 `-creator' commandline option (see above), but they take up a little bit of space and users might sometimes want to get rid of them.) * `-no_warn_offpage' Do not warn if items are offpage. (Contrast this with `-warn_offpage'.) * `-output PS_file_name' Specify the PostScript filename. If this is not specified, the PostScript filename is derived from the name of the commandfile (e.g. `mygraph.gri' produces `mygraph.ps'), or, for interactive use, it will have a name like `gri-00.ps', or `gri-01.ps' if the former file exists, etc. * `-output SVG_file_name' 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 *Note 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. * `-no_startup_message' Stops Gri from printing the startup message. * `-private' Prevents inserting any information about the user into the PostScript file (see `-no_private', next). As of version 2.12.10, this privacy option is assumed by default. * `-no_private' 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 `-creator' commandline argument. Until version 2.12.10, the default was to include this information, but a change was made out of privacy concerns. * `-publication' or `-p' Sets the built-in variable `..publication..' to 1. You may use this to distinguish between working plots and publication plots, as in this example: if !..publication.. draw time stamp draw title "working version of plot" end if * `-superuser' (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 `-superuser' is set in addition to `-debug'). An optional value can be inserted (e.g. `-superuser 2') to set the debugging level (retrievable by the function superuser()) to indicated integer value. Specifying the `-superuser' command-line option sets the built-in variable `..superuser..' to 1 or the specified value.) For flag meanings, see `superuser' command (*Note Superuser::). Using the question-mark symbol `?' instead of a flag number makes Gri print out the list of flags. * `-trace' or `-t' Makes Gri print out command lines as they are executed; this has the same effect as the `set trace' command. * `-version' or `-v' Display version information and exit successfully. * `-warn_offpage' Causes warnings to be issued for all items drawn far off a 8.5x11 inch page. This is the default. (Contrast with `-no_warn_offpage'.) * `-yes' or `-y' Bypasses all `query' commands, making Gri act as though the user typed a carriage-return (thus giving the default) for each `query'. * `-help' or `-h' Prints explanation of options. * `CommandFile' If a command file `CommandFile' is specified, then commands will be read from that file instead of the keyboard. If the `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 `.gri'. If the filename does end in `.gri', you may delete this suffix; Gri will assume it as implied. *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 #!/usr/bin/gri (or point to wherever Gri is located on your machine), and `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. *How Gri locates the* `gri.cmd' *file*. In a normal installation, Gri finds the `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 `gri.cmd'. _Case 1_ If `-directory' was given on the commandline used to invoke Gri (e.g. `gri -directory /some/place mycommand_file.gri'), then Gri will use the `gri.cmd' in the named directory. An error will result if `gri.cmd' is not found there. _Case 2_ If `-directory' was not given on the commandline, then Gri looks for `gri.cmd' in a location that was specified during compilation. If `gri.cmd' is found there, then it is used. If it is not found, then Gri checks to see if an environment variable named `GRI_DIRECTORY_LIBRARY' is defined. If so, then Gri takes this to be the name of a directory that contains the `gri.cmd' file. If `gri.cmd' is not found there, an error results. 3.3 Extracting commandfile from a PostScript file ================================================= gri -creator PostScriptFile *See also* `-no_cmd_in_ps'. The `-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 `-no_private' commandline argument.)  File: gri.info, Node: Getting More Control, Next: Simple Example Revisited, Prev: Invoking Gri, Up: Top 4 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  File: gri.info, Node: Simple Example Revisited, Next: Axis Scaling, Prev: Getting More Control, Up: Getting More Control 4.1 An example ============== Below is a followup to the previous example, which names the x and the y axes. # 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 The difference is that the x and y axes are named with a `set' command. There are many `set' commands, and they are all pretty simple, e.g. `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 `$\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 `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. [image src="./examples/example3.png" text="example3.gri "] # 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 1 ------------------------------------------------ # # 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 x-axis be 5 cm long; in other words, make the plot 5 cm wide. set x size 5 # Put 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 simply # 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 (diameter 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" at \ {rpn 8.5 2.54 * "\label" width - 2 /} \ {rpn ..ytop.. yusertocm 2 +}\ cm  File: gri.info, Node: Axis Scaling, Next: Log And Linear, Prev: Simple Example Revisited, Up: Getting More Control 4.2 Axis scaling ================ Gri normally assumes that you are plotting scientific graphs, and therefore whenever it sees a command like `draw curve' or `draw symbol', it draws an appropriate axis first. You can turn this feature off, by using `draw axes none' before the other `draw' command. Furthermore, Gri picks axis scales by itself, by scanning the (`x', `y') columns. If you don't like the scales Gri picks, you can override them (*Note 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 `draw x axis' and `draw y axis' are placed before the `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 *axes* in the variables `..xleft..', `..xright..', `..ybottom..', and `..ytop..'. It also stores the increments used in labelling these axes in the `..xinc..' and `..yinc..' variables. To determine the minimum and maximum values of column data, you may use the built-in RPN functions `min', `max', and `mean' (*Note Manipulation of Columns etc::). Gri stores the last (x,y) pair on a curve (whether data or axis) in the `..xlast..' and `..ylast..' variables Gri stores the axis sizes in `..xsize..' and `..ysize..'. It stores the space to the left of the plot in `..xmargin..' and the space below the plot in `..ymargin..'.  File: gri.info, Node: Log And Linear, Next: Length, Prev: Axis Scaling, Up: Getting More Control 4.3 Logarithmic and linear axes =============================== Axes are linear by default; to make logarithmic axes, use commands `set x type log' and `set y type log'.  File: gri.info, Node: Length, Next: Range, Prev: Log And Linear, Up: Getting More Control 4.4 Axis Length =============== The axes are normally 10 centimetres long. To set the axis lengths (in centimetres), use commands like `set x size 5' and `set y size 7'. Some people like the ratio of axes to be in the so-called golden ratio `(root(5)-1)/2'; to get that, you could do this: set x size 15 set y size {rpn ..xsize.. 5 0.5 power 1 - 2 / *} For maps, you'll want the plot scaled so that shapes retain their aspect ratio. To do this, do `set x size .cm.' and then do `resize y for maps' (or vice versa).  File: gri.info, Node: Range, Next: Labels, Prev: Length, Up: Getting More Control 4.5 Axis Range ============== To override axis ranges set by Gri, use `set x axis' and `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, `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.  File: gri.info, Node: Labels, Next: Position, Prev: Range, Up: Getting More Control 4.6 Axis Name ============= To set the name of the x axis, use `set x name "string"', and similarly for the y-axis. The default names are `x' and `y'.  File: gri.info, Node: Position, Next: Fonts, Prev: Labels, Up: Getting More Control 4.7 Axis location ================= 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 `draw y axis at right' (so the y axis is at the right-hand end of the x range) or `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 `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 `set axes style offset' command (*Note Set::). If you want this axis style for all their plots, put the line `set axes style offset' in your `~/.grirc' startup file (*Note Resource File::).  File: gri.info, Node: Fonts, Next: Pen Color, Prev: Position, Up: Getting More Control 4.8 Fonts ========= Fonts are selected with `set font to' (*Note Set Font To::) and font sizes are selected with `set font size' (*Note 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 (*Note Text::).  File: gri.info, Node: Pen Color, Next: X-y Plots, Prev: Fonts, Up: Getting More Control 4.9 Colour of ink in pen ======================== The darkness of the "pen" used in drawing commands (for either lines or for text) is set by `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, `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: # 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. 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. The `set color \name' command Set the pen color to the indicated name. There are two types of names: hexadecimal-triplet names and English names. 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, set color ACD4EF sets a pastel blue color, almost the color of a robin's egg. The English colors are written simply in the form set color blue 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. 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 To get more colors than those provided in the above list, use the `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: `black', `red', `yellow', `green', `cyan', and `magenta'. The `set color rgb .red. .green. .blue.' 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 `set color hsb ...' style described below. Set the individual color components as follows. 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 set color rgb 0 1 0 # pure green set color rgb 1 1 0 # yellow: red + green The `set color hsb .hue. .saturation. .brightness.' command In this color model, the color ("hue") is specified with a single parameter. Many people find this easier than using the corresponding `rgb' command. Set the individual color components as follows. 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. (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 `.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 `.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: 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  File: gri.info, Node: X-y Plots, Next: Linegraphs, Prev: Pen Color, Up: Top 5 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::  File: gri.info, Node: Linegraphs, Next: Scattergraphs, Prev: X-y Plots, Up: X-y Plots 5.1 Linegraphs ============== The following Gri commands will draw a linegraph. For the output graph (*Note Getting More Control::). This plots a simple linegraph: # 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 Here's what the command lines mean: * The first line is a comment. Anything to the right of a hash-mark `#' is considered to be a comment. (This symbol is also called a "pound".) * The second line is blank. Gri ignores blank lines between commands. * `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., `open ~/data/TS/section1/T_S.dat' or `open ../data/file.dat'). You can even use "synonyms" (*Note Synonyms::.) in filenames, as in `open \BASENAME.dat'. * `read columns x y' tells Gri to start reading columnar data, the first column being `x', the second `y'. `x' and `y' are predefined names for whatever ends up on the horizontal and vertical axes. 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 `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 `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 `read columns y x'. If there were an initial column of extraneous data, the command would be `read columns * x y', or `read columns x=2 y=3' (*Note Read Columns::). * `draw curve' tells Gri to draw a curve connecting the points in the `x' and `y' columns. A nice scale will be selected automatically. (You can change this or any other plot characteristics easily, as you'll see later.) * `draw title' tells Gri to write the indicated string centered above the plot. The title *must* be enclosed in quotes. * `quit' tells Gri to exit. 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 `draw curve overlying' instead of `draw curve'. This will make it easier to distinguish the different curves.  File: gri.info, Node: Scattergraphs, Next: Formula Plots, Prev: Linegraphs, Up: X-y Plots 5.2 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 `draw symbol' for `draw curve'. Both symbols and a curve result if both `draw curve' and `draw symbols' are used. See *Note Getting More Control:: for an example. By default, the symbol used is an x. To get another symbol, use a command like `draw symbol 0' or `draw symbol plus'. To change the symbol size from the default of 0.2 cm use commands like `set symbol size 0.1' to set to 1 mm (*Note Set Symbol Size::). 5.2.1 Coding data with 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 `read columns x y z', and then draw them with `draw symbol'. Gri will interpret the rounded-integer values of the `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 `draw symbols' command; thus `draw symbol 0' puts a `+' at the data points whether or not you've read in a symbol column. 5.2.2 Drawing a 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; *Note Draw Symbol Legend::. The lines in the legend are double-spaced vertically. To change the location of the legend, alter the `.legend_x. =' and `.legend_y. =' lines. To change the spacing, alter the `.legend_y. +=' line. 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 *} 5.2.3 Coding data with symbol colors ------------------------------------ To get different colors for different symbols, read a color code into the z column, and do for example `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.  File: gri.info, Node: Formula Plots, Next: Contour Plots, Prev: Scattergraphs, Up: X-y Plots 5.3 Formula Plots ================= There are two methods for formula graphs. 1. *Use the system yourself.* Do as in this example: open "awk 'BEGIN{for(i=0;i<3.141;i+=0.05)\ {print(i,cos(i))}}' |" read columns x y close draw curve 2. *Let Gri calculate things for you* The simplest is to let Gri calculate things for you with the `create columns from function' command (*Note Create::). The command assumes that you have defined the synonym called `\function' which defines `y' in terms of `x'. Gri uses the program `awk' to create the columns, and cannot work without it. Here is an example of using `create columns from function': 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" Here's another example, in which the curve `y = 1/(\int + \sl*x)' is drawn through some data. Note how `sprintf' is used to set `\xmin' and `\xmax' using the scales that Gri has determined in reading the data. 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  File: gri.info, Node: Contour Plots, Next: Pre-gridded Data, Prev: Formula Plots, Up: Top 6 Contour Plots *************** 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  File: gri.info, Node: Pre-gridded Data, Next: Ungridded Data, Prev: Contour Plots, Up: Contour Plots 6.1 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). 6.1.1 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. \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 6.1.2 Complicated example ------------------------- To get a simple contour graph based on pre-gridded data, with full control of axes, etc, do something like this: [image src="./examples/example4.png" text="example4.gri "] # 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 for # 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" 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 `read grid x 3'. The y-grid for this example is uniform, however, so it may be specified with the `set y grid' command. It obtains values (10, 12.5, 15, 17.5, 20). The `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 `/' before the third number; thus `set x grid 0 1 /5' and `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 `read grid data' command. Since Gri already knows the grid dimensions, it will read the data appropriately. You could also have told it (`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 `bycolumns' keyword is present at the end of the `read grid' command, the first dataline will contain the first *column*, of the data. If you have an extraneous column of data to the left of your data matrix, do `read grid data * 2 3' Now Gri has the grid in its head. We tell it to draw some contours with the `draw contour' command. As the comments in the example show, the contour values will be selected automatically, but you can alter that.  File: gri.info, Node: Ungridded Data, Next: Images, Prev: Pre-gridded Data, Up: Contour Plots 6.2 Ungridded data ================== 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. 6.2.1 Example ------------- 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. [image src="./examples/example5.png" text="example5.gri "] # 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 # 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)" 6.2.2 Discussion of Methods --------------------------- The various commands for converting columns to a grid are given in (*Note Convert Columns To Grid::). Generally, the Barnes method is best.  File: gri.info, Node: Images, Next: Reading and Creating Image Data, Prev: Ungridded Data, Up: Top 7 Image Plots ************* 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. 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  File: gri.info, Node: Reading and Creating Image Data, Next: Image PostScript Output, Prev: Images, Up: Images 7.1 Reading and Creating Image Data =================================== Gri can do black and white image plots, such as satellite images. There are several ways to create image data in Gri * Create images from gridded data using `convert grid to image'. For examples see *Note Grayscale Images::), *Note Combination::, and *Note Contouring::. * Read raw ascii image data files. Use `read grid'. * Read PGM (portable graymap) ascii files. (That is, a file with magic characters `P1' or `P3' at the start.) Use the `read image pgm' command, for a file opened in ascii mode with `open filename'. * Read raw binary data, with or without headers. Use `read image', after skipping any header bytes using the `skip' command, for a file opened in binary mode with `open filename binary'. * Read a Sun "rasterfile" file (but only in uncompressed form). Use `read image rasterfile' for a file opened in binary mode with `open filename binary'. * Read a PGM (portable graymap) binary file. (A file with magic characters `P2' or `P4' at the start.) Use the `read image pgm' for a file opened in binary mode with `open filename binary'. * Aside: Images can be converted to grids (for contouring) using `convert image to grid' (*Note Convert::). Once the image is created, its grayscale/colorscale may be manipulated with the commands `set image grayscale' and `set image colorscale', which permit linear and histogram-equalized blendings over the grayscale or color range, or with `read image grayscale' and `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 `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 `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 *clip* all data outside the indicated range. In this case, any data greater than 1 in the grid would translate to *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 `draw image palette', and check it on a color monitor for bandedness, which is a sign of resolution problems.  File: gri.info, Node: Image PostScript Output, Next: Example Image, Prev: Reading and Creating Image Data, Up: Images 7.2 About The PostScript Output =============================== 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 `im': %BEGIN_IMAGE 170.70 170.70 534.86 534.86 128 128 im 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 `im' is always present on this line. Gri inserts the following comment line at the end of the image data %END_IMAGE  File: gri.info, Node: Example Image, Next: Examples, Prev: Image PostScript Output, Up: Images 7.3 Example (Satellite image) ============================= Here's an example that will plot different types of images, depending on your answers to `query' questions. The file called `\filename' is the data file, in binary format with one byte (`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 `\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 `\histo' is 1. The file in this example covers 128 * 128 pixels over the Gulf of Maine. The numbers in `\filename' correspond to surface temperatures according to the equation T = 5 + 0.1 * pixel_value which explains the following lines in the command file: \0val = "5" # 0 in image \255val = "30.5" # 255 in image Depending on `\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. Examples are shown for linear mapping and histogram mapping. [image src="./examples/example6.png" text="example6.gri "] [image src="./examples/example6histogram.png" text="example6histogram.gri "] # 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 temperature 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, then mask, each in 8-bit image format open \filename 8bit set image range \0val \255val read image .rows. .cols. box 0 0 .km. .km. close open \maskname 8bit 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  File: gri.info, Node: Examples, Next: Box Plots, Prev: Example Image, Up: Top 8 Real-world examples ********************* 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 `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  File: gri.info, Node: Box Plots, Next: Contouring, Prev: Examples, Up: Examples 8.1 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 (*Note Adding New Commands::). [image src="./examples/example7.png" text="example7.gri "] # 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"  File: gri.info, Node: Contouring, Next: Grayscale Images, Prev: Box Plots, Up: Examples 8.2 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 `awk' and `wc' from the unix system. (In the plot shown, all `query' questions were answered with carriage return, yielding the defaults; the `-p' flag was specified on execution, so the time stamp was not drawn.) [image src="./examples/example8.png" text="example8.gri "] # 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  File: gri.info, Node: Grayscale Images, Next: Combination, Prev: Contouring, Up: Examples 8.3 Image created from coarsely gridded data ============================================ This example reads gridded ascii station data (`Read Data'), creates an interpolated image (`convert grid ...'), and then plots the image. There are some other useful tricks in this example, such as calling `awk' and `wc' from the unix system. (In the plot shown, all `query' questions were answered with carriage return, yielding the defaults; the `-p' flag was specified on execution, so the time stamp was not drawn.) [image src="./examples/example9.png" text="example9.gri "] # 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  File: gri.info, Node: Combination, Next: Fancy, Prev: Grayscale Images, Up: Examples 8.4 Combination of image and contour ==================================== 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 `query' questions were answered with carriage return, yielding the defaults; the `-p' flag was specified on execution, so the time stamp was not drawn.) [image src="./examples/example10.png" text="example10.gri "] # 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'" # Example 10color -- 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'"  File: gri.info, Node: Fancy, Next: Legend, Prev: Combination, Up: Examples 8.5 Fancy x-y linegraph ======================= The following code shows a fancy plot with lots of bells and whistles. [image src="./examples/example11.png" text="example11.gri "] # Example 11 -- Fancy plot # Pen sizes, etc. # .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  File: gri.info, Node: Legend, Next: Polygons, Prev: Fancy, Up: Examples 8.6 Legends and annotated lines =============================== The following example shows how to handle annotated curves and legends. [image src="./examples/example12.png" text="example12.gri "] # 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; its 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"  File: gri.info, Node: Polygons, Next: TS Diagram, Prev: Legend, Up: Examples 8.7 Drawing gray 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. `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. }  File: gri.info, Node: TS Diagram, Next: PDF Diagram, Prev: Polygons, Up: Examples 8.8 Temperature-Salinity Diagram ================================ Here is how you might draw an oceanographic "TS" (temperature salinity) diagram: [image src="./examples/example13.png" text="example13.gri "] # 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 .Smin. = 33.4 .Smax. = 35.0 .Sinc. = 0.5 .Sincinc. = 0.1 .thetamin. = -2.0 .thetamax. = 11.0 .thetainc. = 1.0 .thetaincinc. = 1.0 set tic size .tic_size. set x name "Salinity / PSU" set y name "Potential Temperature / $\circ$C" set x axis .Smin. .Smax. .Sinc. .Sincinc. set y axis .thetamin. .thetamax. .thetainc. .thetaincinc. set axes style offset draw axes 1 set clip on .old. = ..fontsize.. set font size .isopycnal_fontsize. draw isopycnal 26.00 draw isopycnal 26.50 unlabelled draw isopycnal 27.00 draw isopycnal 27.50 unlabelled draw isopycnal 28.00 draw isopycnal 28.50 unlabelled draw isopycnal 29.00 set clip off set font size .old. # # Draw the data. open example13.dat read columns x y draw symbol bullet set font size .. draw title "Example 13 -- TS diagram, with isopycnals"  File: gri.info, Node: PDF Diagram, Next: Running Means, Prev: TS Diagram, Up: Examples 8.9 Probability Density Function Diagram ======================================== 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 `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 `tmp-xy.\.pid.'. # 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  File: gri.info, Node: Running Means, Next: Finite Element Model Mesh, Prev: PDF Diagram, Up: Examples 8.10 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). `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  File: gri.info, Node: Finite Element Model Mesh, Next: Handling Data, Prev: Running Means, Up: Examples 8.11 Finite Element Model mesh ============================== 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, `model.nodes' say, consists of a description of the x-y coordinates of the nodes (vertices) of the triangles. The second, `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 `model.nodes': 1 1 1 2 2 1 3 1 2 4 3 1.5 5 2 2 6 1.5 3 Here is the corresponding file of the elements, called `model.elements' 1 1 2 3 2 2 5 3 3 2 4 5 4 3 5 6 In each of these files, the first column is a reference number. Thus, `model.elements' indicates that the first triangle is defined by the nodes numbered `1', `2' and `3' as defined in `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 `FEM.gri', to draw the nodes is the following. 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 The work of interpreting the data files is done by the perlscript that follows, named `FEM.pl' #!/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"; }  File: gri.info, Node: Handling Data, Next: Handling Headers, Prev: Finite Element Model Mesh, Up: Examples 8.12 Handling Data ================== * 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  File: gri.info, Node: Handling Headers, Next: Ignoring Columns, Prev: Handling Data, Up: Handling Data 8.12.1 Handling headers ----------------------- 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: open file skip 10 read columns x y ... 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: open file read .skip. skip .skip. read columns x y ... Case 3 - header lines marked by a textual key. Sometimes header lines are indicated by a textual key, for example, the characters `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: open "grep -v '^HEADER' file |" For more on the `|' mechanism, see *Note Open::. The Grep command prints lines which do not match the indicated string (because of the `-v' switch), and the `^' character stands for the start of the line (*Note Grep::). Thus all lines with the key word at the *start* of the line are skiped. 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: open file read .time. read columns x y draw curve sprintf \label "Time of observation is %f hour" .time. draw title "\label" where the `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 (*Note 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 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" Here the `%.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. ... .dday. = {rpn .day. .hour. 24 / .min. 24 / 60 /} sprintf \label "Decimal day is %.4f" .dday. ... (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!)  File: gri.info, Node: Ignoring Columns, Next: Column Algebra, Prev: Handling Headers, Up: Handling Data 8.12.2 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: open file read columns y * * x draw curve where the `*' 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 open file read columns y=1 x=4 draw curve 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 open "gawk '{print($1, $4)}' file |" read columns y x draw curve For more on the Gawk command see *Note Awk::.  File: gri.info, Node: Column Algebra, Next: Combining Columns, Prev: Ignoring Columns, Up: Handling Data 8.12.3 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 open file read columns x y y *= 2 draw curve or you could use a system tool, e.g. gawk, as in this example (*Note Awk::). open "gawk '{print($1,2*$2)}' file|" read columns x y draw curve 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 (*Note 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 (*Note Awk::). open "gawk 'print {($1, $2/$1)}' file |" read columns x y draw curve  File: gri.info, Node: Combining Columns, Next: Plotting Several Columns, Prev: Column Algebra, Up: Handling Data 8.12.4 Combining columns from different files --------------------------------------------- Suppose you want to plot a column (`y', say) from one file versus a second column (`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 `paste' - but of course you don't want to clutter your filesystem with such files, so you should do this withing Gri: open "paste file1 file2 |" read columns x y draw curve  File: gri.info, Node: Plotting Several Columns, Next: Commands, Prev: Combining Columns, Up: Handling Data 8.12.5 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 1 8 11 9 2 22 21 20 3 11 10 9 4 20 15 10 in a file called `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 `~/.grirc' file and you can just use it without re-defining it each time. This will give Gri a command called `draw curves'. `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  File: gri.info, Node: Commands, Next: Overview Of Gri Commands, Prev: Plotting Several Columns, Up: Top 9 List of Commands in the Gri Language ************************************** * Menu: * Overview Of Gri Commands:: General classification of commands * Command Syntax:: Syntax of the commands * List Of Gri Commands::  File: gri.info, Node: Overview Of Gri Commands, Next: Command Syntax, Prev: Commands, Up: Commands 9.1 Overview of Gri Commands ============================ The Gri commands may be divided roughly into a few categories, as indicated in the following list. * *Working with files*: Commands are `open', `close', `skip', `read', and `rewind'. * *Controlling parameters of the drawn material*: Various `set' commands control values of parameters, like size of plot, linewidth, font, etc. * *Drawing things*: Various `draw' commands let you draw data, axes, etc. * *Interacting with the user*: The `query' command gets instructions from the user. The `show' command displays messages to user. * *Controlling program flow*: The `if' statement controls optional execution of commands (*Note If Statements::). The `while' statement allows loops. * *Moving around in directories*: The `pwd', `cd' and `ls' commands do the usual unix things. * *Using the operating system* The `system' command passes instructions to the operating system; the output may be saved into a synonym by using `\syn = system ...'. The `get env' command determines the value of any unix environment variables the system has defined. For more discussion (*Note Operating System::). * *Statistical operations*: Some very limited capabilities exist; for example, `regress' does linear regression. * *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, `set x size 10' could also be written `set x size {rpn 20 2 /}'. For details (*Note Mathematics::).  File: gri.info, Node: Command Syntax, Next: List Of Gri Commands, Prev: Overview Of Gri Commands, Up: Commands 9.2 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 `draw contour \ [.value. | \ {.min. .max. .inc. [.inc_unlabelled.]}] \ [unlabelled]' indicates that following are legal: 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 Note that items enclosed in braces must appear in their entirety; for example, draw contour 0 10 # WRONG; missing .inc. which might look similar `draw contour .min. .max. .inc.' to you, looks like garbage to Gri. Gri will recognize it as an attempt at the `draw contour' command (because the first 2 words match the syntax) but it will then get confused, spit out an error message, and quit.  File: gri.info, Node: List Of Gri Commands, Next: Assert, Prev: Command Syntax, Up: Commands 9.3 List of all Gri commands ============================ Commands are listed below in the order in which they are defined in the `gri.cmd' file (*Note 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 `grey' anywhere the manual says `gray', and `colour' for `color'.) * 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  File: gri.info, Node: Assert, Next: Cd, Prev: List Of Gri Commands, Up: List Of Gri Commands 9.3.1 `assert' -------------- `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 `"message"' string. If no `"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 `"message"' string is given, and if it ends in a newline (`"\\n"'), then this string is printed. If a `"message"' 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.)  File: gri.info, Node: Cd, Next: Close, Prev: Assert, Up: List Of Gri Commands 9.3.2 `cd' ---------- `cd [\pathname]' If a pathname specified, change to that directory. Normal unix filenames are used, as in the C-shell convention. For example, the commands `cd ~/src' and `cd $HOME/src' are equivalent. You may specify relative pathnames as in `cd ../sister_directory'. If no \pathname directory path is specified, go to the home directory, exactly as `cd ~' and `cd $HOME' do.  File: gri.info, Node: Close, Next: Convert, Prev: Cd, Up: List Of Gri Commands 9.3.3 `close' ------------- `close [\filename]' If no filename is specified, close the most recently opened data-file; otherwise close the indicated file.  File: gri.info, Node: Convert, Next: Convert Columns To Grid, Prev: Close, Up: List Of Gri Commands 9.3.4 The `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  File: gri.info, Node: Convert Columns To Grid, Next: Convert Columns To Spline, Prev: Convert, Up: Convert 9.3.4.1 `convert columns to grid' ................................. Various forms exist: `convert columns to grid OPTIONS' where the `OPTIONS' may be omitted or selected from this list: `neighbor' `boxcar [.xr. .yr. [.n. .e.]]' `objective [.xr. .yr. [.n. .e.]]' `barnes [.xr. .yr. .gamma. .iter.]' For more discussion on the methods see *Note 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 `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 is 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 (*Note 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 `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 `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. 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' (`0255 into the user values 10->20, as in set image range 10 20 set image grayscale black 10 white 20 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.  File: gri.info, Node: Create, Next: Create Columns From Function, Prev: Convert Image To Grid, Up: List Of Gri Commands 9.3.5 The `create' commands --------------------------- * Menu: * Create Columns From Function:: prepare to draw a function * Create Image Grayscale:: prepare to draw banded image  File: gri.info, Node: Create Columns From Function, Next: Create Image Grayscale, Prev: Create, Up: Create 9.3.5.1 `create columns from function' ...................................... `create columns from function' Plot a function of x which is defined in synonym \function. 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 NOTE: This only works on machines which have the `awk' command available at the commandline. This means most unix machines and some vax machines.  File: gri.info, Node: Create Image Grayscale, Next: Debug, Prev: Create Columns From Function, Up: Create 9.3.5.2 `create image grayscale' ................................ `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).  File: gri.info, Node: Debug, Next: Delete, Prev: Create Image Grayscale, Up: List Of Gri Commands 9.3.6 `debug' ------------- `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'.  File: gri.info, Node: Delete, Next: Differentiate, Prev: Debug, Up: List Of Gri Commands 9.3.7 `delete' -------------- `delete .variable.|\synonym [.variable.|\synonym [...]]' `delete columns [where missing]' `delete columns [randomly .fraction.]' `delete grid' `delete [x|y] scale' Delete some item or characteristic. * `delete .variable.' Delete definition of variable `.variable.', making it undefined. Any number of variables or synonyms may be specified on one line. * `delete \synonym' Delete definition of synonym `\synonym', making it undefined. Any number of variables or synonyms may be specified on one line. * `delete \@alias' Delete the item named by the alias (*Note Alias Synonyms::). * `delete' with an `&' item Delete the item in the calling program. * `delete columns' Delete column data. * `delete columns where missing' Completely delete all column data for which any one of x, y, etc is missing. * `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.  File: gri.info, Node: Differentiate, Next: Draw, Prev: Delete, Up: List Of Gri Commands 9.3.8 `differentiate' --------------------- `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).  File: gri.info, Node: Draw, Next: Draw Arc, Prev: Differentiate, Up: List Of Gri Commands 9.3.9 The `draw' commands ------------------------- Draw commands do actual drawing on the page. You can draw axes, lineplots, symbols, contours, images, and text. *NOTE* Gri likes drawings to have axes, so if a `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 `draw' commands with the command `draw axes none'.) Many users have been surprised by the results of this rule. For example, if you do `set graylevel 0.5' before `draw curve', you'll find that the axes are drawn in gray also. To avoid this, make sure to do `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  File: gri.info, Node: Draw Arc, Next: Draw Arrow, Prev: Draw, Up: Draw 9.3.9.1 The `draw arc' command .............................. `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 *Note Set Line Width::.  File: gri.info, Node: Draw Arrow, Next: Draw Arrows, Prev: Draw Arc, Up: Draw 9.3.9.2 `draw arrow' .................... 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.  File: gri.info, Node: Draw Arrows, Next: Draw Axes If Needed, Prev: Draw Arrow, Up: Draw 9.3.9.3 `draw arrows' ..................... `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, use `draw arrow'.  File: gri.info, Node: Draw Axes If Needed, Next: Draw Axes, Prev: Draw Arrows, Up: Draw 9.3.9.4 `draw axes if needed' ............................. `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.  File: gri.info, Node: Draw Axes, Next: Draw Border Box, Prev: Draw Axes If Needed, Up: Draw 9.3.9.5 `draw axes' ................... `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. Since this is the default, it's best to leave it out altogether to make your code easier to understand. * `.style. = 1' Draw axes without tics at top and right * `.style. = 2' Draw axes frame with no tics or labels; same as `draw axes frame' With the keyword `frame' specified, draw axes frame with no tics or labels (just like `.style.' = 2, but preferable because it makes for code that is easier to read and understand). With the keyword `none' specified, prevent Gri from automatically drawing axes when drawing curves. Note: `set axes style' can also be used to set axes properties, and then simply using `draw axes', or letting axes be auto-drawn, will result in the desired effect (*Note Set Axes Style::). However, if the `draw axes' command explicitly asks for a particular style, then it over-rides the style set by `Set Axes Style'.  File: gri.info, Node: Draw Border Box, Next: Draw Box, Prev: Draw Axes, Up: Draw 9.3.9.6 `draw border box' ......................... `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.  File: gri.info, Node: Draw Box, Next: Draw Circle, Prev: Draw Border Box, Up: Draw 9.3.9.7 `draw box' .................. `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 `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.  File: gri.info, Node: Draw Circle, Next: Draw Contour, Prev: Draw Box, Up: Draw 9.3.9.8 `draw circle' ..................... 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).  File: gri.info, Node: Draw Contour, Next: Draw Curve, Prev: Draw Circle, Up: Draw 9.3.9.9 `draw contour' ...................... `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', 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 (`.value.'), draw the indicated contour. With the addition of `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. `draw contour 1e-5 labelled "10$^{-5}$"'. 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 Interpolation method: The interpolation scheme is the same used for converting grid-values to image values (*Note Convert Grid To Image::). *See also* `set contour labels'  File: gri.info, Node: Draw Curve, Next: Draw Essay, Prev: Draw Contour, Up: Draw 9.3.9.10 `draw curve' ..................... Several forms exist. `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' `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 overlie other curves or the axes. *See also* `draw curve'. `draw curve filled [to {.y. y}|{.x. x}]' The form `draw curve filled ...' draws filled curves. If the `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 between the first and last points. 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.'  File: gri.info, Node: Draw Essay, Next: Draw Gri Logo, Prev: Draw Curve, Up: Draw 9.3.9.11 `draw essay' ..................... `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, use `set font size' before `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"  File: gri.info, Node: Draw Gri Logo, Next: Draw Grid, Prev: Draw Essay, Up: Draw 9.3.9.12 `draw gri logo' ........................ `draw gri logo .x_cm. .y_cm. .height_cm. .style. \fgcolor \bgcolor' Draw a Gri logo at given location with given style and colors. The lower-left corner of the logo will be `.x_cm.' centimeters from the left-hand side of the page and `.y_cm.' centimeters from the bottom of the page. The logo will be `.height_cm.' centimeters tall. The textual parameters `\fgcolor' and `\bgcolor' give the foreground and background colors, respectively, and these are used in styles as noted in the table below .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 An example is given below draw gri logo 1 1 3 4 blue green  File: gri.info, Node: Draw Grid, Next: Draw Image Histogram, Prev: Draw Gri Logo, Up: Draw 9.3.9.13 `draw grid' .................... `draw grid' Draw plus-signs at locations where grid data are non-missing.  File: gri.info, Node: Draw Image Histogram, Next: Draw Image Palette, Prev: Draw Grid, Up: Draw 9.3.9.14 `draw image histogram' ............................... `draw image histogram \ [box .llx_cm. .lly_cm. .urx_cm. .ury_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.  File: gri.info, Node: Draw Image Palette, Next: Draw Image, Prev: Draw Image Histogram, Up: Draw 9.3.9.15 `draw image palette' ............................. `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 *Hint* Continuous-tone images with superimposed contours are often effective. To get the contour lines drawn on the image palette, do something like this 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  File: gri.info, Node: Draw Image, Next: Draw Isopycnal, Prev: Draw Image Palette, Up: Draw 9.3.9.16 `draw image' ..................... `draw image' Draw black/white image made by `convert grid to image' or by `read image'.  File: gri.info, Node: Draw Isopycnal, Next: Draw Isospice, Prev: Draw Image, Up: Draw 9.3.9.17 `draw isopycnal' ......................... `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 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, `.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.  File: gri.info, Node: Draw Isospice, Next: Draw Label Boxed, Prev: Draw Isopycnal, Up: Draw 9.3.9.18 `draw isospice' ........................ `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 unix 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>(tabbed) second line" show "first line\<<\>>(tabbed) second line"  File: gri.info, Node: Skip, Next: Sleep, Prev: Show, Up: List Of Gri Commands 9.3.43 `skip' ------------- `skip [forward|backward] [.n.]' * `skip' For ascii files, skip next 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.' or `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.  File: gri.info, Node: Sleep, Next: Smooth, Prev: Skip, Up: List Of Gri Commands 9.3.44 `sleep' -------------- `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 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!  File: gri.info, Node: Smooth, Next: Source, Prev: Sleep, Up: List Of Gri Commands 9.3.45 `smooth' --------------- 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. `smooth {x [.n.]} \ | {y [.n.]} \ | {grid data [.f.|{along x|y}]}' 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 with 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 across `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* *Note Filter::, a generalization of `smooth x|y' which allows for more sophisticated filters.  File: gri.info, Node: Source, Next: Sprintf, Prev: Smooth, Up: List Of Gri Commands 9.3.46 `source' --------------- `source \filename' Perform the commands in the indicated file. If the file cannot be found, an error results. Contrast this with the `insert' command (*Note Insert::), which has the ability to search for the file through a user-specified path (*Note Set Path To::).  File: gri.info, Node: Sprintf, Next: State, Prev: Source, Up: List Of Gri Commands 9.3.47 `sprintf' ---------------- `sprintf \synonym "format" .variable. [.variable. [...]]' Write numbers into a synonym (text string). This is useful for labelling plots. `sprintf \out "a = %lf 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 with 2 decimal places. %9.2f -- As above, but number takes 9 characters. %e -- Use exponential notation. *CAUTION*: Variables are stored in the *floating point* in Gri, so you must use a format like `"%f"', *not* an integer code like `"%d"'. If you want an integer, use `"%.0f"'.  File: gri.info, Node: State, Next: Superuser, Prev: Sprintf, Up: List Of Gri Commands 9.3.48 `state' -------------- `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 `display' 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.  File: gri.info, Node: Superuser, Next: System, Prev: State, Up: List Of Gri Commands 9.3.49 `superuser' ------------------ `superuser [value]' 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 the system commands that are used with `open "...|"' and in other instances. * *128* Changeable; only author should use this. * *256* Changeable; only author should use this. 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.  File: gri.info, Node: System, Next: Unlink, Prev: Superuser, Up: List Of Gri Commands 9.3.50 `system' --------------- `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. 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. `system cat A | sed -e "s/foo//g" | cat > B'. (In the particular case of the `sed' command you could also do `system cat A | sed -e "s:foo::g" | cat > B'. 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 is 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. Be careful 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 (*Note Parsing::). *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. \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 *Some more examples*: * To get the first 15 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 = "-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 * 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 *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 `~' is not expanded to the home directory. For example, you should write 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 use. RETURN VALUE: Sets `\.return_value' to system status `N status'  File: gri.info, Node: Unlink, Next: While, Prev: System, Up: List Of Gri Commands 9.3.51 `unlink' --------------- `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 (*Note Using OS Inside Gri::), e.g. \tmp = tmpname # do some system commands to put data into this file open \tmp read columns x y draw curve unlink \tmp  File: gri.info, Node: While, Next: Write, Prev: Unlink, Up: List Of Gri Commands 9.3.52 `while' -------------- `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 "This loops forever. Need to 'break'" end while * 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 `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 `read' will not update the variables when the end of file is encountered.) 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  File: gri.info, Node: Write, Next: Write Columns, Prev: While, Up: List Of Gri Commands 9.3.53 The `write' commands --------------------------- The `write' commands write various things. If the filename is `stdout', the information is written to the standard output device (ie, the screen); if it is `stderr', the information is written to the standard error device (ie, the screen). *IMPORTANT NOTE*: The `write' commands *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 system rm -f the_grid.dat write grid to grid.dat * 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  File: gri.info, Node: Write Columns, Next: Write Contour, Prev: Write, Up: Write 9.3.53.1 `write columns' ........................ `write columns to \filename' Append data columns to the end of the indicated file.  File: gri.info, Node: Write Contour, Next: Write Grid, Prev: Write Columns, Up: Write 9.3.53.2 `write contour' ........................ `write contour .value. to \filename' 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 write contour 10 to contour.out open contour.out read .contour_value. .missing. set missing value .missing. read columns x y draw curve  File: gri.info, Node: Write Grid, Next: Write Image, Prev: Write Contour, Up: Write 9.3.53.3 `write grid' ..................... `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.  File: gri.info, Node: Write Image, Next: Programming, Prev: Write Grid, Up: Write 9.3.53.4 `write image' ...................... `write image ... to \filename' The variants of this command write various things about the image to the named file, as illustrated in the following table. * `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 mask.dat' Append image mask to the end of the named file, in PGM 'rawbits' format. * `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. * `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. * `write image colorscale to colorscale.dat' 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. * `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 `read image grayscale' command.  File: gri.info, Node: Programming, Next: Defaults, Prev: Write Image, Up: Top 10 Programming in the Gri Language ********************************** The Gri programming language has `if' statements to control program flow, and a `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  File: gri.info, Node: Defaults, Next: Online Help, Prev: Programming, Up: Programming 10.1 Defaults ============= 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: 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 (NOTE: Programmers may alter the gri source file `defaults.h' and then recompile Gri, if they feel the need to change these things. Also, see the file `startup.c' and the function `gr_begin()' in `gr.c'.)  File: gri.info, Node: Online Help, Next: Long Command Lines, Prev: Defaults, Up: Programming 10.2 Online Help ================ Type `help' to get a list of available commands and other topics of interest. Here's how Gri responds 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 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 `help set' and `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, help help draw help draw zero help draw zero line narrow in on the command `draw zero line'. The response to the most complete request is `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 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 `{}', 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.  File: gri.info, Node: Long Command Lines, Next: Variables, Prev: Online Help, Up: Programming 10.3 Long Command Lines ======================= To extend a command across several lines, use a backslash `\' at the *very* end of all lines but the last: draw line from \ 10 20 \ to \ 10 30  File: gri.info, Node: Variables, Next: About Variables, Prev: Long Command Lines, Up: Programming 10.4 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  File: gri.info, Node: About Variables, Next: User Variables, Prev: Variables, Up: Variables 10.4.1 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 `.number.' is a variable storing the value 10, so the two `read' statements have the same effect: .number. = 10 read columns .number. x y read columns 10 x y Variable names begin and end with a single period (example: `.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 `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., `..xsize..' saves the width of the plot). To store a number into a variable, use a command like .time. = 10 or .time. = {rpn 10 sin} 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, `new' (*Note New::), allows you to have several "versions" of a variable. This is useful for local storage in new commands, inside `if' statements, etc, since it lets you use temporary variables without worrying about overwriting values outside the local block of code. The syntax is `new .variable. = value' (where, as usual, `value' may be an rpn expression (*Note rpn Mathematics::). Here is an 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 To see if a given named variable (or synonym) exists, use the RPN operator `defined' (*Note rpn Mathematics::).  File: gri.info, Node: User Variables, Next: Built-in Variables, Prev: About Variables, Up: Variables 10.4.2 User 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: open file.dat read .num. read columns .num. x y You can define variables within the Gri program: .num. = 10 read columns .num. x y You can get variables interactively from the user, using the `query' command. (If the user types carriage-return, or if the command-line flag `-y' was specified when invoking Gri, the value 100 will be assigned to `.num.'). For example, query .num. "Number of rows to read?" (100) read columns .num. x y Gri allows you to use a previous value of the variable in the default string, as in this example: .start. = 8 # default .stop. = 2 # default query .start. "Start time? " (.start.) query .stop. "Stop time? " (.stop.) Variables can be manipulated using reverse polish notation (RPN) mathematical operations (*Note rpn Mathematics::). Variables are often useful in `if' statements. Here are some examples: 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  File: gri.info, Node: Built-in Variables, Next: Synonyms, Prev: User Variables, Up: Variables 10.4.3 Built-in variables ------------------------- Built-in variables (*Note Index of Builtins::) have names which begin and end with *two* periods. For example, `..xsize..' is the width of the x-axis in centimetres. You may use these variables as you wish (example: `..xsize.. = 4' is an alternative to `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 `show variables'. There are two types of variables * *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 `delete' them. * *Spontaneous* variables (which are created by certain Gri commands, and only exist if these commands have been executed). For example, the `regress' command defines `..coeff0..' (the intercept of the fitted line), `..coeff1..' (the slope of the fitted line), `..R2..' (the correlation coefficient). To see the values of the built-in variables (along with the user variables), use `show variables'. Here are some useful builtin variables: * `..arrowsize..' 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 (*Note Set Arrow Size::). * `..batch..' Flag used for batch mode. * `..debug..' Equal to 1 if the `-debug' command-line flag was set. Flag used for debugging (*Note Invoking Gri::). The `..debug..' built-in variable is useful in isolating code to use only in test runs. For example, you might use if ..debug.. show "Following are the column data" show columns end if When you run the program with command-line `gri -debug file.gri' the code in the `if' block will print out the columnar data, but when you run it with `gri file.gri' these lines are not printed. * `..eof..' Flag indicating whether an end-of-file was encountered on the last `read columns'. * `..words_in_dataline..' Number of words on last dataline. This is useful in constructs like 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." * `..fontsize..' Size of letters, measured in points; there are 72.27 points in an inch and 28.45 points in a centimetre. The mathematical operators `pttocm' and `cmtopt', which do conversion between points and centimetres, are often useful in labelling data curves (*Note rpn Mathematics::). * `..graylevel..' Graylevel to use in drawing lines, text, etc. Black ink is 0; white paper is 1. *See also* `..red..' etc. * `..image_height..' Height of image, or 0 if no image defined yet. * `..image_width..' Width of image, or 0 if no image defined yet. * `..length_dash..' Length in cm of dashes in dashed lines. * `..length_blank..' Length in cm of blanks in dashed lines. * `..linewidth..' Width of lines for data curves (*Note Set Line Width::). * `..linewidthaxis..' Width of lines on axes (*Note Set Line Width::). * `..linewidthsymbol..' Width of lines in symbols (*Note Set Line Width::). * `..missingvalue..' Missing value code, also stored in the synonym `\.missingvalue.'; (*Note Set Missing Value::). * `..num_col_data..' Number of column data that exist. You might want to use this after `read columns' to see if a data file actually had any data in it, or use it in accessing individual elements of columns (*Note rpn Mathematics::). * `..publication..' Flag for final copy of plot. The command-line option `-p' sets the value of `..publication..' to 1. A typical, and highly recommended, code fragment is if !..publication.. draw time stamp end if * `..red..', `..green..', `..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 *not* change the color. * `..symbolsize..' Size of symbols in centimetres. * `..superuser..' Equal to 0 if the flag was not set, or equal to the flag if it was. * `..tic_direction..' Direction of axis tics, 1 for inside or 0 for outside. * `..tic_size..' Size of axis tics in centimetres. * `..trace..' Equal to 1 if the `-trace' command-line flag was set. Used for tracing program execution. * `..xinc..' x increment on axes. * `..xleft..' x value at left of plot. * `..xmargin..' Left margin, in centimetres. * `..xright..' x value at right of plot. * `..xsize..' x-axis length in centimetres. * `..ybottom..' y value at bottom of plot. * `..yinc..' y increment on axes. * `..ymargin..' Bottom margin in centimetres. * `..ysize..' y-axis length in centimetres. * `..ytop..' y value at top of plot * `..exit_status..' The exit status from the most recent `system' call (or 0 if no system calls have been done yet). You may use any of these built-in variables anywhere. For example, here's how to stack 3 graphs vertically on the page: .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 The first line needs a bit of explanation. It is a reverse-polish expression. The format is `{' followed by `rpn' followed by an expression followed by `}'. Within the expression, spaces must separate operands. This makes `.offset.' equal to the height of y-axis plus 3 cm, so plots are separated by 3 cm. To learn more about `{rpn ... }' (*Note rpn Mathematics::). Another possibly unfamiliar thing is the 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 `.offset.'.)  File: gri.info, Node: Synonyms, Next: Naming Convention, Prev: Built-in Variables, Up: Programming 10.5 Synonyms ============= Synonyms are used by Gri to store character strings. Gri denotes synonyms with words beginning with backslash (e.g., `\syn'), following the TeX convention. * Menu: * Naming Convention:: Their names with a backslash, e.g. `\syn' * Using Synonyms:: Some usage examples * Important Builtin Synonyms:: e.g. `\.command_file.' * Alias Synonyms:: e.g. `\@alias' * Local Synonyms:: Working with the arguments of newcommands  File: gri.info, Node: Naming Convention, Next: Using Synonyms, Prev: Synonyms, Up: Synonyms 10.5.1 Naming convention for synonyms ------------------------------------- Synonym names begin with a backslash (e.g., `\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 \simple = "Howdie" \.longer_example. = "Dots and underscores are ok too" \a2 = "OK for number at end ..." \a3bb = "... and inside" 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. \{foo.bar} = "Foo bar" This is used particularly for files in the netCDF format, for reading variable attributes, which by netCDF convention use a colon (`:') to separate variable name and attribute name (*Note Read Synonym or Variable::). For more information on netCDF format, see `http://www.unidata.ucar.edu/packages/netcdf/index.html' Synonyms may be freely embedded in strings (a common example is `draw title "Data from file `\datafile'"'. They may also appear anywhere in commands (e.g., `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 `\alpha' as a synonym storing the value `"foo bar"', but Gri will ignore this within math-mode, so that `$\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., `show "The backslash character \\ is used for synonyms."'). This may sometimes be required in `system' commands (*Note System::), to prevent Gri from converting substrings like `\n' (which many system commands use to represent the newline character). For example, the command `system perl -e 'print "foo\nbar";'' will be mangled if Gri has already been told that `\nbar' is a synonym. (There will be no problem if `\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 `fooled you!' on one line line, because Gri substituted for what it thought was a synonym called `\nbar'; the second (correctly) prints `foo' on one line and `bar' on the next. \nbar = "led you!" system perl -e 'print "foo\nbar\n";' system perl -e 'print "foo\\nbar\\n";' Similarly, if your system command is expecting to see `\t' (for a tab character), then you must write `\\t' to prevent Gri from trying to substitute a synonym named `\t'. The `show' command has a special syntax for permitting newlines and tabs in strings (*Note Show::).  File: gri.info, Node: Using Synonyms, Next: Generalizing Code, Prev: Naming Convention, Up: Synonyms 10.5.2 Some uses for synonyms ----------------------------- 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::  File: gri.info, Node: Generalizing Code, Next: Storing OS Output, Prev: Using Synonyms, Up: Using Synonyms 10.5.2.1 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. \filename = "columns.dat" open \filename # a lot more code using the file name  File: gri.info, Node: Storing OS Output, Next: Storing User Responses, Prev: Generalizing Code, Up: Using Synonyms 10.5.2.2 Using synonyms to store OS output .......................................... Synonyms provided a convenient way to store information from the OS. # 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" This example uses the Unix system commands `echo' and `basename' to construct a filename ending in `.dat', from the command file name (stored in the builtin string `\.command_file.'), assuming that the command file name ends in `.gri'. NOTE: As usual, if the system command contains the Gri comment designator (the string `#'), protect it with double-quotes (*Note System::).  File: gri.info, Node: Storing User Responses, Next: Storing File Contents, Prev: Storing OS Output, Up: Using Synonyms 10.5.2.3 Storing user responses via `query' ........................................... You can ask the user for the contents of strings: query \filename "What's the data file?" ("file.dat") The prompt `What's the name of the data file?' is typed to the terminal, and whatever string the user types is inserted into the synonym `\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 `\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.  File: gri.info, Node: Storing File Contents, Next: Extracting Words From Strings, Prev: Storing User Responses, Up: Using Synonyms 10.5.2.4 Storing File Contents .............................. You can read the contents of synonyms from a file: open \directory_file read \file_name close open \file_name read columns x y The first (space-separated) word is read into the the first synonym after the `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 `read line' to get the whole line, then use the method described above to extract the word you want. Indexing begins with 0, remember.  File: gri.info, Node: Extracting Words From Strings, Next: Important Builtin Synonyms, Prev: Storing File Contents, Up: Using Synonyms 10.5.2.5 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. _The `word of' syntax._ \sentence = "This sentence has five words" \first_word = word 0 of "\sentence" \last_word = word 4 of "This sentence has five words" _The `[]' syntax_ 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 *no number* appears in the square brackets, the result is the number of words in a synonym. \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"  File: gri.info, Node: Important Builtin Synonyms, Next: Alias Synonyms, Prev: Extracting Words From Strings, Up: Synonyms 10.5.3 Some important builtin synonyms -------------------------------------- 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 (*Note Mathematical Text::). Global synonyms are shared among commands. To see the built-in global synonyms (*Note Index of Builtins::) use `show synonyms', which produces output that looks something like the following. 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. = "." These things will be obvious to unix users; for example `\.pid.' is the process ID of the job (often used in names for temporary files), and `\.wd.' is the working directory (often used in `draw title' commands to indicate in which directory the gri job was run. Some commands set `\.return_value.' to non-blank; the meaning of the return value varies from command to command.  File: gri.info, Node: Alias Synonyms, Next: Local Synonyms, Prev: Important Builtin Synonyms, Up: Synonyms 10.5.4 Alias synonyms: the `\@alias' syntax ------------------------------------------- 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 `\pointer' say, contains the *name of* another synonym, or a variable. Then you may use `\@pointer' anyplace you would normally use the item named. _Illustrations of using the value of a named item_ The following prints an approximation to Pi followed by the name of movie star. .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"' _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. # 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"  File: gri.info, Node: Local Synonyms, Next: If Statements, Prev: Alias Synonyms, Up: Synonyms 10.5.5 Local 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 `show synonyms', but they can be used freely in commands like `show "Number of words is \.words."'. * Within any new Gri command, the number of words in the line that called the command is available in `\.words.'. The RPN operator `wordc' also yields the same value (*Note Solitary Operators::). * The first word in the calling line is `\.word0.', the second `\.word1.', etc. (Note that this is the C convention, *not* the FORTRAN convention. If `\.words.' is 2, then `\.word0.' and `\.word1.' are defined, but `\.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 `\.word0.' versus `\.word1.'), then use the RPN operator `wordv' instead (*Note Unary Operators::). * Within any new Gri command, the proper calling usage is available in `\.proper_usage.'. This is useful in tests of syntax (*Note Adding New Commands::). For 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... } These synonyms help you scan for optional words in commands. Suppose you have defined a new command `New Thing [option]'. If you call it with `New Thing', then (within `New Thing') `\.words.' will be `"2"', `\.word0.' will be `"New"' and `\.word1.' will be `"Thing"'. On the other hand, if you call it with `New Thing 22.3' then `\.words.' will be `3', `\.word0.' will be `"New"', `\.word1.' will be `"Thing"' as before, and `\.word2.' will be `"22.3"'. *EXAMPLE* Here is a new command to label lines drawn by `draw curve': `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" (Note that Gri has a built-in command `draw label for last curve "\label"' written much as above, so there is no need for you to enter this new command into your `.grirc' file. But you might want to check `gri.cmd' to see how a full command does checking of the calling syntax (*Note Invoking Gri::).  File: gri.info, Node: If Statements, Next: Loops, Prev: Local Synonyms, Up: Programming 10.6 If Statements ================== Gri has `if' statements to make your programs more flexible. Here's an example: query \thick "Use thick lines? (0 or 1)" ("0") if \thick set line width 2 else set line width 0.5 end if 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 `if' can be * a number (1 means true; anything else means false) * a variable (1 means true; anything else means false). Example: if .plot_contours. draw contour end if * a synonym which expands to a number (1 means true; anything else means false). Example: \plot_contours = "1" if \plot_contours draw contour end if (Don't worry about the fact that synonyms are strings; Gri expands the string value before interpreting the `if' statement.) * an expression of the form `{string1 == string2 }'. The symbol `==' is an operator which tests for string equality. This expands to `1' if the strings are equal, or `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: if {"\variable" == "Salinity"} set x name "Salinity" else set x name "Unknown" end if * a rpn (reverse polish notation) expression (*Note rpn Mathematics::): 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 There is no need to put the else part in if you don't need it. You can do set line width 0.5 if \use_thick_lines set line width 2 end if if you wish. If you want just the else part, you can do if ! \use_thick_lines set line width 0.5 end if (The exclamation point denotes logical negation: `! true' equals `false'.) If statements may be nested many levels deep. You may also have `else if' blocks, as in: 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  File: gri.info, Node: Loops, Next: Mathematics, Prev: If Statements, Up: Programming 10.7 Loops ========== Gri provides only one type of loop, the `while' loop, described elsewhere (*Note While::).  File: gri.info, Node: Mathematics, Next: rpn Mathematics, Prev: Loops, Up: Programming 10.8 Mathematics ================ Gri lets you do some simple mathematical manipulations on your column and grid data. 10.8.1 Column data ------------------ The column operators are `=', `+=', `-=', `*=', `/=', `^=' (exponentiation) and `_=' (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 `x' and `y' as shown, but also to `z' (used to hold data to be contoured or written as symbols), and `u' and `v' (used to store vector fields). The axis scales are *not* changed by mathematical operations on the columns, regardless of whether the scales were set manually or by Gri command (*Note Axis Scaling::). Elements of columns are available by the `@' reverse polish operator (*Note rpn Mathematics::). Examples: * To multiply all the x data by 10, use `x *= 10'; to add 5 to each y-value, use `y += 5'. * To set all the y data to 10, do `y = 10'. (This will only work if you've already read column data.) See also *Note Tertiary Operators:: for a method of assigning or altering column data using the RPN operator. 10.8.2 Grid data ---------------- Various commands let you alter grid data as used in contouring (*Note Contour Plots::). Possible commands are as follows. 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' 10.8.2.1 Image data ................... Various commands let you alter image data (*Note Images::.). Possible commands are as follows. image += number image -= number image *= number image /= number image ^= number # power image _= number # logarithm 10.8.2.2 Image grayscale/colorscale ................................... Various commands let you alter image data (*Note Images::). Possible commands are as follows. 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 10.8.2.3 Variables .................. Possible commands are: .variable. = number .variable. += number .variable. -= number .variable. *= number .variable. /= number .variable. ^= number # power .variable. _= number # logarithm  File: gri.info, Node: rpn Mathematics, Next: Stack Operators, Prev: Mathematics, Up: Programming 10.9 Rpn (reverse-polish notation) Calculator ============================================= Gri can do simple mathematics on numbers. The syntax is reverse-polish notation (`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. *Syntax*: rpn expressions can be used anywhere Gri expects a number. RPN expressions start with a opening curly brace (`{') which is immediately followed by the word `rpn'. rpn expressions end with a closing curly brace (`}'). Instead of `set x size 10' you could write `set x size {rpn 20 2 /}', where the expression `{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: 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 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  File: gri.info, Node: Stack Operators, Next: Rpn Functions, Prev: rpn Mathematics, Up: rpn Mathematics 10.9.1 Stack Operators ---------------------- Stack operators manipulate or display the stack. `pop' removes the top item from the stack (*Note Unary Operators::). `dup' duplicates the top item on the stack (*Note Unary Operators::). `exch' reorders the top two items on the stack (*Note Binary Operators::). `pstack' prints the items on the stack (without changing the stack). `roll_right' rolls the items to the right. `roll_left' rolls the items to the left. For example, the following shows how you might use `exch' or `roll_right' to change the sense of a subtraction. show {rpn 1 2 -} " ... yields -1" show {rpn 1 2 exch -} " ... yields 1" show {rpn 1 2 roll_right -} " ... yields 1"  File: gri.info, Node: Rpn Functions, Next: Tertiary Operators, Prev: Stack Operators, Up: rpn Mathematics 10.9.2 Rpn function Operators ----------------------------- `rpnfunction' operators are user-defined operators. The parser replaces any such operator with the user-defined rpn expression. The `rpnfunction' operators are both general and powerful. An `rpnfunction' may be composed of any legal primitive rpn constructs or even other legal `rpnfunction' constructs. For details, (*Note Rpnfunction::).  File: gri.info, Node: Tertiary Operators, Next: Binary Operators, Prev: Rpn Functions, Up: rpn Mathematics 10.9.3 Tertiary Rpn Operators ----------------------------- `{rpn 0 4 "hello" substr }' 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 `\"hell\"'.  File: gri.info, Node: Binary Operators, Next: Unary Operators, Prev: Tertiary Operators, Up: rpn Mathematics 10.9.4 Binary Operators ----------------------- Binary operators act on the *top two* items on the stack. Most binary operators replace two items on the stack with one item, e.g. `{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 `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. `{rpn 3 2 +}' Add 2 to 3. `{rpn 3 2 -}' Subtract 2 from 3. `{rpn 3 2 *}' Multiply 3 by 2. `{rpn 3 2 /}' Divide 3 by 2. `{rpn 3 2 <}' 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 `>' where Gri uses `<'. `{rpn 3 2 <=}' Test whether 2 is less than or equal to 3. `{rpn 3 2 >}' Test whether 2 is greater than 3, yielding 0. `{rpn 3 2 >=}' Test whether 2 is greater than or equal to 3, yielding 0. `{rpn 3 2 ==}' Test whether 2 and 3 are equal, yielding 0. (Do not confuse this with the asignment operator `=', described next.) `{rpn 10 ".ten." =}' Assign the value `10' to the variable named `.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 {rpn 3.1415 ".pi." =} show .pi. the first line evaluates to a blank line, and the second prints the value of Pi. NOTE: Do not confuse this with the `==' equality operator described above. `{rpn "hello" "\\greeting" =}' Assign the value `"hello"' to the synonym `\greeting'. See notes at the above item. `{rpn 3.14159 0 "x" =}' Assign the value Pi to the first element (at index `0') of the `x' column. All columns may be assigned to in this way, e.g. the following is a technique for plotting a quadratic function: .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 `{rpn 0 1 &}' Test whether 0 and 1 are both true, yielding 0. `{rpn 0 1 and}' Test whether 0 and 1 are both true, yielding 0. `{rpn y x area}' Calculate the area under the curve y=y(x). For details (*Note Manipulation of Columns etc::). `{rpn 0 1 |}' Test whether either 0 or 1 is true, yielding 1. `{rpn 0 1 or}' Test whether either 0 or 1 is true, yielding 1. `{rpn 2 3 exch}' Exchange 2 and 3 on the stack, yielding `3 2' on the stack. (See also `pop' and `dup'.) `{rpn x 0 @}' Yields the value of the first number in the x column. A similar form also works for `y', etc. (*Note Manipulation of Columns etc::). `{rpn 2 3 inf}' Pick the smaller of two values, yielding 3. (Opposite to `sup'.) `{rpn 2 3 power}' 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 `y^x', but older calculators used the reverse convention, labelling the key `x^y'. `{rpn 2 3 remainder}' Calculate the remainder after dividing 2 by 3, yielding 2. The return value for `{rpn A B remainder}' is `B - n * A', where `n' is the quotient of `A/B', rounded towards zero to an integer. In this case, `2/3' rounds to an `n' value of zero, yielding 2 as the resulting remainder. `{rpn "heLLo" "s/L/l/g" sed}' Switch all instances of `L' into `l', yielding the string `"hello"' on the stack. This can be helpful for working with filenames, etc. The work is preformed with a system call to the `sed' utility (present on unix systems), and therefore this command will fail if `sed' is not installed, or if the OS cannot be contacted. `{rpn "file" ".dat" strcat}' Concatenate the two strings, yielding the string `"file.dat"'. `{rpn 2 3 sup}' Pick the larger of two values, yielding 3. (Opposite to `inf'.)  File: gri.info, Node: Unary Operators, Next: Solitary Operators, Prev: Binary Operators, Up: rpn Mathematics 10.9.5 Unary Operators ---------------------- Unary operators replace the last item on the stack with another item. For example, the `sin' operator takes the sine of the number on the top of the stack; e.g., `{rpn 45 sin}' yields the sine of 45 degrees. The unary operators are illustrated below, in rough alphabetical order. `{rpn 0 !}' Replace 0 (false) with its logical negation 1 (true). `{rpn 0 not}' Replace 0 (false) with its logical negation 1 (true). `{rpn -3 abs}' Calculate the absolute value of `-3'. `{rpn 0.5 acos}' Calculate the inverse cosine of 0.5, yielding 60 (degrees). `{rpn 2 acosh}' Calculate the inverse hyperbolic cosine of 2, yielding 1.317. (Note: argument must equal or exceed 1, or an error results.) `{rpn "filename" 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 `age' operator. On unix (and similar) machines, the calculation is done on unix machines with the `stat()' subroutine. On other machines, the `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.dat' using the system-executable script `creator.pl', but only to do so if `creator.pl' is younger than `file.dat'. if {rpn "file.dat" age "creator.pl" age <} system "./creator.pl > file.dat" end if open file.dat 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. `{rpn 0.5 asin}' Calculate the inverse sine of 0.5, yielding 30 (degrees). `{rpn 1 atan}' Calculate the inverse tangent of 1, yielding 45 (degrees). `{rpn 0.5 atanh}' Calculate the inverse hyperbolic tangent of 0.5, yielding 0.549306 (radians). `{rpn 0 argv}' 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 `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 `argc' solitary operator (*Note Solitary Operators::), which returns the number of optional arguments. For example, if Gri is invoked as gri myscript.gri file1.dat file2.dat and if `myscript.gri' contained .n. = {rpn argc} .i. = 0 while {rpn .n. .i. <} show "argument " .i. " is " {rpn .i. argv} .i. += 1 end while then the output would be argument 0 is myscript.gri argument 1 is file1.dat argument 2 is file2.dat For usage within the Emacs gri-mode, see *Note Filename arguments when running gri::. `{rpn "hi" ascent}' Determine ascent of this string (in cm), in the present font and fontsize. (See also `descent' and `width'.) `{rpn "3.1" atof}' Calculate the numerical value contained in indicated string. `{rpn 1.5 ceil}' Calculate the next higher integer, yielding 2. (Opposite of `floor'.) `{rpn 45 cos}' Calculate the cosine of 45 degrees, yielding 0.707. `{rpn 1 cosh}' Calculate the hyperbolic cosine of 1 (radian), yielding 1.543. `{rpn 1 cmtopt}' Convert from 1 centimeter to so-called "point" units, yielding 28.45. (Opposite of `pttocm'.) `{rpn 170 dec2hex}' 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 `\hex = {rpn 63 dec2hex}' is equivalent to `\hex = "3F"'. Compare with `hex2dec', the inverse. `{rpn "\\syn" defined}' 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.) `{rpn ".var." defined}' Test whether the variable is defined at the moment, returning 1 if so and 0 if not. `{rpn "\\@alias" defined}' Test whether the variable/synonym item that is named by the alias (*Note Alias Synonyms::) is defined at the moment, returning 1 if so and 0 if not. `{rpn "hi" descent}' Calculate the descent (below the baseline in cm) for the given string, in the present font and fontsize. (See also `ascent' and `width'.) `{rpn "/home/me/data/timeseries" directory_exists}' Determine whether indicate directory exists, yielding `1' if it does and `0' otherwise. (See also `file_exists'.) `{rpn 2 dup}' Duplicate the top item on stack, yielding `2 2' on the stack. (See also `exch' and `pop'.) `{rpn 1 exp}' Calculate the value of `e' raised to the indicated power, yielding 2.71828. `{rpn 2 exp10}' Calculate the value of `10' raised to the indicated power, yielding 100. `{rpn "foo.dat" file_exists}' Determine whether the indicate file exists, yielding `1' if it does and `0' otherwise. (See also `directory_exists'.) `{rpn 1.5 floor}' Calculate the nearest smaller integer, yielding 1. (Opposite of `ceil'.) `{rpn "AA" hex2dec}' 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, `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 `dec2hex', the inverse. `{rpn 3 ismissing}' Yields 1 if the indicated value is a "missing value" or 0 otherwise. `{rpn 100 log}' Calculate the base-10 logarithm of 100, yielding 2. `{rpn 10 ln}' Calculate the natural logarithm of 10, yielding 2.30259. `{rpn x mean}' Yields the mean value of the (non-missing) numbers in the x column. A similar form also works for `y', etc. (*Note Manipulation of Columns etc::). `{rpn x max}' Yields the largest value of the (non-missing) numbers in the x column. A similar form also works for `y', etc. (*Note Manipulation of Columns etc::). `{rpn x min}' Yields the smallest value of the (non-missing) numbers in the x column. A similar form also works for `y', etc. (*Note Manipulation of Columns etc::). `{rpn 28.45 pttocm}' Calculate the number of centimeters in 28.45 printers points, yielding 1. (Opposite of `cmtopt'.) `{rpn 1 2 pop}' Remove the top item from the stack, yielding `1' on the stack. Generates an error if the stack is empty. (See also `exch' and `dup'.) `{rpn 4 sqrt}' Calculate the square root of 4, yielding 2. (Negative arguments yield errors.) `{rpn 45 sin}' Calculate the sine of 45 (degrees), yielding 0.707107. `{rpn 2 sinh}' Calculate the hyperbolic sine of 2, yielding 3.62686. `{rpn "hello" strlen}' Determine the number of characters in string, including the quotation marks, e.g. 7 here. `{rpn "date" system}' Call the indicated system function and insert its ouput on the stack, yielding the date as a character string. `{rpn 45 tan}' Calculate the tangent of 45 (degrees), yielding 1. `{rpn tanh}' Calculate the hyperbolic tangent of 2, yielding 0.964028. `{rpn "hi" width}' Determine width of this string (in cm), in the present font and fontsize. (See also `ascent' and `descent'.) `{rpn 0 wordv}' Returns the first word used in invoking the present command. Similar to the `\.word0.' synonym (*Note Local Synonyms::). 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} 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 (`let', `us', and `test'). `{rpn 1 xusertocm}' Calculate the x coordinate, in centimeters measured from left-hand side of page, corresponding to a user-value of x=1. (Opposite of `xcmtouser'.) `{rpn 1 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 `xusertocm'.) `{rpn 1 yusertocm}' Calculate the y coordinate, in centimeters measured from bottom side of page, corresponding to a user-value of x=1. (Opposite of `ycmtouser'.) `{rpn 1 ycmtouser}' Calculate the y value, in user units, for a point that is 1 centimeter from the bottom edge of the paper. (Opposite of `yusertocm'.)  File: gri.info, Node: Solitary Operators, Next: Manipulation of Columns etc, Prev: Unary Operators, Up: rpn Mathematics 10.9.6 Solitary Operators ------------------------- 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. `{rpn argc}' Yields number of command-line arguments given by the user when Gri was invoked. Thus, invoking Gri as gri myfile.gri file1.dat file2.dat yields 3, for arguments `myfile.gri', `file1.dat', and `file2.dat'. These arguments are accessible through the `argv' unary operator (*Note Unary Operators::). `{rpn e}' Yields the base of natural logarithms, i.e. `2.718'... `{rpn pi}' Yields Pi, i.e. `3.141'... `{rpn rand}' Generate a random number in the range 0 to 1, using the C subroutine `drand48()' if it is available, otherwise the less well-distributed `rand()' subroutine. `{rpn wordc}' Returns number of words used in invoking the present command. Similar to the `\.words.' synonym (*Note Local Synonyms::). 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" The operator `wordv' may be used to extract the words of the command (*Note Unary Operators::).  File: gri.info, Node: Manipulation of Columns etc, Next: rpn Examples, Prev: Solitary Operators, Up: rpn Mathematics 10.9.7 Manipulation of Columns etc ---------------------------------- 10.9.7.1 Columns ................ Individual data in the `x', `y', `z', `u', `v' and `weight' columns can be accessed with the `@' operator. The first point has index 0. Examples: 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 The mean value is available from the `mean' operator (e.g., `.xmean. = {rpn x mean }', while the standard deviation is given by `stddev', the skewness is given by `skewness', and the kurtosis is given by `kurtosis' (using the definition that yields 3 for a gaussian distribution). The minimal and maximal values are given by `min' and `max'. The area under the curve y=y(x) is found by `{rpn y x area }', defined by `0.5 * sum ( (y[i] + y[i-1]) * (x[i] - x[i-1]) )' for `i' ranging from 1 to `..num_col_data..'-1. 10.9.7.2 Grid ............. Grid data can be accessed with e.g. `{rpn grid min } ', `{rpn grid max } ', and `{rpn grid mean } '. The value of the grid at a given `(.x.,.y.)' coordinate may be found by by e.g. `{rpn grid .x. .y. interpolate}'. The interpolation scheme is the same as that used in converting grids to images.  File: gri.info, Node: rpn Examples, Next: Text, Prev: Manipulation of Columns etc, Up: rpn Mathematics 10.9.8 rpn Examples ------------------- Here are some reverse-polish expressions and the corresponding algebraic interpretations: * `{rpn 1 2 + 10 / }' = (1+2)/10 * `{rpn .a. .b. + .c. + .d. / }' = (.a.+.b.+.c.)/.d. * `{rpn e 2 / }' = e/2 (Gri knows values of "e" and "pi") * `{rpn 23 sin 100 * 12 cos + }' = cos(12) + 100sin(23) * `{rpn 5 2 power }' = 25 * `{rpn 2 log exp }' = exp(log 2) * `{rpn 2 ln exp10 }' = 10^ln2 * `{rpn 1.7 floor }' = 1 (rounds down to nearest integer. Note that the floor of -1.7 is -2) * `{rpn 10.1 2 remainder }' = 0.1 (remainder of 10.1 after division by 2; see C function `remainder(x,y)') * `{rpn -10.1 2 remainder }' = -0.1 * `{rpn -10.1 -2 remainder }' = -0.1 * `{rpn .num. 10 > }' = 1 if 10 exceeds .num., or 0 otherwise NOTES: * The units of `sin', `cos', etc, are degrees, not radians. * The scales of the plot are accessible to `rpn'. For example, with the command draw label "hi" at 10 20 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: draw label "\label" at \ {rpn .x. xusertocm 0.15 + xcmtouser} \ {rpn .y. yusertocm 0.10 - ycmtouser} (Note that the x and y scales have individual translations from "user" to "cm" coordinates.) * Some conversion factors are built into `rpn'; `cmtopt' converts from centimetres to points (by dividing by 28.45; the conversion factor to inches is 72.27) while `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: draw curve .y. = {rpn ..ylast.. yusertocm 0.5 - ycmtouser} draw label "Smoothed" at ..xlast.. .y.  File: gri.info, Node: Text, Next: Embedded Synonyms, Prev: rpn Examples, Up: Programming 10.10 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  File: gri.info, Node: Embedded Synonyms, Next: Mathematical Text, Prev: Text, Up: Text 10.10.1 Embedding synonyms in quoted text strings ------------------------------------------------- *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 query \filename "File to read from?" ("data.file") open \filename read columns x y draw curve draw title "data from \filename" Within math strings (ie, between matched dollar-signs), these synonyms are disabled, and only the mathematical symbols and Greek letters work.  File: gri.info, Node: Mathematical Text, Next: Non-English Text, Prev: Embedded Synonyms, Up: Text 10.10.2 Mathematical text ------------------------- 10.10.2.1 Subscripts .................... As in TeX and LaTeX, 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: draw title "$a_2$" For multiple-character subscripts, insert braces before and after the item to be subscripted: draw title "$a_{22}$" 10.10.2.2 Superscripts ...................... As in TeX and LaTeX, 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: draw title "$a^2$" For multiple-character superscripts, insert braces before and after the item to be superscripted: draw title "$a^{22}$" 10.10.2.3 Mathematical symbols .............................. 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): \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 For example, you might use these as follows: draw title "$\alpha$ = thermal expansion coefficient" 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. TeX and LaTeX handle combinations of superscripts and subscripts very cleanly, putting one above the other. Presently, Gri does not do this; for example `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 `\!' 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 `set x name "$A_1\!\!\!^2"', the 2 will be positioned above the 1. (Equivalently, you could write `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 `\,' 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 `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"): draw label "h${\!\!\!^{^\wedge}}$" at 10 12 cm To get an overbar on a rho, do this: draw label "$\rho\!\!\!\!^-$" at 3 3 cm  File: gri.info, Node: Non-English Text, Next: Adjustment Of Character Position, Prev: Mathematical Text, Up: Text 10.10.3 Non-English characters ------------------------------ 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 `Set Font Encoding' command (*Note 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. Since many users will prefer the Emacs editor, a few words about that are in order. For complete information about entering iso-latin-1 characters in Emacs, consult your Emacs manual in the section *Note (emacs)Single-Byte Character Support:: which describes the available methods suitable for the Emacs version you are using. A few examples are nevertheless provided below. Consider the task of inserting French text, with the Emacs text-editor. There are several ways of doing this (and you may wish to consult your emacs info manual). A method that works in emacs-19 up to current emacs-20 versions uses the emacs `iso-transl.el' package by putting the following in your `~/.emacs' file: (require 'iso-transl) (iso-transl-set-language "French") (standard-display-european t) Loading the iso-transl package defines three ways of entering the non-ASCII printable characters with codes above 127: the prefix `C-x 8', or the key, or a dead accent key. For example, you can enter uppercase A-umlaut as `C-x 8 " A' or `Alt-" A' (if you have an Alt key) or `umlaut A' (if you have an umlaut/diaeresis key). A more recently introduced method is to enter the mode which allows quick insertion of iso-latin-1 characters. Do the Emacs command `M-x iso-accents-mode' (either manually, or in a hook that's done automatically). Now, suppose the x-axis is to represent temperature. All you'd have to do is type in the command set x name "Temp'erature" As you type, the quote mark will dissappear, and reappear as an accent on the `e'. And then, Gri will recognize this accented `é', and it will draw the accent on the axis label. Perhaps the future default way of accomplishing this task is to use MULE support directly. First, customize MULE using `M-x customize-group RET mule' setting the `current language environment' (e.g. latin-1) and the `default input method' (e.g. latin-1-prefix). Then, invoking `M-x toggle-input-method' (e.g. ) toggles into a mode similar to the `iso-accents-mode' minor-mode described above.  File: gri.info, Node: Adjustment Of Character Position, Next: Adding New Commands, Prev: Non-English Text, Up: Text 10.10.4 Adjustment Of Character Position ---------------------------------------- Micro-positioning is available within math-mode, via the symbols `\!' (which means go left one thin-space) and `\,' (which means go right one thin-space). (A thin-space is 1/6 the width of the letter "M").  File: gri.info, Node: Adding New Commands, Next: Purpose, Prev: Adjustment Of Character Position, Up: Programming 10.11 Adding new commands to Gri ================================ 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  File: gri.info, Node: Purpose, Next: Parsing, Prev: Adding New Commands, Up: Adding New Commands 10.11.1 Purpose of newcommands ------------------------------ Gri can be extended easily. Primitive commands (e.g. `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: new .old_graylevel. .old_graylevel. = ..graylevel.. set graylevel 0.5 draw curve filled to 0 y set graylevel .old_graylevel. delete .old_graylevel. This gets a bit tedious, and it would obviously be nicer to just say something like Draw my kinda curve To make this shortcut, you'd tell Gri about the existence of a new command called `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., (*Note Resource File::).  File: gri.info, Node: Parsing, Next: Simple New Command, Prev: Purpose, Up: Adding New Commands 10.11.2 How Gri parses commands ------------------------------- Whenever Gri reads a command line, it compares it with its list of commands. This list is searched in this order: (1) the universal `gri.cmd' file (*Note Invoking Gri::), (2) your resource file (*Note 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 * A quote (e.g. `"string"') * A synonym name (e.g. `\file') * A variable name (e.g. `.number.') * An opening square bracket (e.g. `[option]') * An opening brace (e.g. `{a|b}') * A choice between two items (e.g. `first|second') * A variable-name with a `&' character immediately to the left (e.g. `&.var.'). This is a signal that the variable may be changed inside the newcommand (*Note The Ampersand Syntax::). * A synonym-name with a `&' character immediately to the left (e.g. `&\syn'). This is a signal that the synonym may be changed inside the newcommand (*Note The Ampersand Syntax::). 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 *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. `Draw foo' Draw a foo. { show "drawing a foo" } `Draw foo bar' Draw a foo bar. { show "drawing a foo bar" } Gri searches the `gri.cmd' file first, so any new command that you create that clashes with built-in commands will be ignored by Gri (*Note 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 `~/.grirc' file).  File: gri.info, Node: Simple New Command, Next: Complicated New Command, Prev: Parsing, Up: Adding New Commands 10.11.3 Simple example of a new command --------------------------------------- To make a new command called `Show The Time' insert the following into your `~/.grirc' resource file or into your command-file somewhere near the top, or at least before you use the command. `Show The Time' New command to show the time of day. { show "\.time." } EXPLANATION: * 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. *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 ERROR: Can't extract syntax for new command * Following the name line, you may optionally insert any number of lines which will become the `help' information for the new command. See the file `gri.cmd' for the recommended stylistic conventions in writing help information (*Note Invoking Gri::). If your `help' text includes an example that uses an opening brace (`{') you must escape the brace with a backslash, e.g. (`\{'). * Following the help lines, if they exist, the body of the new command is given, sandwiched between a starting line containing an opening brace (`{') as the *only* nonwhite character, and an ending line containing a closing brace (`}') 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). *Formatting convention:* It is usual, but not necessary, to use an indentation level of 2 spaces in the body of the new command. The new command is invoked by `Show The Time'. Help for the command is found by `help Show The Time' or `help Show'.  File: gri.info, Node: Complicated New Command, Next: Changeable Command Arguments, Prev: Simple New Command, Up: Adding New Commands 10.11.4 Complicated example of a new command -------------------------------------------- The following example from the global `gri.cmd' file illustrates how to parse/check the commandline (*Note Local Synonyms::), which is a good practice in any code you expect to re-use. The first `if' statement checks that the word `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 `cm' is checked for, and user units or cm units are used accordingly. Local variables are created (`new') and then destroyed (`delete') so that this new command cannot affect outside code. `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. }  File: gri.info, Node: Changeable Command Arguments, Next: The Ampersand Syntax, Prev: Complicated New Command, Up: Adding New Commands 10.11.5 Altering command arguments - the `&' 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. `&.variable.') * Manipulating A Synonym:: Synonyms (e.g. `&\synonym') * Nesting:: Newcommands called by newcommands * Using New And Delete:: Isolating local variables and synonyms * Determining Calling Information:: The `\&.word?.' and `\&&.word?.' syntax * Implementation of Ampersand Syntax:: Algorithm Gri uses  File: gri.info, Node: The Ampersand Syntax, Next: Doubling A Variable, Prev: Changeable Command Arguments, Up: Changeable Command Arguments 10.11.5.1 Overview of the `&' 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 `&' to the left of the item on the calling line. Then, within the newcommand, the corresponding local synonym (i.e. `\.word1.', etc.) will behave as though it were the instance of the original variable or synonym. The `&' is placed to the left of the variable-name or synonym-name without intervening space. For example `foo &.var. &\syn' tells the parser that the newcommand named `foo' may possibly alter the values of the variable `.var.' and the synonym `\syn', as they exist in the calling context. It is important to note that Gri pays very little attention to the `&' in a syntax-declaration line. All it does is to note that the item to the right of the `&' is not a fixed word in the newcommand being defined; this follows the usual rules for parsing newcommand syntax (*Note Parsing::).  File: gri.info, Node: Doubling A Variable, Next: Manipulating A Synonym, Prev: The Ampersand Syntax, Up: Changeable Command Arguments 10.11.5.2 Example: doubling a variable ...................................... Consider the task of adding a fixed amount to a variable. If the variable we wish to double is `.x.', we might write `double_a_particular_variable' { .x. = {rpn .x. 2 *} } .x. = 10 double_a_particular_variable Code such as that presented above occurs in many applications. (Turn the multiplication into an addition, and change `.x.' to `..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. `double &.value.' { \.word1. = {rpn \.word1. 2 *} # line 3 } .x. = 10 # line 5 double &.x. .y. = 3.14 double &.y. At line 3 Gri interprets the `\.word1.' to the *left* of the equals sign as a reference to the variable that is set to the value 10 in line 5. Similarly, the `\.word1.' to the *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 \.word1. = "hello" # ERROR an error would be reported, since `double' was called with a variable as an argument, and variables cannot hold strings.  File: gri.info, Node: Manipulating A Synonym, Next: Nesting, Prev: Doubling A Variable, Up: Changeable Command Arguments 10.11.5.3 Example: manipulating a synonym ......................................... Synonyms are treated in the same way, as is illustrated in the following example. Q: what does the following print? `add_a_dat &\filename' { \.word1. = {rpn "\.word1." ".dat" strcat} } \filename = "test" add_a_dat &\filename show "\filename" A: it prints `test.dat'.  File: gri.info, Node: Nesting, Next: Using New And Delete, Prev: Manipulating A Synonym, Up: Changeable Command Arguments 10.11.5.4 Nesting ................. One newcommand may call another, letting a deeply-nested newcommand alter values of synonyms and variables that may otherwise be hidden behind `new' items of the same name. This is done by using the `&' notation at each step. The following provides an example of passing a variable through two levels of newcommands. Q: what does the following print? `food critic &food' { \.word2. = "\.word2.s" yummy &\.word2. } `yummy &foods' { \.word1. = "\.word1. are tasty" } \a = "apple" food critic &\a show "\a" A: it prints `apples are tasty'.  File: gri.info, Node: Using New And Delete, Next: Determining Calling Information, Prev: Nesting, Up: Changeable Command Arguments 10.11.5.5 About `new' and `delete' .................................. If `new' and `delete' are executed on local synonyms inside newcommands (e.g. `new \.word1.') they create and destroy variables and synonyms in the context of the *calling program*. For example, consider the following. Q: what does the following print? `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" A: it prints `A rose is a rose'. The key point here is that the instance of the synonym named `\s' in the calling program, set in line 8, is modified by the `poetry' newcommand, in line 6. This modification involves the use of a synonym, *also named* `\s', that "lives" wholly within the newcommand, being created in line 3 and destroyed in line 6.  File: gri.info, Node: Determining Calling Information, Next: Implementation of Ampersand Syntax, Prev: Using New And Delete, Up: Changeable Command Arguments 10.11.5.6 Determining calling information ......................................... 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. `NC &.var.' { show "\&.word1. (expect '.a.')" show "\&&.word1. (expect 0)" } .a. = 1 NC &.a. *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 (*Note Alias Synonyms::).  File: gri.info, Node: Implementation of Ampersand Syntax, Next: Hints, Prev: Determining Calling Information, Up: Changeable Command Arguments 10.11.5.7 How Gri implements the `&' syntax ........................................... When the parser encounters an unquoted `&' followed immediately by the name of a variable or a synonym, it converts the whole token (`&' plus name) into a specially-encoded string that can be recognized inside newcommands. (This is *only* done if the `&' and the variable name are *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 `new', that won't be misinterpreted for the identically-named variables in the calling program. The format of these specially-encoded strings is `#\bn\ba\bm\be\b:\bN \b_ \bl\be\bv\be\bl\b:\bL#\b', where `N' stands for the name of the variable/synonym, `L' stands for the current level, and `\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 `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 `N_L'. Examples: `.a.' in the main program (i.e. at level 0) encodes to `#\bn\ba\bm\be\b:\b.a. \b_ \bl\be\bv\be\bl\b:\b0#\b' and `&\my_syn' inside a newcommand called by the main program (i.e. at level 1) encodes to `#\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. `\.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 `new' inside the newcommand.  File: gri.info, Node: Hints, Next: Debugging, Prev: Implementation of Ampersand Syntax, Up: Programming 10.12 Hints for Gri Programming =============================== Here are some hints for good Gri programs: * Whenever working with grids (for contouring) or images, make use of the `show grid' or `show image' commands. They will give you useful information about the statistics (min/max/histogram) of the items. * 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: open "gawk '{print $1/100, sin($3)}' |" read columns x y 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 (*Note Open::). * Use the `pstack' operator liberally in your rpn expressions to see what is going on (*Note rpn Mathematics::). * While developing programs, put a `show columns statistics' command after every `read column' command, to check that the data have been read correctly. * 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 `.n.' into something large.) .n. = 100 # 10000 for later ... # Panel 1 read columns .n. x y ... # Panel 2 read columns .n. x y ... * Create new commands to do repetitive work. * Use `draw time stamp' on all plots except for publication versions: if !..publication.. draw time stamp end if * For multiple panels on one page, do `delete x scale' or `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. * Use the `..num_col_data..' built-in variable to see how many data have passed the `set input data window' data window in the last `read columns' command. The following example shows how to avoid drawing an unwanted curve: 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 * Use synonyms and `query' for filenames. This makes programs much more flexible. Note that you can string synonyms together: \dir = "~/EOS/iso0/" query \file "Give file in directory \dir" ("1.dat") open \dir/\file It is also a good idea to give a restrictive list of possibilities in your `query' command, to avoid complicated `if' commands later (*Note Query::). * Use multiple `draw title' commands: draw title "Atlantic water entering Arctic Ocean" draw title "\.command_file. \.time." * Use the `query' command to interact with the user (*Note Query::). The results can be stored in variables and synonyms.  File: gri.info, Node: Debugging, Next: Error Messages, Prev: Hints, Up: Programming 10.13 Debugging Gri Programs ============================ Here are some hints for debugging Gri programs: * If no data appear on an xy plot, insert `show columns statistics' or `show columns' after the `read columns' command. It may be that you have fixed your axes, and that the axes frame does not include the data. * If you get an error message, rerun your Gri program using the `-trace' command-line option, to see which line is causing the problem. This often reveals logic errors (e.g. in (`if' statements). You may also turn tracing on or off at any point in your Gri program by setting the built-in variable `..trace..' to 1 or 0. Many Gri users have the Gri command aliased to be in trace mode by default. * If Gri complains of a syntax error, consult the printed manual, one of the online manuals, or the online help facility (*Note Online Help::). * 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. * Sprinkle `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 `show' statements so are they executed if the `-debug' flag is set: if ..debug.. show "X=" .x. "and label is `\label'" end if * If your `draw' commands don't draw anything, check to see whether you've fooled yourself by enforcing an improper scaling; remove explict scaling (`set x axis ...'), clipping (`set clip'), data selection windows (`set input data window x|y') and missing values (`set missing value'). Another trick is to read only a portion of the data set (`read columns 10 x y') and then print out all the values (`show columns'). 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; (*Note Reporting Bugs::).  File: gri.info, Node: Error Messages, Next: Missing Values, Prev: Debugging, Up: Programming 10.14 Error Messages ==================== Gri error messages are in three types: 1. Operating system error messages, such as `segmentation fault'. These should never appear, and indicate a bug in Gri. Please report these to the author (*Note Reporting Bugs::). 2. Internal Gri error messages. The message starts with the words `FATAL error', and quotes a file number and a line number, e.g. FATAL error: startup.c:199: ... 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 (*Note Reporting Bugs::). For fatal error messages on a unix system, Gri dumps core, unless you have turned that feature off, with the `ulimit -c 0' unix command in a startup file. This creates a file called `core', which can help you in diagnosing the Gri bug. If you have the `gdb' debugger, just type `gdb gri core' and then type `where' to get a traceback stack. Please email this with your other information about the Gri bug. 3. 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 `set x axis 0 1 -1' yields: ERROR: `set x axis .left. .right. .incBig.' has .incBig. of wrong sign Bad command: `set x axis 0 1 -1 ' 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.  File: gri.info, Node: Missing Values, Next: Operating System, Prev: Error Messages, Up: Programming 10.15 Missing data ================== Most Gri commands will ignore data points equal to a "missing value." For example, `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 `set missing value .value.'. The built-in variable `..missingvalue..' stores the current value of the missing-value. Additionally, Gri will ignore anything it reads that is equal to the string `NaN' or `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 `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.  File: gri.info, Node: Operating System, Next: Using OS Inside Gri, Prev: Missing Values, Up: Programming 10.16 Interaction Between Gri and Operating System ================================================== * Menu: * Using OS Inside Gri:: Accessing the OS from inside Gri * Using Gri Inside OS:: Tricks for using Gri in unix  File: gri.info, Node: Using OS Inside Gri, Next: Using Gri Inside OS, Prev: Operating System, Up: Operating System 10.16.1 Using the OS from within Gri ------------------------------------ Gri uses the operating system internally for things like paging through help information. The operating system may be called *within* Gri commands, using a syntax borrowed from the `Bash' unix shell. After substituting synonyms in the commandline, Gri scans for dollar-parenthesis blocks (e.g. `\$(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. Often the dollar-parentheis syntax is used in title commands, to indicate the full pathname of the Gri commandfile, e.g. draw title "\$(pwd)/\.command_file." 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 `gri -s8 -t'. \dir = "\$(echo $MY_DIR)" show "\$(head -1 \dir/MY_FILE)" *Syntax Note* Dollar-parenthesis blocks must be prefixed with backslash to avoid confusion with math expressions within strings, for example to avoid breaking `draw label "$(x,y)$" at 3 3 cm'. This is an example of how TeX notation and unix shell notation collide. *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. # 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" Another method is to pass instructions to the operating system with the `system' command. This discards output. Whatever follows the word `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 `awk', `head', `grep' and `sed'. Examples: * 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.) system paste -d" " 1.dat 2.dat 3.dat > tmp.\.pid. open tmp.\.pid. read columns x y close system rm tmp.\.pid. * Here's how to plot each line in a file called `inp' which has the string `;' at the start of the line. system cat inp | grep -v "^;" | cat > tmp.\.pid. open tmp.\.pid. read columns x y system rm tmp.\.pid. * Here's how to use the `awk' system command to create a tabulated function for plotting. 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 This example is more cleanly written using the piping facility of the `open' command (which automatically creates a temporary file, and destroys it when `close' is done) open "awk 'BEGIN { \ for(x=0;x<1;x+=0.1) { \ print(x,sin(x)) \ } \ }'|" read columns x y close draw curve * 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 `\synonym = system ...' assignment command. * subroutine A related command is `\synonym = tmpname', which stores in the synonym the name of a temporary file created by the system. The file is created with the `tmpname' system call, so it is guaranteed not to clash with any existing files. Typically, the filename is something like `/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 `unlink' (*Note Unlink::) or with a `system rm -f' command. A useful bit of code is as follows \file = tmpname system ... SOME_SYSTEM_COMMANDS ... > \file ... use this new file for something ... unlink \file  File: gri.info, Node: Using Gri Inside OS, Next: Resource File, Prev: Using OS Inside Gri, Up: Operating System 10.16.2 Using Gri from within the OS ------------------------------------ *This section only applies to unix systems.* Save the following into a file called `p' and then make it executable using `chmod'. It runs Gri on a named file, with the `-yes' flag set so that any `query' commands are automatically answered in the affirmative, and then displays the results in a Ghostscript window. (USAGE: `p cmdfile.gri') #!/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  File: gri.info, Node: Resource File, Next: Environment, Prev: Using Gri Inside OS, Up: Programming 10.17 Sample Resource File ========================== The following shows a sample `~/.grirc' resource file. Much of the code here is adding new commands (*Note Adding New Commands::.) # 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 }  File: gri.info, Node: Environment, Next: Extras, Prev: Resource File, Up: Top 11 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. `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  File: gri.info, Node: Extras, Next: gri_merge, Prev: Environment, Up: Environment 11.1 Extra things provided with Gri =================================== * Menu: * gri_merge:: Merge files to one page * gri_unpage:: Separate multipage doc into separate files  File: gri.info, Node: gri_merge, Next: gri_unpage, Prev: Extras, Up: Extras 11.1.1 `gri_merge' - combine PostScript files --------------------------------------------- Merge separate PostScript files, created by Gri, into one page. To learn how it works, type `gri_merge -h' at the system prompt, to see: 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.  File: gri.info, Node: gri_unpage, Next: Using System Tools, Prev: gri_merge, Up: Extras 11.1.2 `gri_unpage' - split pages into files -------------------------------------------- Given a multipage PostScript file, `gri_unpage' creates several new PostScript files, one for each page. To learn how it works, type `gri_unpage -h' at the system prompt, to see: 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.  File: gri.info, Node: Using System Tools, Next: Why Use The Environment, Prev: gri_unpage, Up: Environment 11.2 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  File: gri.info, Node: Why Use The Environment, Next: Grep, Prev: Using System Tools, Up: Using System Tools 11.2.1 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. open "awk '{print $1, $3/$2}' MyFile |" which creates a temporary file (automatically erased when Gri finishes) which contains the output from running the system command that preceeds the pipe symbol (`|') (*Note Open::). (Here and in all the examples of this chapter, it is assumed that the user's input file is named `MyFile'.) For more complicated appplications, you may use the Gri `system' command as follows. 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 Here a temporary file, named `tmp', has been used to store the results of the calculation. Note that this file was specifically cleaned up by the second `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.)  File: gri.info, Node: Grep, Next: Sed, Prev: Why Use The Environment, Up: Using System Tools 11.2.2 Grep ----------- 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: open "grep -v 'HEADER' MyFile |" ... Note that Gawk and Perl do this just as easily.  File: gri.info, Node: Sed, Next: Awk, Prev: Grep, Up: Using System Tools 11.2.3 Sed ---------- 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 open "sed -e 's/,/ /g' MyFile |" Where the `-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.  File: gri.info, Node: Awk, Next: Perl, Prev: Sed, Up: Using System Tools 11.2.4 Awk ---------- 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: open "awk 'NR>10' MyFile |" read ... Here the pattern was that `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. To plot the cosine of the second column against the first column: open "awk '{print ($1, cos($2))}' MyFile |" read columns x y draw curve 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 `MyFile', but only for the first 10 lines of the file: open "awk NR<=10 {print ($1, $8)} MyFile |"  File: gri.info, Node: Perl, Next: Discussion Group, Prev: Awk, Up: Using System Tools 11.2.5 Perl ----------- Perl can do almost *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 `-e' indicates that a Perl command is given in the next word of the command line. The commandline switch `-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: open "perl -pe 's/,/ /g' MyFile |" Perl also has a commandline switch `-a' indicating that lines should be "autosplit" into an array called `$F'. The first element of this array is `$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: open "perl -pea 'print($F[0], cos($F[1]))' MyFile |"  File: gri.info, Node: Discussion Group, Next: Emacs Mode, Prev: Perl, Up: Environment 11.3 Gri Discussion Group ========================= Before emailing to the Gri newsgroup, it is a good idea to consult the 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 `http://gri.sourceforge.net' about which little need be said here, because the website is very easy to use.  File: gri.info, Node: Emacs Mode, Next: About Gri Mode, Prev: Discussion Group, Up: Top 12 Editing Gri Files in GNU 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 `'. * 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.  File: gri.info, Node: About Gri Mode, Next: Gri-mode screenshots, Prev: Emacs Mode, Up: Emacs Mode 12.1 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: * It can *complete* partially typed commands, builtin variables and synonyms (`gri-complete', ) and help you edit the syntax that was thus inserted for you (`gri-option-select', `C-c C-o'; `gri-option-kill', `C-c C-k'). * It can provide a short help synopsis concerning the command on the current line (`gri-help-this-command', `C-c C-h'), or load the info manual for that command (`gri-info-this-command', `C-c C-i'). It knows the list of all Gri commands, and can provide help or info regarding any of them (`gri-help', `C-c M-h'; `gri-info', `C-c M-i') using command name completion at the prompt (). * 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. * It can help you find an unknown command by listing all containing a given word (`gri-apropos', `C-c C-a'). * It fontifies your Gri code using colour coding. * It indents if statements, loops, and so on (`gri-indent-line', ). * It can let you run Gri and view its output without leaving the editor (`gri-run', `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. * If you've already run Gri, and therefore have a PostScript output file, the mode will let you view that file (`gri-view', `C-c C-v') even if that file is compressed. Thus one never has to leave Emacs; type `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 `C-h m' for help on the mode, including a list of all commands and key definitions.  File: gri.info, Node: Gri-mode screenshots, Next: Screenshot 1, Prev: About Gri Mode, Up: Emacs Mode 12.2 Gri-mode screenshots, what it looks like. ============================================== * Menu: * Screenshot 1:: * Screenshot 2:: * Screenshot 3:: * Screenshot 4::  File: gri.info, Node: Screenshot 1, Next: Screenshot 2, Prev: Gri-mode screenshots, Up: Gri-mode screenshots 12.2.1 Screenshot 1 ------------------- Screenshots are not visible in the info node; see the online HTML documents. In the first screenshot, the user has entered the text `set font' and has pressed twice to see the list of possible completions. The `*Completions*' buffer is displayed in a separate frame because the user is using the `framepop.el' add-on package. A similar effect can be obtained using `special buffers' in Emacs.  File: gri.info, Node: Screenshot 2, Next: Screenshot 3, Prev: Screenshot 1, Up: Gri-mode screenshots 12.2.2 Screenshot 2 ------------------- Screenshots are not visible in the info node; see the online HTML documents. Here, the user has selected the command `set font to' and, forgetting what valid font name could be used, then invoked `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.  File: gri.info, Node: Screenshot 3, Next: Screenshot 4, Prev: Screenshot 2, Up: Gri-mode screenshots 12.2.3 Screenshot 3 ------------------- Screenshots are not visible in the info node; see the online HTML documents. Here we see the user cascading through the Gri commands pull-down menu until `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.  File: gri.info, Node: Screenshot 4, Next: Installing gri-mode.el, Prev: Screenshot 3, Up: Gri-mode screenshots 12.2.4 Screenshot 4 ------------------- Screenshots are not visible in the info node; see the online HTML documents. With the output previewed in a `gv' window after pressing `C-c C-v' (or pressing the `gv' icon in the toolbar, or selecting it from the `Perform' pull-down menu), the user is ready to print the file, here using the `Perform' pull-down menu.  File: gri.info, Node: Installing gri-mode.el, Next: Step 1, Prev: Screenshot 4, Up: Emacs Mode 12.3 Installing gri-mode.el, the nuts and bolts. ================================================ The Emacs `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 http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/gri/gri/gri-mode.el The following installation steps appear a *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 `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 `.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.  File: gri.info, Node: Step 1, Next: Step 2, Prev: Installing gri-mode.el, Up: Installing gri-mode.el 12.3.1 Placing gri-mode.el where Emacs can find it. --------------------------------------------------- (Those using gri from gri's *RPM* package, a *Debian* package or a *Red Hat* package users can skip this, as it is 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 this in Emacs: 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))  File: gri.info, Node: Step 2, Next: Step 3, Prev: Step 1, Up: Installing gri-mode.el 12.3.2 Telling gri-mode where gri resides ----------------------------------------- (Those using gri from gri's *RPM* package, a *Debian* package or a *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 `/usr/local/bin/gri-2.12.23' and `/usr/local/share/gri/2.12.23/gri.cmd' (the default when compiling gri yourself). If not, then you may need to set the Emacs variable `gri*directory-tree' in a startup file such as in your `~/.emacs' file. The Emacs variable `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: `gri*directory-tree/2.12.23/gri.cmd' and `/usr/local/bin/gri-'2.12.23 where `gri*directory-tree' is by default set to `/usr/local/share/gri/'. If you have only one version of gri installed on your system, gri-mode will also look to find `gri.cmd' and the gri executable like so: 1. Gri executable in the PATH, with startup file `gri*directory-tree/gri.cmd'. 2. Gri executable in the PATH, with startup file `gri*directory-tree/lib/gri.cmd'. 3. Gri executable `gri*directory-tree/bin/gri', with startup file `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' (This is the way Debian packages are set up): the file `gri*directory-tree/VERSION/gri.cmd' and the `gri-VERSION' executable in the PATH (e.g. `/usr/share/gri/2.1.18/gri.cmd' and `/usr/bin/gri-2.1.18' with `gri*directory-tree' set to `"/usr/share/gri"') *Important note:* You may have more than one tree and make a list of them: (setq gri*directory-tree '("/opt/gri/" "/usr/share/gri/")) *Examples:* 1. If you use a RedHat package installed 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. 2. If you use a Debian GNU/Linux installation like: /usr/bin/gri -> /usr/bin/gri-2.1.18 /usr/share/gri/2.1.18/gri.cmd then you'd use: (setq gri*directory-tree "/usr/share/gri/") Note that all gri binaries must exist in the path with version number suffixes (e.g. `gri-2.1.18') since there is no `/usr/share/gri/2.1.18/bin/' directory (using a similar structure to `opt/gri' below) where gri-mode can find the binary corresponding to a given version number. 3. If you had multiple versions of Gri installed like so (this reflects the installation paths used in older gri releases): /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/")  File: gri.info, Node: Step 3, Next: Step 4, Prev: Step 2, Up: Installing gri-mode.el 12.3.3 Telling emacs to load gri-mode ------------------------------------- (Those using a *Debian* package can skip this, as it is 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 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 `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)) The first line tells Emacs that it will find out what it needs to know about running the command `M-x gri-mode' by loading the file `gri-mode.el'. The second line tells it to run the command `M-x gri-mode' when a file with extension `.gri' is visited (thus using gri-mode with all those files).  File: gri.info, Node: Step 4, Next: Major Gri-mode commands, Prev: Step 3, Up: Installing gri-mode.el 12.3.4 Extra user configuration of gri-mode ------------------------------------------- *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: 1. using the Custom interface (see the Help or Gri-Help menu or run the command `M-x gri-customize'), or 2. manually setting variables in your `~/.emacs' file. These are briefly described by typing `C-h m' while in gri-mode. Then, for further infomation, use emacs' `describe-variable' command, bound to `C-h v'. For example, for more information about the `gri*WWW-program' variable, you'd type `C-h v gri*WWW-program' (note that emacs does completion, so pressing the key after typing-in gri will display all gri related variables.)  File: gri.info, Node: Major Gri-mode commands, Next: Gri command names, Prev: Step 4, Up: Emacs Mode 12.4 Major Gri-mode 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.  File: gri.info, Node: Gri command names, Next: Possible completions, Prev: Major Gri-mode commands, Up: Major Gri-mode commands 12.4.1 How gri-mode 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 draw label "\string" [centered|rightjustified] at .x. .y. [cm] [rotated .deg.] is named by gri-mode simply `draw label at'. Note how the `at' stays in the name because it is not optional. So when you see `draw label at' in gri-mode's menus or prompts, you are more likely to associate the name with what the command actually does.  File: gri.info, Node: Possible completions, Next: Command abbreviations, Prev: Gri command names, Up: Major Gri-mode commands 12.4.2 Possible completions of gri command names ------------------------------------------------ When you press 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 `gri-complete' () again, gri-mode will respond by showing all possible completions in the `*completions*' buffer. 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 expands to show and informs you that 12 possible completions exists; then show will display these completions in the completions buffer; then typing again 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 possibilities or less. In this case they are displayed in the minibuffer. Note: 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.  File: gri.info, Node: Command abbreviations, Next: Variable completion, Prev: Possible completions, Up: Major Gri-mode commands 12.4.3 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 dr x a and it will expand1 all the words to draw x axis [at bottom|top|{.y. [cm]} [lower|upper]] 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.  File: gri.info, Node: Variable completion, Next: Editing the syntax, Prev: Command abbreviations, Up: Major Gri-mode commands 12.4.4 Variable (and synonym) completion ---------------------------------------- It's also possible to do completion on gri builtin variable and synonym names while editing a command. Simply type in the leading `.' (dot) or `\' (slash) character and invoke completion with . For example, ..x displays a completions buffer listing the possible completions: ..xmargin.. ..xsize.. ..xleft.. ..xright.. ..xlast.. Typing in an extra `m' will complete to `..xmargin..' and the following help information will be displayed in the minibuffer: margin to left of axis area. Default is 6 cm.  File: gri.info, Node: Editing the syntax, Next: User commands, Prev: Variable completion, Up: Major Gri-mode commands 12.4.5 Editing the syntax output by gri-complete ------------------------------------------------ You might wonder what to do with all the bracketed code left behind by `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 `gri-option-select' (`C-C C-o') and `gri-kill-option' (`C-C C-k') to 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. For 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. The above syntax description is a shortcut formulation for all of: 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' (`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 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 have put the cursor over either the word `lower' or `upper', and invoke `gri-kill-option' (`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.  File: gri.info, Node: User commands, Next: Gri code fragments, Prev: Editing the syntax, Up: Major Gri-mode commands 12.4.6 User commands with gri-mode ---------------------------------- User gri commands defined in `~/.grirc' (*Note Resource File::) or at the beginning of a gri file can also be used with `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.  File: gri.info, Node: Gri code fragments, Next: Info interface, Prev: User commands, Up: Major Gri-mode commands 12.4.7 Inserting gri code fragments in Emacs -------------------------------------------- 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 twice to `gri-complete' it and display possible choices. The gri commands used to replace them are found in the `*gri-syntax*' buffer.  File: gri.info, Node: Info interface, Next: Other features, Prev: Gri code fragments, Up: Major Gri-mode commands 12.4.8 Info interface for help on current command ------------------------------------------------- The Info system is built into Emacs (`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 (`C-h i') be able to navigate through all of gri's inline manual, but gri-mode's function `gri-info-this-command' (`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 `gri-info' (`C-c M-i') which will prompt you (using 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.  File: gri.info, Node: Other features, Next: Dealing with many Gri versions, Prev: Info interface, Up: Emacs Mode 12.5 Other features of gri-mode =============================== * `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 `new command declarations' as well as value settings for `variables' and `synomyns'. * `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). * `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 `set font size 10', it will display `set font size: default is 12 point in variable ..fontsize..'.  File: gri.info, Node: Dealing with many Gri versions, Next: Filename arguments when running gri, Prev: Other features, Up: Emacs Mode 12.6 Dealing with many Gri versions, gri-mode handles it. ========================================================= Earlier we explained that you might have many versions of gri installed on your system (*Note Installing gri-mode.el::). You may use gri-mode to access these various versions with the following gri-mode commands: * `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 `gri*directory-tree' is not correctly set (*Note Installing gri-mode.el::)). Your selection is stored in the file `~/.gri-using-version' and is remembered across editing sessions. If you select *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 `~/.gri-using-version' file. * `gri-set-local-version': Tells gri-mode to use a given version of gri *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 `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 *default* as your answer, gri-mode reverts to using the default version of gri as selected by `gri-set-version' and deletes the Emacs variable setting at the bottom of the gri file.  File: gri.info, Node: Filename arguments when running gri, Next: History, Prev: Dealing with many Gri versions, Up: Emacs Mode 12.7 Filename arguments when running gri ======================================== Usually, gri is run specifying only a gri command file to process, which lends itself well to the gri-mode command `gri-run'. But Gri can be also invoked from the command line using optional arguments, usually filenames but not necessarily, e.g. $ gri somefile.gri datafile.dat datafile2.dat ... or $ gri somefile.gri *.dat The arguments are accessed with RPN operators `argc' and `argv' (*Note Unary Operators::). gri-mode provides a method to set the arguments (usually filenames) to use when `gri-run' is called in a specific gri script. Use the gri-mode command `gri-set-command-postarguments' to setup a string that gri-mode will use, and the gri-mode command `gri-unset-command-postarguments' to clear it. For ease-of-use, these commands are made available from the menubar under the `Perform -> Run Settings' entries. The specified string will be stored in the locally-defined (aka buffer-local) variable `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.  File: gri.info, Node: History, Next: Stable Stream, Prev: Filename arguments when running gri, Up: Top 13 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." _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. `2.6.0', while unstable versions always have an odd number there, e.g. `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 `2.6.1' fixed bugs in version `2.6.0'. To learn more about the bugs, and their resolution, visit the bugs page at gri.sourceforge.net (http://sourceforge.net/tracker/?func=browse&group_id=5511&atid=105511) and adjust the "status" menu to read "closed". * Menu: * Stable Stream:: * Unstable Stream:: * Deprecated Commands::  File: gri.info, Node: Stable Stream, Next: Version 2.12, Prev: History, Up: History 13.1 Stable Stream ================== In any given stable stream, only the version with a `0' as the last number in the triplet has new features; the later versions only correct flaws. For example, version `2.6.0' offers new features compared to any of the `2.4.x' versions, but `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::  File: gri.info, Node: Version 2.12, Next: Version 2.10, Prev: Stable Stream, Up: Stable Stream 13.1.1 Version 2.12 ------------------- 13.1.1.1 Version 2.12.23 [2011 July 6 Malawai Independence Day (http://en.wikipedia.org/wiki/Malawi)] ..................................................................................................... *Bug fixes* * `https://sourceforge.net/projects/gri/forums/forum/16975/topic/4596628/index/page/1' ... `pgm' images grayscale was wrong 13.1.1.2 Version 2.12.22 ........................ *Bug fixes* * Fix github bug `http://github.com/dankelley/gri/issues#issue/5' ... `draw image' failed on some black/white images 13.1.1.3 Version 2.12.21 [2010 June 8 World Ocean Day (http://en.wikipedia.org/wiki/World_Oceans_Day)] ...................................................................................................... *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 13.1.1.4 Version 2.12.20 [2010 April 9 Vimy Ridge Day (http://en.wikipedia.org/wiki/Vimy_Ridge_Day)] .................................................................................................... *New Features* * add `labelling' option to `set x axis' and `set y axis'. * add `directly' option to `convert grid to image'. *Bug Fixes* * Fix SourceForge bug #2913919 (https://sourceforge.net/forum/forum.php?thread_id=2913919&forum_id=16974) ... SVG: all symbols are "." * Fix SourceForge bug #2913893 (https://sourceforge.net/forum/forum.php?thread_id=2913893&forum_id=16974) ... svg segfault on draw label * Fix SourceForge bug #2913841 (https://sourceforge.net/forum/forum.php?thread_id=2913841&forum_id=16974) ... svg draw box filled not filled * Fix SourceForge bug #2913840 (https://sourceforge.net/forum/forum.php?thread_id=2913840&forum_id=16974) ... svg images are upside-down * Fix SourceForge bug #2913838 (https://sourceforge.net/forum/forum.php?thread_id=2913838&forum_id=16974) ... image postscript clip problem 13.1.1.5 Version 2.12.19 [2009 July 17 World Day for International Justice (http://en.wikipedia.org/wiki/World_Day_for_International_Justice)] .............................................................................................................................................. *New Features* * Fix SourceForge "bug" #2977816 (https://sourceforge.net/forum/forum.php?thread_id=2977816&forum_id=16974) ... Fedora packaging requires more precise license declarations. *Bug Fixes* * Fix SourceForge bug #3266884 (https://sourceforge.net/forum/forum.php?thread_id=3266884&forum_id=16974) ... error in docs for strlen. 13.1.1.6 Version 2.12.18 [2008 Sep 8 International Literacy Day (http://en.wikipedia.org/wiki/International_Literacy_Day)] .......................................................................................................................... *Bug Fixes* * Improve security of temporary-file handling. * Fix SourceForge bug #1985862 (http://sourceforge.net/tracker/index.php?func=detail&aid=1985862&group_id=5511&atid=105511) ... SVG output had axis linewidth equal to curve line width. 13.1.1.7 Version 2.12.17 [2008 May 29 Oak Apple Day (England) (http://en.wikipedia.org/wiki/Oak_Apple_Day)] ........................................................................................................... *New Features* * Add GNU readline support so that interactive mode will have history, command editing, etc. *Bug Fixes* * Fix SourceForge bug #1913577 (https://sourceforge.net/tracker/?func=detail&atid=105511&aid=1913577&group_id=5511) ... superscripts did not end correctly, if preceeded by an inline `{}' block. * Fix SourceForge bug #1761562 (https://sourceforge.net/tracker/index.php?func=detail&aid=1761562&group_id=5511&atid=105511) ... y axis name printed upside down, for log axes in which user specified a high values at the bottom end of the axis 13.1.1.8 Version 2.12.16 [2007 Jul 20 anniversary of the first moon landing (http://en.wikipedia.org/wiki/Apollo_11)] ..................................................................................................................... *Bug Fixes* * Fix Debian bug #130802 (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=130802) ... postscript problem in landscape mode, refreshed in gv viewer * Fix Debian bug #434010 (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=434010) ... `set page landscape' requires `set page size' first, but it should really default to something reasonable instead. 13.1.1.9 Version 2.12.15 [2007 Apr 16 celebration of birthday of Muhammad (http://en.wikipedia.org/wiki/Mawlid)] ................................................................................................................ *Bug Fixes* * Fix SourceForge bug #1700978 (https://sourceforge.net/tracker/index.php?func=detail&aid=1700978&group_id=5511&atid=105511) ... html concept index mostly broken * Fix SourceForge bug #1698924 (https://sourceforge.net/tracker/index.php?func=detail&aid=1698924&group_id=5511&atid=105511) ... box plots show missing data * Fix Debian bug #417217 ... will not compile in GCC 4.3 * Fix SourceForge bug #1698116 (https://sourceforge.net/tracker/index.php?func=detail&aid=1698116&group_id=5511&atid=105511) ... poorly-positioned name of RHS y-axis 13.1.1.10 Version 2.12.14 [2007 Jan 08: Coming-of-Age Day (Japan) (http://en.wikipedia.org/wiki/Seijin_shiki)] .............................................................................................................. *Bug Fixes* * Fix SourceForge bug #1630768 (https://sourceforge.net/tracker/index.php?func=detail&aid=1630768&group_id=5511&atid=105511) ... Fix to segfault in clipped images (a bug that may have developed after version 2.13.3) 13.1.1.11 Version 2.12.13 [2006 Nov 06: Constitution Day (Tajikistan) (http://en.wikipedia.org/wiki/Public_holidays_in_Tajikistan)] ................................................................................................................................... *Bug Fixes* * Fix SourceForge bug #1591475 (https://sourceforge.net/tracker/index.php?func=detail&aid=1591475&group_id=5511&atid=105511) ... Fix to compile in Solaris CC * Fix SourceForge bug #1591062 (https://sourceforge.net/tracker/index.php?func=detail&aid=1591062&group_id=5511&atid=105511) ... Fix to compile in OpenBSD 13.1.1.12 Version 2.12.12 [2006 July 16: Yellow Pigs Day (http://en.wikipedia.org/wiki/Yellow_Pig%27s_Day)] ........................................................................................................... *Bug Fixes* * Fix SourceForge bug #1523033 (https://sourceforge.net/tracker/index.php?func=detail&aid=1523033&group_id=5511&atid=105511) ... Malloc error (freeing something already freed?) * Fix SourceForge bug #1523032 (https://sourceforge.net/tracker/index.php?func=detail&aid=1523032&group_id=5511&atid=105511) ... `create columns from function' bug, if there is an existing directory called `tmp'. * Fix SourceForge bug #1491105 (https://sourceforge.net/tracker/index.php?func=detail&aid=1491105&group_id=5511&atid=105511) ... `set x axis labels' had no affect for log axes (same for y) 13.1.1.13 Version 2.12.11 [2006 Mar 30: Hindu New Year] ....................................................... *Bug Fixes* * Fix SourceForge bug #1449546 (https://sourceforge.net/tracker/index.php?func=detail&aid=1449546&group_id=5511&atid=105511) ... x axis limits not correctly inferred from `set x grid' (same for y). 13.1.1.14 Version 2.12.10 [2006 Jan 26: Australia Day] ...................................................... *Bug Fixes* * Fix SourceForge bug #1408259 (https://sourceforge.net/tracker/?func=detail&atid=105511&aid=1408259&group_id=5511) ... 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 (*Note Invoking Gri::). * Fix SourceForge bug #1285180 (http://sourceforge.net/tracker/index.php?func=detail&aid=12851803&group_id=5511&atid=105511) ... NaN was mishandled. (The bug may have arisen in version 2.12.7 or thereabouts.) * Port to the FreeBSD (http://www.freebsd.org/) operating system, with help from Christopher Illies and Roman Neuhauser. * Fix SourceForge bug #1217273 (http://sourceforge.net/tracker/index.php?func=detail&aid=1217273&group_id=5511&atid=105511) ... missing some version numbers within docs * Fix SourceForge bug #1196613 (http://sourceforge.net/tracker/index.php?func=detail&aid=1196613&group_id=5511&atid=105511) ... user-supplied x-axis labels can run offscale (fix for y-axis later...) * Fix SourceForge bug #1198341 (http://sourceforge.net/tracker/index.php?func=detail&aid=1198341&group_id=5511&atid=105511) ... x-axis labels incorrectly rotated (sometimes) * Fix SourceForge bug #1199280 (http://sourceforge.net/tracker/index.php?func=detail&aid=1199280&group_id=5511&atid=105511) ... warning about `malloc' for RPN assignments * Fix SourceForge bug #1196115 (http://sourceforge.net/tracker/index.php?func=detail&aid=1196115&group_id=5511&atid=105511) ... `gri_unpage' and `gri_merge' mis-installed * Fix SourceForge bug #1153209 (http://sourceforge.net/tracker/index.php?func=detail&aid=1153209&group_id=5511&atid=105511) ... Emacs mode incompatible with new version of `gv' PostScript viewer Fix SourceForge bug #1101172 (http://sourceforge.net/tracker/index.php?func=detail&aid=1101172&group_id=5511&atid=105511) ... `gri -help' incorrectly stated meaning of last argument(s) * Fix SourceForge bug #835711 (http://sourceforge.net/tracker/index.php?func=detail&aid=835711&group_id=5511&atid=105511) ... `draw gri logo' fails. * Fix SourceForge bug #1098269 (http://sourceforge.net/tracker/index.php?func=detail&aid=1098269&group_id=5511&atid=105511) ... problem compiling on AMD64 machine. (Solution provided by Andreas Jochens, a Debian user.) * Fix SourceForge bug #867515 (http://sourceforge.net/tracker/index.php?func=detail&aid=867515&group_id=5511&atid=105511) ... problem with junk appearing in images. * Fix SourceForge bug #875881 (http://sourceforge.net/tracker/index.php?func=detail&aid=875881&group_id=5511&atid=105511) ... problem compiling with gcc 2.95.3 compiler. 13.1.1.15 Version 2.12.9 [2005 Jan 6: Feast of Epiphany (http://en.wikipedia.org/wiki/Epiphany_%28feast%29)] ............................................................................................................ *Bug Fixes* * Fix SourceForge bug #1094087 (http://sourceforge.net/tracker/index.php?func=detail&aid=1094087&group_id=5511&atid=105511) ... `set path to' incorrectly parsed colon-separated paths * Fix SourceForge bug #1085788 (http://sourceforge.net/tracker/index.php?func=detail&aid=1085788&group_id=5511&atid=105511) ... `image *=', `image /=', `image ^=', and `image _=' all gave incorrect results * Fix SourceForge bug #1084123 (http://sourceforge.net/tracker/index.php?func=detail&aid=1084123&group_id=5511&atid=105511) ... does not compile in fink * Fix SourceForge bug #676767 (http://sourceforge.net/tracker/index.php?func=detail&aid=676767&group_id=5511&atid=105511) ... on fink systems, `help' does not work 13.1.1.16 Version 2.12.8 [2004] ............................... *Bug Fixes* * Fix SourceForge bug #1019141 (http://sourceforge.net/tracker/index.php?func=detail&aid=1019141&group_id=5511&atid=105511) ... `draw arc' ignores the present pen color * Fix SourceForge bug #997741 (http://sourceforge.net/tracker/index.php?func=detail&aid=997741&group_id=5511&atid=105511) ... PostScript broken on images with y-axis decreasing, and enclosed by PostScript clipping * Fix SourceForge bug #978822 (http://sourceforge.net/tracker/index.php?func=detail&aid=978822&group_id=5511&atid=105511) ... documentation wrong on `set path to' * Fix SourceForge bug #932203 (http://sourceforge.net/tracker/index.php?func=detail&aid=932203&group_id=5511&atid=105511) ... misplaced labels caused by `set x axis labels' * Fix SourceForge bug #928277 (http://sourceforge.net/tracker/index.php?func=detail&aid=928277&group_id=5511&atid=105511) ... `draw polygon' should take `cm' and `pt' units * Fix SourceForge bug #930259 (http://sourceforge.net/tracker/index.php?func=detail&aid=930259&group_id=5511&atid=105511) ... fix `draw arc''s drawing of an extra line (thanks for the fix, Wolfgang Voegeli) * Fix SourceForge bug #923719 (http://sourceforge.net/tracker/index.php?func=detail&aid=923719&group_id=5511&atid=105511) ... `draw curve overlying' ignored the effect of `set dash' * Fix SourceForge bug #914125 (http://sourceforge.net/tracker/index.php?func=detail&aid=914125&group_id=5511&atid=105511) ... offpage points in axes were reported as having been drawn by `draw curve'. * Fix SourceForge bug #877613 (http://sourceforge.net/tracker/index.php?func=detail&aid=877613&group_id=5511&atid=105511) ... `help' (and other commands using temporary files) does not work in OSX/Fink version. * Fix SourceForge bug #874483 (http://sourceforge.net/tracker/index.php?func=detail&aid=874483&group_id=5511&atid=105511) ... `state save' doesn't keep track of `dash' settings. * Fix SourceForge bug #873245 (http://sourceforge.net/tracker/index.php?func=detail&aid=873245&group_id=5511&atid=105511) ... inaccurate times are given in the warnings about slow operations on OSX platform (days are reported instead of seconds) * Fix SourceForge bug #871477 (http://sourceforge.net/tracker/index.php?func=detail&aid=871477&group_id=5511&atid=105511) ... 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. 13.1.1.17 Version 2.12.7 [2003 Sep 4] ..................................... *Bug Fixes* * Fix SourceForge bug #800022 (http://sourceforge.net/tracker/index.php?func=detail&aid=800022&group_id=5511&atid=105511) AKA Debian bug #208589 (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=208589), ... did not build on some Debian platforms because it was based on an old version of `automake'. 13.1.1.18 Version 2.12.6 [2003 Sep 1: Labour Day] ................................................. *New Features* * Add `age' RPN function, for testing file ages (*Note age-rpn-operator::). *Bug Fixes* * Fix SourceForge bug #773850 (http://sourceforge.net/tracker/index.php?func=detail&aid=773850&group_id=5511&atid=105511) ... bounding-box is increased by `draw symbol' even if (rectangular) postscript clipping is active. * Fix SourceForge bug #760130 (http://sourceforge.net/tracker/index.php?func=detail&aid=760130&group_id=5511&atid=105511) ... Solaris cannot compile with in Makefile. * Fix SourceForge bug #743134 (http://sourceforge.net/tracker/index.php?func=detail&aid=743134&group_id=5511&atid=105511) ... bounding box not limited by `set clip postscript' * Fix SourceForge bug #750561 (http://sourceforge.net/tracker/index.php?func=detail&aid=750561&group_id=5511&atid=105511) ... during compilation, `make' rebuilds HTML docs even if up-to-date 13.1.1.19 Version 2.12.5 [2003 May 19: Victoria Day] .................................................... *New Features* * 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. * Add hexadecimal colornames (*Note pen-color-hexadecimal::). *Bug Fixes* * Fix SourceForge bug #739761 (http://sourceforge.net/tracker/index.php?func=detail&aid=739761&group_id=5511&atid=105511) ... `draw time stamp' named the command-file incorrectly * Fix SourceForge bug #720607 (http://sourceforge.net/tracker/index.php?func=detail&aid=720607&group_id=5511&atid=105511) ... the emacs mode looked for html documentation files in an incorrect location on linux/redhat systems 13.1.1.20 Version 2.12.4 [2003 Apr 06] ...................................... *Bug Fixes* * Fix SourceForge bug #696073 (http://sourceforge.net/tracker/index.php?func=detail&aid=696073&group_id=5511&atid=105511) ... did not handle `\$()' syntax correctly. * Fix SourceForge bug #715884 (http://sourceforge.net/tracker/index.php?func=detail&aid=715884&group_id=5511&atid=105511) ... mixup on protected-quotes within double-quoted strings * Fix Debian bug #183912 (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=183912) ... would not compile on m86k architecture. * Fix SourceForge bug #711354 (http://sourceforge.net/tracker/index.php?func=detail&aid=711354&group_id=5511&atid=105511) ... `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! * Fix SourceForge bug #706202 (http://sourceforge.net/tracker/index.php?func=detail&aid=706202&group_id=5511&atid=105511) ... 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. 13.1.1.21 Version 2.12.3 [2003 Mar 1] ..................................... *Bug Fixes* * Fix SourceForge bug #685919 (http://sourceforge.net/tracker/index.php?func=detail&aid=685919&group_id=5511&atid=105511) ... `-output' commandline argument failed on `.eps' file extension. 13.1.1.22 Version 2.12.2 [2003 Feb 7: Munro Day at Dalhousie University (http://www.dal.ca/)] ............................................................................................. *Bug Fixes* * Fix SourceForge bug #675304 (http://sourceforge.net/tracker/index.php?func=detail&aid=675304&group_id=5511&atid=105511) ... 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 (http://sourceforge.net/tracker/index.php?func=detail&aid=647234&group_id=5511&atid=105511) ... 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 (http://sourceforge.net/tracker/index.php?func=detail&aid=671022&group_id=5511&atid=105511) ... `flip image x|y' did not flip images correctly, except in special circumstances. * Fix SourceForge bug #669603 (http://sourceforge.net/tracker/index.php?func=detail&aid=669603&group_id=5511&atid=105511) ... `skip backward .n.' erroneously skipped forward * Fix SourceForge bug #667754 (http://sourceforge.net/tracker/index.php?func=detail&aid=667754&group_id=5511&atid=105511) ... `read image pgm' segfaults on memory if an image has already been created by `convert grid to image' * Fix SourceForge bug #664388 (http://sourceforge.net/tracker/index.php?func=detail&aid=664388&group_id=5511&atid=105511) ... `read image pgm' fails if an image already exists * Fix SourceForge bug #654129 (http://sourceforge.net/tracker/index.php?func=detail&aid=654129&group_id=5511&atid=105511) ... ignoring `~/.grirc' file * Fix SourceForge bug #654127 (http://sourceforge.net/tracker/index.php?func=detail&aid=654127&group_id=5511&atid=105511) ... configure scripts are broken * Fix SourceForge bug #649132 (http://sourceforge.net/tracker/index.php?func=detail&aid=649132&group_id=5511&atid=105511) ... removed unused LDFLAGS phrase from Makefile * Fix SourceForge bug #649134 (http://sourceforge.net/tracker/index.php?func=detail&aid=649134&group_id=5511&atid=105511) ... tweak gcc optimization * Fix SourceForge bug #649136 (http://sourceforge.net/tracker/index.php?func=detail&aid=649136&group_id=5511&atid=105511) ... examples 8 and 9 broken * Fix SourceForge bug #641406 (http://sourceforge.net/tracker/index.php?func=detail&aid=641406&group_id=5511&atid=105511) ... RPN too aggressive on missing values 13.1.1.23 Version 2.12.1 [2002 Sep 25] ...................................... *Bug Fixes* * Fix SourceForge bug #613075 (http://sourceforge.net/tracker/index.php?func=detail&aid=613075&group_id=5511&atid=105511) ... RPN operators `sin', `cos', and `tan' were limited in range (new bug in last release) 13.1.1.24 Version 2.12.0 [2002 Sep 15: Terry Fox Day (http://www.terryfox.org/), Canada.] ......................................................................................... *New Features* * Add `sed' RPN operator, to work on strings *Note Binary Operators::. * Add `skewness' and `kurtosis' RPN operators, to work on columns *Note Manipulation of Columns etc::. *Removed Features* * n/a *Bug Fixes* * Fix SourceForge bug #606303 (http://sourceforge.net/tracker/index.php?func=detail&aid=606303&group_id=5511&atid=105511) ... web-pages were not valid html-4.0. * Fix SourceForge bug #593958 (http://sourceforge.net/tracker/index.php?func=detail&aid=593958&group_id=5511&atid=105511) ... missing-values should be ignored if they occur in intermediate results of RPN calculations. * Fix SourceForge bug #600395 (http://sourceforge.net/tracker/index.php?func=detail&aid=600395&group_id=5511&atid=105511) ... won't compile with recently released version (3.2) of GCC compiler. * Fix SourceForge bug #600233 (http://sourceforge.net/tracker/index.php?func=detail&aid=600223&group_id=5511&atid=105511) ... segfaults if some RPN operators are used on stacks that do not contain enough entries (e.g. `show {rpn cosh}').  File: gri.info, Node: Version 2.10, Next: Version 2.8, Prev: Version 2.12, Up: Stable Stream 13.1.2 Version 2.10 ------------------- 13.1.2.1 Version 2.10.1 [2002 Jun 1] .................................... *Bug Fixes* * Fix SourceForge bug #562911 (http://sourceforge.net/tracker/index.php?func=detail&aid=562911&group_id=5511&atid=105511) ... won't build with `gcc-3.0' compiler. This was reported by the Debian hppa builder as Debian bug #148572 (http://bugs.debian.org/148572). * Fix SourceForge bug #562558 (http://sourceforge.net/tracker/index.php?func=detail&aid=562558&group_id=5511&atid=105511) ... `draw title' terminates program if have non-positive data and had initially specified log axes. * Fix SourceForge bug #562014 (http://sourceforge.net/tracker/index.php?func=detail&aid=562014&group_id=5511&atid=105511) ... won't build if `popt' library is unavailable. This was reported by the Debian ia64 builder as Debian bug #148493 (http://bugs.debian.org/148493). * Fix SourceForge bug #558463 (http://sourceforge.net/tracker/index.php?func=detail&aid=558463&group_id=5511&atid=105511) ... in HTML docs, the "press" margin tag was misdirected. * Fix SourceForge bug #562017 (http://sourceforge.net/tracker/index.php?func=detail&aid=562017&group_id=5511&atid=105511) ... parser fails with DOS end-of-line. * Fix SourceForge bug #562113 (http://sourceforge.net/tracker/index.php?func=detail&aid=562113&group_id=5511&atid=105511) ... `new page' postscript error in `gv' viewer. 13.1.2.2 Version 2.10.0 [2002 May 20: Victoria Day] ................................................... *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 *Note Binary Operators::, along with negation operator `not' *Note Unary Operators::. * Add `draw arc' command (*Note Draw Arc::). * Add `set x axis labels' (*Note Set X Axis::) and `set y axis labels' (*Note Set Y Axis::) commands. * Permit specification of `pt' units for `draw label' (*Note Draw Label::), `draw box' (*Note Draw Box::), `draw symbol at' (*Note Draw Symbol At::), and `draw line from' (*Note Draw Line From::). * Add `set clip to curve' (*Note Set Clip::) command. _Caution:_ this needs extension, and may have a bug if called twice in succession [but is this with an intervening `set clip off'] * 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 (*Note Axis Scaling::). * Make the `open' command accept URLs as filenames (*Note Open::). *Removed Features* * Remove `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. * Make the `-chatty' commandline option require a value (*Note Invoking Gri::). *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).  File: gri.info, Node: Version 2.8, Next: Version 2.6, Prev: Version 2.10, Up: Stable Stream 13.1.3 Version 2.8 ------------------ 13.1.3.1 Version 2.8.7 [2002 Apr 03] .................................... * Fix SourceForge bug #482120 (`regress' ignores data weights) * Fix SourceForge bug #508657 (missing backslash in drawing undefined synonyms) * Fix SourceForge bug #523450 (log axes detect non-positive values too late) * Fix SourceForge bug #521045 (installation/compilation with Solaris Workshop V6 Update 2 compiler) 13.1.3.2 Version 2.8.6 [2002 Feb 14] .................................... * Fix SourceForge bug #513002 (minor documentation error in `set clip') * Fix SourceForge bug #509592 (HTML docs had midordered indices) * Fix SourceForge bug #506534 (map axes give wrong minutes in negative regions). Thanks, Brian, for the patch on this! * Fix SourceForge bug #508088 (grimode: gv should update, not be relaunched) * Fix SourceForge bug #506490 (`-v' commandline option returned wrong version number) 13.1.3.3 Version 2.8.5 [2001 Dec 13] .................................... * Fix SourceForge bug #492472 (`inf' rpn operator caused segfault) 13.1.4 Version 2.8.4 [2001 Oct 4] --------------------------------- * Fix SourceForge bug #467973 (`gri -version' gave wrong version number, breaking the Emacs Gri mode.) * Fix SourceForge bug #468014 (`draw grid' disobeyed pencolor.) 13.1.4.1 Version 2.8.3 [2001 Oct 1] ................................... * Fix SourceForge bug #462243 (endian problem in Rasterfile images + reading problem in PGM images). 13.1.4.2 Version 2.8.2 [2001 Sep 19] .................................... * Fix SourceForge bug #461444 (wouldn't compile with the `mingw32' compiler, for windows 32 machines). * Fix SourceForge bug #454557 (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) 13.1.4.3 Version 2.8.1 [2001 Sep 7] ................................... * 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) 13.1.5 Version 2.8.0 [2001 Jul 30] ---------------------------------- New command syntax * Add `unlink' command as a unix-familiar way to delete files (*Note Unlink::). * Add `set page size' command to clip to a given page size (*Note Set Page::). * Add `substr' RPN operator to permit extraction of sub-strings (*Note Tertiary Operators::). * Add `default' possibility for the `set x name' and the `set y name' commands. * Add Perl-like ability to put underscores in numerical constants, to guide your eye. These underscores are ignored by Gri, so that for example `.v. = 1_000' and `.v. = 1000' are equivalent as far as Gri is concerned. Emacs mode (*Note Emacs Mode::) * Give the ability to complete builtin variables and synonyms as well as commands * Add "idle-timer minibuffer help" to display defaults for builtin variables under the cursor. * Add fontification of builtin variables _only_ if they are 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. * Complete the port to IBM's compiler for their AIX operating system.  File: gri.info, Node: Version 2.6, Next: Version 2.4, Prev: Version 2.8, Up: Stable Stream 13.1.6 Version 2.6 ------------------ 13.1.7 Version 2.6.4 [2001 Jul 9: Dan's birthday] ------------------------------------------------- * Fix SourceForge bug #435688 (remnants of `polar' column type, no longer supported, remained in documentation) * Fix SourceForge bug #435603 (`set dash' produced broken PostScript) * Fix SourceForge bug #431114 (`-0' could appear on axes) 13.1.8 Version 2.6.3 [2001 Jun 22] ---------------------------------- * 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. 13.1.8.1 Version 2.6.2 [2001 May 19] .................................... * Fix SourceForge bug #425174 (synonym interpolation broken on e.g. `show "[\syn]"' * Fix SourceForge bug #425175 (`while !..eof..' acted ignored end of file) 13.1.8.2 Version 2.6.1 [2001 May 10] .................................... * 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) 13.1.8.3 Version 2.6.0 [2001 April 1] ..................................... * 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 (*Note Set Path To::). * Remove functioning of `GRIINPUTS' environment variable, since this is more cleanly handled with the newly added `set path to' command (*Note Set Path To::). * Remove `\.awk.' synonym, which was deemed to be unhelpful. Users with many scripts that use this variable might wish to put a line like \.awk. = "gawk" in their `~/.grirc' file. * 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 (*Note Changeable Command Arguments::). * Add "at-sign" (`@') syntax for aliases (*Note Alias Synonyms::). * Add ability to embed newlines in `show' commands with the `\<<' sequence (*Note Show::). * Add ability to embed TAB characters in `show' commands with the `\>>' sequence (*Note Show::). * Make various `read' commands (*Note Read::) able to decode synonyms as well as variables and simple numbers. * Add `strlen' RPN operator (*Note Unary Operators::). * Add `default' option to `set x format' and `set y format' commands. * Add `new postscript file' (*Note New Postscript File::) command. * Switch email list from `majordomo' to GNU `mailman'. * 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 `sed' pipe in any case. * Make the first element of the `argv' array be the name of the command-file. (This makes Gri consistent with languages such as C.) * Add chapter on test suite (*Note Test Suite::). * Let newcommands have changeable arguments (*Note Changeable Command Arguments::). * Remove `-s' as an abbreviation for the commandline option `-superuser'. * Remove the `:' syntax from the commandline options. * Add commandline option `-output PS_file_name'. * Add `assert' command (*Note Assert::). * Add test suite (mainly for developers). * Add `sleep' command (*Note Sleep::). * Remove command `show hint of the day', since I no longer permission to use cgi-bin to provide the hints via web-server. * Permit indexing of synonym words with variables, in addition to constants. * Fix bug in interpolating synonyms in the test-expression of `while' loops. * Put source on the Source Forge open-source development website, at `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 (`http://sourceforge.net/forum/?group_id=5511') and email lists (`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. (`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). * Add `set colorname' command (*Note Set Colorname::). * Add `source' command (*Note Source::). * Add RPN operators `wordc' (*Note Solitary Operators::) and `wordv' (*Note Unary Operators::) for accessing the words in the present Gri command. * Add RPN operators `argc' (*Note Solitary Operators::) and `argv' (*Note Unary Operators::) for accessing the command-line arguments used when Gri was invoked from the operating system. * Add automatic support for compressed data files. So far, this only works with gzipped files (*Note Open::). * Add two new RPN operators, `file_exists' and `directory_exists' (*Note Unary Operators::). * Reorganize parts of manual (e.g. changing the section about the Emacs `gri-mode.el' into a chapter, with screen snapshots). * 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.). * Add several new features to `gri-mode.el': 1) Add a menubar pull-down menu listing all Gri commands, allowing the user to get `Help' or `Info' on any command or `Insert' it in the current Gri file. 2) Add a menubar pull-down entry to `Perform' to set `gri-run' settings such as flag options passed to gri. 3) Gri info file can have *.info* extension now. 4) Made `gri-apropos' an alias for `gri-help-apropos'. 5) gri-mode now uses the customize interface (See `gri-customize'). 6) The `~/.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 *Completions* buffer.  File: gri.info, Node: Version 2.4, Next: Version 2.2, Prev: Version 2.6, Up: Stable Stream 13.1.9 Version 2.4 ------------------ 13.1.9.1 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. `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. 13.1.9.2 Version 2.4.3 [2000 Apr 1] ................................... Change location of all files, to be consistent with Redhat convention. Previously, things were in `/opt/gri'; now they are in more standard locations. 13.1.9.3 Version 2.4.2 [2000 Mar 25] .................................... Remove bug in which `convert grid to image' produced incorrect images, visible as a patchy appearance with coarse grids. 13.1.9.4 Version 2.4.1 [2000Jan 31] ................................... 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. 13.1.9.5 Version 2.4.0 [2000 Jan 05] .................................... Add `set input data separator'. Make `read columns' work with various input separators. Make `read .x.', etc, work with various input separators.  File: gri.info, Node: Version 2.2, Next: Unstable Stream, Prev: Version 2.4, Up: Stable Stream 13.1.10 Version 2.2 ------------------- 13.1.10.1 Version 2.2.6 [1999 Nov 25] ..................................... Make web-based manual easier to read by putting a light-grey background under sample code. 13.1.10.2 Version 2.2.5 [1999 Nov 10] ..................................... Fix bug in RPN calculations that prevented using a negative exponent. 13.1.10.3 Version 2.2.4 [1999 Nov 7] .................................... Add `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!). 13.1.10.4 Version 2.2.3 [1999 Jun 30] ..................................... Fix bug in which word-of-synonym (e.g. `\[0]mysyn') was not detected correctly (thanks to bug report from Kazuhiko Nakayama in Japan) 13.1.10.5 Version 2.2.2 [-] ........................... Clean a few spelling and cross-reference errors in documentation. 13.1.10.6 Version 2.2.1 [1999 Mar 31] ..................................... For debian, properly locate the `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 `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. 13.1.10.7 Version 2.2.0 [1999 Mar 25] ..................................... First debian release. Versions exist for intel, alpha, 68K and powerpc.  File: gri.info, Node: Unstable Stream, Next: Development Version, Prev: Version 2.2, Up: History 13.2 Unstable Stream ==================== * Menu: * Development Version:: * Plans::  File: gri.info, Node: Development Version, Next: Plans, Prev: Unstable Stream, Up: Unstable Stream 13.2.1 Development Version -------------------------- The list below shows changes that have been made in the development version of Gri, i.e. the version on CVS at `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 _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. 13.2.1.1 New Features ..................... * n/a 13.2.1.2 Removed Features ......................... * n/a 13.2.1.3 Bug Fixes .................. * Fix SourceForge bug #618041 (http://sourceforge.net/tracker/index.php?func=detail&aid=618041&group_id=5511&atid=105511) ... solaris compile error, relating to the subroutine `gethostname()' in the `startup.cc' source code file.  File: gri.info, Node: Plans, Next: Deprecated Commands, Prev: Development Version, Up: Unstable Stream 13.2.2 Plans ------------ 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 (`http://gri.sourceforge.net'), which is also the place to go if you have suggestions for other changes to Gri. 13.2.2.1 High Priority ...................... 1. 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. 2. Switch to `popt' library for the processing of command-line options. (Docs on this are at `http://cvs.gnome.org/lxr/source/popt'.) 3. Change `set axes style' from number-based selection to word-based selection, and print a deprecation warning if the number-based syntax is used. 4. Switch from `tmpname' to `mkstemp' subroutine, for temporary filenames. 5. Add readline support, to handle history, command-line editing, etc, for interactive usage (Docs on this are at `http://cnswww.cns.cwru.edu/~chet/readline/readline.html'.) 13.2.2.2 Medium priority ........................ 1. Add optimal interpolation as another method for gridding data (*Note Convert Columns To Grid::). 2. Add ability to read PNG images (*Note Read Image::) (Docs on this are at `http://www.libpng.org/pub/png/'.) 13.2.2.3 Low priority ..................... 1. Add non-RPN mathematics. 2. Add graphical output to the screen as commands are executed. 3. Add support for both little-endian and big-endian binary data.  File: gri.info, Node: Deprecated Commands, Next: Installation, Prev: Plans, Up: History 13.3 Deprecated Commands ======================== * _version 2.9.0_ * Replace `set y axis label horizontal' with `set y axis name horizontal'. * Replace `set y axis label vertical' with `set y axis name vertical'.  File: gri.info, Node: Installation, Next: Unix-install, Prev: Deprecated Commands, Up: Top 14 Installing Gri ***************** * Menu: * Unix-install:: * Msdos-install:: * OS2-install:: * Mac-install:: * Beos-install::  File: gri.info, Node: Unix-install, Next: Archiving Old Versions, Prev: Installation, Up: Installation 14.1 Unix 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  File: gri.info, Node: Archiving Old Versions, Next: Linux, Prev: Unix-install, Up: Unix-install 14.2 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 mkdir -m 755 -p /usr/local/share/gri/2.12.23 cp /usr/bin/gri /usr/local/share/gri/2.12.23 cp /usr/share/gri/gri.cmd /usr/local/share/gri/2.12.23 and then create a shellscript called `/usr/local/bin/gri-2.12.23' containing #!/usr/bin/sh /usr/local/share/gri/2.12.23/gri \ -directory /usr/local/share/gri/2.12.23 \ "$@" 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 `gri*directory-tree' like so in the file `~/.emacs' (*Note Step 2:: in *Note Installing gri-mode.el::) (setq gri*directory-tree '("/usr/local/share/gri/" "/usr/share/gri/"))  File: gri.info, Node: Linux, Next: Precompiled Unix, Prev: Archiving Old Versions, Up: Unix-install 14.2.1 Installation on Linux computers -------------------------------------- Installation is easy on various flavors of linux. Versions are available from the official distributions and also at `http://sourceforge.net/project/showfiles.php?group_id=5511' 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: rpm -i gri-2.12.23 Debian-linux installation may be done with any of several GUI-based tools, or with the following system command: dkpg -i gri_2.12.23-1_i386.deb or via a properly configured `apt' interface that will fetch the latest version from the net: apt-get install gri  File: gri.info, Node: Precompiled Unix, Next: Uncompiled Unix, Prev: Linux, Up: Unix-install 14.2.2 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 2.12.23, and a SPARC solaris machine, show how to install these. The compressed tar file, with a name like `gri-binary-SunOS5-2.12.23.tar.gz' (in this example a Sun OS 5 binary is assumed, with gri version number 2.12.23) contains a directory which holds the executable Gri file, `gri', the library file `gri.cmd', an instructions file, `README', and a Makefile to install Gri. Here's how to install Gri, starting with this tar file: 1. First, uncompress (unzip) the file, and un-tar it, by doing gunzip -c gri-binary-SunOS5-2.12.23.tar.gz | tar xvf - or zcat gri-binary-SunOS5-2.12.23.tar.gz | tar xvf - This will yield a new directory, with a name like `gri-binary-SunOS5-2.12.23', which contains the indicated files. 2. Follow the instructions in the `README' file to install Gri.  File: gri.info, Node: Uncompiled Unix, Next: Msdos-install, Prev: Precompiled Unix, Up: Unix-install 14.3 Compilation on Unix computers ================================== The following steps indicate how to compile Gri on unix computers. The procedure is quite standard. _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 `control' file found in the `debian' directory, to which you must add the package `build-essential'. _Unpack the source_ Type gunzip gri-2.12.23.tgz tar xvf gri-2.12.23.tar (or similar commands) to uncompress and untar the contents. This will yield a new directory named `gri-2.12.23' which contains many files. _Move to the Gri directory_ cd gri-2.12.23 _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 `/usr/local', type ./configure at this time. If you'd rather the files go into another location, run the `configure' script differently, e.g. to get the Gri files to reside within the `/opt' directory, type: ./configure --prefix=/opt 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. As an example, typing `./configure' without a `--prefix' option yields the directory tree (`...' indicates several files not displayed in this list, for brevity). In this example, the most up-to-date version is 2.12.23, but a previous version 2.12.22 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.) /usr/local |-- bin | |-- gri -> gri-2.12.23 | |-- gri-2.12.23 | |-- gri-2.12.22 | |-- 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 |-- ... Trouble-shooting 1: If the permission of the `configure' file is wrong, you'll get an error like `Permission denied'; if so, try typing `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 `Makefile.generic' into `Makefile', and try the following steps, perhaps editing the `Makefile' if you run into errors. 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 `-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 `-frepo' flag. On many machines (e.g. Solaris) you should answer `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: ./configure --enable-frepo ./configure --disable-frepo (Such switches will be ignored unless you're using the GNU compiler.) 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 `LD_LIBRARY_PATH'. For example, on my machine the `netcdf' library is not installed in `/usr/lib', as the `configure' script assumes, but rather in `/usr/local/share/netcdf/lib'. Therefore I have the following line in one of my startup files: export LD_LIBRARY_PATH=/usr/lib:/usr/local/share/netcdf/lib _Compiling Gri_ Now compile Gri by typing make _Testing Gri_ Type make check 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. _Installing Gri_ Assuming compilation succeeds, install `gri' and the ancillary file `gri.cmd', by typing make install If you wish to see where files where be installed, first try a dry run typing make -n install _Cleaning up_ Once these things are done, you may type make clean cd doc ; make clean 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?  File: gri.info, Node: Msdos-install, Next: OS2-install, Prev: Uncompiled Unix, Up: Installation 14.4 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.) 14.4.0.1 MSDOS Operating System ............................... To compile and install Gri under MSDOS, do this: 1. To begin, install `DJGPP V2', if it is not on your system already. It can be found at `http://www.delorie.com/djgpp' 2. Uncompress and extract from gri source package (*Note Uncompiled Unix::). 3. Type `make -f Makefile.dj2' to compile. If it fails, you might have to edit the file `Makefile.dj2' to match the characteristics of your system. Please inform the author, Dan Kelley at Dan.Kelley@Dal.CA, if you think your modifications might be useful to others. 4. Type `make -f Makefile.dj2 install' to install it (normally on the `C:' drive). If you encounter problems, read the first few lines of the Makefile (i.e. the file `Makefile.dj2') for hints on things to try. For example, in the present version of `Makefile.dj2' these hints are given: 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. To view the output, use a PostScript viewer such as GSview. 14.4.0.2 LINUX Operating System ............................... 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 `gri-binary-solaris-2.1.10.tar.gz'; treat it as in other unix systems (*Note Uncompiled Unix::).  File: gri.info, Node: OS2-install, Next: Mac-install, Prev: Msdos-install, Up: Installation 14.5 Compilation under OS/2 =========================== Gri compiles, using the gcc compiler under OS/2, provided that the included `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.  File: gri.info, Node: Mac-install, Next: Beos-install, Prev: OS2-install, Up: Installation 14.6 Compilation in Macintosh OS X ================================== 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 `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. _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: * 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.) * Visit the `darwinports' directory of the newly-created directory tree, and type sudo port -d -v build 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 (`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 `build version' of the `port' command. * Do a "destroot" operation: sudo port -d -v destroot * Install it: sudo port -d -v install Note: if you already have an older version of Gri in the Darwinports system, you must first issue the command sudo port deactivate gri  File: gri.info, Node: Beos-install, Next: Bugs, Prev: Mac-install, Up: Installation 14.7 Compilation under BeOS =========================== The BeOS system compiles Gri cleanly without modification; just follow the instructions for unix.  File: gri.info, Node: Bugs, Next: Known Bugs, Prev: Beos-install, Up: Top 15 Bugs ******* * Menu: * Known Bugs:: Bugs in the current version * Reporting Bugs:: How to report bugs * Killing Bugs:: How to (try to) kill bugs  File: gri.info, Node: Known Bugs, Next: Reporting Bugs, Prev: Bugs, Up: Bugs 15.1 Known bugs =============== To get a list of known bugs, in the present or past versions, visit `http://sourceforge.net/tracker/?atid=105511&group_id=5511&func=browse'.  File: gri.info, Node: Reporting Bugs, Next: Killing Bugs, Prev: Known Bugs, Up: Bugs 15.2 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. 1. Visit the bug-tracking part of the Source Forge Gri development site, at `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 *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.) 2. 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. 3. 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 (*Note Killing Bugs::).  File: gri.info, Node: Killing Bugs, Next: Debugging Software You Will Need, Prev: Reporting Bugs, Up: Bugs 15.3 Killing Bugs ================= * Menu: * Debugging Software You Will Need:: * Debugging at a Glance:: * Debugging Example::  File: gri.info, Node: Debugging Software You Will Need, Next: Debugging at a Glance, Prev: Killing Bugs, Up: Killing Bugs 15.3.1 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 `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 `gdb' from within Emacs. Otherwise, you'll want to glance at the documentation on `gdb' to see how to use it in standalone mode.  File: gri.info, Node: Debugging at a Glance, Next: Debugging Example, Prev: Debugging Software You Will Need, Up: Killing Bugs 15.3.2 Debugging at a glance ---------------------------- The list below is a sketch of what you might try, and in what order. * Check the bug list to see if other users have found your bug, and also to see if there is a workaround. * Try a more recent version of gri. If it works, you might wish to archive the version you have at the moment and upgrade. * If you suspect your bug has something to do with system calls, as in the `system' command (*Note System::) or as in piped input files (*Note Open::), you should re-run the script with `gri -superuser8' instead of with `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.) * If your bug results in early termination, you should run Gri inside a debugger (e.g. GDB, assumed henceforth). When the program terminates, type `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 `Makefile' for a hint at how to use a popular one, called "Electric Fence." * 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.  File: gri.info, Node: Debugging Example, Next: Test Suite, Prev: Debugging at a Glance, Up: Killing Bugs 15.3.3 A debugging Example -------------------------- Let's take a recent bug as an example. Peter Galbraith found that the gri script 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 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.) 1. Copy the above script (called `test.gri') into the Gri source directory, and the script into an Emacs buffer. Note: all the following steps are done within Emacs, and the items in parentheses are the Emacs keys to get the indicated actions. 2. If you're working from a pre-compiled version, you'll need to get the source first and do a compile yourself (*Note Uncompiled Unix::). Then do a `make tags' command (type this to the unix shell) to create a so-called "tag" table. 3. Run Gri in this emacs buffer (`C-cC-r') noting from the postscript window that pops up that the colors are, indeed, mixed up. 4. Load up the `gdb' debugger by typing `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. 5. Reasoning that the error probably occurs at `set color' or `draw box', try replacing the latter by a command such as `draw label "hi" at 3 3 cm"'. The color is still wrong, indicating that it is the `set color' command that has the problem. 6. Next, we must find where the C++ code corresponding to the `set color' command resides. As it turns out, all `set' commands are defined in the source file `set.cc', and this command is defined in a subroutine called `set_colorCmd()'. But the author knows this - how would you? The answer is to look in the `gri.cmd' file, for the `set color' command. (Search for the string ``set color '.) Then read down to see the body of the command, enclosed in braces; you'll see { extern "C" bool set_colorCmd(void); } which indicates that the subroutine name is `set_colorCmd()'. 7. Next we need to edit this subroutine to see what it is doing. There are several ways to find it (e.g. `grep' through the source files), but the easiest is to use the "tags" feature of Emacs, by typing `M-. set_colorCmd'. This will bring you to the indicated subroutine. 8. 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 switch (_nword) { line. (That's line `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 (`set color hsb 1.000 1 1'), so move down to the line case 6: and you'll see that there is an `if' statement seeing whether this word is `rgb' or `hsv'. These statements are checking `_word[2]', which is the third word of the command. (In Gri, as in C, words start at zero. Thus, for this command, `_word[0]' is `set', `_word[1]' is `color', and `_word[2]' is expected to be either `rgb' or `hsb'. We are having problems with the `hsb' style, so we'll move down to that code. The code that's being executed is as follows. } 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; The `Require' lines are ensuring that we could decode the values of the variables `hue', etc, from the commandline. Then we clip the range of these values. Then we convert from `hsb' color format to `rgb' color format, save the values of the colors in Gri variables with `PUT_VAR', and then set the color with `c.setHSV'. Finally we save this color in the Gri "state" with `_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 `gr_hsv2rgb()' line. 9. 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 `C-x SPC'. Then move to the `gdb' buffer and re-run Gri by typing run -directory . test.gri to run Gri on our script. Then, magic happens! Gri stops at the indicated breakpoint, and Emacs will display both the `gdb' buffer and the `set.cc' buffer. The latter has a margin indication telling what line were are on. You may now type `gdb' commands in the `gdb' buffer. In particular, type p hue to print the hue. Then type p red to see the red value. Then type c 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 `test.gri' and run gri again (type `r' in `gdb'). This seems to indicate that the conversion is working strangely. 10. To see how the conversion is done, clear the breakpoints by typing `delete' in the `gdb' buffer, then insert a breakpoint *before* `gr_hsv2rgb' is called. Then, run Gri again (`r' in the `gdb' buffer). When it stops just before this subroutine, type `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 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); ... in the present version of Gri, but in the previous (buggy) version, the `if' statement was missing. Without this `if' statement, Gri produced wrong colors. With the statement, the colors are correct. And so ends the example. You may wish to read the Foley and Van Dam textbook to see just what I'm doing in `gr_hsv2rgb', but suffice it to say that the problem in the (older) version of Gri was that `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 `~/.emacs' file, which is used to customize the Emacs editor: (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) 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.  File: gri.info, Node: Test Suite, Next: Gri in the Press, Prev: Debugging Example, Up: Top 16 Test Suite ************* The following test files are invoked by typing `make test', after compiling Gri. They are provided here because they are examples of scripts that are *known to work* for the version of Gri described in this manual. Heavy use is made of the `assert' command (*Note Assert::) in these test files. Thus the *code itself* demonstrates the features, instead of comments in the code. This is advantageous since comments tend to be incorrect!  File: gri.info, Node: Gri in the Press, Next: Acknowledgments, Prev: Test Suite, Up: Top 17 Gri in the Press ******************* A gentle introduction to Gri is provided in a Linux Journal article, available at `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. Journals in Oceanography, Atmospheric Science, Earth Science, etc. * *Bulletin on Coastal Oceanography* (in Japanese with English abstract) * *Fisheries Oceanography* * *Deep-Sea Research* * *EOS, Transactions of the American Geophysical Union* * *Estuarine, Coastal and Shelf Science* * *Geophysical Research Letters* * *Journal of Atmospheric and Oceanic Technology* * *Journal of Geophysical Research* * *Journal of Marine Research* * *Journal of Plankton Research* * *Journal of Physical Oceanography* * *Journal of the Japan Scoiety for Marine Surveys and Technology* (in Japanese with English abstract) * *Limnology and Oceanography* * *Marine Biology* * *Marine Ecology Progress Series* * *Monthly Weather Review* * *Oceanography* * *Paleoceanography* * *Progress in Oceanography* * *Quaternary Research* * *Scientia Marina* * *South African Journal of Marine Science* * *Umi no Kenkyu* (Japanese version for Journal of Oceanography, in Japanese with English abstract) Journals in Physics, Chemistry, etc. * *Applied Physics A* * *Journal of Fluid Mechanics* * *Journal of Physical Chemistry B* * *Physica D* * *Physics of Fluids* * *Physics A* * *Physics Letters B* * *Physical Review C* * *Physical Review Letters* * *Research on Chemical Intermediates* * *Theoretical Computational Fluid Dynamics* Other Journals * *Nature* Books, Monographs, etc. * *The Atlas of Hawai'i* (University of Hawai'i Press) * *Differential Equations with Applications to Biology* (American Mathematical Society) * *Ocean Drilling Program* publications  File: gri.info, Node: Acknowledgments, Next: License, Prev: Gri in the Press, Up: Top 18 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, Karin Bryan, Sara Bennett, Luke Blaikie, Dave Brickman, Steve Cayford, Clyde Clements, Andrew Collier, Pierre Flament, Peter Galbraith, Dave Hebert, David A. Holland, Christopher Illies, Cody Kirkpatrick, Thomas Larsen, Alejandro López-Valencia, Kawamura Masao, Steve Matheson, Brian May, Ed Nather, Roman Neuhauser, Carl Osterwisch, Richard Andrew Miles Outerbridge, Tim Powers, Jinyu Sheng, Toru Suzuki, Keith Thompson, David Trueman, Wolfgang Voegeli, Jeff Whitaker, and 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.  File: gri.info, Node: License, Next: Concept Index, Prev: Acknowledgments, Up: Top 19 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. 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. gri-2.12.23/doc/gri.info-3000644 000767 000024 00000376747 11607300641 015465 0ustar00kelleystaff000000 000000 This is gri.info, produced by makeinfo version 4.8 from gri.texi. INFO-DIR-SECTION Scientific Applications START-INFO-DIR-ENTRY * Gri: (gri). Programming language for scientific illustration END-INFO-DIR-ENTRY  File: gri.info, Node: Concept Index, Next: Index of Commands, Prev: License, Up: Top Index, general ************** [index] * Menu: * ! rpn operator: Unary Operators. (line 14) * & rpn operator: Binary Operators. (line 82) * & syntax, how it is parsed: Implementation of Ampersand Syntax. (line 6) * * rpn operator: Binary Operators. (line 23) * + rpn operator: Binary Operators. (line 17) * - rpn operator: Binary Operators. (line 20) * -batch command-line option: Invoking Gri. (line 86) * -chatty command-line option: Invoking Gri. (line 88) * -creator command-line option: Invoking Gri. (line 282) * -debug command-line option: Invoking Gri. (line 132) * -directory command-line option: Invoking Gri. (line 139) * -directory_default command-line option: Invoking Gri. (line 135) * -help command-line option: Invoking Gri. (line 238) * -no_bounding_box command-line option: Invoking Gri. (line 148) * -no_cmd_in_ps: Invoking Gri. (line 158) * -no_private command-line option: Invoking Gri. (line 194) * -no_startup_message command-line option: Invoking Gri. (line 188) * -no_warn_offpage command-line option: Invoking Gri. (line 164) * -output PS_file_name commandline option: Invoking Gri. (line 167) * -output SVG_file_name commandline option: Invoking Gri. (line 173) * -private command-line option: Invoking Gri. (line 190) * -publication command-line option: Invoking Gri. (line 202) * -superuser command-line option: Invoking Gri. (line 211) * -trace command-line option: Invoking Gri. (line 224) * -version command-line option: Invoking Gri. (line 227) * -warn_offpage command-line option: Invoking Gri. (line 230) * -yes command-line option: Invoking Gri. (line 234) * / rpn operator: Binary Operators. (line 26) * < comparison operator in rpn expressions: Binary Operators. (line 6) * < rpn operator: Binary Operators. (line 29) * <= rpn operator: Binary Operators. (line 36) * = rpn operator assigns to variables, synonyms, and columns: Binary Operators. (line 49) * == comparison operator in rpn expressions: Binary Operators. (line 6) * > comparison operator in rpn expressions: Binary Operators. (line 6) * >= rpn operator: Binary Operators. (line 42) * @ rpn operator, for accessing columnar data: Binary Operators. (line 102) * [] syntax for optional words in commands: Invoking Gri. (line 40) * [] syntax for selecting words in synonyms: Extracting Words From Strings. (line 16) * \$() syntax for system commands: Using OS Inside Gri. (line 9) * \& and \&& notation: Determining Calling Information. (line 6) * \.return_value., from read columns: Read Columns. (line 85) * \.return_value., from read grid ...: Read Grid. (line 88) * \.return_value., from system ...: System. (line 131) * \.return_value., general: Important Builtin Synonyms. (line 32) * \.wd. synonym, storing working directory: Important Builtin Synonyms. (line 6) * \<<, for newline in show commands: Show. (line 79) * \>>, for horizontal tab in show commands: Show. (line 79) * \@alias notation: Alias Synonyms. (line 6) * \\.path_commands. builtin synonym <1>: Invoking Gri. (line 240) * \\.path_commands. builtin synonym: Set Path To. (line 6) * \\.path_data. builtin synonym: Set Path To. (line 6) * abs rpn operator: Unary Operators. (line 20) * accented characters in text: Non-English Text. (line 6) * acknowledgments: Acknowledgments. (line 6) * acos rpn operator: Unary Operators. (line 23) * acosh rpn operator: Unary Operators. (line 26) * adding new commands to Gri: Adding New Commands. (line 6) * adding new commands, complicated example: Complicated New Command. (line 6) * age rpn operator: Unary Operators. (line 30) * Alejandro Lopez-Valencia (contributor): Acknowledgments. (line 12) * alias synonyms, checking for existence of: Unary Operators. (line 145) * alias synonyms, with the \@alias notation: Alias Synonyms. (line 6) * aligning superscripts and subscripts with \!: Mathematical Text. (line 68) * American Geophysical Union, recommended font size: Set Font Size. (line 17) * American Geophysical Union, recommended gray levels: Set Graylevel. (line 11) * American Geophysical Union, recommended image gray levels: Images. (line 10) * American Geophysical Union, recommended line thickness: Set Line Width. (line 20) * and rpn operator: Binary Operators. (line 85) * Andrew Collier (contributor): Acknowledgments. (line 10) * annotating lines: Legend. (line 6) * arc, drawing: Draw Arc. (line 6) * area rpn operator: Manipulation of Columns etc. (line 30) * area under curve: Manipulation of Columns etc. (line 30) * argc rpn operator, yielding number of commandline arguments: Solitary Operators. (line 6) * argc, RPN operator to access commandline arguments: Invoking Gri. (line 71) * arguments on command line, accessing with argv rpn operator: Unary Operators. (line 68) * arguments on commandline, accessing: Invoking Gri. (line 71) * arguments to new commands, how to alter: Changeable Command Arguments. (line 6) * argv rpn operator, access commandline arguments: Unary Operators. (line 68) * argv, RPN operator to access commandline arguments: Invoking Gri. (line 71) * arrows: Set Arrow Type. (line 6) * arrows, drawing single: Draw Arrow. (line 6) * arrows, how to read direction field: Read Columns. (line 62) * arrows, setting size of heads: Set Arrow Size. (line 6) * arrows, size of heads stored in ..arrowsize..: Built-in Variables. (line 29) * ascent rpn operator: Unary Operators. (line 103) * asin rpn operator: Unary Operators. (line 58) * assert command, for debugging: Assert. (line 6) * assigning to columns, variables and synonyms within RPN expressions: Binary Operators. (line 49) * atan rpn operator: Unary Operators. (line 61) * atof rpn operator: Unary Operators. (line 107) * awk system tool: Awk. (line 6) * awk, sample of use: Operating System. (line 6) * axes, and mathematical operations on columns: Axis Scaling. (line 6) * axes, automatic drawing of: Grayscale Images. (line 14) * axes, autoscaling of: Axis Scaling. (line 6) * axes, displaying information about: Show. (line 12) * axes, forcing rescaling: Rescale. (line 6) * axes, guide to choosing length of: Length. (line 6) * axes, labels for: Labels. (line 6) * axes, length of: Built-in Variables. (line 138) * axes, linear: Log And Linear. (line 6) * axes, location of: Position. (line 6) * axes, logarithmic: Log And Linear. (line 6) * axes, range of values on: Range. (line 6) * axes, scales: Simple Example Revisited. (line 6) * axes, setting tic size: Set Tic Size. (line 6) * axis labels, controlling: Set X Axis. (line 66) * axis sizes, scaled with golden ratio: Length. (line 9) * Barnes method for gridding data: Ungridded Data. (line 23) * batch processing <1>: Invoking Gri. (line 86) * batch processing: Built-in Variables. (line 34) * beeping on errors: Set Beep. (line 6) * beginners, simple example: Simple Example. (line 6) * BeOS unix compilation: Beos-install. (line 6) * big-endian vs little-endian data, caution: Binary Files. (line 3) * big-endian vs little-endian data, plans: Plans. (line 12) * binary data: Binary Files. (line 3) * binary operators in rpn expressions: Binary Operators. (line 6) * bounding box: Invoking Gri. (line 148) * bounding box, setting: Set Bounding Box. (line 6) * Brian May, contributor: Acknowledgments. (line 13) * bug, resulting in bus error: Reporting Bugs. (line 25) * bug, resulting in segmentation fault: Reporting Bugs. (line 25) * bugs in Gri: Known Bugs. (line 6) * bugs, how to kill them: Killing Bugs. (line 3) * bugs, how to report: Reporting Bugs. (line 3) * built-in synonyms, global: Important Builtin Synonyms. (line 6) * built-in synonyms, local: Local Synonyms. (line 6) * built-in variables: Built-in Variables. (line 6) * builtin colors, list of: Pen Color. (line 50) * builtin synonym \\.path_commands. <1>: Set Path To. (line 6) * builtin synonym \\.path_commands.: Invoking Gri. (line 240) * builtin synonym \\.path_data.: Set Path To. (line 6) * bus error, what to do: Reporting Bugs. (line 25) * calling OS from within strings: Using OS Inside Gri. (line 40) * Carl Osterwisch (contributor): Acknowledgments. (line 13) * cd command: Cd. (line 6) * ceil rpn operator: Unary Operators. (line 110) * changeable arguments, using delete on: Using New And Delete. (line 6) * changeable arguments, using new on: Using New And Delete. (line 6) * changes to Gri, protection against: Expecting. (line 6) * changing directories: Cd. (line 6) * character variables (synonyms) <1>: Synonyms. (line 6) * character variables (synonyms): Using Synonyms. (line 6) * checking for missing value in rpn expressions: Unary Operators. (line 6) * Christopher Illies (contributor): Acknowledgments. (line 11) * circles, drawing: Draw Circle. (line 6) * clipping data using set input clip: Set Clip. (line 46) * clipping data using set input data window: Set Input Data Window. (line 30) * close command: Close. (line 6) * closing files: Close. (line 6) * Clyde Clements (contributor): Acknowledgments. (line 10) * cmtopt rpn operator: Unary Operators. (line 120) * Cody Kirkpatrick (contributor): Acknowledgments. (line 12) * colon on commandline: Invoking Gri. (line 71) * color, displaying names and RGB values of: Show. (line 17) * color, for text: Set Font Color. (line 6) * color, symbols: Scattergraphs. (line 67) * colors, list of: Pen Color. (line 50) * colors, reading from X11 database: Read Colornames. (line 6) * colorscale modification: Mathematics. (line 72) * colorscale of image, reading from file: Read Image Colorscale. (line 6) * colorscale, drawing: Draw Image Palette. (line 11) * colorscale, setting for images: Set Image Colorscale. (line 6) * colour vs Color spelling: List Of Gri Commands. (line 13) * column dat, assigning within RPN expressions: Binary Operators. (line 49) * column data, accessing individual values and stats: Manipulation of Columns etc. (line 9) * column data, statistics: Manipulation of Columns etc. (line 22) * column data, writing to a file: Write Columns. (line 6) * column data, x in one file and y in another: Read Columns. (line 67) * column mathematics: Mathematics. (line 12) * column, displaying statistics of: Show. (line 24) * columns, assigning within RPN expressions: Binary Operators. (line 49) * columns, creating from grid: Convert Grid To Columns. (line 6) * columns, filtering <1>: Filter. (line 6) * columns, filtering: Smooth. (line 6) * columns, reordering: Reorder. (line 6) * comma-separated values: Opening Pipes. (line 36) * command arguments, how to alter: Changeable Command Arguments. (line 6) * command files: Invoking Gri. (line 240) * command files, path to search for: Set Path To. (line 6) * command lines, parsing in new Gri commands: Local Synonyms. (line 6) * command-line interface: Plans. (line 6) * command-line option -creator: Invoking Gri. (line 282) * command-line option -warn_offpage: Invoking Gri. (line 230) * command-line options: Invoking Gri. (line 84) * command-line, specifying command file: Invoking Gri. (line 240) * CommandFile command-line option: Invoking Gri. (line 240) * commandfile, pathname: Using OS Inside Gri. (line 17) * commandline arguments, accessing: Invoking Gri. (line 71) * commandline arguments, accessing with argv rpn operator: Unary Operators. (line 68) * commandline flag colon: Invoking Gri. (line 71) * commandline option -output PS_file_name: Invoking Gri. (line 167) * commandline option -output SVG_file_name: Invoking Gri. (line 173) * commands extending over several lines: Long Command Lines. (line 6) * commands, complete list of: List Of Gri Commands. (line 13) * commands, how to add new ones to Gri: Adding New Commands. (line 6) * comments, # style: Linegraphs. (line 24) * comments, and system commands: System. (line 12) * comparison operators in rpn expressions: Binary Operators. (line 6) * compilation in Macintosh OS X: Mac-install. (line 6) * compilation under BeOS: Beos-install. (line 6) * compilation under Linux: Msdos-install. (line 57) * compilation under MSDOS: Msdos-install. (line 13) * compilation under OS/2: OS2-install. (line 6) * compiling gri: Uncompiled Unix. (line 9) * compressed files, opening: Ascii Files. (line 30) * computational cost, of convert columns to grid command: Convert Columns To Grid. (line 99) * configure script, how to use to compile gri: Uncompiled Unix. (line 9) * continued lines: Long Command Lines. (line 6) * contour data, writing to a file: Write Contour. (line 6) * contouring: Draw Contour. (line 6) * contouring, clipping out invalid areas: Set Grid Missing. (line 6) * contouring, interpolating to new grid: Interpolate. (line 6) * contours: Contour Plots. (line 6) * contours on images: Combination. (line 6) * contours, orientation of labels: Set Contour Labels. (line 6) * contours, pre-gridded data: Pre-gridded Data. (line 6) * contours, smoothing grid data: Smooth. (line 25) * contours, spacing of labels on: Set Contour Label Position. (line 6) * contours, ungridded data: Ungridded Data. (line 6) * contours, whiting/nowhiting under the labels: Set Contour Labels. (line 6) * contributor and bug-fixer, Wolfgang Voegeli: Acknowledgments. (line 15) * contributor, Alejandro Lopez-Valencia: Acknowledgments. (line 12) * contributor, Andrew Collier: Acknowledgments. (line 10) * contributor, Brian May: Acknowledgments. (line 13) * contributor, Carl Osterwisch: Acknowledgments. (line 13) * contributor, Christopher Illies: Acknowledgments. (line 11) * contributor, Clyde Clements: Acknowledgments. (line 10) * contributor, Cody Kirkpatrick: Acknowledgments. (line 12) * contributor, Dave Brickman: Acknowledgments. (line 10) * contributor, Dave Hebert: Acknowledgments. (line 11) * contributor, David A. Holland: Acknowledgments. (line 11) * contributor, David Trueman: Acknowledgments. (line 15) * contributor, Ed Nather: Acknowledgments. (line 13) * contributor, George White: Acknowledgments. (line 16) * contributor, Ivo Alxneit: Acknowledgments. (line 9) * contributor, Jeff Whitaker: Acknowledgments. (line 15) * contributor, Jinyu Sheng: Acknowledgments. (line 14) * contributor, Karin Bryan: Acknowledgments. (line 9) * contributor, Kawamura Masao: Acknowledgments. (line 12) * contributor, Keith Thompson: Acknowledgments. (line 15) * contributor, Luke Blaikie: Acknowledgments. (line 9) * contributor, Peter Galbraith: Acknowledgments. (line 11) * contributor, Pierre Flament: Acknowledgments. (line 10) * contributor, Richard Andrew Miles Outerbridge: Acknowledgments. (line 14) * contributor, Roman Neuhauser: Acknowledgments. (line 13) * contributor, Sara Bennett: Acknowledgments. (line 9) * contributor, Steve Cayford: Acknowledgments. (line 10) * contributor, Steve Matheson: Acknowledgments. (line 13) * contributor, Thomas Larsen: Acknowledgments. (line 12) * contributor, Tim Powers: Acknowledgments. (line 14) * contributor, Toru Suzuki: Acknowledgments. (line 14) * conversion between user and page units: Binary Operators. (line 6) * conversion, hour-minute-second to decimal hour: Opening Pipes. (line 64) * conversion, string to number, in rpn expressions: Unary Operators. (line 6) * convert columns to grid command: Convert Columns To Grid. (line 6) * convert columns to spline command: Convert Columns To Spline. (line 6) * convert grid to columns command: Convert Grid To Columns. (line 6) * convert grid to image command: Convert Grid To Image. (line 6) * convert image to grid command: Convert Image To Grid. (line 6) * converting decimal values to hexadecimal strings: Unary Operators. (line 124) * converting grids to images: Reading and Creating Image Data. (line 6) * converting hexadecimal strings to decimal values: Unary Operators. (line 179) * cookbook: Examples. (line 6) * cos rpn operator: Unary Operators. (line 114) * cosh rpn operator: Unary Operators. (line 117) * create columns from function command: Create Columns From Function. (line 6) * csv data: Opening Pipes. (line 36) * curves, drawing: Draw Curve. (line 6) * darwinport: Mac-install. (line 6) * dashed lines: Set Dash. (line 6) * data files, opening: Open. (line 6) * data files, path to search for: Set Path To. (line 6) * data files, positioning within: Skip. (line 6) * data files, protecting against movement of: Length. (line 6) * data files, words in lines: Built-in Variables. (line 53) * data format: Linegraphs. (line 39) * data in columns, writing to a file: Write Columns. (line 6) * data in contours, writing to a file: Write Contour. (line 6) * data in grid, writing to a file: Write Grid. (line 6) * data in image, writing to a file: Write Image. (line 6) * data, clipping using set input clip: Set Clip. (line 46) * data, clipping using set input data window: Set Input Data Window. (line 30) * data, comma-separated values: Opening Pipes. (line 36) * data, csv: Opening Pipes. (line 36) * data, dealing with odd datasets: Handling Data. (line 6) * data, from a spreadsheet: Opening Pipes. (line 36) * data, images: Reading and Creating Image Data. (line 6) * data, missing values: Missing Values. (line 6) * data, spreadsheet: Opening Pipes. (line 36) * data, stored in comma-separated values: Opening Pipes. (line 36) * date: Important Builtin Synonyms. (line 32) * Dave Brickman (contributor): Acknowledgments. (line 10) * Dave Hebert (contributor): Acknowledgments. (line 11) * David A Holland (contributor): Acknowledgments. (line 11) * David Trueman (contributor): Acknowledgments. (line 15) * day-of-week axis: Set X Axis. (line 66) * debian: Linux. (line 6) * debug command: Debug. (line 6) * debug command-line option: Built-in Variables. (line 36) * debugger used with Gri: Reporting Bugs. (line 25) * debugging: Debug. (line 6) * debugging Gri programs: Debugging. (line 6) * debugging using superuser flags: Superuser. (line 6) * debugging, using ..debug..: Built-in Variables. (line 36) * debugging, with assert command: Assert. (line 6) * default values: Defaults. (line 6) * defining rpn functions: Rpnfunction. (line 6) * delete command: Delete. (line 6) * delete, used on changeable arguments: Using New And Delete. (line 6) * deleting variables, synonyms, scales, etc: Delete. (line 6) * deprecated commands: Deprecated Commands. (line 6) * descent rpn operator: Unary Operators. (line 150) * developer command set environment: Set Environment. (line 6) * developer command set flag: Set Flag. (line 6) * differentiate command: Differentiate. (line 6) * differentiation: Differentiate. (line 6) * direction field, how to read: Read Columns. (line 62) * directories, changing: Cd. (line 6) * directory listing: Ls. (line 6) * directory structure of Gri installation: Unix-install. (line 6) * directory, how to find out: Pwd. (line 6) * directory, stored in synonym \.wd.: Important Builtin Synonyms. (line 6) * directory_exists rpn operator: Unary Operators. (line 155) * discussion Group: Discussion Group. (line 3) * dollar-parenthesis syntax for system commands: Using OS Inside Gri. (line 9) * draw arrows command: Draw Arrows. (line 6) * draw axes command: Draw Axes. (line 3) * draw axes if needed command: Draw Axes If Needed. (line 3) * draw border box command: Draw Border Box. (line 3) * draw box command: Draw Box. (line 6) * draw circle command: Draw Circle. (line 6) * draw contour command: Draw Contour. (line 6) * draw curve command: Draw Curve. (line 6) * draw essay command: Draw Essay. (line 6) * draw gri logo command: Draw Gri Logo. (line 6) * draw grid comman: Draw Grid. (line 6) * draw image comman: Draw Image. (line 6) * draw image histogram command: Draw Image Histogram. (line 6) * draw image palette comman: Draw Image Palette. (line 6) * draw isopycnal command: Draw Isopycnal. (line 6) * draw isospice command: Draw Isospice. (line 6) * draw label boxed command: Draw Label Boxed. (line 6) * draw label command: Draw Label. (line 6) * draw label for last curve command: Draw Label For Last Curve. (line 6) * draw label whiteunder command: Draw Label Whiteunder. (line 6) * draw line command: Draw Line From. (line 6) * draw line legend command: Draw Line Legend. (line 6) * draw lines command: Draw Lines. (line 6) * draw patches command: Draw Patches. (line 6) * draw polygon command: Draw Polygon. (line 6) * draw regression line command: Draw Regression Line. (line 6) * draw symbol at command: Draw Symbol At. (line 6) * draw symbol command: Draw Symbol. (line 6) * draw symbol legend command: Draw Symbol Legend. (line 6) * draw time stamp command: Draw Time Stamp. (line 6) * draw title command: Draw Title. (line 6) * draw values command: Draw Values. (line 6) * draw x axis command: Draw X Axis. (line 6) * draw x box plot command: Draw X Box Plot. (line 6) * draw y axis command: Draw Y Axis. (line 6) * draw y box plot command: Draw Y Box Plot. (line 6) * draw zero line command: Draw Zero Line. (line 6) * drawing arcs: Draw Arc. (line 6) * drawing contours: Draw Contour. (line 6) * drawing contours of pregridded data: Pre-gridded Data. (line 35) * drawing contours of ungridded data: Ungridded Data. (line 23) * drawing curves: Draw Curve. (line 6) * drawing data lines: Linegraphs. (line 55) * drawing image plots: Example Image. (line 34) * drawing labels: Draw Label Boxed. (line 6) * drawing labels for data curves: rpn Examples. (line 58) * drawing labels on xy curves: Draw Label For Last Curve. (line 6) * drawing legends: Legend. (line 6) * drawing linegraphs: Linegraphs. (line 7) * drawing patches: Draw Patches. (line 6) * drawing polygons: Draw Polygon. (line 6) * drawing satellite images: Example Image. (line 34) * drawing single symbols: Draw Symbol At. (line 6) * drawing text strings: Draw Label Boxed. (line 6) * drawing titles: Linegraphs. (line 58) * drawing x-y graphs, simple: Simple Example. (line 6) * dup rpn operator: Unary Operators. (line 159) * dup rpn stack operator: Stack Operators. (line 6) * e, base of natural logarithms, in RPN expressions: Solitary Operators. (line 22) * Ed Nather (contributor): Acknowledgments. (line 13) * editing Gri code with Emacs: Emacs Mode. (line 6) * electric fence, for debugging: Debugging at a Glance. (line 3) * emacs, editing mode for Gri: Emacs Mode. (line 6) * email list: Discussion Group. (line 3) * end group command: End Group. (line 6) * endian file compatibility, caution: Binary Files. (line 3) * endian file compatibility, plans: Plans. (line 12) * environment variables: Get Env. (line 6) * eof on files: Set Ignore Error Eof. (line 6) * error messages: Error Messages. (line 6) * errors, beeping: Set Beep. (line 6) * example 01, linegraph using data in a separate file <1>: Simple Example. (line 14) * example 01, linegraph using data in a separate file <2>: Linegraphs. (line 7) * example 01, linegraph using data in a separate file: Simple Example. (line 60) * example 03 (controlling scales, etc): Simple Example Revisited. (line 30) * example 03, controlling scales, etc: Simple Example Revisited. (line 31) * example 04 (contouring pregridded data): Pre-gridded Data. (line 35) * example 05 - Contouring ungridded data, from figure: Ungridded Data. (line 30) * example 06, plot IR image of Gulf of Maine: Example Image. (line 40) * example 07, box plots of mixing efficiency vs density ratio (meddy): Box Plots. (line 20) * example 08, plot T=T(x,rho) section of eubex data: Contouring. (line 20) * example 09, plot dTdrho-rho section: Grayscale Images. (line 19) * example 10 (image plot with contours): Combination. (line 11) * example 10, draw image plot of flushing of dye out of cove: Combination. (line 16) * example 11, fancy plot: Fancy. (line 11) * example 12, linegraph with key inside plot: Legend. (line 11) * example 13, TS diagram, with isopycnals: TS Diagram. (line 7) * examples of rpn mathematics: rpn Mathematics. (line 6) * exch rpn operator: Binary Operators. (line 98) * exch rpn stack operator: Stack Operators. (line 6) * existence of a synonym, testing: Unary Operators. (line 136) * existence of a variable, testing: Unary Operators. (line 141) * existence of an alias synonym, testing: Unary Operators. (line 145) * exp rpn operator: Unary Operators. (line 163) * exp10 rpn operator: Unary Operators. (line 167) * expecting command: Expecting. (line 6) * exponentiation: Mathematics. (line 12) * extending Gri by adding new commands: Adding New Commands. (line 6) * extending Gri by adding new commands, complicated example: Complicated New Command. (line 6) * fancy plot: Fancy. (line 6) * FEM mesh plot: Finite Element Model Mesh. (line 6) * file age, determined with the age rpn operator: Unary Operators. (line 30) * file permissions, testing with file_exists and directory_exists: Unary Operators. (line 155) * file, saving results into: Write. (line 6) * file, selecting between open files: Read From. (line 6) * file, temporary: Using OS Inside Gri. (line 108) * file_exists rpn operator: Unary Operators. (line 171) * filename, temporary: Using OS Inside Gri. (line 108) * filenames, constructing using the operating system: Using Synonyms. (line 6) * files, closing: Close. (line 6) * files, Command-file: Invoking Gri. (line 240) * files, listing: Ls. (line 6) * files, positioning within: Skip. (line 6) * files, testing for eof: Set Ignore Error Eof. (line 6) * files, ~/.grirc initialization file: Resource File. (line 6) * filled regions: Draw Curve. (line 6) * filter command: Filter. (line 6) * filtering column data: Filter. (line 6) * filtering image data: Filter. (line 6) * Finite Element Model mesh: Finite Element Model Mesh. (line 6) * fink: Mac-install. (line 6) * first-time usage: Simple Example. (line 6) * flip command: Flip. (line 6) * flipping grids and images: Flip. (line 6) * floor rpn operator: Unary Operators. (line 175) * font encoding: Set Font Encoding. (line 6) * font size: Set Font Size. (line 6) * font, selecting: Simple Example Revisited. (line 6) * font, setting color of: Set Font Color. (line 6) * font, setting encoding vector of: Set Font Encoding. (line 6) * font, size: Built-in Variables. (line 70) * format for columnar data: Linegraphs. (line 39) * format, for sprintf command: Sprintf. (line 23) * formulae, how to plot: Formula Plots. (line 6) * French accents in text: Non-English Text. (line 6) * FTP site, cookbook: Introduction. (line 78) * functions in rpn expressions: Rpnfunction. (line 6) * functions, how to plot: Formula Plots. (line 6) * gawk system tool: Awk. (line 6) * gawk, sample of use: System. (line 6) * gawk, using to convert files from HMS to decimal: Opening Pipes. (line 64) * geography, converting hour-minute-second to decimal hour: Opening Pipes. (line 64) * George White (contributor): Acknowledgments. (line 16) * get env command: Get Env. (line 6) * global built-in synonyms: Important Builtin Synonyms. (line 6) * global synonyms: Important Builtin Synonyms. (line 6) * golden ratio, used for axes sizes: Length. (line 9) * graphics state, saving and restoring: State. (line 6) * gray level: Built-in Variables. (line 76) * gray level, example for polygons: Polygons. (line 6) * gray vs Grey spelling: List Of Gri Commands. (line 13) * graylevel for lines, example: Fancy. (line 6) * graylevel, command: Set Graylevel. (line 6) * graylevel, explanation: Pen Color. (line 6) * grayscale modification: Mathematics. (line 72) * grayscale of image, reading from file: Read Image Grayscale. (line 6) * grayscale, setting for images: Set Image Grayscale. (line 6) * greek Letters: Mathematical Text. (line 39) * grep system tool: Grep. (line 6) * grey vs Gray spelling: List Of Gri Commands. (line 13) * gri code, editing: Emacs Mode. (line 6) * gri commands, categories of: Overview Of Gri Commands. (line 6) * gri commands, complete list of: List Of Gri Commands. (line 13) * Gri newsgroup: Introduction. (line 79) * gri version: Introduction. (line 82) * gri-mode, command name abbreviation: Command abbreviations. (line 6) * gri-mode, Configuring gri-mode to where gri lives on your system: Step 2. (line 6) * gri-mode, editing gri syntax: Editing the syntax. (line 6) * gri-mode, editing in emacs: Emacs Mode. (line 6) * gri-mode, enter chunks of code with short-cuts: Gri code fragments. (line 6) * gri-mode, Extra user configuration of gri-mode: Step 4. (line 6) * gri-mode, gri code fragments: Gri code fragments. (line 6) * gri-mode, gri command names: Gri command names. (line 6) * gri-mode, handling argv and argc: Filename arguments when running gri. (line 6) * gri-mode, handling filename command arguments: Filename arguments when running gri. (line 6) * gri-mode, handling multiple Gri versions: Dealing with many Gri versions. (line 6) * gri-mode, how it names gri commands: Gri command names. (line 6) * gri-mode, imenu support: Other features. (line 6) * gri-mode, Info interface: Info interface. (line 6) * gri-mode, installing: Installing gri-mode.el. (line 6) * gri-mode, major commands: Major Gri-mode commands. (line 6) * gri-mode, Placing gri-mode.el where Emacs can find it.: Step 1. (line 6) * gri-mode, possible completions: Possible completions. (line 6) * gri-mode, screenshots: Gri-mode screenshots. (line 6) * gri-mode, sysnonym completion: Variable completion. (line 6) * gri-mode, Telling emacs to load gri-mode: Step 3. (line 6) * gri-mode, toolbar: Other features. (line 6) * gri-mode, user-defined commands: User commands. (line 6) * gri-mode, variable completion: Variable completion. (line 6) * gri.cmd, how it is located: Invoking Gri. (line 260) * gri_merge: gri_merge. (line 6) * gri_unpage: gri_unpage. (line 6) * grid data - accessing individual values and stats: Manipulation of Columns etc. (line 37) * grid data - minimum, maximum, mean: Manipulation of Columns etc. (line 37) * grid data mathematical operations: Mathematics. (line 39) * grid data, determining geometry from file: Pre-gridded Data. (line 21) * grid data, displaying: Show. (line 28) * grid data, smoothing: Smooth. (line 25) * grid data, write to file: Write Grid. (line 6) * grid data, writing to a file: Write Grid. (line 6) * grid mask, displaying: Show. (line 31) * grid, converting to image: Reading and Creating Image Data. (line 6) * grid, creating from image: Convert Image To Grid. (line 6) * grid, deleting: Delete. (line 6) * grid, flipping: Flip. (line 6) * grid, interpolating from one to another: Interpolate. (line 6) * grid, interpolating to given (x,y) value: Manipulation of Columns etc. (line 40) * grid, missing values: Set Grid Missing. (line 6) * grid, reading: Read Grid. (line 6) * gridding data, advice on methods: Ungridded Data. (line 6) * group command: Group. (line 6) * gzipped files, opening: Ascii Files. (line 30) * Handling errors with set error command: Set Error Action. (line 6) * handling multiple gri versions: Uncompiled Unix. (line 59) * hat, drawing hat on top of character: Mathematical Text. (line 91) * header lines, reading information from: Handling Headers. (line 40) * header lines, skipping: Handling Headers. (line 6) * heal command: Heal. (line 6) * help command: Help. (line 6) * help, online: Online Help. (line 6) * hexadecimal, converting to decimal: Unary Operators. (line 179) * hexadecimal, converting to from decimal: Unary Operators. (line 124) * hint, color palette range: Pen Color. (line 103) * hint, contour lines on image palette: Draw Image Palette. (line 38) * hint, first-time usage: Simple Example. (line 6) * hint, palette range: Draw Image Palette. (line 30) * hint, using query to interact with user: Hints. (line 77) * hints: Hints. (line 6) * histogram enhancement of image plots: Example Image. (line 34) * hms format: Opening Pipes. (line 64) * hour, minute, second data: Opening Pipes. (line 64) * how to compile gri: Uncompiled Unix. (line 9) * HP calculators, RPN notation different from: Binary Operators. (line 110) * if command: If. (line 6) * if statements <1>: If. (line 6) * if statements: If Statements. (line 6) * ignore command: Ignore. (line 6) * image colorscale, reading: Read Image Colorscale. (line 6) * image data, determining geometry from file: Pre-gridded Data. (line 21) * image data, write to file: Write Image. (line 11) * image data, writing to a file: Write Image. (line 6) * image formats, other than 8-bit: Plans. (line 6) * image grayscale, reading: Read Image Grayscale. (line 6) * image grayscale/colorscale modification: Mathematics. (line 72) * image mask data, write to file: Write Image. (line 21) * image mask, reading: Read Image Mask. (line 6) * image mathematical operations: Mathematics. (line 59) * image palette data, write to file: Write Image. (line 31) * image plot, with contours: Combination. (line 6) * image plots, general: Images. (line 6) * image plots, setting colorscale: Set Image Colorscale. (line 6) * image plots, setting grayscale: Set Image Grayscale. (line 6) * image, banded: Create Image Grayscale. (line 6) * image, creating from grid: Convert Grid To Image. (line 6) * image, data format: Reading and Creating Image Data. (line 6) * image, displaying histogram of: Show. (line 34) * image, drawing colorscale palette: Draw Image Palette. (line 11) * image, drawing palette: Draw Image Palette. (line 11) * image, flipping: Flip. (line 6) * image, histogra: Draw Image Histogram. (line 6) * image, interpolation from grid: Convert Grid To Image. (line 33) * image, masking: Mask. (line 6) * image, PostScript output: Image PostScript Output. (line 6) * images, filtering: Filter. (line 6) * images, histogram scaling: Example Image. (line 26) * images, linear scaling: Example Image. (line 26) * images, reading: Read Image. (line 6) * incompatibilities, keeping track of: Expecting. (line 6) * inf rpn operator: Binary Operators. (line 107) * inf rpn operator, finds smaller of pair: Binary Operators. (line 6) * initialization commands: Resource File. (line 6) * input command: Input. (line 6) * input data window: Set Input Data Window. (line 30) * insert command: Insert. (line 6) * installation, debian linux: Linux. (line 6) * installation, linux redhat/debian: Linux. (line 6) * installation, redhat linux: Linux. (line 6) * interaction with user, -y command-line option: Invoking Gri. (line 234) * interaction with user, query command <1>: Storing User Responses. (line 6) * interaction with user, query command <2>: Embedded Synonyms. (line 8) * interaction with user, query command <3>: Query. (line 6) * interaction with user, query command <4>: If Statements. (line 7) * interaction with user, query command: User Variables. (line 19) * interpolate command: Interpolate. (line 6) * interpolating grid to given (x,y) value: Manipulation of Columns etc. (line 40) * interpolation, from grid to image: Convert Grid To Image. (line 33) * ismissing rpn operator: Unary Operators. (line 191) * ISO latin 1 font encoding: Set Font Encoding. (line 6) * iso-latin-1 font encoding: Non-English Text. (line 6) * isopycnals <1>: TS Diagram. (line 6) * isopycnals: Draw Isopycnal. (line 6) * Ivo Alxneit (contributor): Acknowledgments. (line 9) * Jeff Whitaker (contributor): Acknowledgments. (line 15) * Jinyu Sheng (contributor): Acknowledgments. (line 14) * Karin Bryan (contributor): Acknowledgments. (line 9) * Kawamura Masao (contributor): Acknowledgments. (line 12) * Keith Thompson (contributor): Acknowledgments. (line 15) * keywords of Gri commands: Commands. (line 6) * kurtosis, calculating for column data: Manipulation of Columns etc. (line 22) * labels on contour lines, controlling orientation and white-under: Set Contour Labels. (line 6) * labels, drawing text anywhere: Draw Label Boxed. (line 6) * labels, example: Fancy. (line 6) * labels, for xy curves: Draw Label For Last Curve. (line 6) * labels, on axes <1>: If Statements. (line 45) * labels, on axes: Labels. (line 6) * labels, on contours: Set Contour Label Position. (line 6) * labels, on data curves: rpn Examples. (line 58) * landscape orientation of page: Set Page. (line 15) * larger of two numbers, rpn operator sup: Binary Operators. (line 6) * latex overline command, emulating: Mathematical Text. (line 95) * legend for symbol: Scattergraphs. (line 38) * legends: Legend. (line 6) * length of axes: Built-in Variables. (line 138) * length of axes, guide on choosing: Length. (line 6) * license: License. (line 6) * line cap: Set Line Cap. (line 6) * line join: Set Line Join. (line 6) * line width: Set Line Width. (line 6) * linear axes: Log And Linear. (line 6) * linear interpolation: Rpnfunction. (line 27) * linear regression: Regress. (line 6) * linear_intercept rpn operator: Rpnfunction. (line 27) * linear_slope rpn operator: Rpnfunction. (line 27) * linegraphs: Linegraphs. (line 7) * lines in data files, parsing: Read Line. (line 6) * lines, dashed: Set Dash. (line 6) * lines, gray, command: Set Graylevel. (line 6) * lines, gray, explanation: Pen Color. (line 6) * linux compilation: Msdos-install. (line 57) * LINUX compilation: Msdos-install. (line 57) * linux distributions: Linux. (line 6) * list command: List. (line 6) * little-endian vs big-endian data, caution: Binary Files. (line 3) * little-endian vs big-endian data, plans: Plans. (line 12) * ln rpn operator: Unary Operators. (line 198) * local built-in synonyms: Local Synonyms. (line 6) * local synonyms: Local Synonyms. (line 6) * log rpn operator: Unary Operators. (line 195) * logarithmic axes: Log And Linear. (line 6) * logarithms: Mathematics. (line 12) * logical negation, ! rpn operator: Unary Operators. (line 14) * logical negation, not rpn operator: Unary Operators. (line 17) * logical operators in rpn expressions: Binary Operators. (line 6) * logo, how to draw: Draw Gri Logo. (line 6) * loops: While. (line 6) * ls command: Ls. (line 6) * Luke Blaikie (contributor): Acknowledgments. (line 9) * macintosh unix compilation: Mac-install. (line 6) * makefiles, emulating action with the age rpn operator: Unary Operators. (line 30) * mapping page location units to user units: rpn Examples. (line 38) * maps, converting hour-minute-second to decimal hour: Opening Pipes. (line 64) * maps, format of x axis: Set X Type. (line 19) * maps, format of y axis: Set Y Type. (line 19) * maps, scales: Resize. (line 6) * maps, scaling: Length. (line 14) * margins: Built-in Variables. (line 134) * mask command: Mask. (line 6) * mask for image, reading: Read Image Mask. (line 6) * masking image: Mask. (line 6) * math on columns, rescaling after: Rescale. (line 6) * mathematical operators in rpn expressions: Binary Operators. (line 6) * mathematical Symbols: Mathematical Text. (line 39) * mathematics, on columns: Mathematics. (line 12) * mathematics, on grid data: Mathematics. (line 39) * mathematics, on image grayscale/colorscale: Mathematics. (line 72) * mathematics, on images: Mathematics. (line 59) * mathematics, on variables: Mathematics. (line 91) * mathematics, rpn notation, description: rpn Mathematics. (line 6) * mathematics, rpn notation, example <1>: Built-in Variables. (line 177) * mathematics, rpn notation, example: rpn Examples. (line 38) * mathematics, trigonometric operations: rpn Examples. (line 36) * maximum, column data: Manipulation of Columns etc. (line 22) * maximum, grid data: Manipulation of Columns etc. (line 37) * mean, calculating for column data: Manipulation of Columns etc. (line 22) * mesh plot for FEM: Finite Element Model Mesh. (line 6) * minimum, column data: Manipulation of Columns etc. (line 22) * minimum, grid data: Manipulation of Columns etc. (line 37) * missing value code: Missing Values. (line 6) * missing value, checking for in rpn expressions: Unary Operators. (line 6) * missing values: Set Missing Value. (line 6) * MSDOS compilation: Msdos-install. (line 13) * Multi-panel plots <1>: Set Panel. (line 6) * Multi-panel plots: Set Panels. (line 6) * multiple datasets in one file: Linegraphs. (line 39) * multiple gri versions: Uncompiled Unix. (line 59) * multiple panels: Simple Example Revisited. (line 30) * multiple panels, example: Fancy. (line 6) * name, of PostScript file: Set Postscript Filename. (line 6) * naming convention for synonyms: Naming Convention. (line 6) * NaN for missing value code: Missing Values. (line 6) * negation, ! rpn operator: Unary Operators. (line 14) * negation, not rpn operator: Unary Operators. (line 17) * netcdf data: NetCDF Files. (line 3) * netCDF files, opening: Open. (line 6) * netCDF files, reading attributes, units, etc: Read Synonym or Variable. (line 35) * netCDF files, reading columns: Read Columns. (line 46) * netCDF files, reading grid data: Read Grid. (line 17) * new command: New. (line 6) * new commands, complicated example: Complicated New Command. (line 6) * new commands, how they are parsed: Parsing. (line 6) * new commands, how to add to Gri: Adding New Commands. (line 6) * new commands, simple example: Simple New Command. (line 6) * new page command: Newpage. (line 6) * new postscript file command: New Postscript File. (line 6) * new, used on changeable arguments: Using New And Delete. (line 6) * newcommand arguments, how to alter: Changeable Command Arguments. (line 6) * newcommands, determining calling argument level with \&&: Determining Calling Information. (line 6) * newcommands, determining calling argument names with \&: Determining Calling Information. (line 6) * newline, in a show command: Show. (line 63) * newline, in a system command: Naming Convention. (line 58) * newline, using \<< in show: Show. (line 79) * newsgroup: Introduction. (line 79) * no_private, command-line flag: Invoking Gri. (line 194) * non-English language text: Non-English Text. (line 6) * not rpn operator: Unary Operators. (line 17) * numbers, stored in variables: Variables. (line 6) * numbers, using underscore to separate thousand parts: Version 2.8. (line 91) * oceanographic plots: TS Diagram. (line 6) * oceanographic plots isopycnals on TS diagram: Draw Isopycnal. (line 6) * oceanographic plots, iso-spice lines on TS diagrams: Draw Isospice. (line 6) * oceanographic plots, isopycnals on TS diagrams: TS Diagram. (line 6) * online help: Online Help. (line 6) * open command: Open. (line 6) * opening compressed files: Ascii Files. (line 30) * opening data files: Open. (line 6) * opening files through pipes: Using OS Inside Gri. (line 90) * opening gzipped: Ascii Files. (line 30) * operating system commands, assigned to synonyms <1>: Operating System. (line 6) * operating system commands, assigned to synonyms <2>: System. (line 6) * operating system commands, assigned to synonyms: Using Synonyms. (line 6) * operating system commands, printing results of <1>: System. (line 6) * operating system commands, printing results of: Operating System. (line 6) * operating system, environment variables: Get Env. (line 6) * operating system, example of using to construct filenames: Using Synonyms. (line 6) * operating system, filtering datafiles: Open. (line 6) * operating system, getenv: Get Env. (line 6) * optional words in commands, [] syntax: Invoking Gri. (line 40) * options on Gri command-line: Invoking Gri. (line 84) * or rpn operator: Binary Operators. (line 95) * orientation of page, landscape: Set Page. (line 15) * orientation of page, portrait: Set Page. (line 13) * OS, embedding system output into strings: Using OS Inside Gri. (line 40) * OS/2 unix compilation: OS2-install. (line 6) * overbar, drawing line on top of character: Mathematical Text. (line 95) * overhead projection images, suggested line widths: Set Line Width. (line 27) * overline, emulating latex command: Mathematical Text. (line 95) * overview of awk system tool: Awk. (line 6) * overview of grep system tool: Grep. (line 6) * overview of gri commands: Overview Of Gri Commands. (line 6) * overview of perl system tool: Perl. (line 6) * overview of sed system tool: Sed. (line 6) * page breaks: Newpage. (line 6) * page orientation, landscape: Set Page. (line 15) * page orientation, portrait: Set Page. (line 13) * page units: rpn Examples. (line 38) * page units, converting to user units: Binary Operators. (line 6) * paint regions with color: Draw Curve. (line 6) * palette for image colorscale, drawing: Draw Image Palette. (line 11) * parsing headers in data files: Read Line. (line 6) * parsing of the & syntax: Implementation of Ampersand Syntax. (line 6) * patches, drawing: Draw Patches. (line 6) * path, for command files: Set Path To. (line 6) * path, for data files: Set Path To. (line 6) * pathname of commandfile: Using OS Inside Gri. (line 17) * perl system tool: Perl. (line 6) * perl, use to create probability density function: PDF Diagram. (line 6) * Peter Galbraith (contributor): Acknowledgments. (line 11) * pi, in RPN expressions: Solitary Operators. (line 25) * Pierre Flament (contributor): Acknowledgments. (line 10) * pipes, opening files through them <1>: Opening Pipes. (line 6) * pipes, opening files through them: Using OS Inside Gri. (line 90) * plans for future versions: Plans. (line 6) * polygons, drawing: Draw Polygon. (line 6) * polygons, filled: Polygons. (line 6) * pop rpn operator: Unary Operators. (line 220) * pop rpn stack operator: Stack Operators. (line 6) * portrait orientation of page: Set Page. (line 13) * positioning axes: Position. (line 6) * postscript bounding box: Invoking Gri. (line 148) * postscript command: Postscript. (line 6) * PostScript file name, specifying: Invoking Gri. (line 167) * postscript file, write to: Postscript. (line 6) * postscript filename: Set Postscript Filename. (line 6) * postscript output, embedded images: Image PostScript Output. (line 6) * postscript-standard font encoding: Set Font Encoding. (line 6) * power rpn operator: Binary Operators. (line 110) * powers, of columns or variables: Mathematics. (line 12) * private, command-line flag: Invoking Gri. (line 190) * probability density function diagram: PDF Diagram. (line 6) * problems and how to cope with them: Debugging. (line 6) * process, causing Gri to sleep: Sleep. (line 6) * programming in Gri: Programming. (line 6) * programming, complete list of Gri commands: Commands. (line 6) * programming, if statements: If Statements. (line 6) * programming, parsing command lines: Local Synonyms. (line 6) * programming, synonyms: Synonyms. (line 6) * programming, using local built-in synonyms: Local Synonyms. (line 6) * programming, variables: Variables. (line 6) * projected images, suggested line widths: Set Line Width. (line 27) * protecting Gri programs against datafile movement: Using OS Inside Gri. (line 9) * protection against changes to Gri: Expecting. (line 6) * pstack rpn stack operator: Stack Operators. (line 6) * pttocm rpn operator: Unary Operators. (line 216) * publication quality plots, built-in variable ..publication..: Built-in Variables. (line 104) * publication quality, command-line flag: Invoking Gri. (line 202) * pwd command: Pwd. (line 6) * query command: Query. (line 6) * quit command: Quit. (line 6) * quiting Gri: Quit. (line 6) * quoting in system commands: System. (line 12) * rand RPN operator: Solitary Operators. (line 28) * random numbers, generating in RPN expressions: Solitary Operators. (line 28) * range of axes: Range. (line 6) * rapidograph scaling for line width: Set Line Width. (line 27) * read ... command: Read Synonym or Variable. (line 6) * read colornames command: Read Colornames. (line 6) * read columns command: Read Columns. (line 6) * read command: Read Colornames. (line 6) * read from command: Read From. (line 6) * read grid command: Read Grid. (line 6) * read image colorscale command: Read Image Colorscale. (line 6) * read image command: Read Image. (line 6) * read image grayscale command: Read Image Grayscale. (line 6) * read image greyscale command: Read Image Grayscale. (line 6) * read image mask command: Read Image Mask. (line 6) * read line command: Read Line. (line 6) * read line raw command: Read Line. (line 6) * reading attributes in NetCDF files: Read Synonym or Variable. (line 35) * reading columns of data: Linegraphs. (line 39) * reading data, checks: Built-in Variables. (line 53) * reading grid data: Read Grid. (line 6) * reading information from header lines: Handling Headers. (line 40) * reading synonyms <1>: Read Synonym or Variable. (line 6) * reading synonyms: Read Line. (line 6) * reading variables <1>: Read Synonym or Variable. (line 6) * reading variables: Read Line. (line 6) * recovering commands from a PostScript file: Invoking Gri. (line 282) * redhat: Linux. (line 6) * region painting: Draw Curve. (line 6) * regress command: Regress. (line 6) * regression, linear: Regress. (line 6) * remainder rpn operator: Binary Operators. (line 117) * removing files with unlink: Unlink. (line 6) * reorder command: Reorder. (line 6) * reordering Columns: Reorder. (line 6) * rescale command: Rescale. (line 6) * rescaling axes: Rescale. (line 6) * resize x command: Resize. (line 6) * resource files: Resource File. (line 6) * restoring graphics state: State. (line 6) * return command: Return. (line 6) * return value, \.return_value.: Important Builtin Synonyms. (line 6) * rewind command: Rewind. (line 6) * RGB values of known colors: Show. (line 17) * Richard Andrew Miles Outerbridge (contributor): Acknowledgments. (line 14) * roll_left rpn stack operator: Stack Operators. (line 6) * roll_right rpn stack operator: Stack Operators. (line 6) * Roman Neuhauser (contributor): Acknowledgments. (line 13) * RPM version of installation package: Linux. (line 6) * rpn functions: Rpnfunction. (line 6) * rpn mathematics, examples: rpn Mathematics. (line 6) * RPN notation, difference from old-series HP calculators: Binary Operators. (line 110) * rpn operator !: Unary Operators. (line 14) * rpn operator &: Binary Operators. (line 82) * rpn operator *: Binary Operators. (line 23) * rpn operator +: Binary Operators. (line 17) * rpn operator -: Binary Operators. (line 20) * rpn operator /: Binary Operators. (line 26) * rpn operator <: Binary Operators. (line 29) * rpn operator <=: Binary Operators. (line 36) * rpn operator =: Binary Operators. (line 49) * rpn operator ==: Binary Operators. (line 45) * rpn operator >: Binary Operators. (line 39) * rpn operator >=: Binary Operators. (line 42) * rpn operator abs: Unary Operators. (line 20) * rpn operator acos: Unary Operators. (line 23) * rpn operator acosh: Unary Operators. (line 26) * rpn operator age: Unary Operators. (line 30) * rpn operator and: Binary Operators. (line 85) * rpn operator area: Manipulation of Columns etc. (line 30) * rpn operator argc, yielding number of commandline arguments: Solitary Operators. (line 6) * rpn operator ascent: Unary Operators. (line 103) * rpn operator asin: Unary Operators. (line 58) * rpn operator atan: Unary Operators. (line 64) * rpn operator atof: Unary Operators. (line 107) * rpn operator ceil: Unary Operators. (line 110) * rpn operator cmtopt: Unary Operators. (line 120) * rpn operator cos: Unary Operators. (line 114) * rpn operator cosh: Unary Operators. (line 117) * rpn operator descent: Unary Operators. (line 150) * rpn operator directory_exists: Unary Operators. (line 155) * rpn operator dup: Unary Operators. (line 159) * rpn operator exch: Binary Operators. (line 98) * rpn operator exp: Unary Operators. (line 163) * rpn operator exp10: Unary Operators. (line 167) * rpn operator file_exists: Unary Operators. (line 171) * rpn operator floor: Unary Operators. (line 175) * rpn operator inf: Binary Operators. (line 107) * rpn operator inf, finds smaller of pair: Binary Operators. (line 6) * rpn operator interpolate: Manipulation of Columns etc. (line 40) * rpn operator ismissing: Unary Operators. (line 191) * rpn operator linear_intercept: Rpnfunction. (line 27) * rpn operator linear_slope: Rpnfunction. (line 27) * rpn operator ln: Unary Operators. (line 198) * rpn operator log: Unary Operators. (line 195) * rpn operator not: Unary Operators. (line 17) * rpn operator or: Binary Operators. (line 95) * rpn operator pop: Unary Operators. (line 220) * rpn operator power: Binary Operators. (line 110) * rpn operator pttocm: Unary Operators. (line 216) * RPN operator rand: Solitary Operators. (line 28) * rpn operator remainder: Binary Operators. (line 117) * rpn operator sed: Binary Operators. (line 124) * rpn operator sin: Unary Operators. (line 229) * rpn operator sinh: Unary Operators. (line 232) * rpn operator sqrt: Unary Operators. (line 225) * rpn operator strcat: Binary Operators. (line 132) * rpn operator strlen: Unary Operators. (line 235) * RPN operator substr: Tertiary Operators. (line 7) * rpn operator sup: Binary Operators. (line 135) * rpn operator sup, finds larger of pair: Binary Operators. (line 6) * rpn operator system: Unary Operators. (line 239) * rpn operator tan: Unary Operators. (line 243) * rpn operator tanh: Unary Operators. (line 246) * rpn operator width: Unary Operators. (line 249) * RPN operator wordc: Solitary Operators. (line 33) * RPN operator wordv: Unary Operators. (line 253) * rpn operator xcmtouser: Unary Operators. (line 280) * rpn operator xusertocm: Unary Operators. (line 275) * rpn operator ycmtouser: Unary Operators. (line 290) * rpn operator yusertocm: Unary Operators. (line 285) * rpn operator |: Binary Operators. (line 92) * rpn stack operator dup: Stack Operators. (line 6) * rpn stack operator exch: Stack Operators. (line 6) * rpn stack operator pop: Stack Operators. (line 6) * rpn stack operator pstack: Stack Operators. (line 6) * rpn stack operator roll_left: Stack Operators. (line 6) * rpn stack operator roll_right: Stack Operators. (line 6) * rpn, conversion of string to number: Unary Operators. (line 6) * rpn, system calls: Unary Operators. (line 6) * rpnfunction command: Rpnfunction. (line 6) * running a commandfile: Source. (line 6) * Running-Mean Skyline Diagram: Running Means. (line 6) * Sara Bennett (contributor): Acknowledgments. (line 9) * satellite images: Example Image. (line 6) * save results in a file: Write. (line 6) * saving graphics state: State. (line 6) * scalar operations: Mathematics. (line 91) * scales: Simple Example Revisited. (line 6) * scales, accessing: rpn Examples. (line 38) * scales, deleting: Delete. (line 6) * scaling for maps: Length. (line 14) * scattergraphs: Scattergraphs. (line 6) * scientific journals with Gri graphs: Gri in the Press. (line 6) * screen snapshots, using Gri: Gri-mode screenshots. (line 6) * sed rpn operator: Binary Operators. (line 124) * sed system tool: Sed. (line 6) * segmentation fault, what to do: Reporting Bugs. (line 25) * set arrow size command: Set Arrow Size. (line 6) * set arrow type command: Set Arrow Type. (line 6) * set axes style command: Set Axes Style. (line 6) * set beep command: Set Beep. (line 6) * set bounding box command: Set Bounding Box. (line 6) * set clip command: Set Clip. (line 6) * set color command: Set Color. (line 6) * set color name command: Set Colorname. (line 6) * set colour command: Set Color. (line 6) * set command: Set. (line 6) * set contour format command: Set Contour Format. (line 6) * set contour label for command: Set Contour Label For. (line 6) * set contour label position command: Set Contour Label Position. (line 6) * set contour labels command: Set Contour Labels. (line 6) * set dash command: Set Dash. (line 6) * set environment command: Set Environment. (line 6) * set error command: Set Error Action. (line 6) * set flag command: Set Flag. (line 6) * set font color command: Set Font Color. (line 6) * set font colour command: Set Font Color. (line 6) * set font encoding command: Set Font Encoding. (line 6) * set font size command: Set Font Size. (line 6) * set font to command: Set Font To. (line 6) * set graylevel command: Set Graylevel. (line 6) * set greylevel command: Set Graylevel. (line 6) * set grid missing command: Set Grid Missing. (line 6) * set ignore error eof command: Set Ignore Error Eof. (line 6) * set ignore initial newline command: Set Ignore Initial Newline. (line 6) * set image colorscale command: Set Image Colorscale. (line 6) * set image colourscale command: Set Image Colorscale. (line 6) * set image grayscale command: Set Image Grayscale. (line 6) * set image grayscale using histogram command: Set Image Grayscale. (line 6) * set image greyscale command: Set Image Grayscale. (line 6) * set image greyscale using histogram command: Set Image Grayscale. (line 6) * set image missing value color command: Set Image Missing Value Color. (line 6) * set image missing value colour command: Set Image Missing Value Color. (line 6) * set image range command: Set Image Range. (line 6) * set input data separator command: Set Input Data Separator. (line 6) * set input data window command: Set Input Data Window. (line 6) * set line cap command: Set Line Cap. (line 6) * set line join command: Set Line Join. (line 6) * set line width command: Set Line Width. (line 6) * set missing value command: Set Missing Value. (line 6) * set page command: Set Page. (line 6) * set page size command: Set Page Size. (line 6) * set panel command: Set Panel. (line 6) * set panels command: Set Panels. (line 6) * set path command: Set Path To. (line 6) * set postscript filename command: Set Postscript Filename. (line 6) * set symbol size command: Set Symbol Size. (line 6) * set tic size command: Set Tic Size. (line 6) * set trace command: Set Trace. (line 6) * set transparency command: Set Transparency. (line 6) * set u scale command: Set U Scale. (line 6) * set v scale command: Set V Scale. (line 6) * set x axis command: Set X Axis. (line 6) * set x format command: Set X Format. (line 6) * set x grid command: Set X Grid. (line 6) * set x margin command: Set X Margin. (line 6) * set x name command: Set X Name. (line 6) * set x size command: Set X Size. (line 6) * set x type command: Set X Type. (line 6) * set y axis command: Set Y Axis. (line 6) * set y format command: Set Y Format. (line 6) * set y grid command: Set Y Grid. (line 6) * set y margin command: Set Y Margin. (line 6) * set y name command: Set Y Name. (line 6) * set y size command: Set Y Size. (line 6) * set y type command: Set Y Type. (line 6) * set z missing command: Set Z Missing. (line 6) * setting line cap type: Set Line Cap. (line 6) * setting line join type: Set Line Join. (line 6) * setting line width: Set Line Width. (line 6) * setting symbol size: Set Symbol Size. (line 6) * show command: Show. (line 6) * show command, \>> for horizontal tab: Show. (line 79) * show command, how to get a newline: Show. (line 63) * show command, how to get a tab: Show. (line 63) * show command, using \<< for newline: Show. (line 79) * show stopwatch command: Show. (line 48) * sin rpn operator: Unary Operators. (line 229) * sinh rpn operator: Unary Operators. (line 232) * skewness, calculating for column data: Manipulation of Columns etc. (line 22) * skip command: Skip. (line 6) * skipping header lines: Handling Headers. (line 6) * sleep command: Sleep. (line 6) * sleep, causing Gri to: Sleep. (line 6) * slides, suggested line widths: Set Line Width. (line 27) * smaller of two numbers, rpn operator inf: Binary Operators. (line 6) * smooth command: Smooth. (line 6) * smooth grid data command: Smooth. (line 25) * smoothing column data <1>: Filter. (line 6) * smoothing column data: Smooth. (line 6) * smoothing grid data: Smooth. (line 25) * snapshots of computer screen, using Gri: Gri-mode screenshots. (line 6) * source command, for running another command file: Source. (line 6) * space in text: Mathematical Text. (line 68) * specifying the PostScript file name: Invoking Gri. (line 167) * specifying the SVG file name: Invoking Gri. (line 173) * spelling of gri commands: List Of Gri Commands. (line 13) * spice lines, on TS diagram: Draw Isospice. (line 6) * spline, fitting to (x,y) data: Convert Columns To Spline. (line 6) * spreadsheet data: Opening Pipes. (line 36) * sprintf command: Sprintf. (line 6) * sqrt rpn operator: Unary Operators. (line 225) * standard deviation, calculating for column data: Manipulation of Columns etc. (line 22) * standard deviation, column data: Manipulation of Columns etc. (line 9) * startup commands: Resource File. (line 6) * startup message: Invoking Gri. (line 188) * statistics of column data: Show. (line 24) * statistics, column data: Manipulation of Columns etc. (line 22) * statistics, performing regression: Regress. (line 6) * Steve Cayford (contributor): Acknowledgments. (line 10) * Steve Matheson (contributor): Acknowledgments. (line 13) * stopping Gri: Quit. (line 6) * stopwatch, for timing things: Show. (line 48) * strcat rpn operator: Binary Operators. (line 132) * string, conversion to number in rpn expressions: Unary Operators. (line 6) * strings, embedding OS output into: Using OS Inside Gri. (line 40) * strings, storing variable values within: Sprintf. (line 6) * strlen rpn operator: Unary Operators. (line 235) * subscripts: Mathematical Text. (line 9) * substr RPN operator: Tertiary Operators. (line 7) * substrings, getting with RPN operator substr: Tertiary Operators. (line 7) * suite of test files: Test Suite. (line 6) * sup rpn operator: Binary Operators. (line 135) * sup rpn operator, finds larger of pair: Binary Operators. (line 6) * superscripts: Mathematical Text. (line 24) * superscripts and subscripts - how to align using \!: Mathematical Text. (line 68) * superuser command: Superuser. (line 6) * superuser flags: Superuser. (line 6) * SVG file name, specifying: Invoking Gri. (line 173) * symbol legend: Scattergraphs. (line 38) * symbol size, stored in ..symbolsize..: Built-in Variables. (line 117) * symbols: Scattergraphs. (line 25) * symbols in color: Scattergraphs. (line 67) * symbols, drawing single ones: Draw Symbol At. (line 6) * symbols, setting size: Set Symbol Size. (line 6) * synonym, and the & syntax: Changeable Command Arguments. (line 6) * synonyms, aliasing with the \@alias notation: Alias Synonyms. (line 6) * synonyms, assigning values to: Using Synonyms. (line 6) * synonyms, assigning within RPN expressions: Binary Operators. (line 49) * synonyms, built-in, list of: Important Builtin Synonyms. (line 6) * synonyms, checking for existence of: Unary Operators. (line 136) * synonyms, constructing using the operating system: Using Synonyms. (line 6) * synonyms, deleting: Delete. (line 6) * synonyms, displaying list of: Show. (line 45) * synonyms, embedding in quoted text strings: Embedded Synonyms. (line 6) * synonyms, extracting individual words from: Using Synonyms. (line 6) * synonyms, for storing character strings: Synonyms. (line 6) * synonyms, for storing output from system commands: Using Synonyms. (line 6) * synonyms, global: Important Builtin Synonyms. (line 6) * synonyms, local: Local Synonyms. (line 6) * synonyms, making local versions: New. (line 6) * synonyms, multiple copies of: New. (line 6) * synonyms, naming convention <1>: Naming Convention. (line 6) * synonyms, naming convention: Synonyms. (line 6) * synonyms, reading <1>: Read Line. (line 6) * synonyms, reading: Read Synonym or Variable. (line 6) * synonyms, storing variable values within: Sprintf. (line 6) * syntax of Gri commands: Commands. (line 6) * system calls in rpn expressions: Unary Operators. (line 6) * system calls, using dollar-parenthesis shell syntax: Using OS Inside Gri. (line 9) * system command: System. (line 6) * system command, how to get a newline: Naming Convention. (line 58) * system command, how to get a tab: Naming Convention. (line 58) * system commands acting as datafiles: Open. (line 6) * system commands, assigned to synonyms <1>: Operating System. (line 6) * system commands, assigned to synonyms <2>: System. (line 6) * system commands, assigned to synonyms: Using Synonyms. (line 6) * system commands, example of using to construct filenames: Using Synonyms. (line 6) * system commands, printing results of <1>: Operating System. (line 6) * system commands, printing results of: System. (line 6) * system rpn operator: Unary Operators. (line 239) * T-S diagram, drawing isopycnals on: Draw Isopycnal. (line 6) * T-S diagram, drawing spice lines on: Draw Isospice. (line 6) * T-S diagram, example of drawing: TS Diagram. (line 6) * tab, in a show command: Show. (line 63) * tab, in a system command: Naming Convention. (line 58) * tab, using \>> in show: Show. (line 79) * tan rpn operator: Unary Operators. (line 243) * tanh rpn operator: Unary Operators. (line 246) * temperature-salinity diagram: TS Diagram. (line 6) * temperature-salinity diagram, drawing isopycnals on: Draw Isopycnal. (line 6) * temperature-salinity diagram, drawing spice lines on: Draw Isospice. (line 6) * temporary file allocation: Using OS Inside Gri. (line 108) * test suite <1>: Uncompiled Unix. (line 142) * test suite: Test Suite. (line 6) * testing for end of file: Set Ignore Error Eof. (line 6) * testing for existence of a synonym: Unary Operators. (line 136) * testing for existence of a variable: Unary Operators. (line 141) * testing for existence of an aliased synonym: Unary Operators. (line 145) * testing for file eof: Set Ignore Error Eof. (line 6) * text strings, drawing: Draw Label Boxed. (line 6) * text strings, embedding synonyms within: Embedded Synonyms. (line 6) * text, color used for: Set Font Color. (line 6) * text, encoding vector of: Set Font Encoding. (line 6) * text, Greek letters: Mathematical Text. (line 39) * text, inserting forward/backward space: Mathematical Text. (line 68) * text, ISO characters: Non-English Text. (line 6) * text, mathematical symbols: Mathematical Text. (line 39) * text, subscripts: Mathematical Text. (line 9) * text, superscripts: Mathematical Text. (line 24) * text, thin-spaces within: Adjustment Of Character Position. (line 6) * the &.variable. notation: Changeable Command Arguments. (line 6) * the &\synonym notation: Changeable Command Arguments. (line 6) * thin-space in text: Adjustment Of Character Position. (line 6) * Thomas Larsen (contributor): Acknowledgments. (line 12) * thousand parts, indicating in numbers using underscore: Version 2.8. (line 91) * tic size, setting: Set Tic Size. (line 6) * Tim Powers (contributor): Acknowledgments. (line 14) * time: Important Builtin Synonyms. (line 32) * timing things: Show. (line 48) * titles, drawing above plot: Linegraphs. (line 58) * tmpname: Using OS Inside Gri. (line 108) * Toru Suzuki (contributor): Acknowledgments. (line 14) * traceback: Show. (line 53) * tracing execution, command-line option: Invoking Gri. (line 224) * tracing execution, using ..trace..: Debugging. (line 12) * transforming page location units to user units: rpn Examples. (line 38) * trigonometric operations in rpn math: rpn Examples. (line 36) * types of gri commands: Overview Of Gri Commands. (line 6) * underscore, in numbers: Version 2.8. (line 91) * unix environment variables: Get Env. (line 6) * unix, dollar-parenthesis notation within Gri commands: Using OS Inside Gri. (line 9) * unlink command: Unlink. (line 6) * unlink, to remove files: Unlink. (line 6) * URL, how to open: Opening URLs. (line 6) * user input to Gri: Acknowledgments. (line 6) * user interaction, query command: Query. (line 6) * user units: rpn Examples. (line 38) * user units, converting to page units: Binary Operators. (line 6) * user-defined synonyms: Using Synonyms. (line 6) * user-defined variables: User Variables. (line 6) * using environment variables for directory names: Using OS Inside Gri. (line 40) * variables: Variables. (line 6) * variables, and the & syntax: Changeable Command Arguments. (line 6) * variables, assigning within RPN expressions: Binary Operators. (line 49) * variables, built-in: Built-in Variables. (line 6) * variables, checking for existence of: Unary Operators. (line 141) * variables, defined by user: User Variables. (line 6) * variables, deleting: Delete. (line 6) * variables, displaying list of: Show. (line 56) * variables, making local versions: New. (line 6) * variables, multiple copies of: New. (line 6) * variables, reading <1>: Read Synonym or Variable. (line 6) * variables, reading: Read Line. (line 6) * variables, storing values within synonyms (strings): Sprintf. (line 6) * vector field, how to read: Read Columns. (line 62) * version 2.10: Version 2.10. (line 6) * version 2.12: Version 2.12. (line 6) * version numbers: Introduction. (line 82) * versions, handling multiple: Uncompiled Unix. (line 59) * while command: While. (line 6) * width rpn operator: Unary Operators. (line 249) * Window-pane plots <1>: Set Panels. (line 6) * Window-pane plots: Set Panel. (line 6) * Wolfgang Voegeli (contributor and bug fixer): Acknowledgments. (line 15) * wordc RPN operator: Solitary Operators. (line 33) * wordv RPN operator: Unary Operators. (line 253) * working directory, stored in synonym \.wd.: Important Builtin Synonyms. (line 6) * write command: Write. (line 6) * write PostScript commands directly to output file: Postscript. (line 6) * writing to a file, column data: Write Columns. (line 6) * writing to a file, contour data: Write Contour. (line 6) * writing to a file, grid data: Write Grid. (line 6) * writing to a file, image data: Write Image. (line 6) * x-y graphs <1>: Draw Curve. (line 6) * x-y graphs: Linegraphs. (line 7) * X11 colors, reading: Read Colornames. (line 6) * xcmtouser rpn operator: Unary Operators. (line 280) * xusertocm rpn operator: Unary Operators. (line 275) * ycmtouser rpn operator: Unary Operators. (line 290) * yusertocm rpn operator: Unary Operators. (line 285) * | rpn operator: Binary Operators. (line 92) * ~/.grirc initialization file: Resource File. (line 6)  File: gri.info, Node: Index of Commands, Next: Index of Builtins, Prev: Concept Index, Up: Top Index of Commands ***************** [index] * Menu: * assert: Assert. (line 6) * cd: Cd. (line 6) * close: Close. (line 6) * convert columns to grid: Convert Columns To Grid. (line 6) * convert columns to spline: Convert Columns To Spline. (line 6) * convert grid to columns: Convert Grid To Columns. (line 6) * convert grid to image: Convert Grid To Image. (line 6) * convert image to grid: Convert Image To Grid. (line 6) * create: Create Columns From Function. (line 6) * create image grayscale: Create Image Grayscale. (line 6) * debug: Debug. (line 6) * delete: Delete. (line 6) * differentiate: Differentiate. (line 6) * draw: Draw. (line 6) * draw arc: Draw Arc. (line 6) * draw arrows: Draw Arrows. (line 6) * draw axes: Draw Axes. (line 3) * draw axes if needed: Draw Axes If Needed. (line 3) * draw border box: Draw Border Box. (line 3) * draw box: Draw Box. (line 6) * draw circle: Draw Circle. (line 6) * draw contour: Draw Contour. (line 6) * draw curve: Draw Curve. (line 6) * draw essay: Draw Essay. (line 6) * draw gri logo: Draw Gri Logo. (line 6) * draw grid: Draw Grid. (line 6) * draw image: Draw Image. (line 6) * draw image histogram: Draw Image Histogram. (line 6) * draw image palette: Draw Image Palette. (line 6) * draw isopycnal: Draw Isopycnal. (line 6) * draw isospice: Draw Isospice. (line 6) * draw label: Draw Label. (line 6) * draw label boxed: Draw Label Boxed. (line 6) * draw label for last curve: Draw Label For Last Curve. (line 6) * draw label whiteunder: Draw Label Whiteunder. (line 6) * draw line: Draw Line From. (line 6) * draw line legend: Draw Line Legend. (line 6) * draw lines: Draw Lines. (line 6) * draw patches: Draw Patches. (line 6) * draw polygon: Draw Polygon. (line 6) * draw regression line: Draw Regression Line. (line 6) * draw symbol: Draw Symbol. (line 6) * draw symbol at: Draw Symbol At. (line 6) * draw symbol legend: Draw Symbol Legend. (line 6) * draw times stamp: Draw Time Stamp. (line 6) * draw title: Draw Title. (line 6) * draw values: Draw Values. (line 6) * draw x axis: Draw X Axis. (line 6) * draw x box plot: Draw X Box Plot. (line 6) * draw y axis: Draw Y Axis. (line 6) * draw y box plot: Draw Y Box Plot. (line 6) * draw zero line: Draw Zero Line. (line 6) * end group: End Group. (line 6) * expecting: Expecting. (line 6) * filter: Filter. (line 6) * flip: Flip. (line 6) * get env: Get Env. (line 6) * group: Group. (line 6) * heal: Heal. (line 6) * help: Help. (line 6) * if: If. (line 6) * ignore: Ignore. (line 6) * input: Input. (line 6) * insert: Insert. (line 6) * interpolate: Interpolate. (line 6) * list: List. (line 6) * ls: Ls. (line 6) * mask: Mask. (line 6) * new: New. (line 6) * new page: Newpage. (line 6) * new postscript file: New Postscript File. (line 6) * open: Open. (line 6) * postscript: Postscript. (line 6) * pwd: Pwd. (line 6) * query: Query. (line 6) * quit: Quit. (line 6) * read: Read Synonym or Variable. (line 6) * read colornames: Read Colornames. (line 6) * read columns: Read Columns. (line 6) * read from: Read From. (line 6) * read grid: Read Grid. (line 6) * read image: Read Image. (line 6) * read image colorscale: Read Image Colorscale. (line 6) * read image grayscale: Read Image Grayscale. (line 6) * read image mask: Read Image Mask. (line 6) * read line: Read Line. (line 6) * regress: Regress. (line 6) * reorder: Reorder. (line 6) * rescale: Rescale. (line 6) * resize x: Resize. (line 6) * return: Return. (line 6) * rewind: Rewind. (line 6) * rpnfunction: Rpnfunction. (line 6) * set: Set. (line 6) * set arrow size: Set Arrow Size. (line 6) * set arrow type: Set Arrow Type. (line 6) * set axes style: Set Axes Style. (line 6) * set beep: Set Beep. (line 6) * set bounding box: Set Bounding Box. (line 6) * set clip: Set Clip. (line 6) * set color: Set Color. (line 6) * set colorname: Set Colorname. (line 6) * set colour: Set Color. (line 6) * set contour format: Set Contour Format. (line 6) * set contour label for: Set Contour Label For. (line 6) * set contour label position: Set Contour Label Position. (line 6) * set contour labels: Set Contour Labels. (line 6) * set dash: Set Dash. (line 6) * set environment: Set Environment. (line 6) * set error: Set Error Action. (line 6) * set flag: Set Flag. (line 6) * set font color: Set Font Color. (line 6) * set font colour: Set Font Color. (line 6) * set font encoding: Set Font Encoding. (line 6) * set font size: Set Font Size. (line 6) * set font to: Set Font To. (line 6) * set graylevel: Set Graylevel. (line 6) * set greylevel: Set Graylevel. (line 6) * set grid missing: Set Grid Missing. (line 6) * set ignore error eof: Set Ignore Error Eof. (line 6) * set ignore initial newline: Set Ignore Initial Newline. (line 6) * set image colorscale: Set Image Colorscale. (line 6) * set image colourscale: Set Image Colorscale. (line 6) * set image grayscale: Set Image Grayscale. (line 6) * set image grayscale using histogram: Set Image Grayscale. (line 6) * set image greyscale: Set Image Grayscale. (line 6) * set image greyscale using histogram: Set Image Grayscale. (line 6) * set image missing value color: Set Image Missing Value Color. (line 6) * set image missing value colour: Set Image Missing Value Color. (line 6) * set image range: Set Image Range. (line 6) * set input data separator: Set Input Data Separator. (line 6) * set input data window: Set Input Data Window. (line 6) * set line cap: Set Line Cap. (line 6) * set line join: Set Line Join. (line 6) * set line width: Set Line Width. (line 6) * set missing value: Set Missing Value. (line 6) * set page <1>: Set Page. (line 6) * set page: Set Page Size. (line 6) * set panel: Set Panel. (line 6) * set panels: Set Panels. (line 6) * set path: Set Path To. (line 6) * set postscript filename: Set Postscript Filename. (line 6) * set symbol size: Set Symbol Size. (line 6) * set tic size: Set Tic Size. (line 6) * set trace: Set Trace. (line 6) * set transparency: Set Transparency. (line 6) * set u scale: Set U Scale. (line 6) * set v scale: Set V Scale. (line 6) * set x axis: Set X Axis. (line 6) * set x format: Set X Format. (line 6) * set x grid: Set X Grid. (line 6) * set x margin: Set X Margin. (line 6) * set x name: Set X Name. (line 6) * set x size: Set X Size. (line 6) * set x type: Set X Type. (line 6) * set y axis: Set Y Axis. (line 6) * set y format: Set Y Format. (line 6) * set y grid: Set Y Grid. (line 6) * set y margin: Set Y Margin. (line 6) * set y name: Set Y Name. (line 6) * set y size: Set Y Size. (line 6) * set y type: Set Y Type. (line 6) * set z missing: Set Z Missing. (line 6) * show: Show. (line 6) * skip: Skip. (line 6) * smooth: Smooth. (line 6) * smooth grid data: Smooth. (line 25) * source: Source. (line 6) * sprintf: Sprintf. (line 6) * state command: State. (line 6) * superuser: Superuser. (line 6) * system: System. (line 6) * unlink: Unlink. (line 6) * while: While. (line 6) * write: Write. (line 6)  File: gri.info, Node: Index of Builtins, Prev: Index of Commands, Up: Top Index of Built-in Variables and Synonyms **************************************** [index] * Menu: * ..arrowsize.., size of arrows: Built-in Variables. (line 29) * ..batch.., flag used for batch mode: Built-in Variables. (line 34) * ..blue..: Built-in Variables. (line 112) * ..debug.., flag used for debugging: Built-in Variables. (line 36) * ..debug.., for debugging (by normal users): Invoking Gri. (line 132) * ..eof.., flag indicating end-of-file: Built-in Variables. (line 50) * ..exit_status.., exit status from system call: Built-in Variables. (line 150) * ..fontsize.., size of letters: Built-in Variables. (line 70) * ..graylevel.., graylevel (0=black): Built-in Variables. (line 76) * ..image_height.., height of image: Built-in Variables. (line 79) * ..image_width.., width of image: Built-in Variables. (line 81) * ..length_blank.., length/cm of blanks <1>: Built-in Variables. (line 85) * ..length_blank.., length/cm of blanks: Set Dash. (line 6) * ..length_dash.., length/cm of dashes <1>: Built-in Variables. (line 83) * ..length_dash.., length/cm of dashes: Set Dash. (line 6) * ..linewidth.., width of lines: Built-in Variables. (line 87) * ..linewidthaxis.., width of lines on axis: Built-in Variables. (line 90) * ..linewidthsymbol.., width of lines in symbols: Built-in Variables. (line 93) * ..missingvalue.., missing value code: Built-in Variables. (line 96) * ..missingvalue.., value for missing data: Missing Values. (line 6) * ..num_col_data.., number column data <1>: Manipulation of Columns etc. (line 9) * ..num_col_data.., number column data: Built-in Variables. (line 99) * ..publication.., flag for final copy of plot: Built-in Variables. (line 104) * ..superuser.., for debugging (by developers): Invoking Gri. (line 211) * ..superuser.., was -superuser flag set?: Built-in Variables. (line 119) * ..symbolsize.., size of symbols: Built-in Variables. (line 117) * ..tic_direction.., direction of axis tics: Built-in Variables. (line 122) * ..tic_size.., size/cm of axis tics: Built-in Variables. (line 125) * ..trace.., for tracing program execution: Built-in Variables. (line 127) * ..use_default_for_query.., simulate -yes commandline flag: Invoking Gri. (line 234) * ..words_in_dataline..: Built-in Variables. (line 53) * ..xinc.., x increment on axes <1>: Built-in Variables. (line 130) * ..xinc.., x increment on axes: Axis Scaling. (line 6) * ..xlast.., last drawn x value: Axis Scaling. (line 6) * ..xleft.., x value at left of plot <1>: Axis Scaling. (line 6) * ..xleft.., x value at left of plot: Built-in Variables. (line 132) * ..xmargin.., left margin <1>: Axis Scaling. (line 6) * ..xmargin.., left margin: Built-in Variables. (line 134) * ..xright.., x value at right of plot <1>: Built-in Variables. (line 136) * ..xright.., x value at right of plot: Axis Scaling. (line 6) * ..xsize.., x-axis length <1>: Axis Scaling. (line 6) * ..xsize.., x-axis length: Built-in Variables. (line 138) * ..ybottom.., y value at bottom of plot <1>: Built-in Variables. (line 140) * ..ybottom.., y value at bottom of plot: Axis Scaling. (line 6) * ..yinc.., y increment on axes <1>: Axis Scaling. (line 6) * ..yinc.., y increment on axes: Built-in Variables. (line 142) * ..ylast.., last drawn y value: Axis Scaling. (line 6) * ..ymargin.., bottom margin <1>: Axis Scaling. (line 6) * ..ymargin.., bottom margin: Built-in Variables. (line 144) * ..ysize.., y-axis length <1>: Built-in Variables. (line 146) * ..ysize.., y-axis length: Axis Scaling. (line 6) * ..ytop.., y value at top of plot <1>: Built-in Variables. (line 148) * ..ytop.., y value at top of plot: Axis Scaling. (line 6) * \.command_file., command-file name: Important Builtin Synonyms. (line 6) * \.home., home directory: Important Builtin Synonyms. (line 6) * \.missingvalue., command-file name: Important Builtin Synonyms. (line 6) * \.pid., process ID of job: Important Builtin Synonyms. (line 6) * \.proper_usage.: Local Synonyms. (line 6) * \.ps_file., PostScript file name: Important Builtin Synonyms. (line 6) * \.readfrom_file., data file name: Important Builtin Synonyms. (line 6) * \.return_value., Return value: Important Builtin Synonyms. (line 6) * \.system., operating system name: Important Builtin Synonyms. (line 6) * \.time., time and date: Important Builtin Synonyms. (line 6) * \.user., user's login name: Important Builtin Synonyms. (line 6) * \.version., version of Gri: Important Builtin Synonyms. (line 6) * \.wd., working directory: Important Builtin Synonyms. (line 6) * \.word0.: Local Synonyms. (line 6) * \.word1.: Local Synonyms. (line 6) * \.words.: Local Synonyms. (line 6) gri-2.12.23/doc/gri.texi000644 000767 000024 00002431520 11605066311 015323 0ustar00kelleystaff000000 000000 \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.23 @set GRI-PREVIOUS-VERSION 2.12.22 @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 2011 @author Dan E. Kelley @page @vskip 0pt plus 1filll Copyright @copyright{} 1991-2011 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 2008 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 range must have previously have been set by @code{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. @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 .0value. .255value. @end example @noindent 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, @code{set image grayscale}, @code{set image colorscale}, @code{draw image grayscale}, etc, all use @strong{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 the 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 @strong{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 is 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. Since many users will prefer the Emacs editor, a few words about that are in order. For complete information about entering iso-latin-1 characters in Emacs, consult your Emacs manual in the section @ifinfo @ref{(emacs)Single-Byte Character Support} @end ifinfo @ifhtml @code{(emacs)Single-Byte Character Support} @end ifhtml which describes the available methods suitable for the Emacs version you are using. A few examples are nevertheless provided below. Consider the task of inserting French text, with the Emacs text-editor. There are several ways of doing this (and you may wish to consult your emacs info manual). A method that works in emacs-19 up to current emacs-20 versions uses the emacs @file{iso-transl.el} package by putting the following in your @file{~/.emacs} file: @example (require 'iso-transl) (iso-transl-set-language "French") (standard-display-european t) @end example Loading the iso-transl package defines three ways of entering the non-ASCII printable characters with codes above 127: the prefix @kbd{C-x 8}, or the @key{Alt} key, or a dead accent key. For example, you can enter uppercase A-umlaut as @kbd{C-x 8 " A} or @kbd{Alt-" A} (if you have an Alt key) or @kbd{umlaut A} (if you have an umlaut/diaeresis key). A more recently introduced method is to enter the mode which allows quick insertion of iso-latin-1 characters. Do the Emacs command @code{M-x iso-accents-mode} (either manually, or in a hook that's done automatically). Now, suppose the x-axis is to represent temperature. All you'd have to do is type in the command @example set x name "Temp'erature" @end example As you type, the quote mark will dissappear, and reappear as an accent on the @code{e}. And then, Gri will recognize this accented @code{é}, and it will draw the accent on the axis label. Perhaps the future default way of accomplishing this task is to use MULE support directly. First, customize MULE using @code{M-x customize-group RET mule} setting the @code{current language environment} (e.g. latin-1) and the @code{default input method} (e.g. latin-1-prefix). Then, invoking @code{M-x toggle-input-method} (e.g. @key{C-\}) toggles into a mode similar 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.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.) @subsubsection 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. @subsubsection 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-2.12.23/doc/._gri2html000755 000767 000024 00000000342 11310756313 015533 0ustar00kelleystaff000000 000000 Mac OS X  2°âATTRäÖâ˜J˜Jcom.apple.acl.text!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write gri-2.12.23/doc/gri2html000755 000767 000024 00000003714 11310756313 015324 0ustar00kelleystaff000000 000000 #!/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-2.12.23/doc/._gri2texi000755 000767 000024 00000000342 11310756313 015540 0ustar00kelleystaff000000 000000 Mac OS X  2°âATTRäÖâ˜J˜Jcom.apple.acl.text!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write gri-2.12.23/doc/gri2texi000755 000767 000024 00000002453 11310756313 015330 0ustar00kelleystaff000000 000000 #!/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-2.12.23/doc/._gri_merge.1-skel000644 000767 000024 00000000342 11310756313 017033 0ustar00kelleystaff000000 000000 Mac OS X  2°âATTRäÖâ˜J˜Jcom.apple.acl.text!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write gri-2.12.23/doc/gri_merge.1-skel000644 000767 000024 00000002747 11310756313 016631 0ustar00kelleystaff000000 000000 .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-2.12.23/doc/._gri_unpage.1-skel000644 000767 000024 00000000342 11310756313 017213 0ustar00kelleystaff000000 000000 Mac OS X  2°âATTRäÖâ˜J˜Jcom.apple.acl.text!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write gri-2.12.23/doc/gri_unpage.1-skel000644 000767 000024 00000001633 11310756313 017002 0ustar00kelleystaff000000 000000 .\" 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-2.12.23/doc/._HTML_subdivide000755 000767 000024 00000000342 11310756313 016605 0ustar00kelleystaff000000 000000 Mac OS X  2°âATTRäÖâ˜J˜Jcom.apple.acl.text!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write gri-2.12.23/doc/HTML_subdivide000755 000767 000024 00000020275 11310756313 016377 0ustar00kelleystaff000000 000000 #!/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;
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-2.12.23/doc/._install-sh000755 000767 000024 00000000342 11310756313 016061 0ustar00kelleystaff000000 000000 Mac OS X  2°âATTRäÖâ˜J˜Jcom.apple.acl.text!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write gri-2.12.23/doc/install-sh000755 000767 000024 00000011243 11310756313 015646 0ustar00kelleystaff000000 000000 #!/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-2.12.23/doc/._make_html_builtinindex000644 000767 000024 00000000342 11310756313 020517 0ustar00kelleystaff000000 000000 Mac OS X  2°âATTRäÖâ˜J˜Jcom.apple.acl.text!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write gri-2.12.23/doc/make_html_builtinindex000644 000767 000024 00000001451 11310756313 020304 0ustar00kelleystaff000000 000000 #!/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-2.12.23/doc/._make_html_commandindex000644 000767 000024 00000000342 11310756313 020467 0ustar00kelleystaff000000 000000 Mac OS X  2°âATTRäÖâ˜J˜Jcom.apple.acl.text!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write gri-2.12.23/doc/make_html_commandindex000644 000767 000024 00000001553 11310756313 020257 0ustar00kelleystaff000000 000000 #!/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-2.12.23/doc/._make_html_index000755 000767 000024 00000000342 11310756313 017133 0ustar00kelleystaff000000 000000 Mac OS X  2°âATTRäÖâ˜J˜Jcom.apple.acl.text!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write gri-2.12.23/doc/make_html_index000755 000767 000024 00000002142 11310756313 016716 0ustar00kelleystaff000000 000000 #!/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-2.12.23/doc/Makefile.am000644 000767 000024 00000017747 11403430371 015711 0ustar00kelleystaff000000 000000 ## 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 $(TEXINDEX) gri.fn $(TEXINDEX) gri.ky $(TEXINDEX) gri.pg $(TEXINDEX) gri.tp $(TEXINDEX) gri.vr $(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 $(TEXINDEX) gri.fn $(TEXINDEX) gri.ky $(TEXINDEX) gri.pg $(TEXINDEX) gri.tp $(TEXINDEX) gri.vr 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-2.12.23/doc/Makefile.in000644 000767 000024 00000100226 11605066212 015706 0ustar00kelleystaff000000 000000 # Makefile.in generated by automake 1.10 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/stamp-vti $(srcdir)/version.texi install-sh mdate-sh \ texinfo.tex 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) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = 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 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 uninstall-recursive 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 = `echo $$p | sed -e 's|^.*/||'`; RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) VPATH = @srcdir@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CXXFLAGS = @AM_CXXFLAGS@ 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_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@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ # gri: doc/Makefile.am srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ 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 \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/Makefile .PRECIOUS: 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 .texi.info: restore=: && backupdir="$(am__leading_dot)am$$$$" && \ am__cwd=`pwd` && 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; \ cd $(srcdir); \ else \ rc=$$?; \ cd $(srcdir) && \ $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \ fi; \ rm -rf $$backupdir; exit $$rc .texi.dvi: TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ $(TEXI2DVI) $< .texi.pdf: TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ $(TEXI2PDF) $< .texi.html: rm -rf $(@:.html=.htp) if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ -o $(@:.html=.htp) $<; \ then \ rm -rf $@; \ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \ mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \ else \ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \ rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \ 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) -@rm -f vti.tmp @cp $(srcdir)/version.texi $@ mostlyclean-vti: -rm -f vti.tmp maintainer-clean-vti: -rm -f $(srcdir)/stamp-vti $(srcdir)/version.texi .dvi.ps: TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ $(DVIPS) -o $@ $< uninstall-dvi-am: @$(NORMAL_UNINSTALL) @list='$(DVIS)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \ rm -f "$(DESTDIR)$(dvidir)/$$f"; \ done uninstall-html-am: @$(NORMAL_UNINSTALL) @list='$(HTMLS)'; for p in $$list; do \ f=$(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)' && \ (install-info --version && \ install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; 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'"; \ install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \ 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)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \ rm -f "$(DESTDIR)$(pdfdir)/$$f"; \ done uninstall-ps-am: @$(NORMAL_UNINSTALL) @list='$(PSS)'; for p in $$list; do \ f=$(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.aux gri.cp gri.cps gri.fn gri.fns gri.ky gri.kys gri.log gri.pg \ gri.pgs gri.tmp gri.toc gri.tp gri.tps gri.vr gri.vrs \ 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. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; 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; \ (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" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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 || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 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) test -z "$(dvidir)" || $(MKDIR_P) "$(DESTDIR)$(dvidir)" @list='$(DVIS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(dvidir)/$$f'"; \ $(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(dvidir)/$$f"; \ done install-exec-am: install-html: install-html-recursive install-html-am: $(HTMLS) @$(NORMAL_INSTALL) test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)" @list='$(HTMLS)'; for p in $$list; do \ if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ if test -d "$$d$$p"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \ $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \ echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \ $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f"; \ else \ echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(htmldir)/$$f'"; \ $(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(htmldir)/$$f"; \ fi; \ done install-info: install-info-recursive install-info-am: $(INFO_DEPS) @$(NORMAL_INSTALL) test -z "$(infodir)" || $(MKDIR_P) "$(DESTDIR)$(infodir)" @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ list='$(INFO_DEPS)'; \ 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 \ relfile=`echo "$$ifile" | sed 's|^.*/||'`; \ echo " $(INSTALL_DATA) '$$ifile' '$(DESTDIR)$(infodir)/$$relfile'"; \ $(INSTALL_DATA) "$$ifile" "$(DESTDIR)$(infodir)/$$relfile"; \ else : ; fi; \ done; \ done @$(POST_INSTALL) @if (install-info --version && \ install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \ list='$(INFO_DEPS)'; \ 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) test -z "$(pdfdir)" || $(MKDIR_P) "$(DESTDIR)$(pdfdir)" @list='$(PDFS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(pdfdir)/$$f'"; \ $(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(pdfdir)/$$f"; \ done install-ps: install-ps-recursive install-ps-am: $(PSS) @$(NORMAL_INSTALL) test -z "$(psdir)" || $(MKDIR_P) "$(DESTDIR)$(psdir)" @list='$(PSS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(psdir)/$$f'"; \ $(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(psdir)/$$f"; \ 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: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am all-local check check-am clean clean-generic ctags \ ctags-recursive 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-recursive uninstall uninstall-am uninstall-dvi-am \ uninstall-html-am uninstall-info-am uninstall-local \ uninstall-pdf-am uninstall-ps-am 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 $(TEXINDEX) gri.fn $(TEXINDEX) gri.ky $(TEXINDEX) gri.pg $(TEXINDEX) gri.tp $(TEXINDEX) gri.vr $(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 $(TEXINDEX) gri.fn $(TEXINDEX) gri.ky $(TEXINDEX) gri.pg $(TEXINDEX) gri.tp $(TEXINDEX) gri.vr 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-2.12.23/doc/._mdate-sh000755 000767 000024 00000000342 11310756313 015505 0ustar00kelleystaff000000 000000 Mac OS X  2°âATTRäÖ â˜J˜Jcom.apple.acl.text!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write gri-2.12.23/doc/mdate-sh000755 000767 000024 00000010130 11310756313 015264 0ustar00kelleystaff000000 000000 #!/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-2.12.23/doc/._README000644 000767 000024 00000000342 11310756313 014735 0ustar00kelleystaff000000 000000 Mac OS X  2°âATTRäÖâ˜J˜Jcom.apple.acl.text!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write gri-2.12.23/doc/README000644 000767 000024 00000000523 11310756313 014521 0ustar00kelleystaff000000 000000 To 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-2.12.23/doc/._refcard.tex000644 000767 000024 00000000342 11310756313 016205 0ustar00kelleystaff000000 000000 Mac OS X  2°âATTRäÖ â˜J˜Jcom.apple.acl.text!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write gri-2.12.23/doc/refcard.tex000644 000767 000024 00000041430 11310756313 015773 0ustar00kelleystaff000000 000000 % 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-2.12.23/doc/resources/000777 000767 000024 00000000000 11607310072 015654 5ustar00kelleystaff000000 000000 gri-2.12.23/doc/screenshots/000777 000767 000024 00000000000 11607310072 016202 5ustar00kelleystaff000000 000000 gri-2.12.23/doc/._stamp-vti000644 000767 000024 00000000342 11605066313 015725 0ustar00kelleystaff000000 000000 Mac OS X  2°âATTRäÖâ˜J˜Jcom.apple.acl.text!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write gri-2.12.23/doc/stamp-vti000644 000767 000024 00000000140 11605066313 015504 0ustar00kelleystaff000000 000000 @set UPDATED 6 July 2011 @set UPDATED-MONTH July 2011 @set EDITION 2.12.23 @set VERSION 2.12.23 gri-2.12.23/doc/._texinfo.tex000644 000767 000024 00000000342 11310756313 016253 0ustar00kelleystaff000000 000000 Mac OS X  2°âATTRäÖ â˜J˜Jcom.apple.acl.text!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write gri-2.12.23/doc/texinfo.tex000644 000767 000024 00000661766 11310756313 016065 0ustar00kelleystaff000000 000000 % 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{2003-05-04.08} % % Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 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 2, 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 texinfo.tex file; see the file COPYING. If not, write % to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, % Boston, MA 02111-1307, USA. % % In other words, you are welcome to use, share and improve this program. % You are forbidden to forbid anyone else to use, share and improve % what you give them. Help stamp out software-hoarding! % % Please try the latest version of texinfo.tex before submitting bug % reports; you can get the latest version from: % ftp://ftp.gnu.org/gnu/texinfo/texinfo.tex % (and all GNU mirrors, see http://www.gnu.org/order/ftp.html) % ftp://tug.org/tex/texinfo.tex % (and all CTAN mirrors, see http://www.ctan.org), % and /home/gd/gnu/doc/texinfo.tex on the GNU machines. % % The GNU Texinfo home page is http://www.gnu.org/software/texinfo. % % The texinfo.tex in any given Texinfo 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. \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} \message{Basics,} \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\ptexgtr=> \let\ptexhat=^ \let\ptexi=\i \let\ptexindent=\indent \let\ptexlbrace=\{ \let\ptexless=< \let\ptexplus=+ \let\ptexrbrace=\} \let\ptexslash=\/ \let\ptexstar=\* \let\ptext=\t % If this character appears in an error message or help string, it % starts a new line in the output. \newlinechar = `^^J % 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\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\putwordDeftypevar\undefined\gdef\putwordDeftypevar{Variable}\fi \ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi \ifx\putwordDeftypefun\undefined\gdef\putwordDeftypefun{Function}\fi % In some macros, we cannot use the `\? notation---the left quote is % in some cases the escape char. \chardef\colonChar = `\: \chardef\commaChar = `\, \chardef\dotChar = `\. \chardef\equalChar = `\= \chardef\exclamChar= `\! \chardef\questChar = `\? \chardef\semiChar = `\; \chardef\spaceChar = `\ % \chardef\underChar = `\_ % Ignore a token. % \def\gobble#1{} % True if #1 is the empty string, i.e., called like `\ifempty{}'. % \def\ifempty#1{\ifemptyx #1\emptymarkA\emptymarkB}% \def\ifemptyx#1#2\emptymarkB{\ifx #1\emptymarkA}% % Hyphenation fixes. \hyphenation{ap-pen-dix} \hyphenation{eshell} \hyphenation{mini-buf-fer mini-buf-fers} \hyphenation{time-stamp} \hyphenation{white-space} % Margin to add to right of even pages, to left of odd pages. \newdimen\bindingoffset \newdimen\normaloffset \newdimen\pagewidth \newdimen\pageheight % 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\undefined\else % etex gives us more logging \tracingscantokens1 \tracingifs1 \tracinggroups1 \tracingnesting2 \tracingassigns1 \fi \tracingcommands3 % 3 gives us more in etex \errorcontextlines\maxdimen }% % 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} % For @cropmarks command. % 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 % 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). \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% \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. % \escapechar = `\\ % use backslash in output files. \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. \shipout\vbox{% % Do this early so pdf references go to the beginning of the page. \ifpdfmakepagedest \pdfmkdest{\the\pageno} \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 \oddfootingxxx.) % The \baselineskip=24pt in plain's \makefootline has no effect. \vskip 2\baselineskip \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 \normalturnoffactive \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 \unvbox#1 \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#1{% \let\next = #1% \begingroup \obeylines \futurelet\temp\parseargx } % If the next token is an obeyed space (from an @example environment or % the like), remove it and recurse. Otherwise, we're done. \def\parseargx{% % \obeyedspace is defined far below, after the definition of \sepspaces. \ifx\obeyedspace\temp \expandafter\parseargdiscardspace \else \expandafter\parseargline \fi } % Remove a single space (as the delimiter token to the macro call). {\obeyspaces % \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} {\obeylines % \gdef\parseargline#1^^M{% \endgroup % End of the group started in \parsearg. % % First remove any @c comment, then any @comment. % Result of each macro is put in \toks0. \argremovec #1\c\relax % \expandafter\argremovecomment \the\toks0 \comment\relax % % % Call the caller's macro, saved as \next in \parsearg. \expandafter\next\expandafter{\the\toks0}% }% } % Since all \c{,omment} does is throw away the argument, we can let TeX % do that for us. The \relax here is matched by the \relax in the call % in \parseargline; it could be more or less anything, its purpose is % just to delimit the argument to the \c. \def\argremovec#1\c#2\relax{\toks0 = {#1}} \def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} % \argremovec{,omment} might leave us with trailing spaces, though; e.g., % @end itemize @c foo % will have two active spaces as part of the argument with the % `itemize'. Here we remove all active spaces from #1, and assign the % result to \toks0. % % This loses if there are any *other* active characters besides spaces % in the argument -- _ ^ +, for example -- since they get expanded. % Fortunately, Texinfo does not define any such commands. (If it ever % does, the catcode of the characters in questionwill have to be changed % here.) But this means we cannot call \removeactivespaces as part of % \argremovec{,omment}, since @c uses \parsearg, and thus the argument % that \parsearg gets might well have any character at all in it. % \def\removeactivespaces#1{% \begingroup \ignoreactivespaces \edef\temp{#1}% \global\toks0 = \expandafter{\temp}% \endgroup } % Change the active space to expand to nothing. % \begingroup \obeyspaces \gdef\ignoreactivespaces{\obeyspaces\let =\empty} \endgroup \def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} %% These are used to keep @begin/@end levels from running away %% Call \inENV within environments (after a \begingroup) \newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} \def\ENVcheck{% \ifENV\errmessage{Still within an environment; press RETURN to continue} \endgroup\fi} % This is not perfect, but it should reduce lossage % @begin foo is the same as @foo, for now. \newhelp\EMsimple{Press RETURN to continue.} \outer\def\begin{\parsearg\beginxxx} \def\beginxxx #1{% \expandafter\ifx\csname #1\endcsname\relax {\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else \csname #1\endcsname\fi} % @end foo executes the definition of \Efoo. % \def\end{\parsearg\endxxx} \def\endxxx #1{% \removeactivespaces{#1}% \edef\endthing{\the\toks0}% % \expandafter\ifx\csname E\endthing\endcsname\relax \expandafter\ifx\csname \endthing\endcsname\relax % There's no \foo, i.e., no ``environment'' foo. \errhelp = \EMsimple \errmessage{Undefined command `@end \endthing'}% \else \unmatchedenderror\endthing \fi \else % Everything's ok; the right environment has been started. \csname E\endthing\endcsname \fi } % There is an environment #1, but it hasn't been started. Give an error. % \def\unmatchedenderror#1{% \errhelp = \EMsimple \errmessage{This `@end #1' doesn't have a matching `@#1'}% } % Define the control sequence \E#1 to give an unmatched @end error. % \def\defineunmatchedend#1{% \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% } %% Simple single-character @ commands % @@ prints an @ % Kludge this until the fonts are right (grr). \def\@{{\tt\char64}} % This is turned off because it was never documented % and you can use @w{...} around a quote to suppress ligatures. %% Define @` and @' to be the same as ` and ' %% but suppressing ligatures. %\def\`{{`}} %\def\'{{'}} % Used to generate quoted braces. \def\mylbrace {{\tt\char123}} \def\myrbrace {{\tt\char125}} \let\{=\mylbrace \let\}=\myrbrace \begingroup % Definitions to produce \{ and \} commands for indices, % and @{ and @} for the aux file. \catcode`\{ = \other \catcode`\} = \other \catcode`\[ = 1 \catcode`\] = 2 \catcode`\! = 0 \catcode`\\ = \other !gdef!lbracecmd[\{]% !gdef!rbracecmd[\}]% !gdef!lbraceatcmd[@{]% !gdef!rbraceatcmd[@}]% !endgroup % Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent % Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. \let\, = \c \let\dotaccent = \. \def\ringaccent#1{{\accent23 #1}} \let\tieaccent = \t \let\ubaraccent = \b \let\udotaccent = \d % Other special characters: @questiondown @exclamdown % Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. \def\questiondown{?`} \def\exclamdown{!`} % Dotless i and dotless j, used for accents. \def\imacro{i} \def\jmacro{j} \def\dotless#1{% \def\temp{#1}% \ifx\temp\imacro \ptexi \else\ifx\temp\jmacro \j \else \errmessage{@dotless can be used only with i or j}% \fi\fi } % 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\*{\hfil\break\hbox{}\ignorespaces} % @/ allows a line break. \let\/=\allowbreak % @. is an end-of-sentence period. \def\.{.\spacefactor=3000 } % @! is an end-of-sentence bang. \def\!{!\spacefactor=3000 } % @? is an end-of-sentence query. \def\?{?\spacefactor=3000 } % @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} % \def\group{\begingroup \ifnum\catcode13=\active \else \errhelp = \groupinvalidhelp \errmessage{@group invalid in context where filling is enabled}% \fi % % The \vtop we start below 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. (See p.82 of % the TeXbook.) Thus, space below is not quite equal to space % above. But it's pretty close. \def\Egroup{% \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 \copy\groupbox \endgroup % End the \group. }% % \setbox\groupbox = \vtop\bgroup % We have to put a strut on the last line in case the @group is in % the midst of an example, rather than completely enclosing it. % Otherwise, the interline space between the last line of the group % and the first line afterwards is too small. But we can't put the % strut in \Egroup, since there it would be on a line by itself. % Hence this just inserts a strut at the beginning of each line. \everypar = {\strut}% % % Since we have a strut on every line, we don't need any of TeX's % normal interline spacing. \offinterlineskip % % OK, but now we have to do something about blank % lines in the input in @example-like environments, which normally % just turn into \lisppar, which will insert no space now that we've % turned off the interline space. Simplest is to make them be an % empty paragraph. \ifx\par\lisppar \edef\par{\leavevmode \par}% % % Reset ^^M's definition to new definition of \par. \obeylines \fi % % 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 } % % 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 \def\need{\parsearg\needx} % Old definition--didn't work. %\def\needx #1{\par % %% This method tries to make TeX break the page naturally %% if the depth of the box does not fit. %{\baselineskip=0pt% %\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak %\prevdepth=-1000pt %}} \def\needx#1{% % 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 \let\br = \par % @dots{} output an ellipsis using the current font. % We do .5em per period so that it has the same spacing in a typewriter % font as three actual period characters. % \def\dots{% \leavevmode \hbox to 1.5em{% \hskip 0pt plus 0.25fil minus 0.25fil .\hss.\hss.% \hskip 0pt plus 0.5fil minus 0.5fil }% } % @enddots{} is an end-of-sentence ellipsis. % \def\enddots{% \leavevmode \hbox to 2em{% \hskip 0pt plus 0.25fil minus 0.25fil .\hss.\hss.\hss.% \hskip 0pt plus 0.5fil minus 0.5fil }% \spacefactor=3000 } % @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. \def\exdent{\parsearg\exdentyyy} \def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} % This defn is used inside nofill environments such as @example. \def\nofillexdent{\parsearg\nofillexdentyyy} \def\nofillexdentyyy #1{{\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'. % \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 } % @include file insert text of that file as input. % Allow normal characters that we make active in the argument (a file name). \def\include{\begingroup \catcode`\\=\other \catcode`~=\other \catcode`^=\other \catcode`_=\other \catcode`|=\other \catcode`<=\other \catcode`>=\other \catcode`+=\other \parsearg\includezzz} % Restore active chars for included file. \def\includezzz#1{\endgroup\begingroup % Read the included file in a group so nested @include's work. \def\thisfile{#1}% \let\value=\expandablevalue \input\thisfile \endgroup} \def\thisfile{} % @center line % outputs that line, centered. % \def\center{\parsearg\docenter} \def\docenter#1{{% \ifhmode \hfil\break \fi \advance\hsize by -\leftskip \advance\hsize by -\rightskip \line{\hfil \ignorespaces#1\unskip \hfil}% \ifhmode \break \fi }} % @sp n outputs n lines of vertical space \def\sp{\parsearg\spxxx} \def\spxxx #1{\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} % \def\paragraphindent{\parsearg\doparagraphindent} \def\doparagraphindent#1{% \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. \def\exampleindent{\parsearg\doexampleindent} \def\doexampleindent#1{% \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 indentat 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} \newdimen\currentparindent % \def\insertword{insert} % \def\firstparagraphindent{\parsearg\dofirstparagraphindent} \def\dofirstparagraphindent#1{% \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{% \global\let\indent=\ptexindent \global\everypar = {}% }% \global\everypar = {% \kern-\parindent \global\let\indent=\ptexindent \global\everypar = {}% }% }% % @asis just yields its argument. Used with @table, for example. % \def\asis#1{#1} % @math outputs its argument in math mode. % We don't use $'s directly in the definition of \math because we need % to set catcodes according to plain TeX first, to allow for subscripts, % superscripts, special math chars, etc. % \let\implicitmath = $%$ font-lock fix % % One complication: _ usually means subscripts, but it could also mean % an actual _ character, as in @math{@var{some_variable} + 1}. So make % _ within @math be active (mathcode "8000), and distinguish by seeing % if the current family is \slfam, which is what @var uses. % {\catcode\underChar = \active \gdef\mathunderscore{% \catcode\underChar=\active \def_{\ifnum\fam=\slfam \_\else\sb\fi}% }} % % Another complication: we want \\ (and @\) to output a \ character. % FYI, plain.tex uses \\ as a temporary control sequence (why?), but % this is not advertised and we don't care. Texinfo does not % otherwise define @\. % % The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. \def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} % \def\math{% \tex \mathcode`\_="8000 \mathunderscore \let\\ = \mathbackslash \mathactive \implicitmath\finishmath} \def\finishmath#1{#1\implicitmath\Etex} % 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 set the catcodes (such as @item or @section). % { \catcode`^ = \active \catcode`< = \active \catcode`> = \active \catcode`+ = \active \gdef\mathactive{% \let^ = \ptexhat \let< = \ptexless \let> = \ptexgtr \let+ = \ptexplus } } % @bullet and @minus need the same treatment as @math, just above. \def\bullet{\implicitmath\ptexbullet\implicitmath} \def\minus{\implicitmath-\implicitmath} % @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{% \iflinks \readauxfile \fi % \openindices needs to do some work in any case. \openindices \fixbackslash % Turn off hack to swallow `\input texinfo'. \global\let\setfilename=\comment % Ignore extra @setfilename cmds. % % If texinfo.cnf is present on the system, read it. % Useful for site-wide @afourpaper, etc. % Just to be on the safe side, close the input stream before the \input. \openin 1 texinfo.cnf \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi \closein1 \temp % \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 \ifx\pdfoutput\undefined \pdffalse \let\pdfmkdest = \gobble \let\pdfurl = \gobble \let\endlink = \relax \let\linkcolor = \relax \let\pdfmakeoutlines = \relax \else \pdftrue \pdfoutput = 1 \input pdfcolor \def\dopdfimage#1#2#3{% \def\imagewidth{#2}% \def\imageheight{#3}% % without \immediate, 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 \ifx\empty\imagewidth\else width \imagewidth \fi \ifx\empty\imageheight\else height \imageheight \fi \ifnum\pdftexversion<13 #1.pdf% \else {#1.pdf}% \fi \ifnum\pdftexversion < 14 \else \pdfrefximage \pdflastximage \fi} \def\pdfmkdest#1{{\normalturnoffactive \pdfdest name{#1} xyz}} \def\pdfmkpgn#1{#1} \let\linkcolor = \Blue % was Cyan, but that seems light? \def\endlink{\Black\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 by1 \expandafter\xdef\csname#1\endcsname{\the\tempnum}} \def\pdfmakeoutlines{{% \openin 1 \jobname.toc \ifeof 1\else\begingroup \closein 1 % Thanh's hack / proper braces in bookmarks \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace % \def\chapentry ##1##2##3{} \def\secentry ##1##2##3##4{\advancenumber{chap##2}} \def\subsecentry ##1##2##3##4##5{\advancenumber{sec##2.##3}} \def\subsubsecentry ##1##2##3##4##5##6{\advancenumber{subsec##2.##3.##4}} \let\appendixentry = \chapentry \let\unnumbchapentry = \chapentry \let\unnumbsecentry = \secentry \let\unnumbsubsecentry = \subsecentry \let\unnumbsubsubsecentry = \subsubsecentry \input \jobname.toc \def\chapentry ##1##2##3{% \pdfoutline goto name{\pdfmkpgn{##3}}count-\expnumber{chap##2}{##1}} \def\secentry ##1##2##3##4{% \pdfoutline goto name{\pdfmkpgn{##4}}count-\expnumber{sec##2.##3}{##1}} \def\subsecentry ##1##2##3##4##5{% \pdfoutline goto name{\pdfmkpgn{##5}}count-\expnumber{subsec##2.##3.##4}{##1}} \def\subsubsecentry ##1##2##3##4##5##6{% \pdfoutline goto name{\pdfmkpgn{##6}}{##1}} \let\appendixentry = \chapentry \let\unnumbchapentry = \chapentry \let\unnumbsecentry = \secentry \let\unnumbsubsecentry = \subsecentry \let\unnumbsubsubsecentry = \subsubsecentry % % Make special characters normal for writing to the pdf file. % \indexnofonts \let\tt=\relax \turnoffactive \input \jobname.toc \endgroup\fi }} \def\makelinks #1,{% \def\params{#1}\def\E{END}% \ifx\params\E \let\nextmakelinks=\relax \else \let\nextmakelinks=\makelinks \ifnum\lnkcount>0,\fi \picknum{#1}% \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{\the\pgn}}% \linkcolor #1% \advance\lnkcount by 1% \endlink \fi \nextmakelinks } \def\picknum#1{\expandafter\pn#1} \def\pn#1{% \def\p{#1}% \ifx\p\lbrace \let\nextpn=\ppn \else \let\nextpn=\ppnn \def\first{#1} \fi \nextpn } \def\ppn#1{\pgn=#1\gobble} \def\ppnn{\pgn=\first} \def\pdfmklnk#1{\lnkcount=0\makelinks #1,END,} \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} \def\skipspaces#1{\def\PP{#1}\def\D{|}% \ifx\PP\D\let\nextsp\relax \else\let\nextsp\skipspaces \ifx\p\space\else\addtokens{\filename}{\PP}% \advance\filenamelength by 1 \fi \fi \nextsp} \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax} \ifnum\pdftexversion < 14 \let \startlink \pdfannotlink \else \let \startlink \pdfstartlink \fi \def\pdfurl#1{% \begingroup \normalturnoffactive\def\@{@}% \let\value=\expandablevalue \leavevmode\Red \startlink attr{/Border [0 0 0]}% user{/Subtype /Link /A << /S /URI /URI (#1) >>}% % #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| \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}} \linkcolor #1\endlink} \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} \fi % \ifx\pdfoutput \message{fonts,} % Font-change commands. % Texinfo sort of supports the sans serif font style, which plain TeX does not. % So we set up a \sf analogous to plain's \rm, etc. \newfam\sffam \def\sf{\fam=\sffam \tensf} \let\li = \sf % Sometimes we call it \li, not \sf. % We don't need math for this one. \def\ttsl{\tenttsl} % Default leading. \newdimen\textleading \textleading = 13.2pt % 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} % \def\setleading#1{% \normalbaselineskip = #1\relax \normallineskip = \lineskipfactor\normalbaselineskip \normalbaselines \setbox\strutbox =\hbox{% \vrule width0pt height\strutheightpercent\baselineskip depth \strutdepthpercent \baselineskip }% } % Set the font macro #1 to the font named #2, adding on the % specified font prefix (normally `cm'). % #3 is the font's design size, #4 is a scale factor \def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4} % Use cm as the default font prefix. % To specify the font prefix, you must define \fontprefix % before you read in texinfo.tex. \ifx\fontprefix\undefined \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} \newcount\mainmagstep \ifx\bigger\relax % not really supported. \mainmagstep=\magstep1 \setfont\textrm\rmshape{12}{1000} \setfont\texttt\ttshape{12}{1000} \else \mainmagstep=\magstephalf \setfont\textrm\rmshape{10}{\mainmagstep} \setfont\texttt\ttshape{10}{\mainmagstep} \fi % Instead of cmb10, you may want to use cmbx10. % cmbx10 is a prettier font on its own, but cmb10 % looks better when embedded in a line with cmr10 % (in Bob's opinion). \setfont\textbf\bfshape{10}{\mainmagstep} \setfont\textit\itshape{10}{\mainmagstep} \setfont\textsl\slshape{10}{\mainmagstep} \setfont\textsf\sfshape{10}{\mainmagstep} \setfont\textsc\scshape{10}{\mainmagstep} \setfont\textttsl\ttslshape{10}{\mainmagstep} \font\texti=cmmi10 scaled \mainmagstep \font\textsy=cmsy10 scaled \mainmagstep % A few fonts for @defun, etc. \setfont\defbf\bxshape{10}{\magstep1} %was 1314 \setfont\deftt\ttshape{10}{\magstep1} \def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} % Fonts for indices, footnotes, small examples (9pt). \setfont\smallrm\rmshape{9}{1000} \setfont\smalltt\ttshape{9}{1000} \setfont\smallbf\bfshape{10}{900} \setfont\smallit\itshape{9}{1000} \setfont\smallsl\slshape{9}{1000} \setfont\smallsf\sfshape{9}{1000} \setfont\smallsc\scshape{10}{900} \setfont\smallttsl\ttslshape{10}{900} \font\smalli=cmmi9 \font\smallsy=cmsy9 % Fonts for small examples (8pt). \setfont\smallerrm\rmshape{8}{1000} \setfont\smallertt\ttshape{8}{1000} \setfont\smallerbf\bfshape{10}{800} \setfont\smallerit\itshape{8}{1000} \setfont\smallersl\slshape{8}{1000} \setfont\smallersf\sfshape{8}{1000} \setfont\smallersc\scshape{10}{800} \setfont\smallerttsl\ttslshape{10}{800} \font\smalleri=cmmi8 \font\smallersy=cmsy8 % Fonts for title page: \setfont\titlerm\rmbshape{12}{\magstep3} \setfont\titleit\itbshape{10}{\magstep4} \setfont\titlesl\slbshape{10}{\magstep4} \setfont\titlett\ttbshape{12}{\magstep3} \setfont\titlettsl\ttslshape{10}{\magstep4} \setfont\titlesf\sfbshape{17}{\magstep1} \let\titlebf=\titlerm \setfont\titlesc\scbshape{10}{\magstep4} \font\titlei=cmmi12 scaled \magstep3 \font\titlesy=cmsy10 scaled \magstep4 \def\authorrm{\secrm} \def\authortt{\sectt} % Chapter (and unnumbered) fonts (17.28pt). \setfont\chaprm\rmbshape{12}{\magstep2} \setfont\chapit\itbshape{10}{\magstep3} \setfont\chapsl\slbshape{10}{\magstep3} \setfont\chaptt\ttbshape{12}{\magstep2} \setfont\chapttsl\ttslshape{10}{\magstep3} \setfont\chapsf\sfbshape{17}{1000} \let\chapbf=\chaprm \setfont\chapsc\scbshape{10}{\magstep3} \font\chapi=cmmi12 scaled \magstep2 \font\chapsy=cmsy10 scaled \magstep3 % Section fonts (14.4pt). \setfont\secrm\rmbshape{12}{\magstep1} \setfont\secit\itbshape{10}{\magstep2} \setfont\secsl\slbshape{10}{\magstep2} \setfont\sectt\ttbshape{12}{\magstep1} \setfont\secttsl\ttslshape{10}{\magstep2} \setfont\secsf\sfbshape{12}{\magstep1} \let\secbf\secrm \setfont\secsc\scbshape{10}{\magstep2} \font\seci=cmmi12 scaled \magstep1 \font\secsy=cmsy10 scaled \magstep2 % Subsection fonts (13.15pt). \setfont\ssecrm\rmbshape{12}{\magstephalf} \setfont\ssecit\itbshape{10}{1315} \setfont\ssecsl\slbshape{10}{1315} \setfont\ssectt\ttbshape{12}{\magstephalf} \setfont\ssecttsl\ttslshape{10}{1315} \setfont\ssecsf\sfbshape{12}{\magstephalf} \let\ssecbf\ssecrm \setfont\ssecsc\scbshape{10}{\magstep1} \font\sseci=cmmi12 scaled \magstephalf \font\ssecsy=cmsy10 scaled 1315 % The smallcaps and symbol fonts should actually be scaled \magstep1.5, % but that is not a standard magnification. % 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 so that font changes will continue to work % in math mode, where it is the current \fam that is relevant in most % cases, not the current font. Plain TeX does \def\bf{\fam=\bffam % \tenbf}, for example. By redefining \tenbf, we obviate the need to % redefine \bf itself. \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 \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 \resetmathfonts \setleading{25pt}} \def\titlefont#1{{\titlefonts\rm #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 \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 \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 \resetmathfonts \setleading{15pt}} \let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf? \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 \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 \resetmathfonts \setleading{9.5pt}} % 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 \smallerfonts (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 % % I wish we used A4 paper on this side of the Atlantic. % % --karl, 24jan03. % Set up the default fonts, so we can use them for creating boxes. % \textfonts % Define these so they can be easily changed for other fonts. \def\angleleft{$\langle$} \def\angleright{$\rangle$} % Count depth in font-changes, for error checks \newcount\fontdepth \fontdepth=0 % Fonts for short table of contents. \setfont\shortcontrm\rmshape{12}{1000} \setfont\shortcontbf\bxshape{12}{1000} \setfont\shortcontsl\slshape{12}{1000} \setfont\shortconttt\ttshape{12}{1000} %% Add scribe-like font environments, plus @l for inline lisp (usually sans %% serif) and @ii for TeX italic % \smartitalic{ARG} outputs arg in italics, followed by an italic correction % unless the following character is such as not to need one. \def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else \ptexslash\fi\fi\fi} \def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx} \def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx} \let\i=\smartitalic \let\var=\smartslanted \let\dfn=\smartslanted \let\emph=\smartitalic \let\cite=\smartslanted \def\b#1{{\bf #1}} \let\strong=\b % 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\frenchspacing{% \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m } \catcode`@=\other \def\t#1{% {\tt \rawbackslash \frenchspacing #1}% \null } \let\ttfont=\t \def\samp#1{`\tclose{#1}'\null} \setfont\keyrm\rmshape{8}{1000} \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}}}} % The old definition, with no lozenge: %\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} \def\ctrl #1{{\tt \rawbackslash \hat}#1} % @file, @option are the same as @samp. \let\file=\samp \let\option=\samp % @code is a modification of @t, % which makes spaces the same size as normal in the surrounding text. \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 \frenchspacing #1% }% \null } % 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 % \global\def\code{\begingroup \catcode`\-=\active \let-\codedash \catcode`\_=\active \let_\codeunder \codex } % % If we end up with any active - characters when handling the index, % just treat them as a normal -. \global\def\indexbreaks{\catcode`\-=\active \let-\realdash} } \def\realdash{-} \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{}{}{}}% {\_}% } \def\codex #1{\tclose{#1}\endgroup} % @kbd is like @code, except that if the argument is just one @key command, % then @kbd has no effect. % @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). \def\kbdinputstyle{\parsearg\kbdinputstylexxx} \def\kbdinputstylexxx#1{% \def\arg{#1}% \ifx\arg\worddistinct \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% \else\ifx\arg\wordexample \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% \else\ifx\arg\wordcode \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% \else \errhelp = \EMsimple \errmessage{Unknown @kbdinputstyle option `\arg'}% \fi\fi\fi } \def\worddistinct{distinct} \def\wordexample{example} \def\wordcode{code} % Default is `distinct.' \kbdinputstyle distinct \def\xkey{\key} \def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% \ifx\one\xkey\ifx\threex\three \key{#2}% \else{\tclose{\kbdfont\look}}\fi \else{\tclose{\kbdfont\look}}\fi} % For @url, @env, @command quotes seem unnecessary, so use \code. \let\url=\code \let\env=\code \let\command=\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. Perhaps eventually put in % a hypertex \special here. % \def\uref#1{\douref #1,,,\finish} \def\douref#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} % 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 % 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 } % 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} \def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} % @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} % 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 % @acronym downcases the argument and prints in smallcaps. \def\acronym#1{{\smallcaps \lowercase{#1}}} % @pounds{} is a sterling sign. \def\pounds{{\it\$}} % @registeredsymbol - R in a circle. For now, only works in text size; % we'd have to redo the font mechanism to change the \scriptstyle and % \scriptscriptstyle font sizes to make it look right in headings. % Adapted from the plain.tex definition of \copyright. % \def\registeredsymbol{% $^{{\ooalign{\hfil\raise.07ex\hbox{$\scriptstyle\rm R$}\hfil\crcr\Orb}}% }$% } \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 \def\shorttitlepage{\parsearg\shorttitlepagezzz} \def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% \endgroup\page\hbox{}\page} \def\titlepage{\begingroup \parindent=0pt \textfonts \let\subtitlerm=\tenrm \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}% % \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines \let\tt=\authortt}% % % Leave some space at the very top of the page. \vglue\titlepagetopglue % % Now you can print the title using @title. \def\title{\parsearg\titlezzz}% \def\titlezzz##1{\leftline{\titlefonts\rm ##1} % print a rule at the page bottom also. \finishedtitlepagefalse \vskip4pt \hrule height 4pt width \hsize \vskip4pt}% % No rule at page bottom unless we print one at the top with @title. \finishedtitlepagetrue % % Now you can put text using @subtitle. \def\subtitle{\parsearg\subtitlezzz}% \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% % % @author should come last, but may come many times. \def\author{\parsearg\authorzzz}% \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi {\authorfont \leftline{##1}}}% % % 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 \oldpage \let\page = \oldpage \hbox{}}% % \def\page{\oldpage \hbox{}} } \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 } %%% 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\oddheading{\parsearg\oddheadingxxx} \def\everyheading{\parsearg\everyheadingxxx} \def\evenfooting{\parsearg\evenfootingxxx} \def\oddfooting{\parsearg\oddfootingxxx} \def\everyfooting{\parsearg\everyfootingxxx} {\catcode`\@=0 % \gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} \gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% \global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} \gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% \global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}% \gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} \gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% \global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} \gdef\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 -\baselineskip \global\advance\vsize by -\baselineskip } \gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}} % }% unbind the catcode of @. % @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{ \global\evenheadline={\hfil} \global\evenfootline={\hfil} \global\oddheadline={\hfil} \global\oddfootline={\hfil}} \HEADINGSoff % 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\undefined \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\settitlezzz} \def\settitlezzz #1{\gdef\thistitle{#1}} \message{tables,} % Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(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, @vtable, 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\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} \def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz} \def\internalBkitem{\smallbreak \parsearg\kitemzzz} \def\internalBkitemx{\itemxpar \parsearg\kitemzzz} \def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% \itemzzz {#1}} \def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}% \itemzzz {#1}} \def\itemzzz #1{\begingroup % \advance\hsize by -\rightskip \advance\hsize by -\tableindent \setbox0=\hbox{\itemfont{#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 \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. (Unfortunately % we can't prevent a possible page break at the following % \baselineskip glue.) However, if what follows is an environment % such as @example, there will be no \parskip glue; then % the negative vskip we just 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. % (Possibly there are other commands that could be followed by % @example which need the same treatment, but not section titles; or % maybe section titles are the only special case and they should be % penalty 10001...) \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 table}} \def\itemx{\errmessage{@itemx while not in a table}} \def\kitem{\errmessage{@kitem while not in a table}} \def\kitemx{\errmessage{@kitemx while not in a table}} \def\xitem{\errmessage{@xitem while not in a table}} \def\xitemx{\errmessage{@xitemx while not in a table}} % Contains a kludge to get @end[description] to work. \def\description{\tablez{\dontindex}{1}{}{}{}{}} % @table, @ftable, @vtable. \def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} {\obeylines\obeyspaces% \gdef\tablex #1^^M{% \tabley\dontindex#1 \endtabley}} \def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} {\obeylines\obeyspaces% \gdef\ftablex #1^^M{% \tabley\fnitemindex#1 \endtabley \def\Eftable{\endgraf\afterenvbreak\endgroup}% \let\Etable=\relax}} \def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} {\obeylines\obeyspaces% \gdef\vtablex #1^^M{% \tabley\vritemindex#1 \endtabley \def\Evtable{\endgraf\afterenvbreak\endgroup}% \let\Etable=\relax}} \def\dontindex #1{} \def\fnitemindex #1{\doind {fn}{\code{#1}}}% \def\vritemindex #1{\doind {vr}{\code{#1}}}% {\obeyspaces % \gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% \tablez{#1}{#2}{#3}{#4}{#5}{#6}}} \def\tablez #1#2#3#4#5#6{% \aboveenvbreak % \begingroup % \def\Edescription{\Etable}% Necessary kludge. \let\itemindex=#1% \ifnum 0#3>0 \advance \leftskip by #3\mil \fi % \ifnum 0#4>0 \tableindent=#4\mil \fi % \ifnum 0#5>0 \advance \rightskip by #5\mil \fi % \def\itemfont{#2}% \itemmax=\tableindent % \advance \itemmax by -\itemmargin % \advance \leftskip by \tableindent % \exdentamount=\tableindent \parindent = 0pt \parskip = \smallskipamount \ifdim \parskip=0pt \parskip=2pt \fi% \def\Etable{\endgraf\afterenvbreak\endgroup}% \let\item = \internalBitem % \let\itemx = \internalBitemx % \let\kitem = \internalBkitem % \let\kitemx = \internalBkitemx % \let\xitem = \internalBxitem % \let\xitemx = \internalBxitemx % } % This is the counter used by @enumerate, which is really @itemize \newcount \itemno \def\itemize{\parsearg\itemizezzz} \def\itemizezzz #1{% \begingroup % ended by the @end itemize \itemizey {#1}{\Eitemize} } \def\itemizey#1#2{% \aboveenvbreak \itemmax=\itemindent \advance\itemmax by -\itemmargin \advance\leftskip by \itemindent \exdentamount=\itemindent \parindent=0pt \parskip=\smallskipamount \ifdim\parskip=0pt \parskip=2pt \fi \def#2{\endgraf\afterenvbreak\endgroup}% \def\itemcontents{#1}% % @itemize with no arg is equivalent to @itemize @bullet. \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi \let\item=\itemizeitem } % \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'. % \def\enumerate{\parsearg\enumeratezzz} \def\enumeratezzz #1{\enumeratey #1 \endenumeratey} \def\enumeratey #1 #2\endenumeratey{% \begingroup % ended by the @end enumerate % % 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 itemizey, 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 \itemizey{#1.}\Eenumerate\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} % Definition of @item while inside @itemize. \def\itemizeitem{% \advance\itemno by 1 {\let\par=\endgraf \smallbreak}% \ifhmode \errmessage{In hmode at itemizeitem}\fi {\parskip=0in \hskip 0pt \hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% \vadjust{\penalty 1200}}% \flushcr} % @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. % % For those who want to use more than one line's worth of words in % the preamble, break the line within one argument and it % will parse correctly, i.e., % % @multitable {Column 1 template} {Column 2 template} {Column 3 % template} % Not: % @multitable {Column 1 template} {Column 2 template} % {Column 3 template} % 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, @multitable or @end multitable 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 part of the @columnfraction before the decimal point, which % is presumably either 0 or the empty string (but we don't check, we % just throw it away). #2 is the decimal part, which we use as the % percent of \hsize for this column. \def\pickupwholefraction#1.#2 {% \global\advance\colcount by 1 \expandafter\xdef\csname col\the\colcount\endcsname{.#2\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 ... @end multitable definitions: % \def\multitable{\parsearg\dotable} \def\dotable#1{\bgroup \vskip\parskip \let\item=\crcrwithfootnotes % 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 encounter the problem it was intended to solve again. --karl, % nathan@acm.org, 20apr99. \let\tab=&% \let\startfootins=\startsavedfootnote \tolerance=9500 \hbadness=9500 \setmultitablespacing \parskip=\multitableparskip \parindent=\multitableparindent \overfullrule=0pt \global\colcount=0 \def\Emultitable{% \global\setpercentfalse \crcrwithfootnotes\crcr \egroup\egroup }% % % To parse everything between @multitable and @item: \setuptable#1 \endsetuptable % % \everycr will reset column counter, \colcount, at the end of % each line. Every column entry will cause \colcount to advance by one. % The table preamble % looks at the current \colcount to find the correct column width. \everycr{\noalign{% % % \filbreak%% keeps underfull box messages off when table breaks over pages. % 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. \global\colcount=0\relax}}% % % 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\relax \multistrut\vtop{\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\setmultitablespacing{% test to see if user has set \multitablelinespace. % If so, do nothing. If not, give it an appropriate dimension based on % current baselineskip. \ifdim\multitablelinespace=0pt \setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip \global\advance\multitablelinespace by-\ht0 %% strut to put in table in case some entry doesn't have descenders, %% to keep lines equally spaced \let\multistrut = \strut \else %% FIXME: what is \box0 supposed to be? \gdef\multistrut{\vrule height\multitablelinespace depth\dp0 width0pt\relax} \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} % In case 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. Otherwise, the insertion is lost, it never migrates to the % main vertical list. --kasal, 22jan03. % \newbox\savedfootnotes % % \dotable \let's \startfootins to this, so that \dofootnote will call % it instead of starting the insertion right away. \def\startsavedfootnote{% \global\setbox\savedfootnotes = \vbox\bgroup \unvbox\savedfootnotes } \def\crcrwithfootnotes{% \crcr \ifvoid\savedfootnotes \else \noalign{\insert\footins{\box\savedfootnotes}}% \fi } \message{conditionals,} % Prevent errors for section commands. % Used in @ignore and in failing conditionals. \def\ignoresections{% \let\chapter=\relax \let\unnumbered=\relax \let\top=\relax \let\unnumberedsec=\relax \let\unnumberedsection=\relax \let\unnumberedsubsec=\relax \let\unnumberedsubsection=\relax \let\unnumberedsubsubsec=\relax \let\unnumberedsubsubsection=\relax \let\section=\relax \let\subsec=\relax \let\subsubsec=\relax \let\subsection=\relax \let\subsubsection=\relax \let\appendix=\relax \let\appendixsec=\relax \let\appendixsection=\relax \let\appendixsubsec=\relax \let\appendixsubsection=\relax \let\appendixsubsubsec=\relax \let\appendixsubsubsection=\relax \let\contents=\relax \let\smallbook=\relax \let\titlepage=\relax } % Used in nested conditionals, where we have to parse the Texinfo source % and so want to turn off most commands, in case they are used % incorrectly. % % We use \empty instead of \relax for the @def... commands, so that \end % doesn't throw an error. For instance: % @ignore % @deffn ... % @end deffn % @end ignore % % The @end deffn is going to get expanded, because we're trying to allow % nested conditionals. But we don't want to expand the actual @deffn, % since it might be syntactically correct and intended to be ignored. % Since \end checks for \relax, using \empty does not cause an error. % \def\ignoremorecommands{% \let\defcodeindex = \relax \let\defcv = \empty \let\defcvx = \empty \let\Edefcv = \empty \let\deffn = \empty \let\deffnx = \empty \let\Edeffn = \empty \let\defindex = \relax \let\defivar = \empty \let\defivarx = \empty \let\Edefivar = \empty \let\defmac = \empty \let\defmacx = \empty \let\Edefmac = \empty \let\defmethod = \empty \let\defmethodx = \empty \let\Edefmethod = \empty \let\defop = \empty \let\defopx = \empty \let\Edefop = \empty \let\defopt = \empty \let\defoptx = \empty \let\Edefopt = \empty \let\defspec = \empty \let\defspecx = \empty \let\Edefspec = \empty \let\deftp = \empty \let\deftpx = \empty \let\Edeftp = \empty \let\deftypefn = \empty \let\deftypefnx = \empty \let\Edeftypefn = \empty \let\deftypefun = \empty \let\deftypefunx = \empty \let\Edeftypefun = \empty \let\deftypeivar = \empty \let\deftypeivarx = \empty \let\Edeftypeivar = \empty \let\deftypemethod = \empty \let\deftypemethodx = \empty \let\Edeftypemethod = \empty \let\deftypeop = \empty \let\deftypeopx = \empty \let\Edeftypeop = \empty \let\deftypevar = \empty \let\deftypevarx = \empty \let\Edeftypevar = \empty \let\deftypevr = \empty \let\deftypevrx = \empty \let\Edeftypevr = \empty \let\defun = \empty \let\defunx = \empty \let\Edefun = \empty \let\defvar = \empty \let\defvarx = \empty \let\Edefvar = \empty \let\defvr = \empty \let\defvrx = \empty \let\Edefvr = \empty \let\clear = \relax \let\down = \relax \let\evenfooting = \relax \let\evenheading = \relax \let\everyfooting = \relax \let\everyheading = \relax \let\headings = \relax \let\include = \relax \let\item = \relax \let\lowersections = \relax \let\oddfooting = \relax \let\oddheading = \relax \let\printindex = \relax \let\pxref = \relax \let\raisesections = \relax \let\ref = \relax \let\set = \relax \let\setchapternewpage = \relax \let\setchapterstyle = \relax \let\settitle = \relax \let\up = \relax \let\verbatiminclude = \relax \let\xref = \relax } % Ignore @ignore, @ifhtml, @ifinfo, and the like. % \def\direntry{\doignore{direntry}} \def\documentdescriptionword{documentdescription} \def\documentdescription{\doignore{documentdescription}} \def\html{\doignore{html}} \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}} % @dircategory CATEGORY -- specify a category of the dir file % which this file should belong to. Ignore this in TeX. \let\dircategory = \comment % Ignore text until a line `@end #1'. % \def\doignore#1{\begingroup % Don't complain about control sequences we have declared \outer. \ignoresections % % Define a command to swallow text until we reach `@end #1'. % This @ is a catcode 12 token (that is the normal catcode of @ in % this texinfo.tex file). We change the catcode of @ below to match. \long\def\doignoretext##1@end #1{\enddoignore}% % % Make sure that spaces turn into tokens that match what \doignoretext wants. \catcode\spaceChar = 10 % % Ignore braces, too, so mismatched braces don't cause trouble. \catcode`\{ = 9 \catcode`\} = 9 % % We must not have @c interpreted as a control sequence. \catcode`\@ = 12 % \def\ignoreword{#1}% \ifx\ignoreword\documentdescriptionword % The c kludge breaks documentdescription, since % `documentdescription' contains a `c'. Means not everything will % be ignored inside @documentdescription, but oh well... \else % Make the letter c a comment character so that the rest of the line % will be ignored. This way, the document can have (for example) % @c @end ifinfo % and the @end ifinfo will be properly ignored. % (We've just changed @ to catcode 12.) \catcode`\c = 14 \fi % % And now expand the command defined above. \doignoretext } % What we do to finish off ignored text. % \def\enddoignore{\endgroup\ignorespaces}% \newif\ifwarnedobs\warnedobsfalse \def\obstexwarn{% \ifwarnedobs\relax\else % We need to warn folks that they may have trouble with TeX 3.0. % This uses \immediate\write16 rather than \message to get newlines. \immediate\write16{} \immediate\write16{WARNING: for users of Unix TeX 3.0!} \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).} \immediate\write16{If you are running another version of TeX, relax.} \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.} \immediate\write16{ Then upgrade your TeX installation if you can.} \immediate\write16{ (See ftp://ftp.gnu.org/non-gnu/TeX.README.)} \immediate\write16{If you are stuck with version 3.0, run the} \immediate\write16{ script ``tex3patch'' from the Texinfo distribution} \immediate\write16{ to use a workaround.} \immediate\write16{} \global\warnedobstrue \fi } % **In TeX 3.0, setting text in \nullfont hangs tex. For a % workaround (which requires the file ``dummy.tfm'' to be installed), % uncomment the following line: %%%%%\font\nullfont=dummy\let\obstexwarn=\relax % Ignore text, except that we keep track of conditional commands for % purposes of nesting, up to an `@end #1' command. % \def\nestedignore#1{% \obstexwarn % We must actually expand the ignored text to look for the @end % command, so that nested ignore constructs work. Thus, we put the % text into a \vbox and then do nothing with the result. To minimize % the chance of memory overflow, we follow the approach outlined on % page 401 of the TeXbook. % \setbox0 = \vbox\bgroup % Don't complain about control sequences we have declared \outer. \ignoresections % % Define `@end #1' to end the box, which will in turn undefine the % @end command again. \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}% % % We are going to be parsing Texinfo commands. Most cause no % trouble when they are used incorrectly, but some commands do % complicated argument parsing or otherwise get confused, so we % undefine them. % % We can't do anything about stray @-signs, unfortunately; % they'll produce `undefined control sequence' errors. \ignoremorecommands % % Set the current font to be \nullfont, a TeX primitive, and define % all the font commands to also use \nullfont. We don't use % dummy.tfm, as suggested in the TeXbook, because some sites % might not have that installed. Therefore, math mode will still % produce output, but that should be an extremely small amount of % stuff compared to the main input. % \nullfont \let\tenrm=\nullfont \let\tenit=\nullfont \let\tensl=\nullfont \let\tenbf=\nullfont \let\tentt=\nullfont \let\smallcaps=\nullfont \let\tensf=\nullfont % Similarly for index fonts. \let\smallrm=\nullfont \let\smallit=\nullfont \let\smallsl=\nullfont \let\smallbf=\nullfont \let\smalltt=\nullfont \let\smallsc=\nullfont \let\smallsf=\nullfont % Similarly for smallexample fonts. \let\smallerrm=\nullfont \let\smallerit=\nullfont \let\smallersl=\nullfont \let\smallerbf=\nullfont \let\smallertt=\nullfont \let\smallersc=\nullfont \let\smallersf=\nullfont % % Don't complain when characters are missing from the fonts. \tracinglostchars = 0 % % Don't bother to do space factor calculations. \frenchspacing % % Don't report underfull hboxes. \hbadness = 10000 % % Do minimal line-breaking. \pretolerance = 10000 % % Do not execute instructions in @tex. \def\tex{\doignore{tex}}% % Do not execute macro definitions. % `c' is a comment character, so the word `macro' will get cut off. \def\macro{\doignore{ma}}% } % @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. Make sure the catcode of space is correct to avoid % losing inside @example, for instance. % \def\set{\begingroup\catcode` =10 \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. \parsearg\setxxx} \def\setxxx#1{\setyyy#1 \endsetyyy} \def\setyyy#1 #2\endsetyyy{% \def\temp{#2}% \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. \fi \endgroup } % Can't use \xdef to pre-expand #2 and save some time, since \temp or % \next or other control sequences that we've defined might get us into % an infinite loop. Consider `@set foo @cite{bar}'. \def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}} % @clear VAR clears (i.e., unsets) the variable VAR. % \def\clear{\parsearg\clearxxx} \def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax} % @value{foo} gets the text saved in variable foo. { \catcode`\_ = \active % % We might end up with active _ or - characters in the argument if % we're called from @code, as @code{@value{foo-bar_}}. So \let any % such active characters to their normal equivalents. \gdef\value{\begingroup \catcode`\-=\other \catcode`\_=\other \indexbreaks \let_\normalunderscore \valuexxx} } \def\valuexxx#1{\expandablevalue{#1}\endgroup} % We have this subroutine so that we can handle at least some @value's % properly in indexes (we \let\value to this in \indexdummies). Ones % whose names contain - or _ still won't work, but we can't do anything % about that. 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. % \def\ifset{\parsearg\doifset} \def\doifset#1{% \expandafter\ifx\csname SET#1\endcsname\relax \let\next=\ifsetfail \else \let\next=\ifsetsucceed \fi \next } \def\ifsetsucceed{\conditionalsucceed{ifset}} \def\ifsetfail{\nestedignore{ifset}} \defineunmatchedend{ifset} % @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been % defined with @set, or has been undefined with @clear. % \def\ifclear{\parsearg\doifclear} \def\doifclear#1{% \expandafter\ifx\csname SET#1\endcsname\relax \let\next=\ifclearsucceed \else \let\next=\ifclearfail \fi \next } \def\ifclearsucceed{\conditionalsucceed{ifclear}} \def\ifclearfail{\nestedignore{ifclear}} \defineunmatchedend{ifclear} % @iftex, @ifnothtml, @ifnotinfo, @ifnotplaintext always succeed; we % read the text following, through the first @end iftex (etc.). Make % `@end iftex' (etc.) valid only after an @iftex. % \def\iftex{\conditionalsucceed{iftex}} \def\ifnothtml{\conditionalsucceed{ifnothtml}} \def\ifnotinfo{\conditionalsucceed{ifnotinfo}} \def\ifnotplaintext{\conditionalsucceed{ifnotplaintext}} \defineunmatchedend{iftex} \defineunmatchedend{ifnothtml} \defineunmatchedend{ifnotinfo} \defineunmatchedend{ifnotplaintext} % True conditional. Since \set globally defines its variables, we can % just start and end a group (to keep the @end definition undefined at % the outer level). % \def\conditionalsucceed#1{\begingroup \expandafter\def\csname E#1\endcsname{\endgroup}% } % @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 \newindex. {\catcode`\@=11 \gdef\newwrite{\alloc@7\write\chardef\sixt@@n}} % \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 \undefined % 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{% \def\@{@}% change to @@ when we switch to @ as escape char in index files. \def\ {\realbackslash\space }% % Need these in case \tex is in effect and \{ is a \delimiter again. % But can't use \lbracecmd and \rbracecmd because texindex assumes % braces and backslashes are used only as delimiters. \let\{ = \mylbrace \let\} = \myrbrace % % \definedummyword defines \#1 as \realbackslash #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{% \expandafter\def\csname ##1\endcsname{\realbackslash ##1\space}% }% \def\definedummyletter##1{% \expandafter\def\csname ##1\endcsname{\realbackslash ##1}% }% % % Do the redefinitions. \commondummies } % For the aux file, @ is the escape character. So we want to redefine % everything using @ instead of \realbackslash. When everything uses % @, this will be simpler. % \def\atdummies{% \def\@{@@}% \def\ {@ }% \let\{ = \lbraceatcmd \let\} = \rbraceatcmd % % (See comments in \indexdummies.) \def\definedummyword##1{% \expandafter\def\csname ##1\endcsname{@##1\space}% }% \def\definedummyletter##1{% \expandafter\def\csname ##1\endcsname{@##1}% }% % % Do the redefinitions. \commondummies } % Called from \indexdummies and \atdummies. \definedummyword and % \definedummyletter must be defined first. % \def\commondummies{% % \normalturnoffactive % % Control letters and accents. \definedummyletter{_}% \definedummyletter{,}% \definedummyletter{"}% \definedummyletter{`}% \definedummyletter{'}% \definedummyletter{^}% \definedummyletter{~}% \definedummyletter{=}% \definedummyword{u}% \definedummyword{v}% \definedummyword{H}% \definedummyword{dotaccent}% \definedummyword{ringaccent}% \definedummyword{tieaccent}% \definedummyword{ubaraccent}% \definedummyword{udotaccent}% \definedummyword{dotless}% % % Other non-English letters. \definedummyword{AA}% \definedummyword{AE}% \definedummyword{L}% \definedummyword{OE}% \definedummyword{O}% \definedummyword{aa}% \definedummyword{ae}% \definedummyword{l}% \definedummyword{oe}% \definedummyword{o}% \definedummyword{ss}% % % 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}% % % Texinfo font commands. \definedummyword{b}% \definedummyword{i}% \definedummyword{r}% \definedummyword{sc}% \definedummyword{t}% % \definedummyword{TeX}% \definedummyword{acronym}% \definedummyword{cite}% \definedummyword{code}% \definedummyword{command}% \definedummyword{dfn}% \definedummyword{dots}% \definedummyword{emph}% \definedummyword{env}% \definedummyword{file}% \definedummyword{kbd}% \definedummyword{key}% \definedummyword{math}% \definedummyword{option}% \definedummyword{samp}% \definedummyword{strong}% \definedummyword{uref}% \definedummyword{url}% \definedummyword{var}% \definedummyword{w}% % % Assorted special characters. \definedummyword{bullet}% \definedummyword{copyright}% \definedummyword{dots}% \definedummyword{enddots}% \definedummyword{equiv}% \definedummyword{error}% \definedummyword{expansion}% \definedummyword{minus}% \definedummyword{pounds}% \definedummyword{point}% \definedummyword{print}% \definedummyword{result}% % % Handle some cases of @value -- where the variable name does not % contain - or _, and the value does not contain any % (non-fully-expandable) commands. \let\value = \expandablevalue % % Normal spaces, not active ones. \unsepspaces % % No macro expansion. \turnoffmacros } % 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 \ ). {\obeyspaces \gdef\unsepspaces{\obeyspaces\let =\space}} % \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\indexdummytex{TeX} \def\indexdummydots{...} % \def\indexnofonts{% \def\ { }% \def\@{@}% % how to handle braces? \def\_{\normalunderscore}% % \let\,=\asis \let\"=\asis \let\`=\asis \let\'=\asis \let\^=\asis \let\~=\asis \let\==\asis \let\u=\asis \let\v=\asis \let\H=\asis \let\dotaccent=\asis \let\ringaccent=\asis \let\tieaccent=\asis \let\ubaraccent=\asis \let\udotaccent=\asis \let\dotless=\asis % % Other non-English letters. \def\AA{AA}% \def\AE{AE}% \def\L{L}% \def\OE{OE}% \def\O{O}% \def\aa{aa}% \def\ae{ae}% \def\l{l}% \def\oe{oe}% \def\o{o}% \def\ss{ss}% \def\exclamdown{!}% \def\questiondown{?}% % % 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 % % Texinfo font commands. \let\b=\asis \let\i=\asis \let\r=\asis \let\sc=\asis \let\t=\asis % \let\TeX=\indexdummytex \let\acronym=\asis \let\cite=\asis \let\code=\asis \let\command=\asis \let\dfn=\asis \let\dots=\indexdummydots \let\emph=\asis \let\env=\asis \let\file=\asis \let\kbd=\asis \let\key=\asis \let\math=\asis \let\option=\asis \let\samp=\asis \let\strong=\asis \let\uref=\asis \let\url=\asis \let\var=\asis \let\w=\asis } \let\indexbackslash=0 %overridden during \printindex. \let\SETmarginindex=\relax % put index entries in margin (undocumented)? % For \ifx comparisons. \def\emptymacro{\empty} % Most index entries go through here, but \dosubind is the general case. % \def\doind#1#2{\dosubind{#1}{#2}\empty} % 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 defuns, which call us directly. % \def\dosubind#1#2#3{% % Put the index entry in the margin if desired. \ifx\SETmarginindex\relax\else \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}% \fi {% \count255=\lastpenalty {% \indexdummies % Must do this here, since \bf, etc expand at this stage \escapechar=`\\ {% \let\folio = 0% We will expand all macros now EXCEPT \folio. \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now % so it will be output as is; and it will print as backslash. % % The main index entry text. \toks0 = {#2}% % % If third arg is present, precede it with space in sort key. \def\thirdarg{#3}% \ifx\thirdarg\emptymacro \else % If the third (subentry) arg is present, add it to the index % line to write. \toks0 = \expandafter{\the\toks0 \space #3}% \fi % % 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\csname#1indfile\endcsname{% \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}% }% % % 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 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. % \iflinks \ifvmode \skip0 = \lastskip \ifdim\lastskip = 0pt \else \nobreak\vskip-\skip0 \fi \fi % \temp % do the write % \ifvmode \ifdim\skip0 = 0pt \else \nobreak\vskip\skip0 \fi \fi \fi }% }% \penalty\count255 }% } % 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). % \def\printindex{\parsearg\doprintindex} \def\doprintindex#1{\begingroup \dobreak \chapheadingskip{10000}% % \smallfonts \rm \tolerance = 9500 \everypar = {}% don't want the \kern\-parindent from indentation suppression. \indexbreaks % % 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{\rawbackslashxx}% \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. \penalty -300 % % 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}% \vskip .33\baselineskip plus .1\baselineskip % % Do our best not to break after the initial. \nobreak }} % This typesets a paragraph consisting of #1, dot leaders, and then #2 % flush to the right margin. It is used for index and table of contents % entries. The paragraph is indented by \leftskip. % \def\entry#1#2{\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 % % Start a ``paragraph'' for the index entry so the line breaking % parameters we've set above will have an effect. \noindent % % Insert the text of the index entry. TeX will do line-breaking on it. #1% % 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. \def\tempa{{\rm }}% \def\tempb{#2}% \edef\tempc{\tempa}% \edef\tempd{\tempb}% \ifx\tempc\tempd\ \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#2.\ \the\toksA % The page number ends the paragraph. \else \ #2% The page number ends the paragraph. \fi \fi% \par \endgroup} % Like \dotfill except takes at least 1 em. \def\indexdotfill{\cleaders \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \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{% \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. \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 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 this as the name of the chapter. % page headings and footings can use it. @section does likewise. \def\thischapter{} \def\thissection{} \newcount\absseclevel % used to calculate proper heading level \newcount\secbase\secbase=0 % @raise/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 % Choose a numbered-heading macro % #1 is heading level if unmodified by @raisesections or @lowersections % #2 is text for heading \def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \chapterzzz{#2} \or \seczzz{#2} \or \numberedsubseczzz{#2} \or \numberedsubsubseczzz{#2} \else \ifnum \absseclevel<0 \chapterzzz{#2} \else \numberedsubsubseczzz{#2} \fi \fi \suppressfirstparagraphindent } % like \numhead, but chooses appendix heading levels \def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \appendixzzz{#2} \or \appendixsectionzzz{#2} \or \appendixsubseczzz{#2} \or \appendixsubsubseczzz{#2} \else \ifnum \absseclevel<0 \appendixzzz{#2} \else \appendixsubsubseczzz{#2} \fi \fi \suppressfirstparagraphindent } % like \numhead, but chooses numberless heading levels \def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \unnumberedzzz{#2} \or \unnumberedseczzz{#2} \or \unnumberedsubseczzz{#2} \or \unnumberedsubsubseczzz{#2} \else \ifnum \absseclevel<0 \unnumberedzzz{#2} \else \unnumberedsubsubseczzz{#2} \fi \fi \suppressfirstparagraphindent } % @chapter, @appendix, @unnumbered. \def\thischaptername{No Chapter Title} \outer\def\chapter{\parsearg\chapteryyy} \def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz \def\chapterzzz #1{% \secno=0 \subsecno=0 \subsubsecno=0 \global\advance \chapno by 1 \message{\putwordChapter\space \the\chapno}% \chapmacro {#1}{\the\chapno}% \gdef\thissection{#1}% \gdef\thischaptername{#1}% % We don't substitute the actual chapter name into \thischapter % because we don't want its macros evaluated now. \xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}% \writetocentry{chap}{#1}{{\the\chapno}} \donoderef \global\let\section = \numberedsec \global\let\subsection = \numberedsubsec \global\let\subsubsection = \numberedsubsubsec } % we use \chapno to avoid indenting back \def\appendixbox#1{% \setbox0 = \hbox{\putwordAppendix{} \the\chapno}% \hbox to \wd0{#1\hss}} \outer\def\appendix{\parsearg\appendixyyy} \def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz \def\appendixzzz #1{% \secno=0 \subsecno=0 \subsubsecno=0 \global\advance \appendixno by 1 \message{\putwordAppendix\space \appendixletter}% \chapmacro {#1}{\appendixbox{\putwordAppendix{} \appendixletter}}% \gdef\thissection{#1}% \gdef\thischaptername{#1}% \xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}% \writetocentry{appendix}{#1}{{\appendixletter}} \appendixnoderef \global\let\section = \appendixsec \global\let\subsection = \appendixsubsec \global\let\subsubsection = \appendixsubsubsec } % @centerchap is like @unnumbered, but the heading is centered. \outer\def\centerchap{\parsearg\centerchapyyy} \def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}} % @top is like @unnumbered. \outer\def\top{\parsearg\unnumberedyyy} \outer\def\unnumbered{\parsearg\unnumberedyyy} \def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz \def\unnumberedzzz #1{% \secno=0 \subsecno=0 \subsubsecno=0 % % 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)}% % \unnumbchapmacro {#1}% \gdef\thischapter{#1}\gdef\thissection{#1}% \writetocentry{unnumbchap}{#1}{{\the\chapno}} \unnumbnoderef \global\let\section = \unnumberedsec \global\let\subsection = \unnumberedsubsec \global\let\subsubsection = \unnumberedsubsubsec } % Sections. \outer\def\numberedsec{\parsearg\secyyy} \def\secyyy #1{\numhead1{#1}} % normally calls seczzz \def\seczzz #1{% \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % \gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}% \writetocentry{sec}{#1}{{\the\chapno}{\the\secno}} \donoderef \nobreak } \outer\def\appendixsection{\parsearg\appendixsecyyy} \outer\def\appendixsec{\parsearg\appendixsecyyy} \def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz \def\appendixsectionzzz #1{% \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % \gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}% \writetocentry{sec}{#1}{{\appendixletter}{\the\secno}} \appendixnoderef \nobreak } \outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} \def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz \def\unnumberedseczzz #1{% \plainsecheading {#1}\gdef\thissection{#1}% \writetocentry{unnumbsec}{#1}{{\the\chapno}{\the\secno}} \unnumbnoderef \nobreak } % Subsections. \outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} \def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz \def\numberedsubseczzz #1{% \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % \subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}% \writetocentry{subsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}} \donoderef \nobreak } \outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} \def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz \def\appendixsubseczzz #1{% \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % \subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}% \writetocentry{subsec}{#1}{{\appendixletter}{\the\secno}{\the\subsecno}} \appendixnoderef \nobreak } \outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} \def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz \def\unnumberedsubseczzz #1{% \plainsubsecheading {#1}\gdef\thissection{#1}% \writetocentry{unnumbsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}} \unnumbnoderef \nobreak } % Subsubsections. \outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} \def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz \def\numberedsubsubseczzz #1{% \gdef\thissection{#1}\global\advance \subsubsecno by 1 % \subsubsecheading {#1} {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}% \writetocentry{subsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}} \donoderef \nobreak } \outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} \def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz \def\appendixsubsubseczzz #1{% \gdef\thissection{#1}\global\advance \subsubsecno by 1 % \subsubsecheading {#1} {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}% \writetocentry{subsubsec}{#1}{{\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}} \appendixnoderef \nobreak } \outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} \def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz \def\unnumberedsubsubseczzz #1{% \plainsubsubsecheading {#1}\gdef\thissection{#1}% \writetocentry{unnumbsubsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}} \unnumbnoderef \nobreak } % These are variants which are not "outer", so they can appear in @ifinfo. % Actually, they should now be obsolete; ordinary section commands should work. \def\infotop{\parsearg\unnumberedzzz} \def\infounnumbered{\parsearg\unnumberedzzz} \def\infounnumberedsec{\parsearg\unnumberedseczzz} \def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} \def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} \def\infoappendix{\parsearg\appendixzzz} \def\infoappendixsec{\parsearg\appendixseczzz} \def\infoappendixsubsec{\parsearg\appendixsubseczzz} \def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} \def\infochapter{\parsearg\chapterzzz} \def\infosection{\parsearg\sectionzzz} \def\infosubsection{\parsearg\subsectionzzz} \def\infosubsubsection{\parsearg\subsubsectionzzz} % 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. \global\let\section = \numberedsec \global\let\subsection = \numberedsubsec \global\let\subsubsection = \numberedsubsubsec % Define @majorheading, @heading and @subheading % NOTE on use of \vbox for chapter headings, section headings, and such: % 1) We use \vbox rather than the earlier \line to permit % overlong headings to fold. % 2) \hyphenpenalty is set to 10000 because hyphenation in a % heading is obnoxious; this forbids it. % 3) Likewise, headings look best if no \parindent is used, and % if justification is not attempted. Hence \raggedright. \def\majorheading{\parsearg\majorheadingzzz} \def\majorheadingzzz #1{% {\advance\chapheadingskip by 10pt \chapbreak }% {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\penalty 200} \def\chapheading{\parsearg\chapheadingzzz} \def\chapheadingzzz #1{\chapbreak % {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\penalty 200} % @heading, @subheading, @subsubheading. \def\heading{\parsearg\plainsecheading} \def\subheading{\parsearg\plainsubsecheading} \def\subsubheading{\parsearg\plainsubsubsecheading} % 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} \def\setchapterstyle #1 {\csname CHAPF#1\endcsname} %%% Define plain chapter starts, and page on/off switching for it % Parameter controlling skip before chapter headings (if needed) \newskip\chapheadingskip \def\chapbreak{\dobreak \chapheadingskip {-4000}} \def\chappager{\par\vfill\supereject} \def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\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 \def\CHAPFplain{ \global\let\chapmacro=\chfplain \global\let\unnumbchapmacro=\unnchfplain \global\let\centerchapmacro=\centerchfplain} % Plain chapter opening. % #1 is the text, #2 the chapter number or empty if unnumbered. \def\chfplain#1#2{% \pchapsepmacro {% \chapfonts \rm \def\chapnum{#2}% \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}% \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright \hangindent = \wd0 \centerparametersmaybe \unhbox0 #1\par}% }% \nobreak\bigskip % no page break after a chapter title \nobreak } % Plain opening for unnumbered. \def\unnchfplain#1{\chfplain{#1}{}} % @centerchap -- centered and unnumbered. \let\centerparametersmaybe = \relax \def\centerchfplain#1{{% \def\centerparametersmaybe{% \advance\rightskip by 3\rightskip \leftskip = \rightskip \parfillskip = 0pt }% \chfplain{#1}{}% }} \CHAPFplain % The default \def\unnchfopen #1{% \chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\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 {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt \hfill {\rm #1}\hfill}}\bigskip \par\nobreak } \def\CHAPFopen{ \global\let\chapmacro=\chfopen \global\let\unnumbchapmacro=\unnchfopen \global\let\centerchapmacro=\centerchfopen} % Section titles. \newskip\secheadingskip \def\secheadingbreak{\dobreak \secheadingskip {-1000}} \def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}} \def\plainsecheading#1{\sectionheading{sec}{}{#1}} % Subsection titles. \newskip \subsecheadingskip \def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}} \def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}} \def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}} % Subsubsection titles. \let\subsubsecheadingskip = \subsecheadingskip \let\subsubsecheadingbreak = \subsecheadingbreak \def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}} \def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}} % Print any size section title. % % #1 is the section type (sec/subsec/subsubsec), #2 is the section % number (maybe empty), #3 the text. \def\sectionheading#1#2#3{% {% \expandafter\advance\csname #1headingskip\endcsname by \parskip \csname #1headingbreak\endcsname }% {% % Switch to the right set of fonts. \csname #1fonts\endcsname \rm % % Only insert the separating space if we have a section number. \def\secnum{#2}% \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}% % \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright \hangindent = \wd0 % zero if no section number \unhbox0 #3}% }% % Add extra space after the heading -- either a line space or a % paragraph space, whichever is more. (Some people like to set % \parskip to large values for some reason.) Don't allow stretch, though. \nobreak \ifdim\parskip>\normalbaselineskip \kern\parskip \else \kern\normalbaselineskip \fi \nobreak } \message{toc,} % Table of contents. \newwrite\tocfile % Write an entry to the toc file, opening it if necessary. % Called from @chapter, etc. We supply {\folio} at the end of the % argument, which will end up as the last argument to the \...entry macro. % % Usage: \writetocentry{chap}{The Name of The Game}{{\the\chapno}} % 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. % \newif\iftocfileopened \def\writetocentry#1#2#3{% \iftocfileopened\else \immediate\openout\tocfile = \jobname.toc \global\tocfileopenedtrue \fi % \iflinks \toks0 = {#2}% \edef\temp{\write\tocfile{\realbackslash #1entry{\the\toks0}#3{\folio}}}% \temp \fi % % Tell \shipout to create a page destination if we're doing pdf, which % will be the target of the links in the table of contents. We can't % just do it 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 \pdfmakepagedesttrue \fi } \newskip\contentsrightmargin \contentsrightmargin=1in \newcount\savepageno \newcount\lastnegativepageno \lastnegativepageno = -1 % Finish up the main text and 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. \unnumbchapmacro{#1}\def\thischapter{}% \savepageno = \pageno \begingroup % Set up to handle contents files properly. \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 % We can't do this, because then an actual ^ in a section % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97. %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi \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 } % Normal (long) toc. \def\contents{% \startcontents{\putwordTOC}% \openin 1 \jobname.toc \ifeof 1 \else \closein 1 \input \jobname.toc \fi \vfill \eject \contentsalignmacro % in case @setchapternewpage odd is in effect \pdfmakeoutlines \endgroup \lastnegativepageno = \pageno \global\pageno = \savepageno } % And just the chapters. \def\summarycontents{% \startcontents{\putwordShortTOC}% % \let\chapentry = \shortchapentry \let\appendixentry = \shortappendixentry \let\unnumbchapentry = \shortunnumberedentry % 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\secentry ##1##2##3##4{} \def\subsecentry ##1##2##3##4##5{} \def\subsubsecentry ##1##2##3##4##5##6{} \let\unnumbsecentry = \secentry \let\unnumbsubsecentry = \subsecentry \let\unnumbsubsubsecentry = \subsubsecentry \openin 1 \jobname.toc \ifeof 1 \else \closein 1 \input \jobname.toc \fi \vfill \eject \contentsalignmacro % in case @setchapternewpage odd is in effect \endgroup \lastnegativepageno = \pageno \global\pageno = \savepageno } \let\shortcontents = \summarycontents \ifpdf \pdfcatalog{/PageMode /UseOutlines}% \fi % 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, ... % Chapters, in the main contents. \def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}} % % Chapters, in the short toc. % See comments in \dochapentry re vbox and related settings. \def\shortchapentry#1#2#3{% \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#3\egroup}% } % Appendices, in the main contents. \def\appendixentry#1#2#3{% \dochapentry{\appendixbox{\putwordAppendix{} #2}\labelspace#1}{#3}} % % Appendices, in the short toc. \let\shortappendixentry = \shortchapentry % Typeset the label for a chapter or appendix for the short contents. % The arg is, e.g., `Appendix A' for an appendix, or `3' for a chapter. % We could simplify the code here by writing out an \appendixentry % command in the toc file for appendices, instead of using \chapentry % for both, but it doesn't seem worth it. % \newdimen\shortappendixwidth % \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.) \dimen0 = 1em \hbox to \dimen0{#1\hss}% } % Unnumbered chapters. \def\unnumbchapentry#1#2#3{\dochapentry{#1}{#3}} \def\shortunnumberedentry#1#2#3{\tocentry{#1}{\doshortpageno\bgroup#3\egroup}} % Sections. \def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}} \def\unnumbsecentry#1#2#3#4{\dosecentry{#1}{#4}} % Subsections. \def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}} \def\unnumbsubsecentry#1#2#3#4#5{\dosubsecentry{#1}{#5}} % And subsubsections. \def\subsubsecentry#1#2#3#4#5#6{% \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}} \def\unnumbsubsubsecentry#1#2#3#4#5#6{\dosubsubsecentry{#1}{#6}} % This parameter controls the indentation of the various levels. \newdimen\tocindent \tocindent = 3pc % 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} % Final typesetting of a toc entry; we use the same \entry macro as for % the index entries, but we want to suppress hyphenation here. (We % can't do that in the \entry macro, since index entries might consist % of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) \def\tocentry#1#2{\begingroup \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks % Do not use \turnoffactive in these arguments. Since the toc is % typeset in cmr, characters such as _ would come out wrong; we % have to do the usual translation tricks. \entry{#1}{#2}% \endgroup} % 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} \let\subsecentryfonts = \textfonts \let\subsubsecentryfonts = \textfonts \message{environments,} % @foo ... @end foo. % @point{}, @result{}, @expansion{}, @print{}, @equiv{}. % % Since these characters are used in examples, it should be an even number of % \tt widths. Each \tt character is 1en, so two makes it 1em. % \def\point{$\star$} \def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} \def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} \def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} \def\equiv{\leavevmode\lower.1ex\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 \tensf error\kern-1.5pt} % \global\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} % @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 tex @ character. \def\tex{\begingroup \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 \escapechar=`\\ % \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\{=\ptexlbrace \let\+=\tabalign \let\}=\ptexrbrace \let\/=\ptexslash \let\*=\ptexstar \let\t=\ptext % \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% \def\@{@}% \let\Etex=\endgroup} % Define @lisp ... @end lisp. % @lisp does a \begingroup 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} % 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. % {\obeyspaces % \gdef\sepspaces{\obeyspaces\let =\tie}} % Define \obeyedspace to be our active space, whatever it is. This is % for use in \parsearg. {\sepspaces% \global\let\obeyedspace= } % 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, 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 \else \penalty-50 \fi \vskip\envskipamount \fi \fi }} \let\afterenvbreak = \aboveenvbreak % \nonarrowing is a flag. If "set", @lisp etc don't narrow margins. \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 \def\cartouche{% \par % can't be in the midst of a paragraph. \begingroup \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=\comment \vbox\bgroup \baselineskip=0pt\parskip=0pt\lineskip=0pt \carttop \hbox\bgroup \hskip\lskip \vrule\kern3pt \vbox\bgroup \hsize=\cartinner \kern3pt \begingroup \baselineskip=\normbskip \lineskip=\normlskip \parskip=\normpskip \vskip -\parskip \def\Ecartouche{% \endgroup \kern3pt \egroup \kern3pt\vrule \hskip\rskip \egroup \cartbot \egroup \endgroup }} % This macro is called at the beginning of all the @example variants, % inside a group. \def\nonfillstart{% \aboveenvbreak \inENV % This group ends at the end of the body \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 \parindent = 0pt \emergencystretch = 0pt % don't try to avoid overfull boxes % @cartouche defines \nonarrowing to inhibit narrowing % at next level down. \ifx\nonarrowing\relax \advance \leftskip by \lispnarrowing \exdentamount=\lispnarrowing \let\exdent=\nofillexdent \let\nonarrowing=\relax \fi } % Define the \E... control sequence only if we are inside the particular % environment, so the error checking in \end will work. % % To end an @example-like environment, we first end the paragraph (via % \afterenvbreak's vertical glue), and then the group. That way we keep % the zero \parskip that the environments set -- \parskip glue will be % inserted at the beginning of the next paragraph in the document, after % the environment. % \def\nonfillfinish{\afterenvbreak\endgroup} % @lisp: indented, narrowed, typewriter font. \def\lisp{\begingroup \nonfillstart \let\Elisp = \nonfillfinish \tt \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. \gobble % eat return } % @example: Same as @lisp. \def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} % @smallexample and @smalllisp: use smaller fonts. % Originally contributed by Pavel@xerox. \def\smalllisp{\begingroup \def\Esmalllisp{\nonfillfinish\endgroup}% \def\Esmallexample{\nonfillfinish\endgroup}% \smallexamplefonts \lisp } \let\smallexample = \smalllisp % @display: same as @lisp except keep current font. % \def\display{\begingroup \nonfillstart \let\Edisplay = \nonfillfinish \gobble } % % @smalldisplay: @display plus smaller fonts. % \def\smalldisplay{\begingroup \def\Esmalldisplay{\nonfillfinish\endgroup}% \smallexamplefonts \rm \display } % @format: same as @display except don't narrow margins. % \def\format{\begingroup \let\nonarrowing = t \nonfillstart \let\Eformat = \nonfillfinish \gobble } % % @smallformat: @format plus smaller fonts. % \def\smallformat{\begingroup \def\Esmallformat{\nonfillfinish\endgroup}% \smallexamplefonts \rm \format } % @flushleft (same as @format). % \def\flushleft{\begingroup \def\Eflushleft{\nonfillfinish\endgroup}\format} % @flushright. % \def\flushright{\begingroup \let\nonarrowing = t \nonfillstart \let\Eflushright = \nonfillfinish \advance\leftskip by 0pt plus 1fill \gobble } % @quotation does normal linebreaking (hence we can't use \nonfillstart) % and narrows the margins. % \def\quotation{% \begingroup\inENV %This group ends at the end of the @quotation body {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip \parindent=0pt % We have retained a nonzero parskip for the environment, since we're % doing normal filling. So to avoid extra space below the environment... \def\Equotation{\parskip = 0pt \nonfillfinish}% % % @cartouche defines \nonarrowing to inhibit narrowing at next level down. \ifx\nonarrowing\relax \advance\leftskip by \lispnarrowing \advance\rightskip by \lispnarrowing \exdentamount = \lispnarrowing \let\nonarrowing = \relax \fi } % 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\"% } % % [Knuth] p. 380 \def\uncatcodespecials{% \def\do##1{\catcode`##1=12}\dospecials} % % [Knuth] pp. 380,381,391 % Disable Spanish ligatures ?` and !` of \tt font \begingroup \catcode`\`=\active\gdef`{\relax\lq} \endgroup % % 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}% \catcode`\`=\active \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 % \def\starttabbox{\setbox0=\hbox\bgroup} \begingroup \catcode`\^^I=\active \gdef\tabexpand{% \catcode`\^^I=\active \def^^I{\leavevmode\egroup \dimen0=\wd0 % the width so far, or since the previous tab \divide\dimen0 by\tabw \multiply\dimen0 by\tabw % compute previous multiple of \tabw \advance\dimen0 by\tabw % advance to next multiple of \tabw \wd0=\dimen0 \box0 \starttabbox }% } \endgroup \def\setupverbatim{% % Easiest (and conventionally used) font for verbatim \tt \def\par{\leavevmode\egroup\box0\endgraf}% \catcode`\`=\active \tabexpand % 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`\{=12\catcode`\}=12 \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] %% Include LaTeX hack for completeness -- never know %% \begingroup %% \catcode`|=0 \catcode`[=1 %% \catcode`]=2\catcode`\{=12\catcode`\}=12\catcode`\ =\active %% \catcode`\\=12|gdef|doverbatim#1@end verbatim[ %% #1|endgroup|def|Everbatim[]|end[verbatim]] %% |endgroup % \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. \gdef\doverbatim#1^^M#2@end verbatim{#2\end{verbatim}}% \endgroup % \def\verbatim{% \def\Everbatim{\nonfillfinish\endgroup}% \begingroup \nonfillstart \advance\leftskip by -\defbodyindent \begingroup\setupverbatim\doverbatim } % @verbatiminclude FILE - insert text of file in verbatim environment. % % Allow normal characters that we make active in the argument (a file name). \def\verbatiminclude{% \begingroup \catcode`\\=\other \catcode`~=\other \catcode`^=\other \catcode`_=\other \catcode`|=\other \catcode`<=\other \catcode`>=\other \catcode`+=\other \parsearg\doverbatiminclude } \def\setupverbatiminclude{% \begingroup \nonfillstart \advance\leftskip by -\defbodyindent \begingroup\setupverbatim } % \def\doverbatiminclude#1{% % Restore active chars for included file. \endgroup \begingroup \let\value=\expandablevalue \def\thisfile{#1}% \expandafter\expandafter\setupverbatiminclude\input\thisfile \endgroup \nonfillfinish \endgroup } % @copying ... @end copying. % Save the text away for @insertcopying later. Many commands won't be % allowed in this context, but that's ok. % % 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{\begingroup % Define a command to swallow text until we reach `@end copying'. % \ is the escape char in this texinfo.tex file, so it is the % delimiter for the command; @ will be the escape char when we read % it, but that doesn't matter. \long\def\docopying##1\end copying{\gdef\copyingtext{##1}\enddocopying}% % % We must preserve ^^M's in the input file; see \insertcopying below. \catcode`\^^M = \active \docopying } % What we do to finish off the copying text. % \def\enddocopying{\endgroup\ignorespaces} % @insertcopying. Here we must play games with ^^M's. On the one hand, % we need them to delimit commands such as `@end quotation', so they % must be active. On the other hand, we certainly don't want every % end-of-line to be a \par, as would happen with the normal active % definition of ^^M. On the third hand, two ^^M's in a row should still % generate a \par. % % Our approach is to make ^^M insert a space and a penalty1 normally; % then it can also check if \lastpenalty=1. If it does, then manually % do \par. % % This messes up the normal definitions of @c[omment], so we redefine % it. Similarly for @ignore. (These commands are used in the gcc % manual for man page generation.) % % Seems pretty fragile, most line-oriented commands will presumably % fail, but for the limited use of getting the copying text (which % should be quite simple) inserted, we can hope it's ok. % {\catcode`\^^M=\active % \gdef\insertcopying{\begingroup % \parindent = 0pt % looks wrong on title page \def^^M{% \ifnum \lastpenalty=1 % \par % \else % \space \penalty 1 % \fi % }% % % Fix @c[omment] for catcode 13 ^^M's. \def\c##1^^M{\ignorespaces}% \let\comment = \c % % % Don't bother jumping through all the hoops that \doignore does, it % would be very hard since the catcodes are already set. \long\def\ignore##1\end ignore{\ignorespaces}% % \copyingtext % \endgroup}% } \message{defuns,} % @defun etc. % Allow user to change definition object font (\df) internally \def\setdeffont#1 {\csname DEF#1\endcsname} \newskip\defbodyindent \defbodyindent=.4in \newskip\defargsindent \defargsindent=50pt \newskip\deflastargmargin \deflastargmargin=18pt \newcount\parencount % 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 = ) {\activeparens % Now, smart parens don't turn on until &foo (see \amprm) % 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. \global\let(=\lparen \global\let)=\rparen \global\let[=\lbrack \global\let]=\rbrack \gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} % This is used to turn on special parens % but make & act ordinary (given that it's active). \gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr} % Definitions of (, ) and & used in args for functions. % This is the definition of ( outside of all parentheses. \gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested \global\advance\parencount by 1 } % % This is the definition of ( when already inside a level of parens. \gdef\opnested{\char`\(\global\advance\parencount by 1 } % \gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. % also in that case restore the outer-level definition of (. \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi \global\advance \parencount by -1 } % If we encounter &foo, then turn on ()-hacking afterwards \gdef\amprm#1 {{\rm\}\let(=\oprm \let)=\clrm\ } % \gdef\normalparens{\boldbrax\let&=\ampnr} } % End of definition inside \activeparens %% These parens (in \boldbrax) actually are a little bolder than the %% contained text. This is especially needed for [ and ] \def\opnr{{\sf\char`\(}\global\advance\parencount by 1 } \def\clnr{{\sf\char`\)}\global\advance\parencount by -1 } \let\ampnr = \& \def\lbrb{{\bf\char`\[}} \def\rbrb{{\bf\char`\]}} % Active &'s sneak into the index arguments, so make sure it's defined. { \catcode`& = \active \global\let& = \ampnr } % \defname, which formats the name of the @def (not the args). % #1 is the function name. % #2 is the type of definition, such as "Function". % \def\defname#1#2{% % How we'll output the type name. Putting it in brackets helps % distinguish it from the body text that may end up on the next line % just below it. \ifempty{#2}% \def\defnametype{}% \else \def\defnametype{[\rm #2]}% \fi % % Get the values of \leftskip and \rightskip as they were outside the @def... \dimen2=\leftskip \advance\dimen2 by -\defbodyindent % % Figure out values for the paragraph shape. \setbox0=\hbox{\hskip \deflastargmargin{\defnametype}}% \dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line \dimen1=\hsize \advance \dimen1 by -\defargsindent % size for continuations \parshape 2 0in \dimen0 \defargsindent \dimen1 % % Output arg 2 ("Function" or some such) but stuck inside a box of % width 0 so it does not interfere with linebreaking. \noindent % {% Adjust \hsize to exclude the ambient margins, % so that \rightline will obey them. \advance \hsize by -\dimen2 \dimen3 = 0pt % was -1.25pc \rlap{\rightline{\defnametype\kern\dimen3}}% }% % % Allow all lines to be underfull without complaint: \tolerance=10000 \hbadness=10000 \advance\leftskip by -\defbodyindent \exdentamount=\defbodyindent {\df #1}\enskip % output function name % \defunargs will be called next to output the arguments, if any. } % Common pieces to start any @def... % #1 is the \E... control sequence to end the definition (which we define). % #2 is the \...x control sequence (which our caller defines). % #3 is the control sequence to process the header, such as \defunheader. % \def\parsebodycommon#1#2#3{% \begingroup\inENV % 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 want to allow a % break after all. Check for penalty 10002 (inserted by % \defargscommonending) instead of 10000, since the sectioning % commands insert a \penalty10000, and we don't want to allow a break % between a section heading and a defun. \ifnum\lastpenalty=10002 \penalty0 \fi \medbreak % % Define the \E... end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% % \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent } % Common part of the \...x definitions. % \def\defxbodycommon{% % As with \parsebodycommon above, allow line break if we have multiple % x headers in a row. It's not a great place, though. \ifnum\lastpenalty=10000 \penalty1000 \fi % \begingroup\obeylines } % Process body of @defun, @deffn, @defmac, etc. % \def\defparsebody#1#2#3{% \parsebodycommon{#1}{#2}{#3}% \def#2{\defxbodycommon \activeparens \spacesplit#3}% \catcode\equalChar=\active \begingroup\obeylines\activeparens \spacesplit#3% } % #1, #2, #3 are the common arguments (see \parsebodycommon above). % #4, delimited by the space, is the class name. % \def\defmethparsebody#1#2#3#4 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 {\defxbodycommon \activeparens \spacesplit{#3{##1}}}% \begingroup\obeylines\activeparens % The \empty here prevents misinterpretation of a construct such as % @deffn {whatever} {Enharmonic comma} % See comments at \deftpparsebody, although in our case we don't have % to remove the \empty afterwards, since it is empty. \spacesplit{#3{#4}}\empty } % Used for @deftypemethod and @deftypeivar. % #1, #2, #3 are the common arguments (see \defparsebody). % #4, delimited by a space, is the class name. % #5 is the method's return type. % \def\deftypemethparsebody#1#2#3#4 #5 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 ##2 {\defxbodycommon \activeparens \spacesplit{#3{##1}{##2}}}% \begingroup\obeylines\activeparens \spacesplit{#3{#4}{#5}}% } % Used for @deftypeop. The change from \deftypemethparsebody is an % extra argument at the beginning which is the `category', instead of it % being the hardwired string `Method' or `Instance Variable'. We have % to account for this both in the \...x definition and in parsing the % input at hand. Thus also need a control sequence (passed as #5) for % the \E... definition to assign the category name to. % \def\deftypeopparsebody#1#2#3#4#5 #6 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 ##2 ##3 {\def#4{##1}% \defxbodycommon \activeparens \spacesplit{#3{##2}{##3}}}% \begingroup\obeylines\activeparens \spacesplit{#3{#5}{#6}}% } % For @defop. \def\defopparsebody #1#2#3#4#5 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 ##2 {\def#4{##1}% \defxbodycommon \activeparens \spacesplit{#3{##2}}}% \begingroup\obeylines\activeparens \spacesplit{#3{#5}}% } % These parsing functions are similar to the preceding ones % except that they do not make parens into active characters. % These are used for "variables" since they have no arguments. % \def\defvarparsebody #1#2#3{% \parsebodycommon{#1}{#2}{#3}% \def#2{\defxbodycommon \spacesplit#3}% \catcode\equalChar=\active \begingroup\obeylines \spacesplit#3% } % @defopvar. \def\defopvarparsebody #1#2#3#4#5 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 ##2 {\def#4{##1}% \defxbodycommon \spacesplit{#3{##2}}}% \begingroup\obeylines \spacesplit{#3{#5}}% } \def\defvrparsebody#1#2#3#4 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 {\defxbodycommon \spacesplit{#3{##1}}}% \begingroup\obeylines \spacesplit{#3{#4}}% } % This loses on `@deftp {Data Type} {struct termios}' -- it thinks the % type is just `struct', because we lose the braces in `{struct % termios}' when \spacesplit reads its undelimited argument. Sigh. % \let\deftpparsebody=\defvrparsebody % % So, to get around this, we put \empty in with the type name. That % way, TeX won't find exactly `{...}' as an undelimited argument, and % won't strip off the braces. % \def\deftpparsebody #1#2#3#4 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 {\defxbodycommon \spacesplit{#3{##1}}}% \begingroup\obeylines \spacesplit{\parsetpheaderline{#3{#4}}}\empty } % Fine, but then we have to eventually remove the \empty *and* the % braces (if any). That's what this does. % \def\removeemptybraces\empty#1\relax{#1} % After \spacesplit has done its work, this is called -- #1 is the final % thing to call, #2 the type name (which starts with \empty), and #3 % (which might be empty) the arguments. % \def\parsetpheaderline#1#2#3{% #1{\removeemptybraces#2\relax}{#3}% }% % Split up #2 (the rest of the input line) at the first space token. % call #1 with two arguments: % the first is all of #2 before the space token, % the second is all of #2 after that space token. % If #2 contains no space token, all of it is passed as the first arg % and the second is passed as empty. % {\obeylines % \gdef\spacesplit#1#2^^M{\endgroup\spacesplitx{#1}#2 \relax\spacesplitx}% \long\gdef\spacesplitx#1#2 #3#4\spacesplitx{% \ifx\relax #3% #1{#2}{}% \else % #1{#2}{#3#4}% \fi}% } % Define @defun. % This is called to end the arguments processing for all the @def... commands. % \def\defargscommonending{% \interlinepenalty = 10000 \advance\rightskip by 0pt plus 1fil \endgraf \nobreak\vskip -\parskip \penalty 10002 % signal to \parsebodycommon. } % This expands the args and terminates the paragraph they comprise. % \def\defunargs#1{\functionparens \sl % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. % Set the font temporarily and use \font in case \setfont made \tensl a macro. {\tensl\hyphenchar\font=0}% #1% {\tensl\hyphenchar\font=45}% \ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi% \defargscommonending } \def\deftypefunargs #1{% % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. % Use \boldbraxnoamp, not \functionparens, so that & is not special. \boldbraxnoamp \tclose{#1}% avoid \code because of side effects on active chars \defargscommonending } % Do complete processing of one @defun or @defunx line already parsed. % @deffn Command forward-char nchars \def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} \def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% \begingroup\defname {#2}{#1}\defunargs{#3}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @defun == @deffn Function \def\defun{\defparsebody\Edefun\defunx\defunheader} \def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{\putwordDeffunc}% \defunargs {#2}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @deftypefun int foobar (int @var{foo}, float @var{bar}) \def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader} % #1 is the data type. #2 is the name and args. \def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax} % #1 is the data type, #2 the name, #3 the args. \def\deftypefunheaderx #1#2 #3\relax{% \doind {fn}{\code{#2}}% Make entry in function index \begingroup\defname {\defheaderxcond#1\relax$.$#2}{\putwordDeftypefun}% \deftypefunargs {#3}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) \def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} % \defheaderxcond#1\relax$.$ % puts #1 in @code, followed by a space, but does nothing if #1 is null. \def\defheaderxcond#1#2$.${\ifx#1\relax\else\code{#1#2} \fi} % #1 is the classification. #2 is the data type. #3 is the name and args. \def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} % #1 is the classification, #2 the data type, #3 the name, #4 the args. \def\deftypefnheaderx #1#2#3 #4\relax{% \doind {fn}{\code{#3}}% Make entry in function index \begingroup \normalparens % notably, turn off `&' magic, which prevents % at least some C++ text from working \defname {\defheaderxcond#2\relax$.$#3}{#1}% \deftypefunargs {#4}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @defmac == @deffn Macro \def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} \def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{\putwordDefmac}% \defunargs {#2}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @defspec == @deffn Special Form \def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} \def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{\putwordDefspec}% \defunargs {#2}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @defop CATEGORY CLASS OPERATION ARG... % \def\defop #1 {\def\defoptype{#1}% \defopparsebody\Edefop\defopx\defopheader\defoptype} % \def\defopheader#1#2#3{% \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% function index entry \begingroup \defname{#2}{\defoptype\ \putwordon\ #1}% \defunargs{#3}% \endgroup } % @deftypeop CATEGORY CLASS TYPE OPERATION ARG... % \def\deftypeop #1 {\def\deftypeopcategory{#1}% \deftypeopparsebody\Edeftypeop\deftypeopx\deftypeopheader \deftypeopcategory} % % #1 is the class name, #2 the data type, #3 the operation name, #4 the args. \def\deftypeopheader#1#2#3#4{% \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index \begingroup \defname{\defheaderxcond#2\relax$.$#3} {\deftypeopcategory\ \putwordon\ \code{#1}}% \deftypefunargs{#4}% \endgroup } % @deftypemethod CLASS TYPE METHOD ARG... % \def\deftypemethod{% \deftypemethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader} % % #1 is the class name, #2 the data type, #3 the method name, #4 the args. \def\deftypemethodheader#1#2#3#4{% \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index \begingroup \defname{\defheaderxcond#2\relax$.$#3}{\putwordMethodon\ \code{#1}}% \deftypefunargs{#4}% \endgroup } % @deftypeivar CLASS TYPE VARNAME % \def\deftypeivar{% \deftypemethparsebody\Edeftypeivar\deftypeivarx\deftypeivarheader} % % #1 is the class name, #2 the data type, #3 the variable name. \def\deftypeivarheader#1#2#3{% \dosubind{vr}{\code{#3}}{\putwordof\ \code{#1}}% entry in variable index \begingroup \defname{\defheaderxcond#2\relax$.$#3} {\putwordInstanceVariableof\ \code{#1}}% \defvarargs{#3}% \endgroup } % @defmethod == @defop Method % \def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} % % #1 is the class name, #2 the method name, #3 the args. \def\defmethodheader#1#2#3{% \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% entry in function index \begingroup \defname{#2}{\putwordMethodon\ \code{#1}}% \defunargs{#3}% \endgroup } % @defcv {Class Option} foo-class foo-flag \def\defcv #1 {\def\defcvtype{#1}% \defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype} \def\defcvarheader #1#2#3{% \dosubind{vr}{\code{#2}}{\putwordof\ \code{#1}}% variable index entry \begingroup \defname{#2}{\defcvtype\ \putwordof\ #1}% \defvarargs{#3}% \endgroup } % @defivar CLASS VARNAME == @defcv {Instance Variable} CLASS VARNAME % \def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} % \def\defivarheader#1#2#3{% \dosubind{vr}{\code{#2}}{\putwordof\ \code{#1}}% entry in var index \begingroup \defname{#2}{\putwordInstanceVariableof\ #1}% \defvarargs{#3}% \endgroup } % @defvar % First, define the processing that is wanted for arguments of @defvar. % This is actually simple: just print them in roman. % This must expand the args and terminate the paragraph they make up \def\defvarargs #1{\normalparens #1% \defargscommonending } % @defvr Counter foo-count \def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader} \def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% \begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} % @defvar == @defvr Variable \def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader} \def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index \begingroup\defname {#1}{\putwordDefvar}% \defvarargs {#2}\endgroup % } % @defopt == @defvr {User Option} \def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader} \def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index \begingroup\defname {#1}{\putwordDefopt}% \defvarargs {#2}\endgroup % } % @deftypevar int foobar \def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader} % #1 is the data type. #2 is the name, perhaps followed by text that % is actually part of the data type, which should not be put into the index. \def\deftypevarheader #1#2{% \dovarind#2 \relax% Make entry in variables index \begingroup\defname {\defheaderxcond#1\relax$.$#2}{\putwordDeftypevar}% \defargscommonending \endgroup} \def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}} % @deftypevr {Global Flag} int enable \def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} \def\deftypevrheader #1#2#3{\dovarind#3 \relax% \begingroup\defname {\defheaderxcond#2\relax$.$#3}{#1} \defargscommonending \endgroup} % Now define @deftp % Args are printed in bold, a slight difference from @defvar. \def\deftpargs #1{\bf \defvarargs{#1}} % @deftp Class window height width ... \def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} \def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% \begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} % These definitions are used if you use @defunx (etc.) % anywhere other than immediately after a @defun or @defunx. % \def\defcvx#1 {\errmessage{@defcvx in invalid context}} \def\deffnx#1 {\errmessage{@deffnx in invalid context}} \def\defivarx#1 {\errmessage{@defivarx in invalid context}} \def\defmacx#1 {\errmessage{@defmacx in invalid context}} \def\defmethodx#1 {\errmessage{@defmethodx in invalid context}} \def\defoptx #1 {\errmessage{@defoptx in invalid context}} \def\defopx#1 {\errmessage{@defopx in invalid context}} \def\defspecx#1 {\errmessage{@defspecx in invalid context}} \def\deftpx#1 {\errmessage{@deftpx in invalid context}} \def\deftypefnx#1 {\errmessage{@deftypefnx in invalid context}} \def\deftypefunx#1 {\errmessage{@deftypefunx in invalid context}} \def\deftypeivarx#1 {\errmessage{@deftypeivarx in invalid context}} \def\deftypemethodx#1 {\errmessage{@deftypemethodx in invalid context}} \def\deftypeopx#1 {\errmessage{@deftypeopx in invalid context}} \def\deftypevarx#1 {\errmessage{@deftypevarx in invalid context}} \def\deftypevrx#1 {\errmessage{@deftypevrx in invalid context}} \def\defunx#1 {\errmessage{@defunx in invalid context}} \def\defvarx#1 {\errmessage{@defvarx in invalid context}} \def\defvrx#1 {\errmessage{@defvrx in invalid context}} \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\undefined \newwrite\macscribble \def\scanmacro#1{% \begingroup \newlinechar`\^^M % Undo catcode changes of \startcontents and \doprintindex \catcode`\@=0 \catcode`\\=\other \escapechar=`\@ % Append \endinput to make sure that TeX does not see the ending newline. \toks0={#1\endinput}% \immediate\openout\macscribble=\jobname.tmp \immediate\write\macscribble{\the\toks0}% \immediate\closeout\macscribble \let\xeatspaces\eatspaces \input \jobname.tmp \endgroup } \else \def\scanmacro#1{% \begingroup \newlinechar`\^^M % Undo catcode changes of \startcontents and \doprintindex \catcode`\@=0 \catcode`\\=\other \escapechar=`\@ \let\xeatspaces\eatspaces\scantokens{#1\endinput}\endgroup} \fi \newcount\paramno % Count of parameters \newtoks\macname % Macro name \newif\ifrecursive % Is it recursive? \def\macrolist{} % List of all defined macros in the form % \do\macro1\do\macro2... % Utility routines. % Thisdoes \let #1 = #2, except with \csnames. \def\cslet#1#2{% \expandafter\expandafter \expandafter\let \expandafter\expandafter \csname#1\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 \. % 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\macrobodyctxt{% \catcode`\~=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\+=\other \catcode`\{=\other \catcode`\}=\other \catcode`\@=\other \catcode`\^^M=\other \usembodybackslash} \def\macroargctxt{% \catcode`\~=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\+=\other \catcode`\@=\other \catcode`\\=\other} % \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\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% \else \expandafter\parsemargdef \argl;% \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% % Add the macroname to \macrolist \toks0 = \expandafter{\macrolist\do}% \xdef\macrolist{\the\toks0 \expandafter\noexpand\csname\the\macname\endcsname}% \fi \begingroup \macrobodyctxt \ifrecursive \expandafter\parsermacbody \else \expandafter\parsemacbody \fi} \def\unmacro{\parsearg\dounmacro} \def\dounmacro#1{% \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\do\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\do \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}} % 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 be ##N where N is the position in that list. % 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. \def\parsemargdef#1;{\paramno=0\def\paramlist{}% \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,} \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} % These two commands read recursive and nonrecursive macro bodies. % (They're different since rec and nonrec macros end differently.) \long\def\parsemacbody#1@end macro% {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% \long\def\parsermacbody#1@end rmacro% {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% % This defines the macro itself. There are six cases: recursive and % nonrecursive macros of zero, one, 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 % many \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}}% \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 % many \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}% \fi \fi} \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\next=#1\futurelet\nchar\braceorlinexxx} \def\braceorlinexxx{% \ifx\nchar\bgroup\else \expandafter\parsearg \fi \next} % We mant to disable all macros during \shipout so that they are not % expanded by \write. \def\turnoffmacros{\begingroup \def\do##1{\let\noexpand##1=\relax}% \edef\next{\macrolist}\expandafter\endgroup\next} % @alias. % We need some trickery to remove the optional spaces around the equal % sign. Just make them active and then expand them all to nothing. \def\alias{\begingroup\obeyspaces\parsearg\aliasxxx} \def\aliasxxx #1{\aliasyyy#1\relax} \def\aliasyyy #1=#2\relax{\ignoreactivespaces \edef\next{\global\let\expandafter\noexpand\csname#1\endcsname=% \expandafter\noexpand\csname#2\endcsname}% \expandafter\endgroup\next} \message{cross references,} % @xref etc. \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 job is to define \lastnode. \def\node{\ENVcheck\parsearg\nodezzz} \def\nodezzz#1{\nodexxx #1,\finishnodeparse} \def\nodexxx#1,#2\finishnodeparse{\gdef\lastnode{#1}} \let\nwnode=\node \let\lastnode=\relax % The sectioning commands (@chapter, etc.) call these. \def\donoderef{% \ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}% {Ysectionnumberandtype}% \global\let\lastnode=\relax \fi } \def\unnumbnoderef{% \ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}{Ynothing}% \global\let\lastnode=\relax \fi } \def\appendixnoderef{% \ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}% {Yappendixletterandtype}% \global\let\lastnode=\relax \fi } % @anchor{NAME} -- define xref target at arbitrary point. % \newcount\savesfregister \gdef\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} \gdef\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} \gdef\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} % \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an % anchor), namely NAME-title (the corresponding @chapter/etc. name), % NAME-pg (the page number), and NAME-snt (section number and type). % Called from \foonoderef. % % We have to set \indexdummies so commands such as @code in a section % title aren't expanded. It would be nicer not to expand the titles in % the first place, but there's so many layers that that is hard to do. % % Likewise, use \turnoffactive so that punctuation chars such as underscore % and backslash work in node names. % \def\setref#1#2{{% \atdummies \pdfmkdest{#1}% % \turnoffactive \dosetq{#1-title}{Ytitle}% \dosetq{#1-pg}{Ypagenumber}% \dosetq{#1-snt}{#2}% }} % @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,,,,,,,]} \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup \unsepspaces \def\printedmanual{\ignorespaces #5}% \def\printednodename{\ignorespaces #3}% \setbox1=\hbox{\printedmanual}% \setbox0=\hbox{\printednodename}% \ifdim \wd0 = 0pt % No printed node name was explicitly given. \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax % Use the node name inside the square brackets. \def\printednodename{\ignorespaces #1}% \else % Use the actual chapter/section title appear inside % the square brackets. Use the real section title if we have it. \ifdim \wd1 > 0pt % It is in another manual, so we don't have it. \def\printednodename{\ignorespaces #1}% \else \ifhavexrefs % We know the real title if we have the xref values. \def\printednodename{\refx{#1-title}{}}% \else % Otherwise just copy the Info node name. \def\printednodename{\ignorespaces #1}% \fi% \fi \fi \fi % % If we use \unhbox0 and \unhbox1 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. \ifpdf \leavevmode \getfilename{#4}% {\turnoffactive \otherbackslash \ifnum\filenamelength>0 \startlink attr{/Border [0 0 0]}% goto file{\the\filename.pdf} name{#1}% \else \startlink attr{/Border [0 0 0]}% goto name{#1}% \fi }% \linkcolor \fi % \ifdim \wd1 > 0pt \putwordsection{} ``\printednodename'' \putwordin{} \cite{\printedmanual}% \else % _ (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 \otherbackslash % 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 a macro. \xrefprintnodename\printednodename % % But we always want a comma and a space: ,\space % % output the `page 3'. \turnoffactive \otherbackslash \putwordpage\tie\refx{#1-pg}{}% \fi \endlink \endgroup} % 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 not square brackets don't work in some documents. Particularly % one that Bob is working on :). % \def\xrefprintnodename#1{[#1]} % \dosetq is called from \setref to do the actual \write (\iflinks). % \def\dosetq#1#2{% {\let\folio=0% \edef\next{\write\auxfile{\internalsetq{#1}{#2}}}% \iflinks \next \fi }% } % \internalsetq{foo}{page} expands into % CHARACTERS @xrdef{foo}{...expansion of \page...} \def\internalsetq#1#2{@xrdef{#1}{\csname #2\endcsname}} % Things to be expanded by \internalsetq. % \def\Ypagenumber{\folio} \def\Ytitle{\thissection} \def\Ynothing{} \def\Ysectionnumberandtype{% \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\Yappendixletterandtype{% \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 } % 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{\the\inputlineno:\space} \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 X#1\endcsname }% \ifx\thisrefX\relax % If not defined, say something at least. \angleleft un\-de\-fined\angleright \iflinks \ifhavexrefs \message{\linenumber Undefined cross reference `#1'.}% \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. % \def\xrdef#1{\expandafter\gdef\csname X#1\endcsname} % Read the last existing aux file, if any. No error if none exists. \def\readauxfile{\begingroup \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 % % Make the characters 128-255 be printing characters {% \count 1=128 \def\loop{% \catcode\count 1=\other \advance\count 1 by 1 \ifnum \count 1<256 \loop \fi }% }% % % Turn off \ as an escape so we do not lose on % entries which were dumped with control sequences in their names. % For example, @xrdef{$\leq $-fun}{page ...} made by @defun ^^ % Reference to such entries still does not work the way one would wish, % but at least they do not bomb out when the aux file is read in. \catcode`\\=\other % % @ is our escape character in .aux files. \catcode`\{=1 \catcode`\}=2 \catcode`\@=0 % \openin 1 \jobname.aux \ifeof 1 \else \closein 1 \input \jobname.aux \global\havexrefstrue \global\warnedobstrue \fi % Open the new aux file. TeX will close it automatically at exit. \openout\auxfile=\jobname.aux \endgroup} % 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 \let\ptexfootnote=\footnote {\catcode `\@=11 % % Auto-number footnotes. Otherwise like plain. \gdef\footnote{% \let\indent=\ptexindent \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 fail inside footnotes because the tokens are fixed when % the footnote is read. --karl, 16nov96. % % The start of the footnote looks usually like this: \gdef\startfootins{\insert\footins\bgroup} % % ... but this macro is redefined inside @multitable. % \gdef\dofootnote{% \startfootins % 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 \futurelet\next\fo@t } }%end \catcode `\@=11 % @| 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). % \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 }% }% } % 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} % @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 \closein 1 % 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 % % 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\undefined \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 this 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 \nobreak\bigskip % 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 \line\bgroup\hss \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 \hss \egroup \bigbreak \fi % space after the image \endgroup} \message{localization,} % and i18n. % @documentlanguage is usually given very early, just after % @setfilename. If done too late, it may not override everything % properly. Single argument is the language abbreviation. % It would be nice if we could set up a hyphenation file here. % \def\documentlanguage{\parsearg\dodocumentlanguage} \def\dodocumentlanguage#1{% \tex % read txi-??.tex file in plain TeX. % Read the file if it exists. \openin 1 txi-#1.tex \ifeof1 \errhelp = \nolanghelp \errmessage{Cannot read language file txi-#1.tex}% \let\temp = \relax \else \def\temp{\input txi-#1.tex }% \fi \temp \endgroup } \newhelp\nolanghelp{The given language definition file cannot be found or is empty. Maybe you need to install it? In the current directory should work if nowhere else does.} % @documentencoding should change something in TeX eventually, most % likely, but for now just recognize it. \let\documentencoding = \comment % Page size parameters. % \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 so finicky about underfull hboxes, either. \hbadness = 2000 % Following George Bush, just 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 \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{46\baselineskip}{6in}% {\voffset}{.25in}% {\bindingoffset}{36pt}% {11in}{8.5in}% }} % Use @smallbook to reset parameters for 7x9.5 (or so) format. \def\smallbook{{\globaldefs = 1 \parskip = 2pt plus 1pt \textleading = 12pt % \internalpagesizes{7.5in}{5in}% {\voffset}{.25in}% {\bindingoffset}{16pt}% {9.25in}{7in}% % \lispnarrowing = 0.3in \tolerance = 700 \hfuzz = 1pt \contentsrightmargin = 0pt \defbodyindent = .5cm }} % 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{51\baselineskip}{160mm} {\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. % \def\pagesizes{\parsearg\pagesizesxxx} \def\pagesizesxxx#1{\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 \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.} % Define macros to output various characters with catcode for normal text. \catcode`\"=\other \catcode`\~=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\+=\other \catcode`\$=\other \def\normaldoublequote{"} \def\normaltilde{~} \def\normalcaret{^} \def\normalunderscore{_} \def\normalverticalbar{|} \def\normalless{<} \def\normalgreater{>} \def\normalplus{+} \def\normaldollar{$}%$ font-lock fix % This macro is used to make a character print one way in ttfont % where it can probably just be output, 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\_} % 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 % Set up an active definition for =, but don't enable it most of the time. {\catcode`\==\active \global\def={{\tt \char 61}}} \catcode`+=\active \catcode`\_=\active % 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} \catcode`\@=0 % \rawbackslashxx outputs one backslash character in current font, % as in \char`\\. \global\chardef\rawbackslashxx=`\\ % \rawbackslash defines an active \ to do \rawbackslashxx. % \otherbackslash defines an active \ to be a literal `\' character with % catcode other. {\catcode`\\=\active @gdef@rawbackslash{@let\=@rawbackslashxx} @gdef@otherbackslash{@let\=@realbackslash} } % \realbackslash is an actual character `\' with catcode other. {\catcode`\\=\other @gdef@realbackslash{\}} % \normalbackslash outputs one backslash in fixed width font. \def\normalbackslash{{\tt\rawbackslashxx}} \catcode`\\=\active % Used sometimes to turn off (effectively) the active characters % even after parsing them. @def@turnoffactive{% @let"=@normaldoublequote @let\=@realbackslash @let~=@normaltilde @let^=@normalcaret @let_=@normalunderscore @let|=@normalverticalbar @let<=@normalless @let>=@normalgreater @let+=@normalplus @let$=@normaldollar %$ font-lock fix } % Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of % the literal character `\'. (Thus, \ is not expandable when this is in % effect.) % @def@normalturnoffactive{@turnoffactive @let\=@normalbackslash} % 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 back turn 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 look ok in all fonts, so just make them not special. @catcode`@& = @other @catcode`@# = @other @catcode`@% = @other @c Set initial fonts. @textfonts @rm @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: gri-2.12.23/doc/._texinfo2HTML000755 000767 000024 00000000342 11310756313 016226 0ustar00kelleystaff000000 000000 Mac OS X  2°âATTRäÖâ˜J˜Jcom.apple.acl.text!#acl 1 user:7907E7C1-F406-4E36-A5F4-DC858894BFB7:kelley:503:allow:write gri-2.12.23/doc/texinfo2HTML000755 000767 000024 00000030532 11310756313 016015 0ustar00kelleystaff000000 000000 #!/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"; require "getopts.pl"; $debug = 0; die if !&Getopts('h'); $print_help = 0; $print_help = $opt_h if $opt_h; if ($print_help) { print "$usage"; exit 0; } $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-2.12.23/doc/tst_suite/000777 000767 000024 00000000000 11607310072 015665 5ustar00kelleystaff000000 000000 gri-2.12.23/doc/version.texi000644 000767 000024 00000000140 11605066221 016213 0ustar00kelleystaff000000 000000 @set UPDATED 6 July 2011 @set UPDATED-MONTH July 2011 @set EDITION 2.12.23 @set VERSION 2.12.23 gri-2.12.23/doc/tst_suite/Makefile.am000644 000767 000024 00000001064 11310756313 017721 0ustar00kelleystaff000000 000000 ## 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-2.12.23/doc/tst_suite/Makefile.in000644 000767 000024 00000021264 11605066212 017735 0ustar00kelleystaff000000 000000 # Makefile.in generated by automake 1.10 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in 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) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) VPATH = @srcdir@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CXXFLAGS = @AM_CXXFLAGS@ 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_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@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ # gri: doc/tst_suite/Makefile.am srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ 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 \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/tst_suite/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/tst_suite/Makefile .PRECIOUS: 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 tags: TAGS TAGS: ctags: CTAGS CTAGS: 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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: info: info-am info-am: install-data-am: install-dvi: install-dvi-am 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 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 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 uninstall uninstall-am %.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-2.12.23/doc/tst_suite/tst_control.gri000644 000767 000024 00000001476 11310756313 020751 0ustar00kelleystaff000000 000000 show "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-2.12.23/doc/tst_suite/tst_control.texi000644 000767 000024 00000002302 11311210332 021111 0ustar00kelleystaff000000 000000 @c Created Sun Dec 13 12:05:46 2009 by ./../gri2texi from tst_control.gri.gri @example show "doc/tst_suite/tst_control.gri ..." ... # If statements @strong{@strong{if}} 0 assert 0 " failed test 1" end @strong{if} @strong{@strong{if}} 1 @strong{@strong{else}} assert 0 " failed test 2" end @strong{if} # Loops. # Loop with @strong{if} inside .i. = 0 @strong{@strong{while}} @{rpn .i. 3 >@} .i. += 1 @strong{if} 1 @strong{else} assert 0 " failed test 3" end @strong{if} end @strong{while} assert @{rpn .i. 3 ==@} " failed test 4" # Loop inside @strong{if} @strong{@strong{if}} 1 .i. = 0 @strong{while} @{rpn .i. 3 >@} .i. += 1 end @strong{while} assert @{rpn .i. 3 ==@} " failed test 5" @strong{@strong{else}} assert 0 " failed test 6" .i. = 0 @strong{while} @{rpn .i. 3 >@} .i. += 1 end @strong{while} assert 0 " failed test 7" end @strong{if} # Nested loops .i. = 0 @strong{@strong{while}} @{rpn .i. 2 >@} .j. = 0 @strong{while} @{rpn .j. 4 >@} .j. += 1 end @strong{while} .i. += 1 end @strong{while} assert @{rpn .i. 2 ==@} " failed test 8" assert @{rpn .j. 4 ==@} " failed test 9" show " passed" @end example gri-2.12.23/doc/tst_suite/tst_IO.gri000644 000767 000024 00000004643 11354710163 017600 0ustar00kelleystaff000000 000000 show "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-2.12.23/doc/tst_suite/tst_IO.texi000644 000767 000024 00000005106 11354710175 017766 0ustar00kelleystaff000000 000000 @c Created Wed Mar 31 15:12:13 2010 by ./../gri2texi from tst_IO.gri.gri @example show "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" @end example gri-2.12.23/doc/tst_suite/tst_IO_1.dat000644 000767 000024 00000000012 11310756313 017770 0ustar00kelleystaff000000 000000 1 11 2 22 gri-2.12.23/doc/tst_suite/tst_IO_2.dat000644 000767 000024 00000000011 11310756313 017770 0ustar00kelleystaff000000 000000 1 11 2 22gri-2.12.23/doc/tst_suite/tst_rpn.gri000644 000767 000024 00000007064 11354710244 020070 0ustar00kelleystaff000000 000000 show "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-2.12.23/doc/tst_suite/tst_rpn.texi000644 000767 000024 00000007427 11354710255 020265 0ustar00kelleystaff000000 000000 @c Created Wed Mar 31 15:13:01 2010 by ./../gri2texi from tst_rpn.gri.gri @example show "doc/tst_suite/tst_rpn.gri ..." ... rpnfunction same - abs 1e-5 > @emph{# 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" @strong{@strong{if}} @{rpn .y. -99 !=@} show " failed test 9.10" end @strong{if} show " passed" @end example gri-2.12.23/doc/tst_suite/tst_var_syn.gri000644 000767 000024 00000022420 11310756313 020742 0ustar00kelleystaff000000 000000 show "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-2.12.23/doc/tst_suite/tst_var_syn.texi000644 000767 000024 00000023375 11311210332 021127 0ustar00kelleystaff000000 000000 @c Created Sun Dec 13 12:05:46 2009 by ./../gri2texi from tst_var_syn.gri.gri @example show "doc/tst_suite/tst_var_syn.gri ..." ... rpnfunction same - abs 1e-10 > @emph{# 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 @strong{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' @strong{if} parts. \str = "Hello" \t = @{rpn "\s" "tr" strcat@} @emph{# construct a name} @strong{@strong{if}} @{rpn "\\t" defined@} @emph{# test @strong{if} defined} .val. = 1 end @strong{if} @strong{@strong{if}} @{rpn "\\x" defined@} @emph{# this one is not defined} .val. = 2 end @strong{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 @strong{else}" ==@} " failed test 18.12" delete \a @} \a = "Or @strong{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. @emph{# 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" #@emph{# # 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" @end example gri-2.12.23/doc/screenshots/gri-screenshot-1-tiny.png000644 000767 000024 00000041142 11311210332 022747 0ustar00kelleystaff000000 000000 ‰PNG  IHDR”x›ØLz pHYsii¦¨N vpAg”xtâALIDATxÚí½WÏeWv¸v8ùœ›Ã—så*’ÅÐM²›Ý¤Ô²Zê¶!AðƒG˜f€~š7ÿ€y†üà7– Ê0 iFj«Ù‰Å ’M«X9|9ÜÎ=yï=ûÞsï÷ÕWÅb‹ r-‚_Ý“vZ{¯½öŠèÖín¯‡ ÃDÑt„‘7ðZí6€@B „!ä„¡ábô®å £ß „@ Ãk„@È¢‡ÏBp!@!,B8mÈǓߎZ3n“üW QmbÔ$@ ;„d³‡•ι¬À¨ÞQñÃ"åãÈÏ!múh G€‡-Ų)é§’RT5ŸÏBªÎÂ0¤ŠB ñ}Ÿ*TÓô8ŠgÿíÿýkJá¡ <þà·WÎ=_®Tïܹ›0N¦„¶;m…*žç‹E 'B†çÜ´LÁ…ç{”PÓ4ã8–aœiš>ìœ#dƒÃ1N1:1“ý”ƒ)&§Í؆‰±›ÀܨP4DÞä$CD‰ ¼gÙäp"„„àãÆ‰Ã_1Äø}˜œ‰)öäŒý£™ §iƒÍVÎDµZñÜ^½¶ÇL7ëŸ\B<ûÜóF}cc}yyeà(%´]ßkìܾñ‰–›®T§EuÝv§ÓÉf³œ‹$I’„qΛÍf¯×WU%I˜BUU¥Ûõê>4 €àFÝJ'¼$w#d „Æ„irqÁÄâ–¶`L‡µ§“=]ÔiC² ãbĘNŠ1eœ$裉5^Lâ,E㸖z¥Ô0ŒN·%¬Ñj릣– ç˜(¥rÙ¸TÑEA|ðƘóc¬ë†‚RÂ7 "KæB.ŒqÚq!„$‰rp“$a,1M+IbŒ çü”=0ÁåäÊc ޽— BG?>üãS`<¾ðÀ’=º’Ò5<ÜtBBˆ”v¤øGçÒƒíœ(jb‘¿â8NÆ9 ƒ@UUª(QBš¦ÇqG¡ô·ûÊ8_[[Èd¬ºzäòqÆâSßAGæýg)íÁKxLôüFM}Ìwþáu=âéƒsHþ@÷ï­«ªB9çœsæºÁ`ضŽ1 ‚ÄqtJ)Â0îtù¼Íçœ+ U’®¹fÓu]×5ÎBày‘ªEQ&!W)´Z}E¡Ù¬Å9o·]MSâ8Éç‰&W™ë®T«9¹Ö£(ö¼0—³Òº]/Š’J%ûÀâò9½žÏ9—…û~H)VE.…a\.gFÕ¸vιìc¼Ùì;Žašº|Üï{à8æƒu¹n ‰iªqÌ1Fª:¬Ë÷#Ï K¥Œ|Í0TŒQ¿ˆLÆLÖïù¼ ù# BÆx&c@»=Èç-„°|4F)BŒ'œ Ê9ðo\õýhi©¢ªäÆÝóçç}?:{vζͫWï½÷ÞÝ×^;ÿÓŸ^™šÊÍÎîÜÙÿ£?ú¦a¨Ýÿð~V©džyfec£¶´Tîv½éé|Dœ B0!8—3çæJIÿûÿ3ŒÑïÿþ³ûûí›7w³YSוååªÛÖ9'ON‚·¶š?ûÙ'¯¾zVˆcF)þè£õ—_>)¬¬T1Æ7nì|òÉöÙ³s¦©EQŒ1B˜¦¦ëÊÒR™1ñ_ÿë»kkSÏ;ï¾{«RÉž:5³¶VÅÿÕ_½W(8KKå8N’„©*õ¼¨ZͶZîÕ«[ôGßt£ÝüÙŸýgÎÌž>=‹1RUúæ›7NšÉçm!8Æ8¢lÖ<}z–1þ£½9„++• Þ|ó†ã'NLŸ;7GùÉO>îv½µµ©©©ÜµkÛßúÖIBÈü¿ðýø[ß:•Ë™ÿ÷w^xa93Kþñ?¸}{ÿ[ß:97W¼téæóϯÄ1;~^Ué‘E‰1¦ÏqÌÊåL»íÊYéÒÍ[·öþå¿ü¾m[qÌ’„¿ûîíõõZÆÁæf£Ýv £˜$,Š’K—nÞ¹sP*9BˆNÇ»¿vûö¾ç…¥’C)¹paan®$AÔlºñ¿bL<ûìr3Ç1_ým!ÄK/€ÝÝÖòr…ì8º®+?ùÉÇ;;-ŒÑ‰Ó¾½óÎí$áKKŒ!Üïû?úÑ›žf2†ah"Š’¥¥ÊŸþéï!Â0qÝàõ×ßÖ4Å4µöÁAwi©¬ª8Ix6küÍß|tÿ~íßXóýè­·n./WƒÐ¶õf³ï8f’°r9“Íš?úѯ Cûƒ?x> xýõ·úýàÿð…ÿøƒBÁþWÿêå’êv½{÷ÚíÁ•+›Ý®wæÌìÚZÕ4IÆ}´~óæîŸüÉwoÝÚ-pÎÛíÁþ~çÞ½ƒï~÷l«å¾þú;ù¼µºZ5 Õ÷£Z­ûŸþÓ¥—_>Õízý×áü|©RɈÃ<3B€Þ~û­S§–óy³Ùì†Úlö}?bŒëºÊŸŸ/ªªÒï{»»mÓÔ\7@Y–Æ9/lÇ1cëëÍÍz¡`/-UZ­~1U%qÌT•‚Ã0q½ZÍ !îÝ«‚£(Q’ËYBU¥õz!T*9a˜ôzÞÒR!†q·ë…aÂO¦(Äó"ÓÔ0FssE„`o¯Ón»ŽcpÎe]¡ ˆ(%ËËØÝm{^¨ëJ’pß4M!/,Bõz/“1:Q””JŽàºADcJq6kårVÅÝ®ç8úÖVKÓèÌL¾Õ˜¦º·×V:5•kµ\„`j*Ý(J\70MÍ÷#U¥ªJçæ áV«¿³ÓÊfÍ©©Ü;û33…\ÎÜÛkÇ1 ÃDו^Ï»{·öâ‹k•JêõžïGQ”hšâºÁúz}mmêĉ©#dóÎõÿ·ÿŽÞzëÍÓgVò9s´ÚB$×tˆ«Ÿ¤øÃ]Mœ±g/Gå C÷mË“G9xàåGõ¸/¤&鲯ã~¥¯~Œ‰&ZûȺàð'âaƒü^‹ã˜qtçîýÿç¯þ;õúþ•_\C‚Ác§ðÿ‡Qƒ>SQG«‡KxÈñ÷±á³°—GÊÄå6ù|Z±±‰Zä[ K°@”q† Ë/Çg1QÎP®)†o®cø&ÿOON‡_ž®C¿ÆGÞC]u mž<%§2™ñïq™éB™ ¦ÈIyæ¡1Â粉‰‰Ò&…\iÄçÃ0Æ©\7í›HEòp1ÑåTL<9V"=N›5ÃÔ ƒê–F³JŲ¾És·, aäyžïûùB~›0:¢‚ü;”k E„àGDÇÀ#ÇüT„Í ªªêº.&ä#)‰çß±ä&Ú9îp*_Æœ3Ïó Ø- Kîv»”˲E*~@AàBTUcq pÎ}ß7 CÊRIJÇcBˆÀ5›Í½½½^¯·°° …ÚI’¬®®ml¬÷z½Á`°°°Àó ‚À÷}˲0Æ„Rê÷{qg2™Û·o?ÿüó¥r„ðÞöÎF¥l \P*Tð!š:%8ðü½~aa„àBt»ÝÁ`@ ªíïƒÞÚ駨B‘€v§½»¿cæìôœ¢(K˜B•Ó§NŸ9sF±±±qppBÄQœËæ/^¼¸»»»»»†!Š¢xvf6ŸÏŸ?þæÍ›‚ ÎøP¬;^©£2‰9€ay3I’›_ùèï~ꨴV?è÷ûruû¾ßjí^¸°òï<›$ý(ŠBáí­õ»7?Ìëwö>øûŸ÷z=©- øá‡þç…a:ÓûýþúúÆÌÌÌ·¿ýíÝÝÝ(Š%‰ØßßßßßgŒ×ëõL&S,åbBìïýúÍ_]}ï½IþØó¼^¿ßl6Ûí¶çyb¤{hµZq´Z-Îäæ:Že™++Ë­V3“ÉØ¶-Ñ_¯×XÒ+•²¶M›Í9$I’ìlo‡?==­ëÚý{÷c²û×]ªæ¦Ê¹Ý{W)¡”Rù cŒ`Òî·:½Æ!Ä9O’äùçŸ___ßÛÛk·Û½^cE‘eYçÏŸÿý÷£(ÚÜÜL’#ðƒ¥¥¥jµúÎ;ï „Ö××')DJ)Ä,KJ{p*YØ[¿Ïš-œ$h¢)ê,• –eÍÍö÷wäÍR¹ªéF}‹ð®’B€¢(Š¢¤ÔŒsΛž™ñÚ *•Ê»ï¾kÆüüüÊÊŠ®ëœsUU———)¥gΜY^^>{ö,0Æ …‚T 0ÆVVV–——“$y€_9†ÉJwP*÷UU_ùÁîܾ}{ÿàÞÝûŸyN ´ Ó¬T¦9ç››»Û;B¡,1”Íæ‚ÖïÞ[\^]=}!“!9çÏ=÷ÜÓO?=ˆÙlvkkë7~:=5FQ¯×“oNOOÿúÃ_ÏÎÌ–Ëåõõu¹ÈDZm[7M˲ҩ—Éd¢(Îf³…BaLU™¦¹p PDZ®ër´,«Þ¨_¾|Å4 ]×jµ†¬r¹ø$Nü÷ß¿:;»øïœB˜¦9ð¼×ÿò/…[›[Ï=÷œ¦iBL°ídzþÌâÉv§—ËÆ*dýÞ`~fQUUÎ9Ò4mwwWÓ´ ö÷÷ Ã0M$ /]ºÁ‚ªªªª"„ øvíZ»ÝÆû¾/'ýä{8{<Ú×ñ‹7(¥QÄ䀄išévÝ~·{ iv>_&„¦Ç—Á`°·»37¿`†ÄÔH+2&Ó“ïÆ¦iV*•|>Ÿ.šZ­¶±±Q(ÊåŠãØR?©>™Ô !¢(Råyáœ× Ë4 ÃH7Bˆãx0ðúýB¨R©ªª"¹›Zm/Ž=„ô­­‹ŸQUU’ÁF£±½½Ïå–WVB£Jy­V‚ E‰QyŸs±_ÛËçò†nȦîïïïììt»ÝL&#Çc|îܹëׯkš&y–b±(„°m{ffæ£>BA ÿš¦yæÌÛ¶'É:¬‰H™JBÐÍ[7ÐÏ~öw“ ˆÆã5Z™éØÅq¬(Ê$( #ÎùÄ@³Ì rt9:{ $8—ûë$£ûèBÒ‰™ mÑS„ÞO ,ÒÂ…Œ1EQåUZ¸ÜÎçü!•Âd %7.F*à8Ž}ß—}aŒIFÔ²,Ïó’$áœ"5e iº¦©’±àœË#ç\ò\ði „Ð4åÎÛTnŒñ#ãŽÂ3ÆÆ„ HkÆÆKc"„˜õ›ãÔd²p„0çG%#–5UÃË—Ý~p( ´aE;®p!`„lœ$ñ¨rl GÝ?Š<Œð±…KT¹/÷<¹¸aò´-„$ª‡±’v皉1Nuú„`„0E9ŽmÛ€1Šçãƒtª1‘ lÂ%ã3¼Tv (x 8¨'ŸcMô‘N=Rvò™$+ÿòäY=vcŽ-öÉDYG䂟R$ã `Œööv›Í¶œUÓÓ§U¡ãju*—+BÐ÷o\É?÷4 ‚æÛïi¥¢µ²„0F)ٌѻ~ËœŸåa5[ÖÊRâân—¡1=%œSÇ&š÷]Áà“DÎÁ‚qL©à\ÍeꕟÀq x) ìîn 5M3 syyñ“k7† ·ˆ{níWo;§O!’ L¶v:W®³(Êœ>Qzñ¬*‰;è^»Õý亚ÏÑL&j·õJe°µ¶Úa­AmËœŸµ×V{×o .Xð(VsÙd0Œ66õjY¯V@ˆ°Õ©¾öm<¢$Oà0:ç€.•ʦiêºFœË=Z¹¸ú¿ý/j.Ë£¸òÝoǽ^Ü鯽^öÌI¬*œ1¬ëXSó/=…ª86µL­PÐÊ%À!¤OWEœð$Ášªò:s†MO‹«WI»^y%!Ù¶éºn·Û×uÍ0ô\.K)y‚¹/Yå@z”¦©°ãˆJvveA¹Ì§¦ÌÌðba ¡\.ǹhµÚ”*¶m ùÔpñ | Íìf„M9™n9ŽxáàyCTW*b¤kµZ-“±³ÙL'q×jõLÆÖ4í«îÜ?r“0yh’$#­&ܾm[ìîâÝ]ôÍo²ÕU~õ*évÑ7¿™¡½½Z³ÙªVËžçK½Ìø¢Û“ÀÄ‚ ÁåY"—® W¯’­-T. © Ïf…¢I6+•2ÆØóÎ…aè•JŽÓ<Ï&Chò‚ŽîÂ`€ªU¡iÉ… ¨P–%`a B;¶¢\.0Æ(¥ív×4 UU~³6=Ç„ôœG)5ÍŒaèívGZi`ƘԠܾ9GAo¼A¥jâæMüþûDþö<{{¯Vo„aÔl¶=Ï— £¯ºwÿøa´ÒpÂX¯×ßÞÞbŒàT ù¼ètàƒH¿¥’hµÐÔ”ÀäA!4;;­(J£ÑJX¢ªÊÌLž¾v¦G<„0áQ¾T­µ8Ž9çÒˆR ”R*#l ßœ´ ?¶¨'˜û’a‚Vær9Ó4u]—V²T>2¹OïEÒw±®U;âÀ24QAH0†B˜Œ­BùÎŒñŽ9ì_#RJž>}2;Ž€týOm5S›J<”° @ÅvóÝKÕßþhtEŸ®"Lânט®*™LÜï3?Ч*XU;¢8vâ´J™¹0y;;ÄГ¾‹ÁšªW*R‹uù>"„èZ2ðˆ¦ñ$ÎY² 4çg£V›h"˜…‘V*PË~ÂM¡˜‡ŸP„± fÀ£ÈÛÚáQL-“èZçòUæZ©(¸€­îõ[Še_ú†1]MÜ#ÁX÷_"JÕR+Jã­w¥Q»#â$÷Ô9­Trï­{Uü½š½ºdÌL5ß~FìºÀ…V)©¹l»ÞêÆÌ”9?Û½r-{ᬳê<9øO‚\vÇáÑ”TêåÒÚÿú?cM!¬ùYs~Ž'‰âØÌ÷X×Á²µJa’¿p†ù’Ë:kË‚1Õ¶„S¿ó £x0Hž³²„ÑË%µ\"ªêxž’q°®U_{TcÂØ„@œ>I›˜QUšÍpÎ%~ Æÿ`dKsŸ¦$ÊâvPAÜjGçÏÍaB|?ªašjhe>üõý“Z—R‚ &šô#Ýp=3“§”NMUšÍv„Œñv§Eq¯?ˆÂ¨ßﯭ­|ðÁÇçÏŸ:8¨AX(ä\w€1fŒÇqœÍ:·nÝ€LÆžžž*‹_õˆ}]@ˆq˜Ï#@¥VA‘ÍšóóEU¥†¡‚ƒÐ¶ ÎE½ÞÃU*ÛÖƒ€\(ØÕj–sq¹œÉç­0Œ!dÒŸQk4šª¢L(%Iœ,--ضùo<“É8ý¾Ûéô!#]×òùl»Ý¥Tyæ™óI’PJ5MÕuíÉAÂd¸Ñ#@‡þÿŠE»RY•Anú}¿\Έ“'§ÓÈ<ÁÂBya¡Ç ctö윌@–$ Â0!1ÆK¥‚ëíö€s4;[B¤ÜG¡Bäó¹|>7yzZ‡Ô{jbõ«´¯;„ŠŒÅˆ66êׯ¯‡a̹PòÃ^4 }g§ÕízÏ?¿vpнqcga¡Ôlºwïäóf­Ö{íµs'NÌüüç×:A’°vÛ›™É¿òÊé(J~üãVV*³³…Ã8€ñÁ§Oà1P2Ô¤ š¦š¦šÉ–¥©*ít<ÓÔ5M±,MQ­f~³é^¿¾cÛúü|IÓÛÖ„ ‹EI¿T*ØîÔ©™RÉ~‚ŽÏŽ— A¥ Cp˜žÎ-,\…ƒAè8†BF“Þ|§N͈ÕÕj6kض‘$Œ,„¸paá©§c< cE!ŠB9gÏÎ*Ê«ÎÏŽ5ýB¤Ž&hk«y÷îf’ð(J„?øÁ³šFïÞ=ˆc¶¼\98èܼ¹»¶6Ýïûo¿}+“1êõþË/Ÿ\^®¾ùæõÁ Œ¢x0 û›ß<áûÑ/y½Rɾúê¹'øûÃñŽ&#:y;b„P6k†Új¹ÓÓ…F£ïÞÁü|±PplÛØÚj\¿¾C))•2ŠB0ÆBQˆ ñ¹·×)—3„`]WΛ9þ= <ÌJQB)BX S––²„`ιŒ&ˆX]­ÎÌäMS#¿ðÂj¯çÏÎJ¥L>oÇqL)Bœ;7sêT5ŽÆ XÌ* á\œ=k|Õ}þGÆ„HCÓQ4388ènmí !‚ ‚äûßZâ˜ÀÎNëþýšmë­–{pÐeŒ÷ûþŋ˳³EÆXÇŒ1DZ…H ë'VeŸçâ%ÇÑ‘bA¼»ÛbL8Žî8z³éÎÌä;¯Ýv——«A›¦v÷î~»=p£ß0FAˆl6“–ú„ÝÿòŘH~r~¾8?ÿ¥’„) Bœ>=ÁÒRΜ™B( €(Šu]BÈì&œ U¥‡cøÏb ¨ ƒêt¼«W·¢(±m=“1Úm·\ÎÞ½»¿¹ÙüÁ.¶ÛnD·ní5®ãèÝ®G).•2år&ŸÏ¥u!øüùùlÖúå/¯‹Ì4ô{÷jíö RÉüð‡Ïù~Ĺ6•Aî Zò§Àš† ŽB\ð­î®£Ù*QÜ:Fh­¸’7òî~¬RE!ŠN´­îN?rMÅ|eé%¨1O EG@„`Ôjõ]7(—3÷ïï €°ÙÚû›¿³×–x…õfÜé¶>¸ ²ÎöoÞÉœ9™¿øLÿÆí°ÙJÜ ”¸ƒÌ©@0VÕÁæ–·±­•KúT%{æ¢þ­»j6Ó»qa¬ä2ÎÉa£ÙzÿÃÌé“Q·+â8êôÂFS+&•,U%jµƒZÃÛÜ&–I =ñé°ÙŽ;]æ‰ç9'×’~QÇéߺ£OM!ü×ß¡„‘‡2cД:årÖÒRYU]WA¾9Žyþü|»=@l[—É©0F %J‰ëúqÌfgó‹‹%Ç1À²tU¥¸YºŠe о{ ¥ôæ²3^ìsÁMÅP‰Ú zn½h(&!‹bž”­ÒlfFW´·f«VÃk(®€ÀqœX–& ØÒR¹Vë•Ë9˜žZþ“ÿ‰Z¤ú½ïFÍVÔé*¶­d3ˆcº ´rB–™ï³0¤¶Éü€…µíìù3J6£WÊHQÁöÊbâyXS©iÃ@QË4f§‘BBHU­ÅycºJL“>"6f§±ªð0Š{ýÄkaNÌÍø»û2[±Z,SU@`ÎÍ|fÌvñ:¼Ï#téÒ/—²Ù<¥\×}¶'î:Ö b˜*‚c‚€#Àdœ6Mà M[ € Æ8Sˆr$p r$Á™ã $ãqP‹ñætt²ŠÉlFCÀQ“împx{;öæáNOVÊ<ˆ¡kp2lÆg䲄ßGœ#Jág?û©Št®|ê©“?ùÉÏ)ŠÅ)øx”æè›¯G¾úªã£³dÄêN$Y“æc‚­zøIºóÓÒLTtdèeËÝÇÞ?zGˆO¿ù@!Ä4†—Ÿöæg!8ʳ Ý—1ÁèÁ q$jËÄýá$aÍf0ƒÖü£ñ…¸õŽ]‡'îã æ2ì-Î1™{еÛ)•©Õº7oîÆ1ã\0Æ{½ b„ð­[{¿û»ÿ׿ûw?9œ3÷ |!p,àŒ Ïy¡­­Æ;›q̤ÝÃø¬a¨}´žÍšï½w·Õru]m6û.ÌŸ;·èyÑÕ«›¯¼rú«î×?rx˜‹—ôÊÃé^‚1’vìÅ¢=;›oµ\XZ*/,”„£……âü|! ÆŒ‘a¨OT?_4<Ì-VîÞ}Äìlaq1›&[”a×Ö¦‚bÑÁaŒOœ˜’lÞÚÚÔù/ÿçÜ\በúK€4éR€%(ÂFâÍW’üfâþðlÖüíß~ €?AÞ ’ù˜æ‘4¦iÀG¸MÀdŠŸ4ÓÒ‘§þþÔÓ߇šýÀ;˜~>pláÙ‹GÂ#“0FŒ!„BHQTMÓd7 œó^¯ëyB\ÆÕLÓ^ ›?NPËëõ†mÛN§T*ÉThb˜1–ôz½\>/ÍNÇ0 UU¤ø “ËåÞxã~¿·ººšÏçã¹\nïôéÓ#KTÀíïï‡aECãnÇqdMÀ˜¨ªÚjµÁ„Ð[·ne3Žaš¹|^×4™™WæµÔ4Íó¼b±¨(Š¢¨Œ%2ÁjǪªÊ´¿2-˜¼L§…¢(2áŸ<ƒ) ¢HUÕ$9¶”$‰ªªQI 16.A¡$ eA‚€‚aBH†I ÃPU×5ÙIŒÉÝ»÷ÞÿýLÆÁ˜¨ªbF©Tb,ÙÛÛûè£4Mã(—ËBö¯]û¤Ùlš¦Áúú}BÈ¥K— Ã|é¥%>Nž<9B✵Ûí™™™Á`E±ïûI’(Š277W­NÅqcœ±dcc½\®ìî[¯×Ç®T*Žc¯¯¯×ëu]7„àNG¦2‘+„ê»îÝ;wæææJ¥’ëÚíV¹\¦”‚B„àZ­V.—³ÙLºaŒ„€ïû2_p§Ó!” !!2‰ s´ /‡Ç­Ñ%B!pèæ(ù6•€&/1Æ€,Ÿ"ߟ,v¨?€Ñ'q.Ð¥·~ièf’p×íR ™LV.“òÉ&Ê|Žóóó2ꕪjªª˜¦)ç&ç\ÎÎ¥$/aFQÄ9¯Õj•J¥Z­ÏåÓ´yœóN§£ëºïû¹lŽq†¡Ì›)k—½ò_p$Åݱ%<¬œo<’“zÄ·ß¼/d 6ÎAQ Õªézc|pp°²²xíúMŠ‘–i8¹c ytÇ]ŠÇ+D<üÑÃ>DuÓþ‡5ìؼ/††C޵Z-™{çTÁyÀ8I2Ôá ãK9¶cÇ®§Çô ?í³G~ñ°Ü“Ÿ!™å§uh¬M+Ì~Ó18¾ò$×ç¢\.‹8Iªš¦SJ“8¡o½õÖOêãoŽFòˆQ‰TÅ Í웪½Rž1ÔÒ¥*$R†s¤ˆñyñ6Ç–IÚ˜¾?lî„’îPxÀ@fȬû(7f”z¬ ;B–a¤^„apîTW SXˆCMŸP õ˜ÇìLÖ&ÕžKÅCU¨¤‘W¯~Bu]§„X†îùAÌ$qây¾ÌŠ—öR ðÈfâðœÿª[Çã50©nE“í=ªí0Vù!©AECÞ‘„ ãÿ¢&Ñrh& $[! ‘£ŒF:âa°X4ò\\L”š6*--M|;éF€`œãy4e‡å y5²;âT À£I-K&„è†Âƒ–0„1!$I"¤P…q&8ÇS]×+ÓÅérþÒ›—dꆱ³»×nµ¤5˜ª* c‚ ÉÄsÎB c ¥¹\öA}ÐhöÁäŒiªïžeÁ(ãÍ¡B&…±è -mÒ’XL”5œCl ÀR4¹ ‡óh89­§ aÈa`Œ;! O!) IUïGôÏcÅþxݧkq¨ZÎúÑåÊf²œ'½n;aLÕŒíí-!øòòj¿Û­×kÅRÉ ¨¢(‘×ÛÛhmoÜÅ™™éÙ9YŒ¢ªv;Žã 0ƪªB9UUó:Û²tÝà\Œ†!ívkI¤ý•ÉÇ ‡º$>§K©Ú±n·É¢>œÊ£µtø ˆiÉa‰ãô¡Mtð0ÍÑ:Iê'-9ÒÞÿŒú2šJî „ ¥ë·o7uÃ0 Ëéw;žïg2™õû÷[­ö ˆ2Æo¬oßþ䣶“1(ÅÞ :¨uOœ˜²mC¾¹ÙPJ•adãLÆ 9jcÃÐjµÎÖV³RÉf³æôt>Šâf³/…Går†s±¿ß)•UUB(ŽMS¢(MS¶·›¥’Øh6{KK•(JÁAcŒ0Får¶Õê×j½¹¹â`T«YÆx­ÖSUEI’° ˆm[WUǬVë-.–²YK¾¿ßét¼r9S*e¿ÂÛo È÷å!ýâoDR¥Õj~ï{ßÙÚÞ¥ KKK4ž>=³µÕlµÜz½×é 4nl48ç/.GQÒíz½žÿÎ;·WV*AÏÍ··›œ‹^ÏŸšÊž=;ç²ÔF£W­fï߯ݼ¹Ûj¹ËË•çŸ_qÝà/ÿòíï~÷ìéÓ³—/o@ƾÝ¿_#?óÌ’¦ÑÛ·÷vwÛù¼ešZ³Ùïv½(Jþòrå¹çTßÖ×kµZ×ó—^:Éã+qÌ¢(yá…Õ½½Î½{5ÇÑ×Ö¦êõž®SÇ1’„]½ºÅ¹H¦(DÚÕøø 0†…Æ!lÛ6ç,BÎ…à‚& “ë> “÷Þ»}âÄ” 6æ8:Æhe¥*/u]Y]­¶Ûƒ©©\&ªJÂ0.—0L4꺺¼\ÝÛk!„T•ž81%½j“„]¼¸dYºª*–¯¾znv6¯(dv¶@ò¼Èqô“'§[-÷üùùƒƒn.g93ë8F³lÖ”¶¼.,X–®i´ZÍÁ”Œ3hš*çâ™g–dàU¥„àÅÅ’®+Œ‰••J%Ò \Î v’ðVËÕ4*©È$×3aÉ8¼ñÈGG?ü¢!.^B ó¤§UÓ‹(NŸ™iµ[Ï<³”ËY–¥·Û}× ]×ÏfÍ~ßÇ1&¦§óIÂîÞ=˜žÎ†º»Ûî÷ÛRˆÜjõG7MÍq ¹Ç0ƳYsj*ǹp]_QèâbÉqô(J¶·›aku}¿óíoŸFéº77Wô¼0›5‚n×WE c¼^ïIëbÑév½\ÎR:–¥Å1Ëå,ÃP+•Œeéq̃@*€d¼‘••j'Fz:ïûáúzmf&ßëyªJe#m[WÒíz!Ƙ¤Ã„á8F'/¤„p.Ò,‘Ý®gÛÚ—æ„€™™ÂÆF}f&ï8F§ã??—Ï[QăP×ÛÖm[Ÿ›+‚1Fžš¸ÑÔTÎqôbÑ)íµµ)Œ‘¦ªgÏÎjšÊ“ñ€WV*ݮǘØÛk ««S_ôúKE©u`Lпþ×ÿ÷üáTÊS”p}/ìZ?1 Ä¡û£CÒXÚÁ¹HO!ߢ(±,Mjû—<,íHuØ„&Äð@ '=ë†ÿȸ’G:ò@4¯£šlF’0Jɱæ=r4¿P/`!À÷1ç@)\ºôKJ-ÆØÖÖÖÿéïüÅ^§8w>°?fHÚ#þ “BÃP C=¢o:ö÷#k?þ÷q·Þ!q„xœ;&ç܃ð¥øo>¥2LðØèöˆ[ÂDûÐ!éÎ#aÒÉFÖ'æÿHñ#©;FÂIÊBõ÷ß¿;œ )@aŒ3ÆÛíÁÁA—sqïÞA’0>Êû,KÓàœGQrÿ~Mª: «Ã9gŒsÎ…Œ M$ç&¿å\È­_õ(}Mab=ŒBÁ9MÕSõ~¿×éxªJû}?—³z=ÿÔ©éÍÍF½Þ;sfÎuýF»íþþï?ëºþÍ›»ã$a®ôz¾¦)§OÏ4›î­[{½žßÿþÓ×®mSJ~’0ÛÖûýàÅO ö¥K7^©”I&yB £Ò}Õcõµ…cô§4ÕïMOç/^œ]_¯¹n }…’„ a¯ç›¦Q·ë3ÆMS“ÇFÎ…œ1®ªÔó"Ét»ÎE¡`†zpÐm6]ÓTã33y™»†1Æ—a<§§s®x^„Æ:°Ï>ßÒ¾6pÈR™Qin&„X[›ÒuQ(ØŒñ ˆ¥£ß÷u]™Ÿ/É`IÂ0ƪJ ûé§MS“È“‚1ÃÐËiÌ!ÄÜ\QiÉS3cCÎíÕWÏ€|$—]J~?sŸߤËu&»»­ÙÙ‚¦Q)°æœ«*Mßc&Ïi#¿j¬|:¤j–I®cBSÌÞ^{sss†q&¿÷{Ïhšzùò ÓT»]ÏuBH³Ù?sfúÔ©ùz½óñÇ›'NLÕë½óçç-K—ã it²V:q…Âxx=é×*Ù¹Ïêp„ôûÁÜWÒé yræ ÒÂA|ãÆ®¢Ð^Ïëv½_qbÊ÷£NÇ“Në×®mg³æÜ\qo¯S©d$_J)&ß»W›-ܸ±ãºÁêêÔÁþ!„‚ ¾ukO&i,•2Íf¿PpBÓÓ¹vÛÝÜlV«©± B!Äþ~G¢<¢ƒƒn·ëµÛîÞ^Çuý‹—¿¶)jG+”šQÈs^ÇTœ9‡ùùâÔÔEà–s®(T8{v.Š’BÁ~þùUËÒ$/ƒ1ÌÍþù?I¦¹¬ÕzrñIe B( ãBÁžŸ/^¿¾ƒñ¸K²ù½ï]PUš$LÓÆ€X^.#„HqëÈ´y|_2òxC'Ûáû„`©T’Nr1pÎ¥wªÙJ±ö=ÒZ)aýâLˆ¢¡‹—e9kkE™h7 ã8Ž)&xwo÷þúfE#UUÂŒ1Ã0ÒvcŒ÷ööúöööÙ³ç®]£#óE¡(ê•+_¼ølëëëkk'666–——Ã0䜫ªÊÃ÷z½¥¥%JÇÁä·67»½^¥RQeggG×õíímù(Š¢µµµÕÕÕ»wïbŒWWWoܸÑh4Ç)—Ësss7oÞ¼{÷îêêªL-«ªêÎÎÎòòòdJŽ(ж··=ÏËårZêχ@¡J»Ý¶,KÑív+ÕŠœQQc€P±X”þÓÙl¶ÕjI_Ã~¿¿¸¸´»»S©Täø”Ëeß÷;Îüü¼DíAí ðÓ4 Ãè÷ûÕjUʱRwCÆXz‰0æ£ËtBBäˆÉ¡~‚ Iúý>Ƹ^?H£!ßšÍ ©…ªªAÎÌLSJS‹‰wß}w}}caaþþýûW¯^mµZI’˜¦yáÂ…n·û“ŸüÄu]!„¦éwîÜÙÝÝÝØØàœKWGÇq¶··ÿøÿ8“ɤ6êa!„<Ïëv»[[[+++råóùF£‘$IFžçIïNBçâöíÛQ•J¥$IB7n܈ãxaa¡P(öû}iÙNó \×¢(ÚØØˆãxooO±¶¶fÆÆæf£^wœ ¥Ô÷ƒn·+Ýt§§§¥‹¶ïûp÷î]Ƙô-—ËžçµÛí$I0Æûûû!UÕz½^³ÙQÝ¿wŸs^,Çq]W×ué¸,U7Š¢A¨ëZÇ©aéºE‘RÆq¬išt—ÒDUUà TµC%hš ÀcèÏþí¿¹øÌÓœC­v€*•ò(õðä+§Fqïï﫪*]Uƒ h4êgÏž«Õ ÃD)ŠÂs]×4Í0 TUCÉá6 ömÎÇ–O;;;!‚‰¢RÙ0 å*‰“#dšV»Ý&„ôz=é©-;\­V}ßB´ÛCÛ'EQ|ߟšš’ëi¸¸A¸}w0ÈQÐu-Ž“N§377×ívåê±,kdÞš ÃÐuÃÐ5=Š¢ýýýL&Óëõ4MÚ Ã0äD”­Õê´ZMÛ¶=Ï[\\”K§×ë@·ÛÅEQ\,³™ì#½µ×NZ|§’X„ÂÐÕ_½y ýú¿gÛ¶í1•=ì–1Œ’$­·G\¢VZøÿ‚*Šý4].zTXtcreate-datexÚ320°Ô54Ò54 14±24´22Ö50±20A} p±{ã.zTXtmodify-datexÚ320°Ô54Ò54 14±24´22Ö50±20A} ‰Œ3zTXtSignaturexÚK1I53MM6723¶L5³0J4O³4´01L±´H±43K‰yŒ…zIEND®B`‚gri-2.12.23/doc/screenshots/gri-screenshot-1.png000644 000767 000024 00000101336 11310756313 022005 0ustar00kelleystaff000000 000000 ‰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¾þ¨›ù3&àÓÜ™+žÍµ9ÅÅïqײdòxâ]ãf|Ü«'øzâ9pbe9ùêɯ0ÆŽï‡ †pscûoø“—®¿,Ëòo†§Ÿ”DPU c4bY&ÆUUÄTˆ"š$TUå4¥#B°è®(J‚Š"À”2Yž”\8ç<bŒ‘¢ÈI’PÊ㺮LŽ"xÄŒÃPEÅñä«Ó8N,Kªg9¥<bÓT€I’H§¢(MSjêñqÇÇ{³çEª*B”Ò8N5M9Ñì(J!CŒ1ç càœø~¨ë2„(ŽY&iJÓ”©ª’¦”1&Ër‡£ÑÀ²,ι®+Q‚1Ƈ’ëÁà,³Bý¶yÏC>x°wëÖÖü|QQÈînof&_©dÊåìO~r[0»×s§§óž½þú„à÷¾w£ß÷¯^]¨×»gÎTÛíQ6kø~¬(B¸´TÖ4ù¿ü—w~\ø°^,:ª*ݹ³½´T>~:“1ÿîïî`ŒÊåL’¤²,¹nÏ[{{}„૯ž ‚è?ý§Íϧ§ó„àýý¥|f&Ÿ$©,Ï‹®][àœ÷»?Õ4ùÔ©r&ÆàêÕ…3gjFï¿ÿ÷÷NªT«ÙÝÝÞË//Þ¸±þÞ{«/¿|J×ån×-•2岞$áOúxw·ûùÏ/¾,K–¥=[•e2\jÅ @d¼N‹v¯çRÊ÷÷û÷îm¿þúÅr9ËsÝðÉ“¦¢H!Ï‹|?6M•1~ÿþn§3Êå,E‘vv:£Q8ú™ŒAÎç-MS(å{{ýÿïÿ»¡iòÜ\a0Þxã~§¯½vîÖ­MÛÖLSw}s³õ×}3ŠÒJÅ!w»îåËs…‚‚üà£8NGÇù~´²R››+1Æã˜þä'÷F£@U¥n×ÍåŒLÆÂéºòÃÞNSzíÚÂ~tÇqtÎùü|1I(c|j*øþ÷~îÜ´i*²Œðƒ›²LΜ™zóÍG‹‹¥LÆH’4Ž“{÷vû}o¿O)]^®BZ­áþþàÛß~ic£93“× øÃÛ.Ì´ZÃwß]ýÎw^²mL)«×{ó7·ææŠ{{=áâbIQ1æú$Á÷Þ祗ÎQJçA˜Ð”r0Fš&K„„aÅ à€1N‚꺌‚¸Õª q#Š!ý!!„)¥¦©b„]/¤)“e,Ë„sÅ)@×Ï u]Á§”¦)MâBÈ8§”a„TM’%)ŠbÏEbŒÎF4eCÓÐcÃQ ÌO†Ô4Y’H'˜ ß‹FŠ"ÅQ’$c0LÄ)BÐ÷cU•‚œƒ ˆ‰„e Çqªª2B0â$¡bÆ‚t]kìwê{ Œ‘¦)£QqtJY§”2ÀpÒ”V¦lE–+SÕ$I㜃NgdYj±èLŠëë[o¿ýáùóž¯~O)…?þÑß--ÔgàH?”xïšàи1¶€“ŠG²KT‡âÕ1!îø'ůCåàM˜ŽtºI‘mâ-àD³Çœx…¸ø©f¡¸!"YÙD`BÀ<8)ÌJâœsY–%Ižhó3ÚOiE Æ¡_²ôóO¿V@…ÉL0èð!p|D|©ëz÷ïß'z'Ú‹(¥ðcv¨Á§äÞ_в£áÂOªôðd~f›pÿ%Ÿ¡>S]<6žÆ!çºm¾òòûÜ‹¢äÚµ…'Oš¹œ™ÉÙ¬‘$tk«ÙnVVj”²$ 76šKKeÓT{=ÈcŠÀ3Æ8ž2Æ—–*¾†aÂ9`Œ‰×+ŠÇ)„°ÝÅqzñâì§ê(áêêþîncøÒK§„ìì8Æ{ï­†rúôÔÛo?^\,·Û£|Žìïï³lº™$)€€1Ž& zž 0t“n!€P>Ç€BO˜K!„iš uqü4Îyš¦Aš¦q`©@À?nt9Î €‡gû‚ƒ dI;Íøz×)Š*É2àÏäŒGQ$+òØ¢ŒâB(2~>¥”sNáœsÀwwvG£‘“q$I xÆáÝ{Û·>Ú|ÿÆj­šë÷}ø¿ý·_¿{wë»ßý©,“\Þ )ÓtÅuÃñ¿|iz:ÿ½ïÝHº¹ÙZZªÇøàƒ'²LµZ~q±òÎ;¶·»ûûýýý~’¤ã™™üþ~?—3G£ðÕWW.^œƒðSM¸¹ÙÚÞîLMe¶¶ÚwîlÉ2ùã?¾²±Ñ:µ\~ôhïÍ7nmµ5Mqœ €@ÅØjµZž;¼³gÏaBe;;›ªB–%"IŽFCϾ‡0)–*š¦<Ï«×ë¦iV*± PJƒA¿ß×u}jjJ ß÷zýþƒ,Ëz饗'Ã>§ÌÉff Â0!„Bf”F#Bˆ$IâH𦻻»Ãá@QÔF£ñ¹Ï}NQ”(Švw7K%s4ò2™„r@ë÷ûŽmïîì‹%UU“$éõzÏÞhaùœ,+qoíl2Æj•i]×9ãÃá°\.ÏÍÍqÎ÷öö<Ïýò—.]¬SÏΟšÊŽFCMƒÿø›$ Ë $ Õ4™³h4¬¬s³vm:TU)›‘ˆD€ƒf³Y)š2AÆÆ8ŽSJ«†¡A\.;­V |JupaÞÉf¥$IM®œ)øAÜétÏž-2–æóÆþáÙ4¥–¥û¾ âéoÝÞ¹yóôç®í7öÏœY!ÄqäyÏþà;»Ùl c´_ß, 4iìípun~‘sÇñ_þå_þÑýјÍ§OŸ^^^þûÿ}.—Wy8¶ÛmƘëy³³³btÛí­‡æ–—ç——…š7 â8‚À²­ É`Œ£(Š¢Èó=Y’Ç‘e™1Æ[ZZzøða>Ÿ'„@]w†}BÌ0ô†Ã^&“ãxwwwzºfÛÖþîG/’Z­æû¾ŒXÎ6ö6îÅ"D-‚I×ïz§ë:!¸¸°Ð t]ã8IÂRÑ.-ŒQšÒS§ÊBJÓBÁ,•,ñ„ñ¶AgŒ--•Äú'TÀùÊÙê˜IœóBÑ*–,!ú0Ê Îð@Rጧiú¬éé=ëè·nÈš.1Ê!äù‚Y„0¥i¹lC(cÕjF¼.ŽI6“!BÂqr¹^©èE‘çzâ9cÇqlÛr]?IBJ)Bhª6óÁ{?•`¨é¦iÙ‚Ó¡¯|åÕÉ-@’å^¯G)m6['3??¯(J†¶e9sfcccaac !˜ž3-»èÛÑ~¿oš¦mÙ!!@!Œy’BÂ0”$IQÃ0úý¾eÙÙlf8ær9I–mÛÞÛk“É'qüèÑÃ8Žz½ÞG7?:sf`šf§å·û=E·‰jŠ F"RFJù\^|…¦é·nß. Š¢d³YÓ4nÜxâºá+¯,mo÷3ÃqôééB&ì6›Ã f)¥„àÇ÷/_žËdŒf³ïy„@–I6k „Z­!„ IhšRÎmkA0Æã««ûßøÆ%ø«*þðîÝíí펢Ï}n9Š’8N§¦œüà#× þè®üä'÷VVjÆàúõù݃fjfÚ)ä776VVÎJ’Ä—eÙ4ó·n­†!Èçk’$qÎ ÃÊj,—ÏœÓuC,€–e½öÚWF7€©JåÎ;¦iÎÎÌ 骪ÇiµZ¦i®¬¬`ŒœI’ Åb¡Xó^UÕB¡`šæX „`„F²,«ª*:(›Íîìì0Æ|?¯°L+‰ cŠï'BÝ0.\¸¸¶¶Öh4þñ·¾5;3#–VU7‚ÀË•gl;#„ιi˜BŒ°X~Â(tGn·Ûµm[Q”‹—ww»}´ùða}f&ßl0Æÿîß}ý£6þâ/ÞÐ4ùÝwSÊE¢”‹–®Ëù—oml´²Y# “ï|çs–¥ýøÇw]7¬×{®ffò­Ö0“1â8­Õ²Œ]ü]<‚VkÐj ŠE{{»sûö¦,“?ù“«õz·ÑèŸ:U¹w§ÝÙ¶F)åÀÿñ?þJÓŒ8Nà¡I¨¶œsƘïûºn|œ62©, 8Ž)¥B ¯rA-ˆsöI¿@øxE9þv˜¦©p@ˆ/I’4MTUKÓT–¥±ƒ•RŠ1æœe÷$I$Iš|à‰W´Ûmñp€®ë¯¿þ%JiÆŒqÀÞ^¯Trff á×n»„ IÂcÑ4Ù²Ôz½G)CÝ¿¿sñâl.gu:ÃCu ‚vªirš2IÂå²ó«MzÃÄóÂ$¡¥’ãya$Å¢=øŒ±LÆè÷½4eš&«*¾qã6üþ÷¿'ËZÅ“âì${ÄÖ5Ùÿlfã9*ì!'<âìø›Å~6¾e|;BˆsÀùø^D±£–pÎÁähÉäe/0À&üÉ!íw]ÄÒ”‚?-ï9çIB)eš& G3ç,ŠJ‡1Â1FoܸMdYžž®qN ¢cÇ,M±¦!1Q8gI8ǪÊh !biÊ¢k*Ä~¨J˜‘`l-úÕGôs$I’ ‘Þ{oµÝÍÍïßß™žÎçrÖéÓ×>ø`­Ý]¸0›¦TQɃûõ/}éL.g¬®î N7˜,ßžbŒ¿øÅÓûû½ÁÀã4bñ¢lÖBBP³5Tdòê«ç>ù €~ðÁúÖVÛ4µW^9åºA§ åÛ··?úh£ÙºnxéÒ\¡`}éKË¢ªjµ: Ó¨÷£T¾þÕ`o¿ïž¹01’2޹8÷q»“Ž©ëf.»= „Œ…ç̘›{û€s±TpJyJ9¥ÄЀHUô™éO««¼`„ÀœƒîÚZc”É7n¬Íξ~ÿþÎ÷¾÷iª««ûŒqI£ӧ§4M~ë­GiJ×ÖW®Ìc 3ãí·©ª$ËR¥â¼òʲËö÷Î(IRI"¹œÙéŒ EË…_ûÚ…ÏÐÐ8Nã˜2ÆÚíÑíÛ›„๹’e©Š"% ‚$Iã8=°`¾ñÆß_ºt±4¸÷aöò…d8Šš-¿¾µ»™Kçœ ç£VÛ{²™ Ä4µj…˜fÔí&½>‹)›Ñ¦ÊcïÉ&K)\-Xœø;uˆ >7Cƒ§iæÒð+ °ÏŸ÷ÈuÝ8N% #„ÁaÛ¶E±ëFA±>§)•$LÖ4y8 3LS‚\7Â")å–¥FQE çc$D“4¥œsIÂÂN iŸÚÁŸ¦T8²GÏ·m-Mi§Œñ(J…È2߸qû€÷”"`Æ¡I ÚX)%‰YSTä»îh0ŠÓBH–9c™Kø`CbB,‚Ž·OÆ!Fœq8ÄŸzßzÁ€†Ã„À¶Mߺ®Šýž1ž$©¢(‡Qô ¢ïh¿çÇ÷{pÒx ˜ïGš&ŸBý [e’Ð(J’„f³Æä~PU9ŽSJcpãÆm"®@ìì€Ç°ms×…SS¤ÞQö÷Áç>G‰,k–FB/ŒJ–…ŽKÈtÜ%! þÝžï_„nÝÚ¬×{•JöñãúÂBI×Õë×ú}ï§?½ßíºçÏÏ$ Õ4éÁƒú7¾q©RÉܼù¤Õ‚u]^\,‚WW÷(å®A¯T²£Q 8¼»Ûû—ÿòË¿²Žßuk«“Ë™×®-v:£4¥gÏNÿå_¾Õé¸ÿú_¿öèÑž¦É»»Ý¯}íà@:•$P­²Nª* P *–Í,Kb'Ibši꿲 âw’$ Fa¯·#–ý›7Ÿ\º4óäIóÆuËRß}÷1cc¨ªR¿ïçóÖ»ï>®×û¹œ±·×ÿgÿìó¹œùàAÝ÷ãv{E ç0›5»ÝQ¡`‡a<3Søµtª¦Iš&C|?Z_o WVª¹œÉ9ƒNgdª®+â]ðÍ7߸páb’ ×…C¦ Xä® }”ËÂ\߈ãØ4 UUcårñ‰4ýmÅq8S@%I*BÙ¢(Š(J™Ë—$† €s¾µÕ®Õr†¡FQrØŒqJ9!HL}Eù5¸ó9ãIJ)eº®PJ㘪ª$̈²L‚ æœË29ÐñD£Ut»à½÷0„ \f…ït`³ ‹EªëZ¹\ØÞ®{ž/Ër©TøÆøê÷}@¹œévGÁLÆØÜlåó¦iê€ ˆ‰À9WU !XY©‰Í[™¤_`ûlñaÂt¡ª äPÑ$‘ÇŒc¶(å2¯Th’Ãàƒ¹96; IJ !ÕjYÁÅq<6¬þÃ!Ñ£Gõ'OZŽ£ol4OŸ®Bêõ^¥’ Øs` ÆH–%JéÌL~yyêÐr~~ûÛ7|¤){Š‚„R HS°·‡l›?x€L“_¿N›MÔíÂóçY'ýþ ÛíëºÆ8wlKQÔ`¬pU•1†®T«ÙlÖxüxoa¡EÉêªØVkƒ/ÂJ³Yãy·öãúþ(M"]³DØ8U;øè#Ôh ÅE–¦PQ¸a¸aècß1Ɔª”JÅOelúŸƒ8çׯ/\»¶0Ž…zùå%Œçüµ×Î& 5 õЫ Ù4E—O¦›þY´·OFG™1Ç‚ØÆÁ[ܲ4Û6â8cÿ}@E᯼BÃ×4.IÀ²8BÐ÷ƒN§'IcL)kµZ¹\î—ÆšýÏG;;]Bp¹œé÷=U•$ oo·m[ÏåLUÙ)X¯wm[³,m²÷wv:ý¾1bŒårf¥’ùÍ´öû^¿ï% ]\,‹×Awv:œƒ™™< âáÐÏfu0^ó ;;( Áî.ªÕØK/Ñ­-´¿?ÿyJ!÷ú]S!DŽcýÃ[ðçüoÿöV¿ïŸ;7M)={¶–Ï[ÿñ?þ÷……’®+AE‘DB’ÐW^YZ\,ï{7:wj*óÇ|õ¿ý·÷Þ~û±¢8Nÿð/ÿ«õÚobêCÞm{»S­f%IÚÜlB¿øÅ3o¼ñàÌ™j’¤7n¬+ ‰¢ô›ß¼ @Î$¹9vó&.Y±ÈÕ*+ Ðï …¼íE1Mã7·d½°!\Y©Ý»·³¸Xj6ÂWûÍo^‚n×ÍçÍ0LÂ0¦”™¦*¢Er]ìׯ/‹!ˆR¶¼<õ›ë?‘0MEו$I!§NU0F¶­«ª$Ëda¡DÀÿøGW®\'ê:OS€Àø(uöx,³8òŽñB¿‡vÀ8º=+„|ÛŽÃÃùá~?æþ%}øñ‰ˆ¿äšÃËJŸhçã8ºqã6!dJ á~æ å\¼8S*Ù”²RÉJ’R&ÂË—çBSSÙs禓„NMe$‚ðgoþôâ…KˆÓdã}z‰%éèÑj2tå\Lý ¨ïg.7æÜÍÔõ‘,ùۻι¥Tè~𠣨ÕÒªSÙ«—ýí¸?`Q²N-Ž­X’@Œå\–§iêzZm bwº™+!B¿#[Éä~à°?>†±,q$ŠBÈÜžä‹B‡²Ã?áávü‚É[øÄe'º‹Œ!a2ü‹î÷€ƒ6ì÷ë9Æòòéˆs?æxñT)kÒ”rÆ1A^¡Ùx,U¤"@ÙÓ3®Ñ0-|îºçzI·ŸL1B•Rj[’$1Δ’³g¶ev«EÐ ˆÄûƒ”RŒp.—yÞ¬ýåÄ9¿}{ca¡´·×«ÕrÃa@)«ÕòI’FQÂo·GBû§”¥)e,›ž0õˆ`Ñõõ†ãè•JF’°ïG€qÊf&£+ŠÜlö5MÖuµÑèg³†ðî(Š„ðý¸ÑäóƨÑärã³d¼ìC·¶Ú{{}øÕ« €$Iu]¹yó‰¢3gjI»nØh DîÁC}ïý÷ïz^„\^®\¿níìöþË/ŸÚÙÊ2Y[kòyëÞ½ŒQÄŸÿüòÙ³Ó²"ë¶Ùl´MÛz¾ïÂÀr¹ÌÆÆöÔT¹ßE ÃaDSJ^]Ý „,,ÌV*¥çÍÖOÈ{ðÑG›Š"½óÎcM“;‘eiÿâ_¼ú³Ÿ=xë­‡‹‹e±_(ØßûÞQ”ììt„ÐqtÓTF£Ð4Õn×Íf×_¿xî\í¿þ×wÓ” ¹!Mé… ³ëëMËRÇiÂÂNgÄÿó?ÿ¢¦ÉõW‡¾ãè³³…v{äya§ã2Æÿù?ÿ‚@/í|ð`w{»S«åžIR„`¡`?~¼·µÕ>wnš1EÉØŸ{‚ÿc<-ĉDtÅ„#øØõâì³{ì÷ñG1 GÿGÿ袰-ˆÙY.g$‰È2Á™™œ¢H„àùùBÓ£ ªˆ2=]}UÕK¶F)ƒʲ”Í:Û¶(MŰUYàLÖjS9¿Ä9ßÙé†ò×ý‘$ÓTãAon¶G«Vs[[íÖpüûÿFcðÃÞY]Ý?~f8 Nª¾˜!ê"vz^ððáfÅa˜ÌÏ3Sä£CïÜÙ6 !ôäISQ¥ì«_=¿¿ßôhR†ñâbùôé©·ß^µmíµ×ΉÔ÷1I‘eiŒ<¨ªÊáÙߥà]ÎÙ—¾´†ÉÜ\^"X7”8NÓ”0Fa˜`ŒVV¦ãšF.\˜6M¹X´%‰Œ†AGB!?2ñ¢ç;Ò4åŒ °`!âSSYB0¥TÕjv¿¿¶Ö`Œ/.–¢(‚!„”2×t]A‹¶;ž^ÃObgþ®ç¬Õl&±G0´,8¥Ô'êVT²àŒƒ˜`Pß­²Yœ$^sàúún’„ûûMUÕ0FÙŒ½»»g&ÂèØFÏ?f÷àÙ('¿èú_BŒñ8áBÄ×uåêÕy„ ïGcŒq>oæó@’ðÒRE’†’¦Œ\(X_øÂršÒ$¡º.C KUŸ3Xàoˆ åJ€â§½‘ss4uîß_/ Œå©êô{k†™'äyv—¢Àóa¿ï½÷ÞÏ‹A§NUr9s}½¹·×ÿüçOml´9ç®®¯7G£”ýÙŸ½²µÕQÉ£QðòËKW®Ìol´TUšžÎ=ÇïùÍÑgMB‡ˆ]G„…tþ¼Å"²_MS¹re!¨ª2çLh®„ Œñ¹sµVkèyáå˳óó¥(Jd™LMe¾øÅå H^œý^€=bŒE’$lÛšªJ”2ß×× ¥BÁ °ïǺ.GQ¢ª²@‘8¿claì÷t‚ÄRÏOh /Fo Ï«ªtîÜ4BÀó"YÆ„ j5[,ÚŠBr9Óqôj5',9¾y^ˆ²mmk«Ýn»"iá÷ô4QHOñ¾D(M…~ÿÎ;w|?’e²´TÎçíz½·»ÛýâOß½»}ÿþn’ÐrÙÉfÍNg45•m·‡Žc\¿¾€1 ‚è÷SÿãH0~²o8ç"'â¹ÓÚ²´Ï½r a8öL†"`ÎWVjµZ.ŽSÛÖÃ0I’´T²«Õ¬ãè"bdj*û{Æ< ëã‡Ø 1ñ‘ðå¤)s½°ÛõVW÷]7Ä™¦:;›Ç ‡Á` ‡A£1ðý¨Z͉" ÆB@)ÛÛë=ï¯ø I½¾IìD”ðˆ¢äÑ£½(JDöFš²á0h4ú•J¶ÝÝ¿¿›$i­–³,m}½!";J%'Žr~]kþ³Š}‹ªM‡x³[K\ü™[pìöãPû?>ÓÃÀù `Ì= B0æœÛ¶öúë1†iJvH.g V’¤++ÕÓ§§¢¦„¦ÉµZV¸ö% «ªœqtÈ!?Ôøà„o6HB KŒ3ŒAÄ8ãPF-Úöclk»m[z.gEQ¼¿?ÀMOçSÏ`Yñ÷ö‰¡cC”aMåœ1 “$õ}À9±Lˆ1àbÌâp1:€ýÃø .¥AƒpðÓ‘KÃPÎfDbB:r!!X–Y’¤žÇâ«*R¬©Ÿ°J2xqŒ`D`aŽFþíÛƒ NSº¸X¾zuqmm_€²ù~”Ï[ å7VUU€ß¿_ïtFŠB^ýâÈ X€»w`ØçœÙ¹sk‹¢d0Ê:à<ºû€%©RÌÛ+§ÃF3Žˆ¡'ƒ!ÖukiÁ}¼NãÂ’4îöXœ`U1——´©JPßówö,)¹¬V› ›­¨ÕaQ$eÎõûÜ™hoß\\ø´ÂúDíˆçÍó#ÞCÀ9 Û¶nYše©²L(M§§óÝ®+꜉l‘Wìû1ư\vDA5ÛÖº~ —8£@²€dA˜F-· !,èyÆãLÂR˜†›ýmMÒÄ) e,‚!ëõážB “¬œEZ–F)µmBàØ:Ëài‡“–E‘؋ῇ?ùéßÙVÖ÷]Æ"'ã0Êã¢éÉ“­4 …<¥ !l†®ëADQDZø$„(ôÕï{iš*  Õê4¥€ó´\. \(„`¿ß‡AhY&ƨÓ‹YK !Žã˜sE¡(]†Ò4-I’4Mƒ ׯÊd2ã›s>šÍV¥RÑ4u0躮(Џ`8ŠeQLUQT€ëŽâ8Re²„Ûoˆ’rãØ_[{¢(*ç|iiöî݇§OŸyþv=EQ–––Â0ÚÜÜqG©ç%ÕjöܹÙ;w6kµEÓÔ‚ fŒI¹~}ic£ŸÍJª*qÎÊ››Í›77UU—eíÌ™R³9¼p!h4€óç!««(JN*e³Æ›o>lµ¢ééìÌLζµÑ(h·Ý4M¯];ÕlÅ‚9×®-L$Ÿ¨“ÌNFÁÂã‚Þ‰²d¿xYÎa@Æ ëvºÝžmgšÍfµZ¹wïás`õSD&BaëtÜ$Im[§”sγYÓ²´cܶµ$¡I’:ŽÑjF£(“ÑEudÏ‹)åÃaP­æ CÙÛë‰ú<B.ŠRU•ÚíQSI’ŠE§RÉnn¶F£@×BH·ë{^”Ï[ý¾¿¿ßWUY´„1þTrù$XÁÇüGÀ'xί‡ BC&„ „Z­ãô¹O÷£æýÅ_|·R©`Œ9gBæŒá{’„b,ö™`Fš28€¦TQ%FÅÎ8Æd‡Vp.êKÛ€#x(“Æ9cŒ`!¤Œ#Dº0-0Að¸ìð¿ˆ'U»CÕåÄC %Ú'Î^ÀQ™â‰7ÀC «o›|cÀhêÁ!!¿uëÞ«¯~E’~ …2~"›;;;€ƒ„R@š¦I’pÐÀj‰ÂñB¡¥ö<^Qtç¸×ê$Nvûás8?*{ỗ‹'º±`òpòçŽèjz2qøÔƒâ]‚I±uÒ xT}|°8ŸÀa!,8¹µc, @€ dTÌ(Ä8CB£8 W!}n¼¯N•—çªÛëÛ푬è[[[®ëA0ÆŒ3J)‚ ¸ÊdY2Më°Ã>v°L# €ÇË$€‡Gž±#g阙‡}xÁ„mìèqãqžL <1q'Ìb%;V¸lÒcwä];›­€;€€3žq2Š,yî0¦Òܯ;™ŒiZûû{ºa¤Iò¼ùDÂhkuýáý~ªLÍÌ3Æ a2Æ“$š¦€˜„a¨ë†D;š”G?úŠƒãk„øßÁ²=1?&'kÎc/ü‘ËþäÚ +ÄØÆø˜QÏb?<ˆfܸ8ò$DÑxñ‰™b"Àc£ðVéÈ5!B÷û½‡÷ïèº)«j}gÇuG’$­­­-,.ÚÎ ‘©Nºwwsuw·UYJâ¸PÈ‹úÒãzišªšš$ à@Ó5FÙ!äQ7kL9ÀxvNöÔ‰åî8äœ-@„gþR»ì†äÓÃ=}lW‡'ßÌÇnyQ¤-ßG‹8ž]sBƒ˜Á‚„`ÆÒ8IDÝ0dU•E–•l.«i/J‘9bÙÖÿúïþ·ýýîÚÚîü|av¶!Ôue4 ú}¿RÉ “”Ò”††‘àEl× )eQ”‹„0ŽS€ˆå:ì ¬¿´ŸÈ3tb£™ÀDŽמ`ä¯ôö¿ûé‡SJ9àœñ$Aœ#ß¾ûî ŒÉÙsç®\¹ð“Ÿ¼ÅØówáUUkµißGž·{ãÆn·›.,”f÷÷Ÿ$ ÚØŒF!HUå/yæÉ“F£Ñ‡V*™¹¹âêêÞæf3—³VW{ZTxù’„özžý®Õò_þò™çý™¿QzzY: AC®Û®Õ¦'[¯ïNMM)Šò¼Û „sÆÃ…a\©dVVªDBišLOçã»»ÝlV×u%â(ŠK%;¢8¦ŠB •J†sÍ[[í©© !Èó"ÇÑ{=c¨irÄÅ¢Å1¹ßñ;Â9`ìŸs.t¨\Ž$IÊ›žÎýùŸÑ4UU•™pòyP,ZGr2ŠBΟŸ>ü0nšêéÓSðÉË€ss“°Dÿ ýѼfœ³£GD©êÄh ‡Á¡D"? ƒ8?øïðO~x„þ>AÏŽHÿµýc.=£]'Lvßs%$ìh"ù²VË‹¶às’ÐÁÀ—ƒ{f¬&|ŠÒ” \M°Ó\7:+E) ‚$M…û Ë8Qd\@ P?d*nI’TüöýøðÕRç¸Ù‡¶˜£‹ÇŽ%v%ñG§¿F¬gqùE u=ÀXëvGkk[ª*ÅqZ©dΞ~üxg0ðmû(Vóúõ¥­­æ`È2ÎåLÃPVW÷Ba˜pÎÓ”*Š4—/ÏEQº½ÝNº°PbŒïï÷㹜¹¸X:^¯ç½÷Þªa(º¡  Æ–¥ÍÎæoÜXçèº,¤Å«Wç ëƒÖŒ1JÙâbY’ðÝ»Ûù¼=†¡ôzÞÜ\Áu#Œ!„°ß÷ Áíöpi©rêT¹ÕA%gÏNïì´ïßß­T2„`‘s’¦Ô¶µåå©÷ß_«V³A,-•?ø`]–¥(J._ž3Œ_](ûôȇ¿5Þ ¼®+„àz½›Ë™a˜PJMSUUy{»M)³m=ŽÓ0Œ C©×{Ýn¢(’¢ÎÁövÇuCBpÆŽ£‚0Fžu»žmk÷ïïºnhYšXBÖÖøÂB c(I¸RÉìï÷!„’„÷:ý™™oéº<…„à'Oš•J6—3ƒ ÙÜlu:îü|1Þ鸽žë8Æh4M“3RÊï÷ýz½—¦ôôé)ÓT³YP¯wUUÖ4Ù0TÇÑE¼Z½Þã,,!„{{Ý8¦TþW”WÄ~2ûysý mÿù?ÿ_ögßAbœ4ŠBP’0¥c„1VÞÁÀE ìÉ2i4úŽ£cŒÇq]º¦¤”¦)ãœ>¥ÌqtÏ‹Áš&kš$ä^Æ\ËÁ&B"w»^’¤¶­Ax÷©ir¯çEQb*„@Ôž·pÎþç¼ß÷t]ñ¼È4Ñ`„¢Áa¢jcŒR.šÚj §§ó"R¡Ý2Æ-KÓ4)I¨à¶ðCBÁÂ/E)+¶€’þ¥4ÆÕtÝÎÜ2M{ww÷K_ºþ½ïýॗ^yî=áY‚žݾõˆ~êT¥Ñ¸n¨ë2Bps³-Ëdn®¸°PÊdôÍÍö“'Íééüîn÷Ì™ê™3ÕGöD¥§j5‹1jµ†ò'WëõîÛo?J ®+o½õèÔ©JĪ*>=Õlß~û„ —3÷÷³³… ˆ––ÊKK•>Ú9ŽEÉk¯›žÎݾ½%‚Àl[‹ã4Iè—¿¼²ººÿàÁ®a(BÓTww»_ùÊY±u».Bpn®põêâ­[›Æ IèÜ\aw·—¦´ZÍrÎû}¿P°*•L¯çýìgfg bƒÛÜlçr†¦)qœz^ÔéŒ.\˜Ñu…RÖnww»Žc”ËÎùó3ªJ>ɶ !|zÙxAöQ+H¶­X´K%{4 K’p&’DG×4y¿'j½ˆ½ÿÔ©Š¦Iœóóçg0ðËeG@5É2ÉfÍsç¦cù¼eÛš˜¾I’6›ƒ••j.gˆÊ¢cÃPOª4›ËÒ$‰,.–EÉ8ÃP CÎïS§*®f2z«5&Å$¡–¥Öj9Y&Ž£ëº,ËÄ0”ååŠë†;;]BP&c@òyKø£K%Ç0TJY¹ìø~$–4¥²Œç把B²Ù"ç\’H&£Û¶EÉÞ^¯ZÍ:Ž'©aÈŠ’³m]’°¢ÝÝÎÜ\ᓀ˚™‡{Aˆ´íöHÄYŒFa¥’)íÑ(‚j5Çi§™Œ±·×SbšªeiŽ£†Æ9n c\Q¤+Wæ›Í$áÙÙ<¥¼^ïrÎ3}~¾ìyA»=BŒÑÙs5U‘â8¢Ä÷ãr9ãºA½Þ]X(om‰¼( ¬¯7+­Ö@ûÐu…1v÷îv¥âÌÌäMSŒqµšív=ö¼¼\Éd I"œ³åå© ˆß|ó!B¨VËq΋EÛuC]W¿ÛuãssEU%APJ Á²L  P«}¬ÇåÓˆOCb¿0r¾Xó“$uýÉ“f·ë-,óyûÞ½õõF±h' ÝÛëqÎ㘾ôÒâ`àïíõΜ©Öjùj5ûøñþúz#—3ÖÖšW®Ì}îsËo¿ýHׯx³9ÈdŒVk(I¤ZÍu»Þ¬GQq­–}õÕ³º®¸nøÆÄDœŸ/V*ÙÑ(€ß¼¹éy¡ei„àééBÆkk$¡³³…RÉæœ¯¯7[­¡eiqœ^¼8{ÿþN³9pãüùé™™B%ƒ—Ï[œsB°iªƒ÷î¶a¨ßúÖõ{÷vž]™Í[–vútU’p«5üÚ×Î 3‘iªKKeËRã8Å‹Öõ닚¦ ‡¾ç…"Çò´/ùŒ@ñ`Œ!NŸ®Àû}_–±P 1†ÕjNŒ'I”²ÙÙBPÔvú!(ŠE‘l[5#Ã0þÃóç§1F—/Ï% Ÿ>=U­æ$ c K%GT¸…Iã–¥>íl±ý<Š’8NGÿÄ=|[þBp^ÄhCƒàñãÍj5;…ÃÑ(«½¨š–$”R¦i2Æhf&óæF&¦©Þ¾½U«å…”JNµš]]ݧ” ‹e©†¡¤)}ò¤Õíº†¡T«YÃPs9£X´(eï¿¿º¸X†nowffòÍ4eag³¦˜+ù¼Ùj ã[[í$I3ãôéêýû;ý¾oYªïÇœsY&ÕjÎuÃj5ÇÉ­[›ï¾ÛÕ4yn®@)‹¢}‘dX«å,K6€‡ëÕj6“1„61úwîl]¿¾ÔíºÆ ã8¦–¥¥)šÊø~Ôïûa˜¨ª”Ë™€N¥’qãjjϪ$ñ¼y~HHè÷¢4v¥Ã¡¯ª²,“Ñ(LSZ¯÷Z­Q³9è÷ý~ßwÝ Mi«5ìõ\ÃPF£0 “8¦±´Æq*¹VW¢èïînG(÷Ù¬Q(Xï~šÒVk$Œ3€;w¶ßyç±°(‡þÎNW`{z^Äo·‡Aض†´m½VË~%ª*‰³"^–‰Àò¼Ðó¢ ˆ{=w8 $‰¤)m6‡ûû}Ѷ$¡†¡Þ½»¦Ôu£ýýA¥Q”6›ƒýý¾ë†Œ±Ng¤(’,K­Ö°ß÷Ä\ïtFš&×j¹O½fŸŒ|!ø ßSJf¹ì‹ë†¹œ1òýX(÷c«§Ȥ”¹nX,ÚâOI"IBàIBÓ”FQZ(XÂNP)ŽÓ^ÏËåÌ4¥A÷z^&cd2:¥Œ1>Œ±J%#ì©Æ˜0ß|?v-MY£1°mÍ0± ¥ì0bv»#ÖdŒ™¦*$Ö4¥Bk‚J%#–î(JG§” ™`w·Ûïû§NUD1gYš¦ÉÂ!lÀÃOŽpÈd†1äŽ:|x ßùË/ýÕ_ýÍÕ«×_ýB»]wg§Óï»õzß¶U×¾þõ‹iÊnßÞ&úVk(jÜY–Æ“o{»;5•Ñ4ys³µ³Óåœ{^dYZ¹ìT*™›77û}/›5.\˜½yscmmÿìÙéýýA£Ñ¿pa¦^ï--•?Þ&Þ f€o½õ(Ih­–ãto¯ßï{SSÙÁÀå•S[[íáÐbÆøÜ¹é4¥ï¼ó8›5 CùðÃ'Š"!K%Çó¢ÅÅ’$á••šeiÍÛ··F£ðêÕya«5|üxs0=›šÊîîvUUn4úŽË9oµÅ¢3ý¾·²RËdŒÑ(pcuuïæÍòO^BèÓ–xšzad=È9ÈdŒk×G#ßqtÇ1|?Jªir¹ìˆëff €$Iãù¼%6õFcP­fLSEÍÏBpBp&£§)5 %—3„¡wj*›ÉÓÓyÓTK Åfs(”‹BÁþùÏŸµ~n®¦TוÑ(œ-$gQõ[(oª*;Ž¡(DU%ßg”²ééœa¨£Q(Ixv¶»®+a˜È2žŸ/‹v³9t]-¾|y^’°$añ-ª*išT,Úš&+ ‘eB*maª×{Žcd2ÆÊJíézt¿”žÖï_„j)¼-é÷½0t³Y£PPÚ푦ɭÖpi©R*9á/€¸àªj YšòJ%³²Ró¼°^ïFQrýúâþ~o¯gY„pm­Q«eƒ Õöz^©dA"J/Hé÷ý¹¹b%¥’sûöÖµk ’D¶·Û’D4M–$¢ér6c‚76Z¢ü–ªJiJ]7œšÊ‹v¯ç% ½pa–1†I©d sM«5<{¶ˆ¢ôƒÖçç‹’„Ó”e2:!8ÀݻۧNULSMS*IB ËR&c wv¶§”Õë]E‘„ݳÓáœ[–úèÑÞÊJõSqîYö|á‹aÛú}$÷ïïH.—× £()—3œó{÷vÖÖŠB–—§Z­¡®+ž†Ã`v¶à8úÆFk{»3=“e)â½½þ‡>¹tiÐéŒÖ×›²LªÕ¬ïG»»=ÛÖvv:¦©NO秦rŠB$‰äóÖh´Z£'OšiJ Ë4Õ¯~õ¼Øb‚ ~ð`7ŠÒLFzD&cX–þäI3âµµÆÌL>Ÿ·ÚíÑþ~W–%E‘NŸžÒuE’H>oöû^«5\_o¦)+•lßTUÚÚêln¶›ÍBh8 ®^?{¶¦(Òþþ`mm¯VËy^ô£Ýùú×/ abmm¿Ý V&³³…ÏàÜ;†Ÿ_£.ü‹¿øî·¾õ§Œ1J„ Æ0ŽSaTÏå,ß)Ž>Yøjà „@Q$U•„×Ü0B° |?Â¥)®XrnDþ½ðÅqŠ*-E‘Z­¡¢HI’‚“„ŠêŽ£§)MS†ü$¡’DøÜ‰ˆÄLFu1AažÛÝíœ?? !îð©©Ì™3SIB…#ds³åyQµš­Õ²IB…×\G»]wyyÊ0aÙÕ4¹P°„&=.©Z­f9‹‹%ƸëF…‚…1 ‚!À9qÂí«ªòìlÁ0Ô|ÞGƒ!„’$›+˜¦*‚HG£ T²›ÍáÒRY–É`àmo·9¥_øÂi1eEZ`j*‹\\,C†Ã —3„Öîy‘páß¿¿[«år9Ó¶µfsP(Øè3ä<Ã÷âør„Î1x7o>¬Õ²¾ïîv…Õj ww»„ k×ggó÷îí†4E¯¼rJÄP¬®îþÚZCxoJ33…|Þ\[k4ƒ©©ìövûóŸ_ž™)|ðÁz¿ïëºÒj ]7tMÓäv{43“ßÙéJþú×/åóæßÿý]ß³YSUå~ßÓuùµ×ÎÿÍß|$VáõÏdŒ^Ï£”åó¦°²‚J™Œ1žýõ_ÔíºSSY]—³Y3Š’ÝÝn·ëú~,öuQR«åD|ÇÙ³µá0jÂ÷¿ÿó+WæÇh4Ãa°»ÛuÝuÃ×_¿`YŸ¨á)Äу÷ÂT§ëÊòò!Ȳ´j5›¦”œÍÙ¬¡ëòÌLBtþüô`àçr¶0uÍÎæ·¶:33ùj5+d4I£‘ŸÏ›‹‹¥LÆ U*ަÉÁùùRÆÁ……b%¢2¶$Q„1›5A¡«Wç]7”$œË™ƒO)n:B°ç…Å¢3x®ž=[ÓuYÔñ`Œ Ï „HQ¤Jű,ÕuÃS§*"»ˆ1®ªR£1aÂtˆÌç­µµBP×U!oÊ29s¦šÏ[Ž£¿ôÒâp”Jv6kŽFÀù æØ_€ôÿ܉B¨!Îy¯ç®¬Tû}B˜Ï›„àõõ¦a¨­ÖP,§œsŒáêê~©dg2æ£G{„ !*ž;WƒõûÞÆFc¤ª’eiŒ±0L¶¶ÚbÁŒc:úKKe±ò ­) Bp¯çu:®ë†ËË•ÁÀÏfMÃPÁkgÎT‚£QèyAµš¯+l@¥’€§)ÝÚj‰mÂq ÆxµšÃ­¯7Ò”‹öÎNwy¹Ò錚͡°VéºlÛZ¹ìPʶ¶ZŒñz½§ª’¢ÁÀ¯×{’„ C¥” ïC»=êv]JÙÔTV ýOØ¿O×ËüE±ça¨ ü7Þ¸¯(ÄqôÕÕ}á‚«Õríö°Õ¨ªT(Ø¢<çüñãÆ«¯®d³V.g>xP¢¤P°Î`w·[¯÷,KÍç­Fc°³ÓÑ4yq±T¯÷nÞܘŸ/åóæúz³Óéº¢ë ¥TÓäz½W¯wËåŒðîø~45•19qœ¾÷ÞjÄÃa ªR½ÞËf @¡`;ŽöèÑîÂB9ŽÓ;wv,KëvÝÙÙ¼ïÇõzOˆ–Ž[,Z²L‹qœjš$Œ—.ÍRÊvv:ž¥)íõ¼ýýÁ¥K3’Dööú‚bÑnµ¶ã8­V³««BÁ§ æófµšÿÄ—'å|Æù ‚µD(c¢.æ·¿ý²a("ŒÎ0Œ1!襗–yšÒ……¢ªJ²,]»¶(tèj5[©d„*1’å „ðÒ¥Ù ˆû}¿P° ‹s>;[\X(Ÿ??£ë²a¨I’ #¨¢+ÄøÅÅ’ijpÕ)&w%/½´´µÕÎdôbÑŽ¢DXU㺮  c$IøÂ…]—dK»=²mM(Šš&A]7´LÍ25\T(XÂK;7WG²L„ë! “3gª"óV–%„ ¢«W0†Ãa(ž&IøÓ†Úž¬“Å^ Þq´A”Èx뭇Ţ½°Pzï½5Bp§3Êf !ÌÇq*¶ö^ϳ,õܹ™½½ž`BP–¥ùùâÆFKh\ž»]÷ _8-IøÎí(Jffò•JæÖ­­Ç÷Ξ­‰Äýý¾¦)/¿¼dYÚpüÝßÝ%Ù2½Ùt»î;ÛÅ¢-Œ}ý¾—$©¢HŠ"]»¶Eé|ïêÕyŒQ³9°mmg§Ûﻺ®È²D)ÝÞî|ç;Ÿoµ†››­á0˜žÎw:â‹Ò”~å+g)e?ûÙCë†ÂýÊ+§â8yãg÷3ŽÁ9¨×»Á/|á´iÚ¿JŠÏŸÐ¾l4 âXß1$e‘ªJ†¡NOçDE‘Dp´mëý¾7ú"W&Š(-•œ¹¹"¥LוrÙÑ49ŠÊžÉè"Ó÷£ÙÙ‚Pƒ Îç­j5C)Õ4ef&Ï3 Udt]„iŒ#»e™܈×4饗çç‹â‚ éõÜr933“ÃctíÚ‚¢ι$á³g«š&[–jYš<‘$,ôXA¥¹œ©(Òôt>M)„H"$I(¥Ô¶5MSšÍáîn÷“ êÏTç^þÅÿóÝoýã?…$‰çyQ>oRÊLS=Pá­[º®”JŽˆØ—e1ç IÒííN¹ì¨ª Žœ\° bsã˜rÎ,K®tJY>o£ ª*¯­íËòA`ŒˆÝCjš !ðýø°^7 5Mi&BYÆ¢^ï ¶¸ Óq [U%× ‚œsÓÔvv:{{½S§*Êatèh"‹E!(V2B°ë††¡ˆº0UñÉ“æÞ^OÄ¢©ª$ LjBÑŸy㺓6ÝW_}å?øÑ… /‚M—s‘‰òæ›·2]ÒKKeÓTe™pÎD–Ó»ï>æ\¹2—ËYwïJ%S¯÷ú}n® Œ£å²# 8Œ±o~óÚ½{»kkLF¿vma4 ?Þ§”u:.@Ó$ßËeçþàÂînÏqô[·6E|X­–Ûßïîs§$‰üøÇw=/JS¦(äÛß~yg§û×}sq±ŒÌdŒË—çnÝÚ¢”I€·Û£+Wæ/]š[_o¬­5G¿vmAõ>üð‰ÈÓÐu9—3ww{™Œ!œ™É¯­í÷z>ÆèôéÊÌLA×eÖ-I¸ß÷ßuk«ó¥/¹paFŒìÏÐËÇkopö‚à銖åóÖ«¯®†"± ˆe™ˆµýÊ•9áZU)“1$ ;7EÉpärfÄBΟ™ÉÇqª(’0ÇJ2fŒÕjÙlÖÈå E‘,K:Ž6œa‡7M!xýúçÀ²ÔlÖ ”Å1ÍåLÓT Á/΢ƒrjPQH¡`ýÁ\(—3››­4¥²L._žÞ&ÆÈq4x­–³m=›54MžŸ/:Ui6‡" Häñär&Bв4+\.gD|b¿ïI&sÎóyë•W– „‹‹åJÅùlŠÙ³ìzàã‚€Û¼r‡Èbl6‡ŠB’„æóf¥iÊvw;a˜,.–+ï¾û¨ß÷$‰pÎ]7¬V³Žcˆ™º·×››+‚[­a«5¤”U«ÙµµF¡`‚67Û¾Ÿ=[j:Æ( “lÖÈfMEoÛð©àWÎ9X^žšü;—3ÅÖË¢ÙÇsý.+•œRÉI¾€s Â:žÉ›‹gŸâ¨ª$Œ}ù¼õ«gå„wãðïç¿åQ/a8ô·¶Úíö¨\¶WVjÔ{=Ot+B°×ó²YCQd„ÐÇu¡•É2©T²ý¾ÿèQÝ÷ãbÑvÃ0Tι§³Y#M™ˆƒ+ív{ôäIC–eÆX£ÑÿÓ?}9 “v{85•=Q¶j ßõ \ ¿ hnò²gºR>îâ;ò‹ÿ2‚r!DišîííA$‰¢Ž=g‚ßýîÿý…/|)I’0ŒÁ¢^Æ"3 Â~¿—Éfr9g¿Q,–¢(Q“Q”DQŠ ·ØÌ’„2Æã8Žca,ßëõ…©@Qd]×K¥|£ÑVÕ±Áp €­Eíõº²,Û¶M)M’„RjƸ¹qA@QU5MÓ4MÅÙ0 Ó4•$IP¡8ŽcÙ& CBH†Š¬H²ð}?M)cŒV?qËOK”BΣÉÈõÂÂ`𓟼ñBÄj&I|ëÖí8ŽÓ4%„@%IÊår¡‡½ûî;½^ß²ÌåååÁ`¨(2¥4Â?üÃ?TUe²VA§#þ=JEˆãxuuU×õ$IvwwÅEQºÝî©S§×××K¥`mmMÓ4Ûv¦¦¦~üã˲”Éd²Ù¬®ëqœÌÍ͉ B¸³³³¿¿?!„sssÃáˆ1zæÌ™ 677³Ù¬çy¾X–i&ãLQTŒÑþþþìì\»ÝÒ4 !Ì9ßÚÚÂY–eš&cL’d¡wˆ¤O„çìc0Ô¡âe8`‡(éOß;q?! ìNÏ—ñ‚1Éç³½^ß÷i>Ÿ€‹†2ÆJ¥ÂÕ«—‡Ã‘çyŠ"Û¶)ئ( !sb÷ „€q WUB>33 ˆ¢°Z­†a$Ë’,K™Œ FŽc«ªšÉX’„¯]»Òï÷‚ ŒãHØþ ô•m[°|>×ëõ0†Iº!IcÃÉØCΩmœs"!ðu]‡2–v»m„ $‘\.˘>¢A$I,I¤XÌÑý&A`OTeE£.zTXtcreate-datexÚ320°Ô54Ò54 14±24´22Ö50±20A} p±{ã.zTXtmodify-datexÚ320°Ô54Ò54 14±24´22Ö50±20A} ‰Œ3zTXtSignaturexÚ³LM2²L1O±4K4N41³4¶°°LJN57J45H232’̤L{:çIEND®B`‚gri-2.12.23/doc/screenshots/gri-screenshot-2.png000644 000767 000024 00000113003 11310756313 022000 0ustar00kelleystaff000000 000000 ‰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-2.12.23/doc/screenshots/gri-screenshot-3-tiny.png000644 000767 000024 00000076455 11311210332 022770 0ustar00kelleystaff000000 000000 ‰PNG  IHDRxpÊ P pHYsii¦¨N vpAgxIFuû|IDATxÚí½wdÉy˜™Ï¿W¯¼¯önz¦ÇõÌìÌìÎúÅî`—€ <4àIº»cH¡ ]\(.q ݉N´ B AðvëÍxoÚû.ïÍó/óþȪêêžžuX3KàÛˆÙêgò¥ÏÏþ>¸¶¶\.— ƒlClÿgè†a˜`€@@0€é¿A  w軀þM€€!$B„ €>‹ "„Z!„– ;E@ €„Z0 Ý/ŒIûW÷* ?Û%„@„@Lpûs¶+mi®ýEÛ·!D«Š‚vÝ „í> Ÿl×Ò²!B„­éô[ûë»Ø®j— !„Òm>„@ºß  Ý±@DB!˜:¤3 ¤[wB¨=d"„íîïö"ZÚ>–åDYBÒqd9Ö²lÚ&žç –iC‚ËÙŽ Èd²?øÁ?ûÙÏ3 >‚Ä:®kšr5Ç1WW×äP2K rÙÜüü"Ïó ÃÀN'uÆŸÎpÐhÔAE±ý7lÏC:"èz íéÛ½Np{|1vÇ1MKVdŽåÚãÓYu9·5‡è(°5­h¯¥ÎÊ  èm¯±žç¸óÿ=k Bj¯@? AwÒûý‹luLïºÝbû¬ï™Û„~ s¥Ý-íŸv‹Þ±hH»/{ZÖùßÖs°=­Iw![ $Ý]ju·=ÒÞ‰X–Çc‘H„"Ër£R©V+ 'xTo!—+—Š,Ë&R}²,7êå\6£xÔf«¥iú‡<µ bEAðHl«ØðG+Ï~¿lÎ|ús¿Š³¶žö»Œ]A×A9¶Ã°Œ‹]]7tM7tCJH¢À×juÀO0!„Ôëõ@ Ðjµ$YÒ5Ýãñp‡1®T*‚ ضíQ=,ú®»ººŠ1v] …,ËVUà Ӵ4M“eÙ0L¯Wí¬IAw.€žÕ×½ À¶}{kq@:ûsg–v§TgšoŸ °³!o;™ DéܳX{>MzΪöt$í Ü[óNi[Ë©w-Ñ¥E¶Ž1°ÕþîbÙÚaÚuÙZ¼ [ãΟÁNôt]‹í× mòV{Ú'clÙ6BH–¤ÌÆJ¡#˜¸†£‰—^|Þ0 ŸW•e¥XÈÿà{ßãyöðáiV>ì‰ýS‹ ±Lóö«"wSo5VÓMÃ0Y–•$AðüùKŠ,ë†áQžŠÅbŸ×ëÝØØ`YζmMÓÊåJ0ø|¾Û3·GGF«µšã8…b"+Šnèý}ý™L¦R©jš–L%Aàdn3¶§Ùh*ŠR­Õt]‚þÍÍMGÍçóË++Ó‡«ª Á˜Àî1Ow²ÎÆ ;,VgJ¡Î²è¾Ü9̺šôwQQ^­éÔ»[o[A[³pÛ–M¶Ê¢Pûï.»¸u¥s@´Ú§-)ËÔó±­e¿Õn³ç˜tÖOûáö2h¯0€ÚÛAgS>B–eY–³,ëÆkëþ@@”dİYàYX©”K¥B­Z) ~¿¿PÈGbI–e?ì¹ýî‰eY)[5æo]KkÇN>(ËB(•H–Êåx,î÷ûéi«išßï—$"$É2Çr†a„Ãažç%IÊçó®ëú}Œ ƘçùÉ=“ù|¾V«ñõÚµ¾Tª^¯ ‚€ „^½z-‹š†™J¥âñX©\¶,‹ã¹kW¯‡Â!Œ1„Èïó«ªÊ²,!„éá (C»GDg¦P^¼;gHgvÓ·ÚìÍ[ ™l›è€€è :û~gÎôÒŒ¼ã™m—ÉÖ¦ ©H³µŒ·VSGzŠtJU¤‡­j7vN@'7`ëH[’  ‚a¯ýX—í•ÌÚ/p G„tÝ€ §ézK7÷î›ò¨Þ–¦e3Ž$IÖu}tx T®8ÈŠÌ0áUWV—ææ …üÊÒ`Ïž=¢¤Œb$I„ʲL;Ñu]–emÛæÞ0 Y’tÝBàºØq–a !Žã@8Ž#„´Z­•••±±±f³ …šÍ¦mÛ~¿BX*•Áv±(Š®ëÚ¶Í0 !¸V«ûý~Bc̲œãØí9Ú³¢gà ¢­íܾ‹Ûû6Ækfö”Ðôwùî¤noÏtßâ¶*Ô)‰ÎN¸µJ·¸ùžÉ¹%©oIi =¿·ŸFdKPßš:+¡[H[ÐþR·[­ÛZdv˜ÉmÓžÜîØm[ûºõ „Çi6[„V«žËf]×í±R) ¿?‹ÅLËÌeÒš®õõ1,óÂó/þƒð>ªÒv¹T‡C§8¾Å_ou:¸sÜùo§K·qÉÝßÅqð™3ó­–ÙhŽƒ-ËEvNµÚúîw/æóµ¡¡(„¨ZmÕjš¢HgÎÌ)Š(Ë"lË™ÝÛ½oÛî7¾qîÖ­T*(ŠÆø‡?¼R*5óùú¹só##1Z™®ÀÝàÃÅÅÜ׿þ†Ç#…þîÝtºüüó7&&¡^­ÿ™3ó?þñÕˆ¢Hpí¨kYÆ~taqqsh(È0B·X¬œ;7;<‚Ðu]s~n.‘ŒŸ=»pá‚$ €º½(Ô­íÚZQy–m›ÒΟ_xî¹ë,ËÄbîçK¥Æ·¿}Þë•ý~ÏåÐs¹êùó KKyÈâb.• ¯®æggÓ}}‘ž&‹—^}6V= Bxóæz£¡ƒ^á… ‹KKùtºÜß…]¸°°²Rˆö4V«Úë¯Ï./çC!UÅVKÿö·/ Exž¿ÛÁ!¬Õjår}iieß¾}£áGŒØ®B˜ÉT_zé։㫫…ååüØXìå—oOO¿üòíT*øØcûiŸ{îÆ}÷ÖëúW¿úÆÚZñðá¡¡¡èÿøçýÒ—N3 „ÎÌl^¸°¨iÖÂB6òæóÕµµâ¿ø¿xæÌ|$â}íµY×Å–å8Ž;:[XÈMOíÝÛ!1MûÇ?¾ÆqL>_;xp(Ÿ¯~ë[þ—ÿ噿ú«—|pϹs óó™hÔW(Ô÷íëK§+ðÈ#S,‹ $€råÊÚƒîûêW_÷ûe×ÅšfíÛ×÷òË3G޼ôÒí½{SÓÓÃt¯v~>»°ùò—_9p` ›­Ê² i&DZ²Ì«ª$ŠÜñãcÀb±þüó7~÷wŸüÎw.f2ÕLJèŒ,—›>ŸrêÔ8I_}uFUEŒÉßþíëP.7ã8¥'ž80?ŸEþ«_}ã×~í¡GÝGÏásçnÜX/W¯®zu___˜ÍV¿üå×8ŽùøÇµZ¦Ç#ÿÍß¼jšÎÜ\6‘ðwFŠ|ûÛFF¢¯¼2ÓhèÓÓ#7n¬Fâñ m»¯¼2³¸˜õx¤ÅÅ|4êswn.mYîÚZáöŒÅµZë+_yBÉTmÛ}䑽o¼176¿re%‘ð?þøÎòÞem¼…(vo˰LoýE‘WUyuµ07—Ñ4Ëuñ•++ßûÞ¥“''~x/Bm•ÃÀsçVW‹’Ä‹u–E€Ülš­–éõnYp Ãzî¹ëá¾¾ Ë¢zÝX_/ݺµñ 7mÛ-•ccñ¹¹Œëâ@@Ù·¯¯û"BèìÙ…L¦j¶$ñÃÃQÈÐPä›ß¼P©41&ÓÓC^¯òüó7E‘=uj’e!€çYYVW o¼1×hè ÃÈ2ÏqŒëº¹\íöí –E‡·õÿ@Ξ]üÞ÷.¾ðÂMQäGF¢Åb#ô,.æöìIÄbþãÇ'ºUr]üƒ\Y]-¾øâͱ±8!dv6£(‰£ºÒÏêjáìÙùr¹É²Ì¿øŸøOÿé‡sséÅże9¯WÔuÓ¶]:Ÿ!ÇŽŒ'þóþÑØX¼P¨ÿ³ö‰sç¢Q_.W½pa!Ÿ¯«ªô¿þ¯Ïü‡ÿðí¥¥\"èë‹´Õ¯Bé¾S,6tÝZ\Ì­¬ä{ä‘öH±,ºukcf&ý÷þÞ‘PÈW(Ô Š"•ËÍFCç8fa!»²’?ztld$bšöK/ÝÊåj86–ƒŽ&ðë_?›J‡†"“ååü /Üìë Ýÿ¯W¼Ãø^°»„0t„ ÿ¯þê©XÌ;7ÇîÛ×·¹Y>vl¤¿?ô…/<”JX¶½$>þñC–eŒÄD‘Îq\Q䎽zuc—µo__.Wcô“Ÿ\ÿâ‰D¼¯¼2S.×§§‡‚AÏéÓ‡0&<Ï*Š`Ûn±X Óþî™g¦‚ñ¸a!Û×€x<âg?{ÿðpô³Ÿ=±ºZôùäxÜ?:=rdBØ­ϳÏ<3½o_Ê0l¿_q]¬if4êžbYtìØH¸+!¸®;5ÕŸL^× ÃRUÉu1ϳ–åd³Õ‰‰!BúNŸ>¼¶VúÕ_}PQ„fÓ(—›Š"2 d†ãÆä±Ç¦R© ¢µšæñˆ ƒFGã_øÂƒ¡FC¯V[^¯ì÷Ë•J«£îçNM†Ãj(äùµ_{Èç“ÅE‘«TZýý!ú Ç1££±_ÿõGƒ*%ÿézÈq\Ót&&££ñ……ìãï7M;™ vô¡ðñØÍ›Ç<8‰(Qd§¦R<σ²e9†¡ëV(¤¶ZÆðpìÚµÕÓ§>ùä!B\ ß¯|á lÛÕu+T¦§‡ ÃN&_úÒSªz·%A:ã‡=»ß-Ásç΢pðÀ8!N {´ d‡ð×+þv;¢ó'é‘Þ Æn6[K$ü»Ø}qKáßSþön&¸ÇµõŸ"Š\ç+´ã+ºn6z4껋b­®®-,¬?ûì Ÿþôg>¢n¶ëD³å¯{{jë߆§í?À®!„’ÉàEmñN¸Ý½]åÒûüŽ/îZþÝZñ ¡³,“H PÓrûÖv-%€ã8Žó²ËÞøæÚ¶]ヒoÓsç[‚J¥Ê0®×«öhÛ÷c±ÀÝǺý§$ñ’$ôèÁvPÛ±gá}ôˆu7“Îj¹ªm›Þuûé*nïJ»>@¶œ;{<¨ß´„7/çM.¾y I׳ú.uÛYUú“ŒMíMFp]×€0 »ë‰GˆÙó±êümß›àÝèE(^]]W%Ï[é›7à.}Þl49UùóO°¶eVVË9޳}âî°Ñ¼µ‰t»÷¼ã.¸ûï»}e×?w-çí|ë-oí¼N±ú]ˆióóK„àññ1Q_}æÜ¹ÅãÇGyžõùäññ$!!ˆ1Á˜üÍß¼úàƒ“ƒƒ]%iû<Öuûk_{ƒã˜_ú¥“<ÏÖjÚ×¾öÆñãc‚rm¢g]@œÝ{¬ÇÙå.ýÛl-Bï y1ÆèbO‰åy1²?¢(ªiZÝ«g‡-å3SÛ{mëÖŽ9 vþîu ØùØnôæ®»Zîöb¯Ñí.l¹0ôB¸ (•j‘HBX*US©äÜ\¦Ri>ÿüÍxÜ·ÿÀââåB¡Î²L±Xàɵµb±XÏfk—//yŸüÉO£‚ûûN2)VôJÔíÒ²m!!cL]ž8Žs±+ðÂîóaç@îpüšÞ"®ÕG…Xª.p‚ݰ³î1îdi¿€R¹äºN$Ý}RÐwÛQxwðôw™ñ[?Õ v;ÎÑn ÍVS×õP(tÇǸ»œ{V*Þñ™]#n¨jo%©)7Cˆ:Ñ‚B¨ë–, …Bci)‡1^ZÊ—J ŒI(¤êº•NW®^]½re%• bŒ¹ÿþIŒ±¦™–嬬xž€Äã~Ó´¯__cæÉ'ò¼ô쯂[7oɲgzzÚuÝW_~% Þ¸qãàÁƒ‚ †¡ªêìììÃ?$ËÊ;9Á íì`ÀG›ƒ »5B(“É”Ë%ÇqTÕ;<<ÜUGjµêÚÚ2ÃXØ…¢(©ªº³× 4M³Ï@’É>„¶M>×u]×¥ZQI’ï8, D×jµ*˲ÏçkÇÓtœ@B­–¶¹¹±¹¹Y«Õü~ÿÃ? ¶BcÌ0Lo< _Ó%¢iº ÔòÚ]!º¡a+Šz–b§Y.ÔÜ!ž:µ'V‡†"étE–yGJ¥ÂW®,OL$Ž÷ûåpØûï»oÌ4íW_I¥‚Û¶÷îíC92,I<ÝFGcŸúÔq¯WòxĆå`æèÑ#++ëôÏ@ pàÀEQŽ;¶ÿþõõu]×ivâŸv/§w·¢½ºãîG—X€Û;3mV¥Z=öÌßûäÓËËËgÏžéAjZëÂ…7ŽLOí·,÷üùyI£æ3!äêå šÖdàU=–å\¿ziúèñd2Õ=4 Ãxþùç×ÖÖFFFžyæ™v¼u‡ Co6›I’+•Š,ËÇ‘v0 cccÝ0LŸÏ—Ëe]ìcë´G¨ÑhÔê5Õ£ªªJÍX€8@]ž¨Þ6—˳,+Š"ý.•J¹Ùl0 k†ã8Á`ç¹íÂéü ccñ±±djj {ûرažg{晣ݹÑjiÇŽD£^B\A`Ÿxâ@OíEÿè£S`»~ù}%×Å—/_ BB†a2™ !äóŸÿü•+WLÓ\]]¥þÿýýý`§‹ž 3âí»JŠžç?Êk„¸¿ôÝï½òßþÆ—Ém.,-/¯RcPwÑÛ¶åõJþ€OQ<Éd,•ôe³éŽB›ú@2pòäq×µ-­Èf«Õê~‰¢ªj«Õ:{öì¾}ûÚ×ÑÆ˜¦™/äE C^¯—åØz½Ö ›€+W®H’45µovvN’dOgÞw Çq°‹3™t.Ÿë*€aè™L&“I¯¯o4š ˲ …B¯·Ÿa’$K’\«V†©×넼 ˜@Á„`U•xžínœ„`B\ER© µ3ölŸ¸ã<׎pøÀ–­›i4òÑu]ŸÏ÷ðÃAFFF®^½zôè‘C‡išæ8Nu¨ÛØö2€Ø º«ìTo3‰|ô¹®ÛݳYžGk»8–ˆíÛ·—Z”zb P­ÖH&£‚ÀB¦ö•J›FB!Aï™*Vš¯¾ô"°j>UÂr×ý„P× BÈäää·¾õ-Ó4ÁÖC8Žƒ\ש×k®ãV«5Ërº±×~ Ñh EQä'&Ɔ™ŸŸë5xA}>_4l6š®ëvG”"P „LÓÌçs,Ê’ …¶°Je™aDZQôûýãV«µÝ†ÃÀÑÙ0;›þÆ7Î..fçç³››eýÆä…n uêÏÚaqP«éçÏ/œ;7¯i„L£a<÷Ü5Ër:¯PCŽ˜©©ý!*5±,§iZ¡Pàyžw2™ìëës·wWê¥Î~Azãv··=b†¡84 B~ªÙj½òÒ‹k¹üÿøߌŒ=A<ÏÐÐ(˲ ƒªÕúå˳>_T–åvØ=Á±x|æöõõ•…}{F U³oø@2™êÀÞ´ÅÖ'Ÿ|R–¥õõîNOG‚a¯×[,<Çñ ËT*Ã08ÎC¿>22ôÒK/«ª÷¾ûŽswõêÕ™™™ƒöT „$I²m;™¤²[«NÄp8R.—X–íëëۮ‚ôËåò®ëšÍ†ãº[öLtÃ’$ i–$ñgÎÌߺµ17—I¥‚{ö$s¹Z©Ô$¾Tj><ôòË·UU,—[««yEe™Wab¢¯P¨ÿÅ_¼xúéiBÈáÃCßûÞ¥d207—I$üÇŽ"ôÁí® @yŸü™Ï'„˜¦ãºX¸þþp©Ô<¿ñËò³$Æx~~^Q|ÔFQ(,Ë‚:ŽÛjµB¥R)ŸÏ¶‘¾¶;’õvéŽß=ñïDCÞ?‚¯¿þZ³Yiš¾¢÷6¬ÿ;ö€^ó'Ô~Û-zˆÀ¶söˆÂ¤ç£d‹7íïð½nìÆ]'¹®ÀÚ®IpnBÞÉØÛœÝ*ß^*““ýý!B\Œ1 1]9a‹ o®®ü~Åç“{µÉÙlu}½´gOBU%¶í>ôO58ý`nÑÍ›·gg×E¥ÚÛ¶BãNßb†a\×eY®Wå½Ûܸó:µähɯüÍÿô§>ýQõ¤ÿ³l˲¬»=Äó¼mÛÛqê¶&-à „mÛw³Wo½¾Û}†a BŽemG>ÛúÐö¯wo‘î믿eåw|@(2¢ã8½{Ùh×ÅÝc{Áhƒ18¸7£?âq<]г¬ñû¿_Ùîö{W³ý{EãN“ÛÝkh‹0ÆË2·÷ôÛû à –å>ÒÇ €0!´S !¤B•ã8ÛcAÁŽmØuÝ.€iÍ®û•\Û¯÷:¡w4ÄuÓc^ØFð._ßš|.v·OÙm£´ýõÞYm5À¯o9÷|—ª\`¹Ü\]ÍG£þT*´ÃY« œCC‹¨ÜECLï\“Ûyö ]×­hÔß]Kï9!Q¸ÛöQøÛüÙ;=Ö{wD]¢ñUÑØTJ,€PÅþþAÛ¶!„<ß C€X¶kY¬,Á»´°×£§çvÞu4xÈ0ì8ˆqÄó £î†×%.F<×[Z¯SæN‡[Ê0B,ò\GûÑFÅëqg¥ cH‘£¶Oîæ/»å4GH  ‚]0 !pŒ±m÷ÿø¹_ÿõG …ºß¯ ›M#ñf2¿_¡}ßüæù£GG|p¢ëöü|6öhšE+nšÓ“É@½®tÝB†Ã¾o~ó¬¦YOä‚ÁÁx4퀶ÞŃڥ7zQ¦p]à8]u“uöÌ…F£E»•ã¸'Žú|êûzÖ½ßÄB–‹F“®ë"8kóÄ2|¦`ªW®4–|{÷xF‡!ƒ“ö¬% €M›#‰ØvÏaË‚ˆ4²™ÚƆoß$#Œ$šÅ’Y*y÷î)¹~ð$±«R±*5ulÔÑ[µë·Ã§N¸†Áˆ"€€-“¸.Ãó®a0²ì&Ãstiéé,çóòÁ`ñ•×ý‡÷ÓZ1’Œ‡…ÞBˆe5ù€Ÿ]C·Êed›&Drü[uï8ÆòòJ4‚f³ù‘‘Á`Ðãó)ͦñå/¿ª(B$âu×0ì••|0¨Š"÷Ì3G—–rƒƒa×Å,˾ôÒÕ‹—ÇÆb.,¹.^\Ì–ËÍÈâbæñǨªtýúš, ¡§Ù4D‘‡|õ«¯íßßÿ™Ïœ|?öÜh4Ôߟz×B±mÓ¤ €­R©Žc !Šâéïï7 óÝ•|K'© •¸$ýý[åòÔÄ#HH–”áÁÆârsu]îKYÕjsyÕ»g Àªÿþ}Ž®çž}QÄ2cFës b8däò|0xæ)†j·f]Ó"‘ÒÅKr_ I¢k9ã0f¹šýÑO°e!Q4 %ßþI@é•òÅ+¡cÓÁcÓŽ®—Î^`$[6±mÎëm,,1¢†õxŒlÎ36 †Ëbk›ib;ÚFš‘D§Ù2rùЉ£CV«|ᲞΠѰ¶ºÁ|Ø´Äd"ÿâ«f©Ü÷©_`ùM N„a˜D"º¸¸DbYvuµ!(‡™¦íõJù|=™ ¨ªèó)¡çÁ÷‹µL¦¢ë¦ª2±˜O–yY’ÉÆ$‘ðÓèð§ž:Ï×1&}}ÁXÌ *ÅbÃ4`ÐC™Ò÷IÅIYw-ßc 1ÆU9ŽF#<ÏB$IBá2ì €u]—ŽÅ Bÿ¡ýn«Yà4[­µ Îëe=²22ØzqÝÕ «ZÓVÖƒ'ŽÒÞ…kW«¬¢°ªâ4[ˆaôL–EFnO5!†, ²+5!V‘õLÖ,–Œt–á9È2ÆFQ!®cŠÚf†óª¼ß Y@‡8#IV¥Êû¼­µu¡‘ËË})»ÑðŒÇѳY=“åC§Þ0 %!cÑÜ /ó~?Dmž ;â9³P¤,‚˜ˆÕgæ]·kuW7E~«^"Š"OŒ@$I¢îÿæß|!D]9è¶"œ®[<DZ?ñ‰#–åŠ"Kˆ{øðàÄD‚çYŒ©µcB8€0 à¦áp<ã8˜ã˜»Y— zJ»S¹µ±R9ê­¡åîib;`am+Wô‘!$BB°24Àû¼B4de9tâhðè!Îëuï3X‡̈Bàðâ9·ÙâCABÁ®Óh!Gà—ú¢=Lq<âXt”BA«Þ¢aB0ëQü÷cËRû­JÕ·Ÿ]¯#A ¶ äü>³Pb=²ÿÐNUXEq!@<ßÿÙO9õ† ‚9¯êß¿¯ÍVéç÷:Í1p~ï›{&`Œóù’m[T%¤Þží?·& ¹#ôàN= ¼ã•mEÑø…¦òÎgØŽ€ª­B „†îõzïðqzGÔ^ØÔ•YD–å(²0˲"„Y–Y–}›Ì‚ãØ‡OðìÙ3„Øû÷OcŒ’D lKɦAP="ô@Ôêº×+»›Òh>¯Ô†¤£¼£@àêZ¾Þ0L ìØ´:¨ÀÌÒrzn. zjÕ–×+=6Æ2¨è¨ç_Ð Ïß~´ó¤@ØF¢ïBÞmÄ{åé·ê"Ñu!Î[=¶ËH¿‰vGú6‹‚B÷½˜4–eåó…T*ÁqïÞ’@H7!©TjÇuÝò)¶]©Töz½o³uš¦-/¯Bx¯@5SÛv{âêºõ“Ÿ\ …M³Êå&½øÙÏÞOÛÿâ‹7tÝ:vlôòå•ýûûÞxc~d$–ÍV<qr2uíÚZ0¨¬¯—b1_µªy<‰ã,ˬ¯—,ËÖ4kq1 ©CC‘|¶zÁXÌwõêêÆFiïÞÔÑ££€L¶¼¹Y.êšf]º¸´o_ßÂBvjªŸ†;ã[ÿ‚Ž÷õŽ‹ôÆ‚ž'x'œ5vm÷h¸ÛF»µÑkš!t®ì #iµŒL¦:>ï*ˆwSÚvóùZ.W=p`°Wã§ë&Ë2,˼eS!¶mó<!j4ªårax8Iˆñ– ¿›åBÀ0[• …¤íŸ3‚ñ¸ïí÷q¹\)• ‘HâÑ\mmBËrj5­^×(TV"á÷xÄr¹ yë륕•B__¨P¨‹ÞJ¥¹¹É5›F­¦G3™J­Öš˜H¾ñÆ\«e92ÜEi?sfA–ù\®6;›öûåjµ¥if¡PöÙk±˜/—«Q7QäOøÖ­'Æ‚AÀ0÷ˆÚ{Ûh™¦}åÊj8¬–Ë IÖëz<î_Y)„Ãj>_Å|_ÿúÙ“'Ç?ö±ƒ -xêº !XYÉ_º´(KK9žg+•V,æ4† °Õª6<ÙØ(E"Þññ„ \n|ù˯þ»—¸vm-ò”Ë-Qä_|ñF(¤~þ󧨒j‹Û Dwâ—^z­¿/5±§ úÖ5)¢vÔd;è¡^›=ÜØ(¹.ˆì6¿w:’í¸ûöç7|g(ôµ­xÔ7I’ø={’<Ï=:ÜhccñùùŒãP—lòðÃ{OÚ †¼¢ÄNN¦"¯®[TÆŠF½}}¡ÁÁˆm;Ï=w½P¨Óåd2pâĘÏ'/.æ$‰øýJ2(•¿ú«¶ZF__ˆî€€¨FËë•ÆÇËËù“'ÇE‘ëz|ôv$íù];™š'Þ¿.ƒÍ̤ÿâ/^ày6õƒ@µÚj4ôL¦âõÊ^¯ôéOŸ¤WÇeY&—«^º´œL꺵´”{õÕ™gŸ½FaæBEX]-|úÓÇ×ÖŠßþö…ûïŸø§ÿôi–e8Ž…ÌÎfþò/_D%þpX­T4Žc-ËEP«é¢ÈaLÇ•$¾Ñ0|>‰nö®ë€b±>†hÒh{ÇÁßûÞåz]SA×íT*07—™˜H\¾¼«Õj«¿?²°i4ôßÿýϽÂÛ|0Ķ Øxž=~|¼ç.9qÂÛݨGpd$™'À\® e!÷+Š ìôôp<î®ÑÐ+•æÈH|l, ‰D|ôuZ2ȶÍóç5ͤK£¡årµ±±øÑ£cC‡†é§«Õ&Ë2ÔÙ ÕÌ‚E5¹Åi´Eè˜u[/K! !˜¸6døíöãŽyðlfÛÁ Bhl,áõIŠ, ee¥°ÿ@&S =~¿|ôèx­Ö\]-Ú¶Ëql<îòɃ C#.@³iʲØlš†qß}cØjŽƒǘH<ôÐ^a­¦íß?@ýˆòùº×' õ±±„¢ª*"„¾tiYÓLI¨îñãc­–¹²R8}úàŸýÙ ÿüŸBUeÏ ‡ŠÆÂtÝãa:]yñÅ›™LåĉñFCG®¯—ŠÅÆÌLzp0\«iŸûÜ–eÏÌlÖjZ4ê}',绣{踀.œÇØÞ·ï ÆØuÅÅ5žg!®‹Ïúz1öÖëz(ä‰A67ËÔ}º¯/D±%+•V³ipS,6åÀêù“Ï×.\XšžžŸÏŒŒD9ޱm7Ÿ¯aLü~¥RiŽ%^xáÆØXÜq°$ñ±˜ïÕWg{lŠò õºî÷˃k×V#¯$ñ““IŸ_¶Ê‹f3/ùÌV–¼ŽQ½}‚'°õr5})ТY˜aX©‘¿ßûIÄJ€R.WUU)›­ƒžýûûß^Iõz£PXßÖk8.îá:Á„aÛvXµÝ!t;w·>q] ,êW®¬ìL E¨¼ƒ èêvS$Y@}±A ¢Ÿ#˜@‚®»U~¹Ü”%cbÙŽÇ#V+­`HEh¾ ÑlZ&8~∦µÎŸ_tì÷ˆžJWV ƒƒ‘tºâóI„ééájµuáÂÒ‘#ÃÁ úþÍZÑÆÆÆÍ›K÷\Á0 .!¸ºZ.êµZëÆõLJnß¾,¬ë’ƒòùZ2EþÊ•Õ|¾æóÉ®‹ç糓“IŒq±Ø˜œLêºÅqÌ•++ÿx€z‰žþúúz±X¬—JÍjµÕlšá°‹ù®˜e™«WWUUŠDT„ÐÂBö•Wnçóµ}ìàÜ\†eÇq—–r„`У*""»V£p‹ÔÜíohäo j¶: V^*¯¾ÆðŠ D±kCÄ8¶}ùÊJ!_;uj²P¨ƒž·ÍÎÇÙ™$—@Ö™Nº>È@BHñ–ºìn- ²-ha@"H¥‚·SdƒN&3&¤-P ì Wôs°s§wÉ…BÚ „€HÔÛqæìq †PQ”T2L‘$þ‘G¦zÛ4>ž€LL$;ã@Àó䓇Þ?w¬{–Ø®ë5! òllU•FGc££±ááèæfÙç“ÆÇår!Då°\®ºwojy¹ (B>_/ê EEˆD|sséW_½MÁ‰‹ÅúèhÜë•÷îM­¬‚Žãr«}}AAà²Ù*B0ó …F±X•½{SCCÑéé¡l¶V(Ô4Íêïe³UQâ+ëg5áZ-[¯ˆj±þþjd²U^¬®Ÿe8"ÖÒK¬èõ„'89Ökë ¯4ó3‡ …z¡PoµÌí±oN$ò‡B¾Ëå¦ß¯ôÆŽÓëwsîÜþX¯– ìմXÌ×ë“û^GP퀻íü¹CŒþÙZí¹rå2ÆÖÄÄTÇ^1Æ•J+ñ€»B«eJ!Êf+ëë¥Éɤ×+ªÕ„Ðç“»¾€¶í”JM–Et?¸.în¢RŽaÚE4ŸZÇõŒF™BŒ } 7®ƒ^tm"B†¦?%CÈ@v,­ ÃI~ªßÈP(B0ql^[_/îÝ›¢"ÊÛvê°wÀI†ý•¯¼öÌ3Óºn)Š`Y!D–„`¥Òúîw/ýý¿ÿ@$âëu¹%„8Ž»±QEN’øz]”R© zêuçYžg5ͲmçþèÙý¯?S©4E ”÷d” t]×Bˆ¶Cèt„%xýúJ4ê¥^ºÂ„hc}ãæÍÅH4yJl¯MѶZ­Î²ˆãØB0è)ê¡Z©´®^]}üñ)ITUŠÇý ƒVV Á šNW*•æáÃ#5Í¢ØaT Y.· ÃJ$ü ƒ¨C¨m»²ÌC›MƒçYª-[‡|ÇÙmÙÚ»ç?½ˆØ6 ]'›|{C…ˆÔ=Š©prÈ2©”˜J…:ùÁ~*×Åss™‘‘è7¾q^¹ZMóû•fÓ˜œL ……ÌÇ?~ˆjfgÓétyr2•H76 ÿñ?~ÿc;ðÚk³µšvôèÈúz©¯/¸±Q>qb¼ÑÐ~øÃ«¿ýÛ.\XüÓ?}þ¾ûÆþçÿùt[né„¿w¿w„B-Ë]__vcll˜*Ì[-óõ×ç|>øgöü¿øH,øÐ&%¼·¢ZY×uhÒ €aØ/¿|{p0|îÜ‚iÚ‡ ]¹²ÂqÌädjc£DÝ]^}Îã®__cYB86³m÷üù…¾¾à¥KËóóYQäâq¿Ç#4„ð駃ð~ô£«££±£GG1ÆgÎ̇Ãj«ež:5ùžÅ ½Õˆ¾wü¬TZ†aml”GF¢µš6?Ÿ9rd°²RèïÉ2?;›Ó,>ŸäõÊ„àÈHôé§§—–rÁ 'ñærU(r–e¯¯—…_^Î[–].7i*„pn.óï\øâýó?á—ùä™3ó€òñO¿ý®+³Xƒƒ}4#4?Ÿ}öÙë=4ùÜs×» ^?'Jlowp›JÉd*TóúšMc¬ª"Ý´ÕuK8ðEX]-®¯—"ï… K‚ÀNLÄK¥æ±c#¥RP.·ñ 0&>ŸL‡!$Üùó‹4ÍÔGH8ìù×ÿúÓ,ËòøàGÔu‹aÐSOÔ4‹eÑéÓeYxì±)Aà‚„€XÌûÄ<ñc;«ÇŽ÷Nöu&Ü'80>xp@’ø'žØ¿¾^J&?›"Ä®Ï?K°=5uØu1B„ãA`Z-S×-¯WÖuK9ð9Ž¡ÜŽm;†¡ªR³iȲ@sÛ‰"gYŽ$ñ ƒ¨Ýª³¯ª"”GQB0;›^ZÊ92ûïVòî´‹\z‚õ:ºŠ®I¤;óvëî-M)ìeŠvóçë– :œû÷~ñ]ß‘+v‰}8ýÛÑÌ.F"÷Œ\Úà4m—5×ŦI4ͺ~}íÑG§XqC¡Óc"l(¤R=)!DYªH‘e¡!Ó–b9ŽézãRi»«±™œLîÙ“¼Mýï„¶vÞî%Ó´yž}¿ÀØÉ-o,ð8Ž€¸.¡Þã®KHW9ÛÃûÝ©&ú)jz9îq¸§ä Œ ¡$°Tª_½:‰x÷ìI:Ž{õêÊÆFY’øL¦’LVW‹–å|îs÷[hK»Aµ©çØíÖ‡·;ýÔä8Ø0,Iâ;¶6`Û.Æäûß¿üÌ3ÓÔpA£=fuÚdÛvAR‹"ÿñÒŒK’°¶V|øá}¶í^¿¾’Ï×OŸžæù÷Ä ÀAˆp·c @&SƘ¤RÁ;àmÞN2ò¿›Äv×(„ Õ2!„’$‹õõõ’e9ª*ÒÄ›™Lµ›OñMöŸ‚ýøÇ—¯][›šê£jƒ@@i6ÍGÝwûöæƒîyá…›››ð0&¿÷{§ÃaoµÚZ[+úýJÈqÜ?ÿód™¿qcC–ùãÇÇlÛ©×õR©¹±QúêW__^ηZf.Wåyî©§nºÜ1b¼3 Æl©˜m¶ªƒ)z¹®;?Ÿ–eaffsffó‹_|lu5ŸHr¹Z  ˜¦mÛîØXì%¸‡¦ÛÅNr]œJYÖE–ç¹cÇFc1_¹Üù_ý«Oñ<Ë0¨ÑÐUUú½ß;­ªb$âõû•ééaÛv#Ðï÷øý*}—ãÐ?ü‡Ëf«Š"PT³i œœLy<¢$ñ¿ø‹÷õXr Ã04TCX†axžeYáÛòXD"j*µ¿§!Øç“ÃaÕ4­fÓ0M[UÅ@@Š Iâðû•®¬ø³FÛ²šMãÌ™yGÐu«Tj:4xåÊÊà`¸^×—— Éä)–enßÞØÜ,'ÍÍ2õÚÈçkt· ‡Õb±¡ªb¥ÒŒD¼,ˬ®GGc++ùT*´¸˜Ç¶í0 :yr\ø……Üâbnp0ò 7$‰GÕëz"á_XÈ80023 {y¹‰¨33éüPµÚ*ë Ìž=)!˲Áb±R.—A°,«\®P èz½žJ%F3 6-DZWVÖ0&­¦–êK¾J¥JÉç ƒƒýÙl! ‹e¿ßçõª¹\A„ÕÕx¼Ï¶µ*+é¬[!hµª² ±^/"ĈFyB°$qô"Ë‚t:½³Ë €F"!®ã´x†BT?N<–ÇqlI€è€ !þñCÔþ1^\ÌŒÄfg7£Qßòr¡¿?X©4+•f à¹}{ct4E>“©‹µµb¹ÜÜØ(]¸°ìñˆºn ë8®e !ðxÄpX½tiy|§ÖU‚ÅãQY–LÓ ‡ƒÇ†‰„$Iä8.ˆ¢X.W8Žm65ATÕcÛ¶ÏçeYÖãQ\×M¥âšf°,£ëÅ©PU)ði𯲬¦i'à÷§’)žg¢ÑðÌÌâääX.—EQZ‘jµÖ×—äù·D—êÒ»À(xOˆÀSïÀÝì$½è Û_ûYb¥àÙsgv8ì8˜a€¢ÀŽbìö@AöžÇ²²’Å|’DóhõvY÷7êü‰&Ç1¢(Ò›M=“©ŒŒÄÙ¶;?Ÿá8†ãØz]Žærµ0Ç1Âb±®ëV˜~ta!(Ô/‘f2å`Ð#ŠÉÑ£#–åLL$æç3Ùlex8*˼Ç#T*ÍT*X©´ÆÆb×®­ù|2BÐãý~en.3<%“Aª¥ŠîÝ›*7on92¤ëv8¬rÃ0hÏžÄÊJáèÑ‘ÿør* BÀòr^Q„‰‰Äúz™†ÒÒj™±˜ïß8sà@³iƒêUñË¿|ÿÌ̆ªJàp¡PF}–å<÷Üõéé!Ërj6 Es¹Z&SÑ4S–·ø~Hõšo>ãw š."ñ=4„ï‚Áccñßùñ<ûÈ#ûtÝ¢™Ž©_¢ˆ†nÛ.ϳª*qó¿ýo¿ IïáA!^¯쥡l€{Ê^Ï;Kˆ35uˆF ¶m‹çYBË2dèºc²Èu1í¾0èdA[€æ˜¦]«éŽã.,d÷íëc¤(-Äã)ãÞj[„J~«˜Â0[Y*é“ͦA_gYšˆtzs]L#ó›NW††"Ç$sç5›ÆÌL:õ‹ –eŠÅÆ•++##1¹Ï0¨ãàÐÛkmv ®:P=wt.ͽé“Ôµ!ÔN Ê0v©œùÑó|0Èy<ަgŸ}Þ*WI†Æ*U ÃŒ‰ã„bšË+õÛ³œªÚµ:DŒ™/´Vׄp¨øÆ9¹/i–*!§Ñ¬\¹ÎyUı€mmáy»VØ¥y\Ã0‹eȲf© 0vZ6ÌúÌp]Ϋ¶V×ÇÚõ±b[v£ \l×êN³Y»9#Å¢v½îj#Š´ÁÚÚDÈi¶°e1¢!j-¯™œÓjikœGÅ–e䋈çÍRu²#X媫ëc«\eDÁÕmFäïôÞ1SÁÅ:Bëõz¡PQõƒšöoA,Ë24É „0“)ß¾½´±QÌçë}}AGúÉO® E¨’çôéC¢È¿ñÆœ °¥RszzèÚµµFC;Ž‹1¾vm­Zm;6öÔS‡\×½reõÑG÷)ŠøÂ 7ûúBª*B<ð­o_YÉ'“ÁPÈ“Ï×ßNEßþíî žÎn|ã»rJŠÅÏI©$dPéÌy1å|ÞâëgÅX”‘%€IäÁ“Hñ4—VÆb<^|ã¬2YE1‹eFàA¨\¹^>wIˆ„ÄhDÏæ8¯jWk¾ûZË«f©¢§3œW ßq\åÒ5ÄsÎÜDÈÈæB( ­oÂéƒR2ÑZY³Êm}ñ¼¶± @<¯ô§œ–æ4[Þɉâ«g ÇF>ÅH µºn•+Í•5Îë ?©^³P´ª5)o.­:¦24 m¤­R¹>3~à¸2ÐoV*•+×ø€ß,•ÇI©„w|Šj~ÓCcÀq EA§ŒÀÅ‹‹ƒƒ‘pXu]—a˜÷gy°Þ[âÄVÍB“¸ÊìñˆÁ çرÑÛ·7ƒAƤ^×9Ž‚7RÖ˲påÊJ½®'“ÁûîÉdªo¼172ËçE 4È0èðáÁáá(E\]-./çëuÝã—–r^¯<4•$ž®“ 8‘,õ%ÿþg”Á~¶l}#-DÃB$ì?°¯µ¶Áù¼€WÓ!e J#‰Äu­r2ˆN\)ÕÖ6¤TBêK²…À‚2ØÏîßçjš‘/ðŽ8´ß( vàh¶ˆÀ²Œ:> !„3_°k5VUÃøöï«ÏγOke•‘%»Þ€°i™¥²ÓlùöMº†"ô9-Í,•ƒGY•ªY*k›iulBœ®QL B€l˜Ú榜Šårµ¯ý\2 >¢È^»¶öÄ–—ó®‹_}uæSŸºpùòòç?ÿÞ½}ïõ€­V£TÌÆÑ{J¨ÀË—/¹®59¹c !1Í&Ë"A`yžu]Ühè4·'„mS(•ü~¹RѨÍNX€e9 ƒÊå¦Ï'ó< ÚÁœe9ÅbÝë•MÓf„4MG–yð½^©ÑÐ%‰§:Á¤¹mû/q]«Zc "dàºv³ÅJv&Ljìj² €X#‰Ž¦±Šì&+Ë®iB„XEbÛ±k5Äó¬"ŒË±eÙ&çUF“EÄsTÄwZ+Kv£‰X–õ(lYĶY‚,K\›Dˆ`—`ÂyUÚuF ÃzBd:Ñízñây‚16M×´XIrM“󪔃²ë â9WÓYÕƒmÈ)òµk _þò«'OŽ?ÿüßÿýOÿõ_¿¼±Q‰/,dÇÇý££±ë××lÛý•_9uüøø{ëU!¬TŒÅÅ™H8Ø×ß—ÉdnÞ¸‡Ð àåË—0¶÷ìic|pœ:\•Jc‹ùi>RÛv0&ìŒç¹W^½1¹§/Pi8„€JÒtêkšyûöæÁƒƒ€_¼ùðÃ{±l[D¹ukãСAÔNÆ÷!uÅAöÍ1Äw¥;¥á» Ç»>¹ãâ®Eu?ôæåï(d×·Ú@lYƵkk¢È!''“Åbci)ß×J§Ë<φB*EÍÊåjSS}”ï}oÉ0L„ ðÀ{MÚfAÎBÐlÏ?!VËåfµªIÇóÜç>w?„@Ó¬W_½MuS†>5Õϱ|¡Ð¸tiŶ]¯Wš˜H\¼¸lÛÎÔTÿÄDÂqð¹s‹ÙlíøñQB@£aüàW8ŽñûeAàVV ¦i><,IžÿÙŽx“ñxû·v}²'ïÍ.¾ý¢Þäâ[<@ºÿð<{ß}cû8óS/éþþ0½FA—‡‡cïJš( àîŽÕ.!×Å.¦˜Y4³Éf«…B]ØD" *™Lhš–®Û>Ÿ\(Ô½^)›­ärµååP4â8V¥Æù}ˆã\]+¾vŽý¦ {‡ËtÏ kçLêÖ›WÓ·Ré‘6l26 FÞºè†UªÈ})×4ê³ ¾©IÈ0´(âºúFZè»c(Ú}ëjdYlÙA«Z““IÐIüK÷u§ÑdU}ÇÕõÚÍÛr_Š„v½n•«ÊÐ@}fÖ7µÛ6bÄñÛÌ“€7›ïÿò÷¿ù“Ÿ<æºäüù…HÄ{äȰ(ršf¹® 8yrÜï÷¼ßÊÓ{ЊG£ŽÚUÑZæÅ‹K·ooŒŒÄxžŠ\¾¼2>§a(4o~>½¾^ =ÃÃÑr¹ÜE.ôˆ"·±QN§ËSSýÉÎÚè:ØÎÝnûñ¾„¨¹²¶ø_þëðÅ·o/D»Ž]­•Μ‡§ô§j·få>Äs€)™@ÐÓFA°juÏðâW›3]WJİa`Ëv- Û–Ól9Ͷ€Iõê ÎçUÇGè†52}øá½¦éøýrµù‰OÝØ(YVß… ‹ ƒ¨Aéå؎›À˜$jµ¼gO2VS© Ë2¦iG£>êã$,„hr2¹¾^:p``s³<1‘‡ÕHÄ«ª’ p÷ß?Aóå¼%FÁO4%ìä?ûÇœßG!#†å|^yh@ŠEQô&ðHb$ì?¸ÛvíÆmGÓ”>1† B #Æ¢žáAËï£]ç´4Ä0rJìã|*!„‘%eh±,µICÕ=ãÞ}{„®nÄ{ˆõxÌR¹¹¸,„C@€ojR8Ÿ2 dY)æå?¸ †UdW×c=dJêø(x³P"B°24Ø!.Æ–eUkB³X‚ ²J!dob bäòf¡"aB¯WúÌgNv»g{ü 9uj¶ÝSCø¡¼téÆöää–\Q«5=‘ahÂ-¼xÊÔvÿÜf„º®5ëë%×ÅCC‘»ÉÐÐÒ6Ø2;ÀN=ÛÕƒˆ[ÛHs^•zó¸n“e!€í¸Hó»Ò›;~´‰æ!íÊ·•ß[ëmع»ÃÊÑëHÚ€í½æ »Z³ª5)GœB£ŽÚ•ÜV؃ÝÀ6õÔû:&÷ž\Ñ«-vwf&{õêÊž=IA`c1ÿÚZ1• R·S¿_f¦Zm­¬b1ŧ(•š %‰¯Vµ±±¸(ò†þòË·öïï_\Ä–eÓBúú‚ÅbÃïWhª¸ññ㓲§ÓÉj~²Cþ!„Æ34HgüÎd­[n½€tíȶM¤÷ùs}§IîÎò»µÛöï]ÌÛ‘ Û_ïi#ç÷ñ~ÿމ>7—1 [«5WV û÷÷ÓÝP×MA`;nÞ?£Y]èä:Z^ÎU«­«WW÷íë«T6_xáf$â£>ŸýìIIbffÒ?øÁåÉÉ”®[ñ¸ïÒ¥¯WŠÅ|­– ª©” ëf.Wû…_8òòË·S©àÍ›ë/¾x+™ är5б§ªR8ìD¼•¾þ;¡·=Û²m;çÏ/ýõ_¿ò›¿ù(0Vÿò/_ü7ÿæ3 Y¿_ùêWßxôÑ}ÃñµµÂÔT?ÅTÿ°ðÁó»¿û;€àp8J çr%ŽcúûC‡¶Z¦m»‰„OxŸOC3™ „PUÅ‘‘˜$ ²Ì'“PH­×µññ„Ç#0 ôxÄááh«eMMõ5†ëâpXŒƒžpØ›LÆÇã,û³ !ña!¼ukí¿ý·×êuí¥—nÏÏgFGãssiŽcÿóþQ³i¤Ó•ð7¾qö¥—n%“ÁÁÁÈû·*îAOrxõêeŒ­ññ¶ËÚ CÓBCB€ã8,ËR†¶sàÇÁ †¡H©„ ëbŽk£KíHABQÊ»à„üL£ªÜÄCH²ÙÂW¿zF×-U%IмôÒÍ“''nßÞ—L›M=T«ÕÖØX|ß¾¾™™tµÚúÊW^+†Îq̹s .,þÚ¯=üØcûß¹:ûÚYX@Ç’ ªÕÖÕ«³€ZMóù$àÚZ!öBâqÿÉ“,‹X–Å"‚À‹%Ó4fg‹ÅR8,•ª‚À;Žsß}ÓׯßLNŽW*UŸÏ{ýúmG)—«=t’ãXË2 …âíÛóñx¤Z­÷÷§<¹ÕÒZ-M× ¿ßŸNgTÕ“Éä~ø$ R©5Íz}YøþþT­ÖEÁ4­L&çóyëõzµZZ_O;Žc†ëâ¡¡þÕÕ¾Z­nYV>_ƒ~Ó´|>o6›K¥’B˲ „««‡í#„`ì²,cY6Ýý†Å—Ë•l¶0MK’ı±aAài¡mÛ Ë–eÕëͱ±áþþd4EñÞ^mBò<(†‘NW†‡£{÷¦ÂaõðáAU}>™â°œ>}h~>³¸˜‹Å|€B çrÕ……œ®›—/¯”Ë-Á±c#¹\ÍuIØç“úê}¸ÄŒqÇæ_­jÂZM›™Ù<|xhm­(I|6[}à=…Bݲl–X–M$↡W«µH$œNg!D¥R¥ÕÒùý¾t:£iz½Þ$) U«5]7\G"¡z½af­V7 K×õl6Ï0l£Ñl4š‰DüÖ­Y„ Vk@£ÑP½ÞlÔ‘H(Î6-AÒé\µZ‹Å"FS%¿ßçºn àE!ðVVÖR,ËÖëMÓ4KåŠmYš¦Ë²lf2ÃX–Ójµúú’¶í,/¯5Íl¶Ðh´Z-½Ñh@t]/—+¡P°ÑhAÈåò€_Åz½øFBØjiår5‘ˆ‚MÓJ$â³÷ž&êøOþÉÓ€ëbG@ ÿ¥/=¥ªÒ?ÿçŸt]—ãXIâãqßÔTŸ(¶æxžm4tŽcÿ÷?­(ÂL@dYhµLEêu=PÞáAÑöƧôa÷ ÀË—/blïÙ³cŒ±»¶¶I.êÓÓÃÒ8ôЄÙ~¿ÒåmÛ¶,[–¥|¾HaƲl¯Wm6›’$êº#мªz4M¯VëªG1-»W®©ªÇ0 Q5MSU˲²,_»v³\®<¸òQ¦i÷x”……åå嵩©=ôŠëbÃ0Ÿ¢È®‹]ו$‰²^FS–%Û¶762áp&¸h65Œ±¢È‚À²Ù¼Ï§úý>B@¥RÕ4e>Ÿªë&Àëõd2ùþþD:óû½ºn‚ (2 ›ÍkšžHÄêõ¦,·±ÞdY®×±X˜eÙw;$ñÔi­íüÕã¢Ö­Di×hð^—«Þ‹„¼KÅT¡P(jõ=Cìü) ^¹r c{b¢mÅSé1Þµ£ŽÖÖŠ‰„¿kŒët X_/bL£»%»%R¸¡¾lÛ¶ã8’$í^ !®ëš¦%Š]ŸEÐ럳#©Wç"ºsÏî½ÕÕ­Þ6ÂΑÝ[ôîåß#ûÜÛ “‚5~8i=Ú˲ggöíÛDzü½q¸Þ‘¡s·@/Ôe/±Žã`ܶWhšyåʲ,óŽƒËåæÞ½©[·6Â¥Rsa!û¹ÏÝϲìâbv}½”J76Ê}}!H:]ø|Òæf9Ÿ¯ûýrµÚòû nyìØ¨(òÕj³Ù4©T°¶V =ͦ‘L»s‹ã8žçw=F†Q™†w®íîçGîpλ“zoõ¼»ëߥΰ}´£ tªÕÖ—¿üêßÿûP#j°£ˆÃï·?ÆxeeUQ”H$Œ±Õj5 q)hÛmÌ­[›)(õÍÍ¥‡†"šfÞ¼¹ *33éÕÕ¢m;>8¹¾^ª×u×Å{÷öIÏ0Ìw¾sñÈ‘áþþ°ëº³³iÇqE‘O¥B»Îé;飳B¸¹Yùë¿~ùҥ嵵âþýýSSý?øÁežg㸿ù›½¯&mŒñ­›³¡PX’¼‚ÐM+Ö׋ÿïÿûƒÓ§'þþ`>_—$!ˆ1‰D¼ǘ¦³ºZPU©Xlx½’aØÂ`ÐS(Ô|>…a ëâxÜóì³×Ο_üìgï$¾z]§0™®‹ÃÇæóµÿò_~ò›¿ù˜ã`˲‡†¢¹Àb‚ &\GÜÔTÿÐPäñǧêu=òøý² ð㉉$Ï3¡±±øÆFiÏžd&SŠPðêD"P,Ö8rd¸RiíÙ“l4ôB¡^«i¢ÈÇ}ê©CÔ¶€ ”›77(ðøÝGÝÉÒô ·Ÿê2l=LÔÖ­Þçß4S+Ø‘´w;W†î`üv¤wÙƒþ–XÅ»E´÷†¯ìLh×{.Ýù¹wGÕj«P¨{_“eBðoÿí/ÇãÙÙÌÿñ³Í¦‘Hø|pòûß¿òôÓ‡oÜXk6Íl¶*˼¢ˆÿçÿùy„Àìlº¯/xãÆÚúzil,vöì¢ã¸óóÙjµõŸþÓ§§G-˹ukc}½ôÍož·m÷w÷c££m° G´â8fr²|ôè(Žƒ:áDíckïÞ¾½{û € ©‚@U]^ŸŽŽÇýããÉÎ-(ìÀ@˜ç9B0°¯/tãÆz$â¥9½DÇÚ¶ÝååŒ×+Iov<î¯TZ¢È‰"‡1Y]ÍS¿ðE‘Óu3Rãq?-AÓ¬r¹¹²R8|xPQDšÉ÷Ö­#G‡•;@ éç cm­ûK¥¦Ç#„Bj«e À4åå¼×+Öë5­Ø¶Ó×ê:W×jZ.W­Õôéé!ŠÊ¾¸˜­TZGŽ£R§Ÿ¨‰ õe³U¿_®TZ’ÄFBÕj+®øýr¹ÜEÞ¶„ÐÐP„Â1B*•Öòr^UÅññä»VvaŒ‡‡Ã¿ök§,ËñxDEá{lïðp8P‰"ﺮë:oZÆOã Á““cˆq,Ó±,‹ªÂxžÅ|¡xÜÿä“3™Š °ýýaÛv$‰§Hm¥Rƒ‚SNO?þøþ¥¥üéÓ‡ǽ}{szzhn.3<¡6¥$‰×4sp0<>ž˜ŸÏB£Qo¨’„BêÑ£#++…HÄkYN/€%Eê·)R?!$›ÍJ‡j6J¥eöÃï¥ê…õõ¢e9>ŸœÏ×GGc¯¾:3>ž  ø€"I|©Ôh6hÔx0Æ™LE×-¿_©Vµµµ"dÿþhÔ !L§Ë7onœ:6eW+׈מ>Àðpc£´¼\Èd*(Š\2<üúë3>¸7P0&?üÑ•û‚\е#GœXu €Žƒ/\Xl6r¹90¾pa BpàÀà©S{^¾¼Òl.,*Š˜J——s££ñÇ›EB˜Ï×fgÓã㉠Ÿ~zúÝíè år}~îDt_ 4(!HU':MßÉxG‹„ ÑÍÅ'=v”aÃplÛá8†çYšÈeº#tüVËdYÄ0 Ë2¶íP¨ M3Eè4°íÝuV ‰„:X•€â,«½ò]Ó4™”X`}6›ú+¯Ìø|Òòrú¢QŸm»TƸreµ¿?xåÊJ(¤jšIS~U*MM3MÓ9rdøÌ™ùpX•$î²/.Åãþ[·6J%Š]Ë?¿øä“ÓuËq]·ÎÔ+ƒê<À¨ß .ð“PHM§+¡c¢ªÒ~pYØFC(ŠèõÊBGæ8¤iæž=ÉÍÍòäd !¸¶V¤Ráåå¼aØt¨ ÃR½bk96Ö¯ìGœx` @2,—›ÇŽ4F2L$ü­–IÇ óærÕ½{Sºn†‰xC!Ïæf% nÝÚH¥‚>ŸlÛØ²lÚ¿¦as[ºåÉ_r 4×o 4×Aò!À²(‘¬¬äï»o4®LOÙ¶Ûhhºnªª”Jgf6¤ÓeºïT*Íd2hYέ[›û÷÷S¬^š]ö]¬ BˆÏ'M9ø6ÖÏÎüåïpù½]mB<©6÷8;»¹±QL§+ׯ¯™¦“ÍV×ÖŠõº!Z_/ݾ½Ñs€Éd Õ2}>bÛŽe9££ñb±Î²ˆ¦ZdYäóÉùbUŒâÀ †€à¡ƒ tÀ˜\º´T©´nßÞ\^ÎSëÏs4:åÆõL¦ìñˆ–åƒE!´á†È¡šÍV½^©Íò.!Ä·Iàyß"¡÷ßJE+•Z,˽öÚ¼a8ÛïòTg¸½Þ¢Ä……ÜÂB†çÅoÝI Ãt&=ÐuËu»>ftfîðÍÛæŒxç“?½“"¼té¢ëZ% !€Å²Èq\]·h¶R–eºÇ ƘãXÊÍSŒqº‘ÐÔGÇöVcB7ï7Ö§§‡‚A•a˶ŠÒéŠÇ#ù¼’ÕØR` ºr2ÆÄ0,„Ï3Žc»8v„ð ‡ g–(R/ŒöGiêq°m7.ÇãA`µàUÀ*?41 Oï$™Øu±iÚµÓÍ0 ²,§»ñÐh„R©î88k¡h¶ÅT2ˆln%Ù9€€îô,‹sƒ1f†ê|lÛµ,‡fÒ¡°ð„Šß5°ln–UUòzß5ì"©V«_ÿú9UiוJ ×%CCá……\2°mGùÙÙt£¡ÿãüôŸþéOžyfúÕWg£Q¯ põºvâÄøðp|i)37—1 ›ò ¢ÈÙ¶39™º}{sjªq1 É¢(,/åE(GŽ ?>¶ÛéÁ€°4Íü£?zîôéƒÉdÐãuÝäùöÑ!íáh6 QäZ-³Ó?@Q„fÓežª•i§ý4°””ckÀ0,–Eºn]º´üÄ Ýë•ëu]XB€ëº‚ÀÑìr;ޤ;AtšFèéÑÛ¾¾½È{;3n{·+ýм ½ïv?ÍqÐ+'Ñ* ¯(‘î9ŽjG“Éñ6païçX–Ù¡¡ï&Îf´#‘@oéCMgÜýœ×+y½ýÓÓ¿Åow¿H^€pG†ŽczU¢½½ÚÝnº]÷®GB¸¶Vüñ¯80P(Ôr¹šªJpéÒR­¦ŒD+•Ö'>qÔç“[-³^×VW‹·ooÎΦoÞ\7 [UEªAþå_¾ŠÅz__(—«ýú¯? !ZXÈJ_­6ËåF6[3 ka!{àÀÀ³Ï^;~|ì.UµšþGôìÍ›33›GŽLOÿä'×ëuvæ?úGOD"þâŸþéOèÞwèÐÐÅ‹‹Öëz¡P7M;ðЪ*~á õ¦A|G´u #s¹Êë ±¸ob"Î0èÒ¥¥b±AÈçk‰„q1çºøWõÁwDp·'·®¿vÒU÷|@Ÿ»»‘ûýÿÜ»*Åë·£ À ƒ¾ýí ÷ß?qß}£—.-'þz]œ>}èòååz]è¡ÉHÄûÙÏžt]üâ‹·ŠÅº,óàÈïüΓ©T°Tj†Å²ÌÔT?à“'Ç£Q¯Ï'ŽÉçëŸøÄQйö&•w·Ù4¨ûÇ?~hc£œNW4Í\Y)È2ϲ,ðÖ­õR©Y­¶ydßOì¿vmõ“Ÿ<öå/¿j¶e9¯¼r{|<(•Jë§Ú5®\¹äºöž=SÍÍÒììR*”$þ•Wn÷õ9ŽmµÌfÓ`¨i–¢O>y0Tï}¸ŸÓÝ©¡J¥JJårCQAàv˜eî4ž”Ëz]£ z`cNWG'µ]{v»Õæ r¹å…¨§öæfYyIâª*S©#“©rãñˆ>Ÿ\*5ÂaUÓÌ|¾A—ã˜FC'„$w-]À‹—.J„¤V+ó<˲L¥Ò ”z]…ÔZM“eÞu‰m;±˜ï£dósÚAԙ¡Ph½ÐÚÔçâÍwÙ÷²½*v8/íˆÛì­½b`7«è»¯!ë:nbL$ƒ3·7úûCÃÃQ¡ß¯@=©×ÌÜëRFDÊÍÓX¥Þ¤À?§{–7o®º.N¥‚Õª ©”›×uËë•: ¦óìÛóÊy‡DÝv$¥éÀßå[„€^ç´®GS¯7*éà&cü.¡9˜ôþ!n4€ÔëÚoܺ|y¹TjRTÌï|ç¢aXÅbZ]¹²rýúZ6[UáÆõk×Ö …z­¦×ëúÙ³ /¿|Hßã1ü9½—Ä@šÍÖ¿ÿ÷ßW«­¥¥|__ðÿø¹‘‘Øÿõ}kjª~>½´”ÛÜ,ÍΦý~E’ÞÄ…2Œ¦5‚ˆq øïÿýŒß¯(ŠHÝڦšZ¦æKêIÔ 1G×®­Po£¿ù›7úûƒ^¯ 膘ÓMœ‚S¯·¾þõs““I†A2gÏέ®£,BR«„årÓu± pšfž81:7—-—›—.-S'Ê©©>ŒÉæfe` ¼°%dca!(‡ ®®Ο_h6 ÛvªÕÖ‡=ê?§· ¡e9†~àÀÀµk« ÙGÝG·XM376Jð?ŽÇý¥Rã3Ÿ9Þ5¿·U0 caa†`gÏä5Wèºõµ¯yöÙkW®¬Gï¿üÌ™y×Ū*º.ù…_˜<…Bý«_}Nt@«e˜¦=>žX^Îüã‡ÇÆâ€[·6C!u~>£iF  ×׋_ùÊk‰DÀqÜr¹94™™IïÛ—Z[+^º´LóÇ'“Á—^ºyìØèƒN± cÒ×t­¯/H}œöîe$‰D¼“œç9áôôÐÆFéĉ±L¦rÿý>Ÿ¤(âÄDRU%G\\Ì E>ìAÿ9½Quþ'>qTQÓtdY¸}{3óaŒ|½®=ýôa·ýÀ{"ßûá6oH$‡(7!l6«WW½^yv6ýùÏߟÍÖΞ](•ºn‰"úô!Ð… ‹.,±,£ëf ài6P.WÛÜ,—ËMh–ÓVµÚÎç“%I€”ËÍr¹¹¾^*êccñµµ"ÆÄ4mðBgÎÌOL$—–r<ϲ,€À çÏbbïÛwØÅ˜A@QºýFzü7Û—À.þž`»`ô³ÖûQ£®´M“!Ræ¾mN¦ÌI‡QAïëPöHö,cãúõõr¹©(Âþýý¶í^½º*˼$ ƒ&&â1ù|õÖ­Mžg¨Ç;ÆÄ¶ÝpX]]-ìßß y-˦®eѨO’xÀS«ieBÆØ0ìXÌ·¾^ol”!’ÄSpñ¥¥üÄDb` B‘ú­ÉɃԶ-Iøç¦¿ëÔ];1~>¼íŒ€À†õ$ˆÛEêýÙQ(ß鿈;H[jâí[ùŽçïl,ÝÓ1Å$ÿù:øY¤|¾æº˜eBH(¤ µhÔ‹ó!ö< ½I–Ê7­ºÛ3ï°5 Û͈@ÍwÚ”^·J°Ó­¼IpLGÓŒ¶Á›§‚ÿ9cöÞ‘®Ûÿñ?~ÿøñ1žg—–r_øÂCßûÞ¥O}ê¾|¾‰xC¡°Ì†œ93;9™êÉRÙÞ²{íw³¾W‹™Eˆ¡8³Ôû:öô<°«\ÑþBHÑÍdª^¯(”¥ÎñšfE"Þ;Cl-Ë.—›>Ÿ¼¾^ŠF½A;¦c5y9 áö”BìZzYPÂ2‹í2·ò~äéßKº;!l6õÅÅÜ—¾ôÔêjÑ4˲çç³gÏ.|÷»ûûCÿìŸ}’úq~ä8î+¯Üü¯ÿõå'ƉÀ‘#÷nmp+ŠÆxzzXQÄFC饛^¯Œr]×4]·úûC««…“''‰À{âuÁ°Õw“¥¥<Ï3Ôƒ?Pòùšß¯4†ªŠ‘ˆP­¶hìX  ˜¦³¹Y®×uBH³i4ÆÐPd|<Î0 „ ^×/_^y衽ét9ó1 Â×j:!$òœ93?6/êËËù}ìBÈuôZúRpð”ÙȲ¢ÏµZ /ór@ˆ[Û¼~Ôjå+Õ2—ý'9ÑÑ4+›­Š"_¯k¡ÑÑè ÷Ï.Ý/&„¨ªxòä¸Ç#¦Ó•VËX\ÌY–³´”Øœ81ñÁ@Êåæ·¿}A’øþðê?ý§OÏÍe¾õ­óétcÌóìüÁoy<òÅ‹K_ÿú9žg«ÕV8¬V«Z"¯­ûûÃÉdð=9.h–'†Ê1ÅÅÅÍVKŸ›ËîÝ›Z^Î[–Ãóìà`D’¸'ž8 ÜÙ³ó››UYXÈŽŽÆÐçç³ ºHJ¥&urœ˜Hpó£]™™Ù8thX¹R©9?ŸQñW~åA`“É@½®Åb> 1d¸z渱ø¼à‰1¼z˜a%„8ÄŠ–VÊÏ? FŒ€]  ¸ukãâÅ¥C‡†*•&Ædt4öçG”ûÝß}’çÙÓ§=ùä„о}ýkk…ûî=qbéÀÔ zž|ò`.WSáØ±Ñz]»ÿþ=’ÄÓм`P$GÝÇql8¬Òô)Áx<àñˆÑ¨¼G˜¿ô© I!„eY¿_‡½^¯Dõ¾‡e³U„È4jµ5>ž¸qc c²¾^Êåj{÷¦&&KKùT*¸¼œ?qb BtóæÚÊJ¡¿?4>žœœLærµþþÏ3‚À7›ÆÚZ‘zã?>¡•fm½*z“Fm] ŽÇÕ¨/9mµ Zy1Ã+F}ƒáDQŒ5®W–†­®¿áÚCÅbËÕÇÆbïU¿üÝ& »$ŠÀ뻪v¿ð¡, Ã0–—øÁ(€pee8=jGìpûÖm„àèÑH/JíС`½–¿v5·³¥€À®dòVj%Z^¾|ɲ´¾¾a×ÅÛ6]Ç-ê#£1ŒI«eˆ"Ï0ˆ`‚œŸÏܺ½yò个J`˲Y–ƒó<‡Cehzþš¦mYŽ(ò†aqâyBhš6Æ„eQ£¡‰¢àº.ÇqAw ¤Ñæ¤ÓeUUUÙñ~­Ö4 ; ö´s¹*ϳÀ•ys¡œµ877W«Õnß¾}ðàùùùH$Òjµ!“““4Ã,Bpiié•W^ ‚ÀqÜððp­V[__Ïd2Édrnn–ò£ý¨T*=ýôÓׯ_D"ÍfÓëõ^»v26}}}¥RÉ0 :Þ?þñ«ÕJ«Õòxýÿý?zꩃñ¸t4¶¹Y–$žF÷õAøÆ7Î1 úÔ§ŽçrUIâ[-!‰ø¾þõ7 „§NíõxøZM“$~Ïž$Ër?üá•r¹ùùÏŸ*•êÇÐpk¿_îÑüî¶*(@ÕÀÀ€iš®ëJ’(Šâ¾}ûh2HŠýÑ™ Œakkkû÷ïÏç tÎ5 BH"‘”$‰ãx×u!@àÂ… š¦9Žãñxêõ!¤Õj¹.¦óÃq\EQΟ?ϲ\©Tl4’$ ¼üò+ÛúŒÓ´®\¹FDQ”$)‰ „t]w]7ŸÏƒÁéé#’$E"Ñ\.ëº.eBF(ºpá¢,Ë óÃÃú®dYv]W–•'Ÿ|òæÍ[–eÕjõJ¥šÍf‹Åb&“M&“’$ípl†ªªZ­V …âÐÐ Ïó‚ –JÅB¡Ñh, ²,æææ–– 𦠅ááájµ&ËJ:öú|ÃÃø: ÏÌÜÖ4½ÕÒ†Õu½PÈ;ŽË²ìþýû† ”7ÃØeYÖïpëóùb¨&!GX–ñù| ÆÃaº‹Åãq–e}>?DZ~¿!cœL&¶íÌÍ¥Ñ4+V©>ps³49™²m§VÓûûƒ…Bƒ"£¾ðÂðB‹ÅæŸþéó†aýå_¾ø¹ÏÝßlßúÖ…l¶*,àÿï%1ÆKK¹ûoÿÖï— Ã0ì_ù•Sßþö…ZM[_/½þú\2Ð4󳟽x8ʲœëâÕÕâ¿ûw_SU‘A ÿýÿå@Àó&Œ!ÛE׃bìÊ2 Ãó !mA‚‹záb Âaÿ{“ÉØÉ“ÇtÝà9vttÐï÷Çãc’JE!Ÿÿü/A1!­fS–e˲8Ž{≇é Ð4ÍçóU*UAä‹…"˲ccC¹\nÿþý±xŒçñÇ!lÛN; Ãà}ûÆ!„آĪªäºj08h˜z  ú|>Ž£cƒË{½²‹M–…ããöm+Š$(P÷í›PUU’$Û¶qcdd€eÙǧ5]gYB(“áýöHçºmð›žHdh¨_ÓZ}}1ÝÁÁ”, .¶¦¦ö(Š "Ïs¹<pX‡†úŠÅ"„n à‘åQEQÙ¿O£Ñðz½,KÍ2.Ïɉ‘R©ä÷êõZ,E‘"I,BˆÍ‚€„ ± 0Ï#BTœ$  pyà"@ DˆËqBL¡p^¯<9™ =Ÿýìý¦i'ýûû£Q/!8ôü«õ‹ŽãÒDô<Ï~á †Ãêûj ¢à4££±|¾6<}üñý¹\-VãqŸëbQä©;0n4Œýûj5&ò}üñ)Œñ¥KËÔå)÷›¦ýè£ûh©}}Átº’LšMƒaàÑQ÷-q´à¹sgXŽŒìÁ#eP7÷»­hêÈá.^'ò£O²ý£àÞktëfn‹tÝìD´k:Þi»Ø)» ‡:;T Ýçi±Ô™¥[“®—[çOÐëÓ©ÆÕë²O`¿N3ÑúÐg¨¿~÷yÛa— ¤%w¼ñv}r›3Ònb.¼»ððv !!€CqÄh éÝ1K·òûFíX<×Å4¦‚ªX–Ã0¨[C:[¨¨cY.Ã@ÚùÓ´yžµm—a„ k³Â˜Ø¶#ml·]o¾0Xcñ,ËRï@†Á¾ÐP¯úå=¡¢Ñí§é„{ ¹ôäÇöî>ïOÀÝ;#ºº_ïâˆö<À0 º3e;Õw‡‚ˆ"ß‹²þvœ ÏqÝ}úçà?#!\]-|÷»!D=.<Àqð_ýÕKåËæ!l4tš‡tŽÐÞ=¾Ù4,ËÛ©ûz¥Òj4 ]·4ÍÒ4«Zm9Ž[,Ö{r½ÂVËxË8*Ö²mŽÛÂß¼§íçôw(óX,6þöoßh4L˲+•ÖãO½ôÒí˜X]-”Jþþð‡ãR.7ÿà~túôáT*HÁ4D‘£ç™ªŠ,Ë}ýëgý~å©§ÕëÇ1tÆŠ"/\¹Üü¿ÿïï|ìc‚‚À©ªøï\ú½ß{êÿù¾ÿOþÉdžaY„ógö“S§ö?>þ&bËqœ®õz•ª®uô¢$ìp‰Û޳-¶»{ÎtySêáGŸƒ=Zç¶€¸UBïp+îžêwG‘ÛÌ3¤çânöš¹€áÖg»h[õéê†wÝ;wà¾!è̼]'Öv‰b·vš`{å´mÏw®»¿»õÎPQ”=J_|ñF¡Ð˜žúÎw.®­•h Ée[¤(iø‡?žÍ,-åºÿþ‰ï|çb£¡§RA×Å¿ñF£ÁZM;~ñÖ­ ?Epç7~ã±ááx:]^XÈþËùÉo~ó‚ß/ÇãþfÓ ÅêjñOþä9GŒD|óó™£GGÞ¼2ÿ?¢Ê[ eßU .zTXtcreate-datexÚ320°Ô54Ò54 14±24´22Ö50±20A} p±{ã.zTXtmodify-datexÚ320°Ô54Ò54 14±24´22Ö50±20A} ‰Œ3zTXtSignaturexÚ³41N56¶4704±0²HL231±43L6L12±°077{ǃ*žKIEND®B`‚gri-2.12.23/doc/screenshots/gri-screenshot-3.png000644 000767 000024 00000051544 11310756313 022014 0ustar00kelleystaff000000 000000 ‰PNG  IHDR"nJ–\R@PLTE  ! (&#++*10.?8/94-443862886===H?@>@>:@@>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-2.12.23/doc/screenshots/gri-screenshot-4-tiny.png000644 000767 000024 00000070403 11311210332 022754 0ustar00kelleystaff000000 000000 ‰PNG  IHDRÌx1ŠÆ pHYsii¦¨N vpAgÌx”8oíIDATxÚíýÙ³dGš~¾œ=öíîKÞ{sG"$–B…êêª&«ÙlÙˆÓiFÍćÙ<éeæE¦¿`Þ5&QzÓP54[{aw­¨*ìKf¹ß}‰{c³Ÿãîß<œˆ¸q3¨êjTÕ]€‹ˆçøñås÷où}Ÿ“÷Þ{¾b„ˆo¿ýV¡P(‹šòM Éÿ~iJ¥’ÌIR¥)Ï65Ä_p¿*FƒÈÀ65‚!{ˆŒþ¢B0•)]ÇÐе_¡nÓDbªh˜BNŒ²32U2ŽnV)jQœæMB !É z¢ $†J§2âŒfÍz¢Èq=FíE$< QAHÖÞÓûžÚÒé^z¬müWí–_/I)‹9Ó24ÀSö R©8N@ãœÂ#äi½ àQAæ³`Q’‚žñDÖUˆ„ÈŠ'à‘H‰­Ç£Z–9â)„éˆàQš’‚e€Ñ`3£RJÎØéuœb…©Rªa(R$¥¼Í(Bpô€’$Æ i¬R0â8M…ÈÛ¦”2IRÓ2££zŽI’b­hÙŒÌBÎôí¸ÚR©a¨ålÉ¢”Ž?º5k>B0ë@ÀQ—ž5ú ¿¢L6ž<€c:ý‰Òû·üów—çæfGÍ“W^¼nš¦ièO–£ „4O¾ÿ£ŸY–yãú3Í“Ö3W.cì£[Ÿ>så%Ô4ìMÄu½ó½?áœ]¾°~íêE0t=#J¨¦ñ$IMÓP €RzëÓ{Žmm¬­Æq’ azš 4t½ÛÜüäîk¯Ü@DMãa›†'©®qH’Ô²L)¥R¨q†ˆ€„ÙÚÙ{ïÃÛßúÆ×Š…ÜÏßýP)dŒ5O^ÿÚ‹·>½ŸsìÏ]E$¦âßþñŸ¦B,-Ìy~Ðéö+åâïç›Išèºˆ„PD5é@¥TÇœqÎÙÐõzýRxne¤”©„g,Œ"!9U ï?|tneéàè¸TÌÛ¶Å‹“ÄÐõ8I÷ÖW—nî,ÌÏrÆ4OFnïà¨Q¯nmïÏÍÖ¿¢L6Yvñ‰˜â¾bn¦Ñéö›Ç?}ûƒæqë[ßøÚÆÚŠRêiÅ@Ö‰BJÎùq«ýþ§6OÚna®ñów?jž´OÚݯݸ¾¾¶„@*„ëùõZe{÷ààèd0¾|ãúÝBª•ÒþAó;¿óõZ­†`8ô¥äí÷?~ðhkcmõþÃ-Mãk«Ëwï?J’´7bVÚùµÕíÝ}ÃÐ9ç'­Îå ë­NÏ‚?ø{¿C¸ xëÓûº®}zïáë_»Q)—~úÖûày~½¶5tÝn¯ac•èùl“í†årig¦~pt|÷Á£w>¸¹²8Ïë†/߸ž/”²v5OÚ‡Í8N.]XÛÜÙ÷i›¦Á+ržçaÔéö¾¢+ª‘ò¤(‰ˆõZ¥Z)¯,η;Ýz­bÆÞÁQ¥T„³‚=?›]eŒnnï ùµÕ Œ¢(žiÔr9'‰©d«Ý­VÊãw€¡ë/=ÿì•‹®ç/-Ì1ÆÊ¥â›?/Œão|íÅæI«\*f‚ 6êÕw?¸•$ÉL½V«” !•r‰X]^¸ssuyò9§Ïݾó`muiuyRúàÑö£­ÝW_~þ¤Õ‰¢Ø±­t$ñ«—οÿÑ­Kç׎ŽOlÛv]Ÿs„ÑßûÖë7wœš](ä¼€s¶´8× ¯^:ˆíNweiáòÅõ·ßÿx}u^¸~uèyN®˜u‰cÛmÏÍÖ)¥k+9Ƕ,+çØØ¸™ìU*\Ï×5 )%6Î¥©àœ!¢„ן¹dFα øzù|*„ƹç¥bÁÃå…¹L›mÔmÇZ^šgŒ‘¯¦vùæ›?.•ª•r±l$:§8=sa$²M$qKîS·4ŒâT+†‘(‰¥3<Ë…c¡õ”-Ã( Á6H’3âXÆ @‚0üÙÛÔjåçž¹œÝí‡IˆVAO³"%ä´VÓÜ>–³‘P‚JBn~romu)Ÿs²Z)¥ü#Áj¹©6 fÂ5%Çr:¤©OÖóL)…ˆ”R@¥€PJ`,t! ” b¡QÐÅp0ì † s3†®áhG„qOdo‘R&È£*ª)Ñ€ ÂHîÏäÝ‘@ÑóDzFMu¹ÿþX0$€£Çz:n-l´JÇ{òtpÏü3.³/gE<[Âø[[›–eÙ–eR‘iZ½N»fô™‘¸9¾N ë3 T€ž¤Â ‚=]48Õ0š‚Fd¢1¢2…c¢GUyT£PÆ"A9¤”<ÖYg›ùØûÈhšPBq¬”e]K™&ÊÒÔ™žþ7¥ ÜØÞÞC†qj{8Û¥“ ”òHR*šuàãêí­— ¡,N¥ÁÉ“MiÑÓµ„ñÜß<¥igœ .Eá{¾f:ºa†aØl)…„Ç–!cŒÐ¬€±Î>žë œnR8é;…Š3Žˆ„Œî&„àdTβÍH—$$ Ãî¸GÇ]sZôiÛab;È„$B&œ>õŠñš• ÇHëœÌ¹Qw §Ý¨2&3Åsã’žä$Èi{¦íS½?mí˜T†Œ–+Ðu£^¯éš®išH“(ŽuÝ@%Ã0´lÛ0Ì0ðQÀ½‡›…Bi~¾Ÿó<¿Ùl¢‚jµ¦iºmÛ¦iôûƒ••˲LÓ †”’ K¥2¢bŒ‹E)ÕÄNN·³Ñn‡ §—©]ë1:# f#zº˜Œšz¶³Î2ÎSEËɪöØB3mF/yOÖŠx\«˜*<¾¯®3€kœ±V»cXPÎ +_(r®;¹¼éä—…ùBÙ;ÇvA:%@ȼOpøYÞÓ¹¡1Ê)ͬƒÆ“LJ'«44(Õ)Ó)'ÑïõZLÍíÓMd$’Úõúâ:o~ˆårA)Å9GT„P®ñ‰ûlZ³˜tôÔ^@Q*I ¥”fšc,“gÆòøÈ½0­.L‰USªã´(uvF|ÎÌ;;€g{ôóèI¥ã1{ âcÿMæîÙ=é±Y¶àÌHIôìOäi/ý¬gŸ¼<­9ŸUI ì3à)JÓ„1 ”ÂϨª:[=Û½åóÞ˜]ßÞÚ™ø(ñs;â©„Ÿ1m+jâv?}Œü’ï™XH*)•RÊ÷Ãû÷÷»]·Ó¶Zý^Ï ˆ€ˆi*<8h·‡žžœô»Ýa%Rf:>÷vwOAJŒã$Šân×÷,9$z=÷Þ½½(JH³Ùk6{;;ǾMnËÌ0ˆ(„¼ÿäd0)äè¨ëyáä†4MïÞÝk·‡ôì»Noxøðp0²V÷¥©RʇûÓïÍ>H©â8Él^®Þ¹³ãû!(D¹»{<xãQPÙßÝÝ]Ïõ;Íf¯ÕêK©Úía%#µð¤ÕßÛ;ÉjÕj ¤TJ©Ã£v³ÙC$AtÆ#ˆˆxrÒßß朗”Ríîž!2M÷ô_5í‘üuÓ_ó5‹?}ôèøÏþìã?øƒ67OÇðýH×µµµÆÆÆœëúÿú_ÿìÿðÆ;ï<$„,.VŽz¯¼²qõê’”ê{ß{g¿÷Üs«¦©ö^{íâöv«ZÍ ‡a’ˆj5Ÿ¦â¥—ÖMÓ|ï½Í÷½wÞøÆåÕÕÆ_üÅ­çž[½ukç7® !df¦8—.ÍÏÍ•£?üá§««uƨ®sJéÞ^g~¾ŒˆW®,ÔëEJé÷¿ÿÉêjÝ÷£j5Ÿ$B)4 nYÚÒRmi©±³süýïß¾zuéà [¯~üã;/½´~åÊâêjÝ÷“õ¯~úÝï^¿}{Weššë†–¥;ŽyxØÃþÏß „Þ½»÷¿ü/?üÚ×.”Ë‹ö_þåíßýÝ«¾ ¡ ëà {åÊ¢®'žýÿÃr9ky¹zõêÒÿñ{‹‹Õ‹ç^ziþøß¿Ç9«Õòkk3·ní}ç;Ï„aò?ÿÏßW oÜX›™)}üñÎåËóŒÑW^9Ïý÷ÿþ½û÷^|qm}}æ½÷6¯][öýèµ×.:ŽqFqB)Uj,z«¿ÊÀ#ùÌ• άd™Ëƶ5Cá N‹çdŒ*¡”,-U£››Ç««µÃÃÞÖVK×ŸÛØ˜# ƒïïw77OÊ»»m]gÇǃ«W—]×£(ùó?ÿèk_»èûñþAûÁƒ£O?•GG½bÑ6M]7صk˦i2FMC¿ukïÎËÒ——«íÎp¿ûÑGÛ•ª½ºzãûßß,í¹¹ !df¦0†}´#¥,ìbÑbŒîî×ê¹z½„ˆŒ‘ÍÍã[·ö4U«yΩçE”’ßÿýç––f£Œ‘»w÷ß~ûQ¡`™&¿ukǶÕÕœ™É3Fô£;®þѽòþû[ý¾oZÜ2rÙñ¼¨P°(¥o¼q%IäO~r·\vþá?¼13Sô¼ø?ø„sö‡xã'oÞ‰¢ôÕWç !–¥SJöö:®u:Þþ~GJõâ‹k„P]ç|°µ°P}æ™åÖÑQ?M…ah­–ûƒ|òê«\7üÓ?ýpuuæÅ×£†Á)%?þñ8Q”þøÇŸH‰/¼°æ8æ]#dEgEƒÄ"úWqD[JæÃ)ë`f›` )°±Œ¨QbP¡MѨò9 ¿ÜkA³Góáý÷ß+W çVgã8B!b¯ç1ž)$Ÿ·lÛRœ 4űÈDxÇ1”ÂrÙ!ƒ°Óq›ÍÁK/­÷z¦)jΩR(„ª×óŒ1Ï‹ƒÀ4µ(JmÛp=ŠcÄu#ÃäùœÝj ‹E˶upÝ꺡ahi*¤DƨBU.9¦© !›Í>çL×y¶qgε0LÊeÇqL)ÕIkÈaŒ !„”RÇ1òyKJåy‘ã­ÖPÓX>o‡a’m”†¡I©Êe‡RmÿP¤  ‡¡ih…‚åù‘ÆY†–Ë™¾qÆ©×kœ?jpêb[Î^ü¬ûÿí1Ù+û5ÈÐc•ªã8Ó÷NkÊJ©Á`X,Vèx•s]·×ëAH É †aBÊ¥ÒSmâI)777«Õjf=(—Ë„|ÞŽÙív]× Œ±ÕÕÕ0 yš¤wߺ¿ýÖ£1‡>îBxÜ+ùùøÎ3­…'îì§Ï¢éžZøì+ðÄ란_ÐLT¸xaùò+çûý¡RªR)œ-s4•û}?ŽÓz½D)D5±Õe7„aLè:ï÷}J)¥$Ÿ·2=4›TÓü亡apMãO0Õ B¥TšÊF£¸ä41ÀNÇ£”T*¹¬u®hg vòùRö)åÎÎ΃\×MÓôܹsÝnWJñGôég쵄ß÷ßÿý‹/îíí ƒòOþ‰¦iŸU=BH·Û½yóæööv¡P ”¾ûî»ÑòcQ£>zêÑ `ù™£ûTFùŒ{N—ÄiÓÔ©ú4Îþœ÷ |îÄ›gŸrž6ž„%µ ©ä÷¾÷Îìlqq±†©ijAsΞ{n•RBýã?~÷“Oöÿ³ÿìEÓÔ»üïþÝ»…‚¥ëüÊ•…““a>o†váÂ\§ãmoŸÄ±¨Õò››'Ï]_™_¨|¶g´Zƒÿô7£P\¸0gYz%»»í‹ç9gÿûÿþó×_¿¤ëüð°çº¡r0¿ýí+Ó%0Æ666fgg‚ $„ض­”’R~ÎÊ„ˆŽã¼öÚk¥Riii)MÓñ&û™´¸¸˜ÏçŸ{î9ÆX½^/•Jœsf” @ŠB2OeÆ×ˆH€Jâ8îv;årÅ0 È|0Õd7ÉF=3NX…P"„@…\›ì,£í&ME’ľï×jµ‰/hÄ8Þ8Ÿ`¶¬zOrØ4€' Ã4Iò…‚R*ƒûe5I’¤Ûí”JeÃ0p䈄¬Î®ç¦ PBVVêï½·ù“ŸÜ Ã4Õë…~ߟ™)=óÌJ øË¿¼}tÔËç-Ï‹þànüð‡ŸþÉŸ|´¸X‰c¡>ó̲i𖥕Jö'Ÿìïíuöö:žÎΖþ»ÿîÿzëÖî¿ÿ÷ï‹ö?ý§_ßÚ:^X(Ï/T?Çb %ŠT !)%{{íÍÍ“‡›ssåJ%'¥R ·¶NÞzëÁúúL>ÿ8 2#Ã0 è՞4‰&QJ—––1—Ëý›Ñ0Œ™™™ÉW˲È;ニ> €¡ëìïÆIœsŠëë눀¹n«Vu’Ô˜™YÌCJ9ô£(t‡}ËrªµF&ƒÁ°Ûíàêê¹)S>öz½^¯çyîÕ«Ïp> @Bt»Ý“““û÷ﯮ®¾ð Yå”Rv+Ÿ/˜–õ䄎ã$MÛv&•q]—bšç<3Q*¥ŽŽŽljãäø¸ù{¿÷{Ù,l6|¯³¸Ô Òz}~‘Rªv»U¯U›ÍæÂâÂ7¿ùr³Ù‰¢De"ê:OS1†³³¥j5ßn»J¡ïGQ”ær†ã˜•Jîè¨×ëùù¼‰AÏÏW «Óñ°ÕÚ¶¡”Ò4Î9™)Ý¿øæ›÷Þxãòòrmgç¤XtÂçŒ;"´ZC©dšÊå¥Z§ûûÝùù²eéûûÎÙÜ\¹Ûõ,KÃD×¹a°û÷¶/^ºþ —Ÿ_+ñÉrôèîÝío.œ[œu:íóç7¤$ˆx|¼åÊâµk—îÝÛéõºår‚ øôæ»ëk(üÍ{wÝáÆµë/(¥Hÿò_þËï~÷»kkë™ \)õàáÃÅ…ù7ÞxãwßÙßß_[[SJÅqüèÑ£F½îy^š¦ËË+y< ÃíGGÇ×_}µ1?¨ˆÂºŒÑ~`š&cÌ4M GQ„×ssN¾T**åûþêê !äöíÛëëkYG#b³¹¿0_ÐuF©ßïwËå*øž×î´«•J­V»wï¾Bðòìlùi~  ±ZÍÅɬEĹ¹òÜ\å ˆˆ™¨T­ÎÂ:ðüù¹óçç²Wœ?¿0í£}*33§¯3 mcc6{di©–],—shš:‘ÂW€èÄUî qÀ•Ò8ETÔjMÓ——g{½¦œœSkÌìÇ~ÛШ¦ë8và)¥–––ŽŽŽÒ4a%(M“¤X(FQ”ÄÉÇ“$JYš¦ Ñ0ŒåååG‚…PY–½~ñÒÒ… ÛÛÛY÷fýš$ÉÑQ3MÃ0F ×4ÝÐ1çä¤q×´b±˜Ëå†C÷âÅK†aFQ „ιjg{ïø¸9´R‘RJNŽ …ÂáÁÁ~ðý{÷î+¥Þ|óÎ[oÝË܈BHDLñ曟nm@¿ïw:n³Ù ‚èÁƒÃ0Œ•B¥PJ™™õǪŒ|,¨pЦF!S|) þcO˜–hǼ¯q‹5ϾüÊüÚڣ͟¾÷ñ /¼8‘xWR¡Úíîýû•Êã eµÆÂŸ½ûóÕ•…™Å++«k#¾TªZ­þ‹ñ/|ß'ôTºZ\\|ó§?ÝØØHEDZ‚s®ëZµRÙÝݽpá½û÷?‹S„R¨Uk¶íHuÚõœkÅbQ)U­Ö CŸ\×u¢(bŒéº>Y±ªÕêýû÷:î… ç¥žçZ–‰ssK†w»»?ùÉû¯¿þ†¦éˆX©V?ùä“Gÿêÿ;ºI’Þ¸qÿøß=:n·‡™¶^/|òÉþ£GÇÿÇÿñ¾RX«åßøÆ¥{÷‹Eûà kYº®s!ÔsÏ­<ûìÊߘçç,QÏK‡ƒv¥Rü² €¼óÎÛaàáÙÖÇ ¢Òu}¢ÓJ)›Í=Îy¹ú×®­ â¿ù7?››+·ZÃï|çÚ;ûŸ|²÷èÑq.g®¯7®^]|¢J¤×ó›Í~’¤ëë3wïlmlmµÿè^)•ìVkðÒKë¼óàAóã·¿ñË®¾pcmô$Ó©‘ãN™j–‡„2¢ç:'G^(ŽŽíð­•…¥½RU)WÊ5ÌBè/îSý€ó¹-9ç0&ñ#½ÀÍöC®›Ä Y2ä EòfG<_fi+RÃIjæ˜Éèx§i6ûÛÛû3Ý®Ûé¸Q” év½ô^^\¬~IŠÒ—F„ÀË/¯ArxØ5 íܹFÆF¶­/,Tþóÿü%Ë22¸„ijõz¡VË÷z>çD7ØÖº7oîær¦eéÿø}n®Üh‹E;ŽÓBÁN13S¼tit_½º˜¦ro¯óÚk¯__9>ég¨ëéú âü|ùÕW/¤©P ¯\Yœ™)•Ë9Ç1,Kÿú×/J©®][^Zª-,”çæÊ¶mL†Œ9j8*ö“ÞŠ€nh`åuòÜŒØñ]cлÆÙÁE‘X)jèë¯%É>3g,´tÞEÃã§ L+”u·›ãpµ¦ï‡É'CÜprã‡éXD~÷Ýw,ËX]]ðÙ<)—íÃÃ^.gPJã8Õ4ž¦bccvRã_(¡ÿm! @޵×Q_[MyÁÃUOþ)eD¶­g²"’S(ÎcB攣i*@ÓXvå©ÕšÎw4Æw(€iWì$š¤”ïþÙÿÏÚÿQ&êiµ ÑÛE™Œß@èaRz”.˜kW÷‹•T7X‡½`-Ã!„ÎFÞ ‚Ljy릞ëK¤ºH¦­€¬ËТCA–ãðÏÓíŸ+Ñè§êÿý{þoß|6“ÉF6M½^χÁ•+ Ywh'„pN³UͶu)U Ãà„Ð$I£–¥ÃßZÛŽo¬ye8 Øj·‡ºÎâ•+‹wîì·Z."Öë…““¥tkëdm­¡ëü•WÎtïÝ;$„h{ð yñâ\·ëeà‹·ß~øÝï>wóæÎ… óÍf/IäÌLñÅ×m]Ç„ ¾×µk:D›Oà HŠ|~~f×r.Ç~!B_*(mõ$m#iŠtÁ¡>E ºšáj €Â zÀŒû¨É<ûéÿi“”u8INù~¼’!Z–ÖhÊçÏÏííµu†V«å!å²o­¯Ïäó&äòF±àüíå0@„üàV’(× ¿ýíkW®,ïïw?üp›Rrî\ãç?¿¿ºZG„þðÓs篼r¾ÛõÞ{ï‘çų³%Bð“Oö·¶NÇÌðûûû½½N¿q eÍ÷¤ ˜Áû ´ JLNm!ƒ4)(rê(¥#` àb|§Š¯Èh7ÀuLÇñJ„OöòBÁ~õÕ ™IµTZžAðÂ…¹ÓŠÀ3Ï,g?~Ùœðk$BÈ+¯\¯][v@½òÊùë×W Æè׿~!Û5ë:€¹þÏ‹ºÎ”Â$I5MCDMc™I(IÄÅ‹ ¦©I©4QJ9g¿¹ù«Î`‚ó uMãB>l—âPÚaí…~õ²ÔMÝГ㓮n”Ë¥xìq“4EZLêºÄ)†~ªr;Ñó¾‚<ŠY‹Ï©Ø'øBÁËn ùžÐ_,ćâ€Uc„Hæ”Ò̤ù´@•§¶üs~ýü1ƒß4=Aíµëã9ˆˆP(è…|†=MS³,ç³~Šºú$~ü´»>K¯ú, ßiá„ç@|ßõ<ß:MA3‚¾'F½g.ß+] ç–sJÍrB㸧nrÓlæ&ÒRâ4o‰Lî ~Ï ÛlØújUHJiz%OP¨–fÍKUcØ “æÔDH5õrþÏCÊóÓ”H¿,ßLÃá?ߎ:ε„˜¦2I„ijOxZÈWu9$J©?ýÓ·£¯½v‘òðáñÅ‹s°»Û^ZªÚ¶!„JS‘yîÞ=X[kh?<ì•Jv³ÙŸ™)Ù¶Î9ˬó{{þðÓW_½°¼\E„4‡‡=)ÕÎNûÕWφ¦”B„Ž.\˜'„ìî¶ʹœ9j+IÒ>ÚÉü¯¼ržR†‰apDüá?™)^»¶’¦B)µ³ÓÖuÎX: fJ§(@³ *ãTtòWŽ–oè¹\¹ù°Ú9Œš{ø¨SYã•ÆqÑ2Î ïµz*>••ÊWà0‹$ µy® /Ò4~Lô8Œ!õ‹º®[æ:ŠºÉÛ‰¬꛳Ü1FÂØ¤šyô1:a\ê8úãð°ã8Æññ \Î5… ×z|ÜŸŸ¯rj‚¨ß‚ ¶mca¡ö½ï½õ½ï½ûßü7ÿàå—Ïg+„Á ˆã´Ñ(&‰R™æ8)õؽóå |J©?|dÛÖýûG_ÿúÅ÷ßßüøãí~ß?8èþ‹ñ­K—–þüÏ?üè£mËÒkµ|¥ý¾ÿðaóädøÒKkÇÇCMgÛ['Y\Ó?ûg¯7›ÝO?Ýõý(ŽSÛ6l[¿wïðµ×.=|xôèQ³ZÍ·Zƒ¯ýâ{ïmÞ¼¹ÓéxÇÇýöϾqíÚò)×h6û·nm'‰xã+ö¶¶NþÁ?x>—3oßÞ]_éÎý›7wöö:Ï=·Úí¹¯¾ºŠ”»¤zÛ+)$¥ú¢‰ƒ4_Ÿ±zûËîå½]ÔsŽ·ÙQúžíxÁu=?Q¡NS]¯ªí:…DˆÕ4ÄþO#1< C Øš )gÔÔCÓP.ÁŽ“çƒŽAÒ þRÊÌ÷7[[{žêº†±Ò¶ÌµµÆÚÚÌíÛ»''Õ•¥ôädàº"Þ¾½·±1kYz>oíî¶>¿»Û^\¬Ü¼¹S(˜…¢½¸XÍ€×¥’½²Z%@ CC¥0Ÿ·ÖÖëiŠšN)µµÙÛ·w…œ³jµð_ü_W oßÞÉÇ6sy£P°bš¦Ž£7KË˵[·vz×®-]¾¼$â±*5Ź8®ûìµ¥T«5dŒš¦¶¾>Óë¹s|°93[*•œ¥å*tY5±Vâj¾m8BÄræz)Škûwç»ojÒuùŒÛx­R/EÝn¹Ž •î{[ÄèsÒ –YàȤès½!Õ@io÷¢ž¤eM4²Ó‰É=Ýð)—¢ª+‘GÜKa?#&眃8¾oo·––j®)… óÕ8N`k«•Å B¨Ìä=†P¯¤Tí¶—éžý~0q’‡a§ãxëë3óóåj5_,æ’Dv{ÞòRåøxAõÃ0Bj;<ìuïÜ9X\¬FqÌù—¹Ž)¥ÞÄép{{H€Ü½Ó>·Ê)ÍêÐëîþèG{ÈÂ<¥„ ¦•2!ÐmÔ %CÂU½š…+ÒëÏæ=/zó'?Ëð3`uEHÓ€8:iÔ‘R¦THiüÉ'7WVX>gØ–Ï9s]ïG?:'{"„P¦(ñÖ­>hÔñÓOn…<>þø8— ,Só½Ã0 žëyTÛ³ÊQ­nÆ!æMŽ –L(®>î¾gJw°ýf7¹&Kçò”ä•híVkŽ÷@C&Ä¿o—Ëqä‡â~O vÙ\Nw$ŽÑÑ 9z JÚaTHã£wä¹ó£ÎÌF•‚z½Ðh\|þùÕbÑÉÜvŒÑ ˆàÙg—]7:w®A)9>î7%ÓÔ2‹cTJù­o]åœB4#b’¤”ÒÙÌ¢kYúw¾smq±úüs«³s%Mã®ÁÂBea¡Âåœ ¡(¥¦©›†nYz½–7-ýK\ƤŒu3uòtﱨ¾ÏÄhÍÌ4¥>KxÊÅù¹™Il& B’‚R„3¸s÷S@¦ç|iiöîíÛpønµ`åfc#:~*avw/.n$\wu*AµQR²”³‚\nîäD?¸“׌QI e6{K>ôýª.ׄ¦Û<% (À‚Œ4€°8íx©”xÙ†RÁÔPÛhq}Ò E”ù$ÞÃô']0)Zcñ›K¥P!!ÉþþçôÞ½ÃRÉñ¼0ÃN}ã—1òèQ³P°›Í"ض±»ÛÎPi¶mÄqú̵%JÈÞ^+—³ªÕÜññ ög!—.-^¾¼œ%)A„RÉ)•œ‰Èºˆ`šÚ8rð— ¤ùõ‘¦±µµÕ_݈ðÅ"„!Q 4HÉ'gúùóö6Ñ´9Çò 笄V¨bW€¬<ã¬\¸×êx¦eh|ˆ°”O)w»yBjÔ%½G)€zÙ›ç¹9+ðT¥14MŽH€˜”ðÀÈ{@$6Óô TË\,iŠ2çtÆ9¤!y™œë·w3¹ÙõdC]?õ-p'ÊÒÈ þææI.gîì´VWõzºBHÏ‹ŠÅ0K5 ¥h·½^/¸qãÜÑQ/âó³–©ß¹s°±1[«å·¶N¶·[ßýîõ ö”EeOu>Ù•ðe3ÖU¯‚拈D)¢N³f&•,ƒ T*êQ³ØôÙ‘š)—çBϧŒYaX´šw㘟8ÁÀÁN.|4Ž[¤]Ò®„†]éï¡O,[XaØI•¦TÊø0ËøÉYÁàD@¹‘³úTOÇ1À¬£Úl“XWDø¾›5²B4p>Éš”Ï›×®­H)×ÖfŠE[)¥š¦N}öÙåL圅a¢iL)eY†RJ×µ$IãXäçw®f:áìl‰qâ8æWŠo~C 'V¶'~ýŸ€ Ú¾ôÞ1hןïê%oH‡ýºeI£p8ð\EÊYäêþ=N¼ÌTƒFçÜB•02\\õr‚hJ¡Âø˜h”(BòJä“Ä6o@“òˆ°ºJ\ÂB €à2k¦-}/H`£^8Œ‚IN>>‰rISÙl¶Ëeûè¨O)B¦©Ôu¾¹y¼±1›Ïâ‹E{ÜòèÀ0´BaôÕ4G.ÞÕÕúêjýË¿%D&P§Ë£PÔ§Õ¨teþ†µUŸÅÀ׆¹RÇÐ-àwP¯Qï|,»ª†!&¢F-——‡„õ¢§½A¾«Šd©$Ĉ TÓ8Ò[)-¥hÕIµ«"êsÒ£Út°ÿ °ŠÍ—£Héš®A˜¤|j[✱씵vÛÝÞ>¡´Ñn³,ƒA ºnT©äË*3i^ö÷·«Õ¯‘p”6ù)a™˜"ü -°Åo­Â®"³ÃÁ0ô‡µ˨7l¢j[Æ3$-»{š÷XyB50dõ#í\·ãÉBAéœ$BctvØïêv¢QLÁ÷£í”SÀ¾f^®°·Ûi®›,æ±e;} ÀŒ8ILØ%!'jÞ„O†ò\ŽiÁG!Øht}ζõ æLSgŒ¤©Ô4ž$"øÀrzb¤EDˆãÔ04B Me{×46Nò¡è/Ëô— q\DÇÌ0€ÐÓd¬J¡”$ Xš``”DÂ9d1/Ó¡8¿“ƒŒ3 ?nŸfæ#¹|8ÈÏ]²™þ€›…ù$öòe=ŒûGYsfA¬ˆp¡Ve©)·ˊh>s W4J—iJzÝ#³Pi‘ÂÐÌW4u>ñ$¤J)¸¨+›ªý„*6#Ÿ’ D9„¦–#ãX†Ñ¦Ô.è¼™’åšþá0ì&P3Æn%D2NE¥T{{ååZpQ,:™òØï{Ž[,ÚI’Aâ8&¥d8 MS«VóûûíÍ͓˗£ÇǃJ%wpÐ]^®e¼ÃÃþ /¬~1Æ{B‚Ýýðà°úµ—Âæ‰¿½cÍÏ™õz꺄3PŠêz°h/.¨$Öòy @M3 ãv׬WÃã½X`¶-£ˆPJ ]Ëç¿lú%Û=rå=F(_~¦6·Ø·rÍ ðj©¤¯Ûû)˜©ä†¡ú •U†¥ØÓÃG„é ÒkuØÒ‰½:q.è±J4­ ÑA¾ær–G,ÄiD™ŒU”àE›q“ !m"Ž1ËÒ¦bíD>.+_8¹À 1N»À w©³I鬑¾Ñˆ~Д'ñØâ?ÊvGÈÉÉ s› âññ`só¤ZÍ--U_ýÒíÛ{I"8gŽ[®äõÂÇͭ­“µµ™?üÃí¶kÛz&ÇÇΩïG®þÅ_Üêv½ÙÙ"çô…V¿˜¾5{Ý®¾ò¢ CªÁîž÷h+Ø;ÐË%³QÏ­ŸK‡nïÇw¯^â9§òÂs(eÒéº÷z¶ŠW/©T¤ý>skn¦òâó_6ÿü’”Åtœ]|SBwìrZ¬î0uÛòü~œ¶ˆPš7øU9S«€Ê1(¶U÷– „(„©ôÍüLçVÞ;,Ê’O+Õ4×ר&ÕT’ühŒ^·KNÓr,TÆÐmðä¼AþøX™Œõ€ ˆÙ6pIT ¬šúJ·c`”¶QÍSyBªÔgÔÄRÉ>~Î0øâbµRÉ-/×4•J!de¥‰”*Îl[w#Ë^ë볌‘Á °,=‹¦Ìç­Fc»lü‹òA"ªòõg —.¥f£Ž©È[‘qì¬.SMÓŠÊ9Ï9¼Q3ª•¨ÕfY" <ïèÕ²³ºlÎԅ磔0þõ7€¦m)“¾$À(ç”\ “f˜žpƒXJ®3åò:A®S»ÝŠEuR„hÄ`® wáC“ “xà›Ö>ÛM0HãX…ÑœFJçrf$ ÜÈ´©cå½aä i÷cÔ545-Ò4,ª›UBðœïÎqm?…Ô^(ñ9‹Ž >“\Ž–e\»¶œe*\[›¤þDÌ’yœ6pe¥>þŠ†Ñ¶ÍùùÊgôÑ&úPà† ˆ<—+\:? ?Ã0—Ÿ}&{a.Ѝ¦!*£V5ëÕ,Ðúi[~3d²i:{ÌE@@ÒÊa(ÚÜÈ¡Zðû ¥~¹È XsžWõŽV*©ŠæeÒ=I½”«p1¼ÇaØÓÞÙGs¥‘k‰"zâW0™÷:¤PÈ£P;+skò=’3(\e`U kûB)ÌRÒe\r Ú‰®Í# Eˆ cÙaY}9cl|0Å™ìg›ö¤íô)šæßlÂïiPût%Fº>3Ók#×ßoKé4fe $´, “¤7@Q”1 ݱ|Û)Gh”õ»½^ÛNVò&1 ÖüUçàA#Øbj¨€"`Î2¶n<Ò.˜Rh"9Øß+”KÖÂ\jät".VJè‡]®ê¶J•Áü<Ê`WÕ4q™ÆQ-Èh%ž¢mÉb& Ê|šžìsNNxz«ŸˆËýzò«`^ÿjÒ“¹²ÿI R(H) %àÙŽ XÅ¢d¦[­­dØÔ¡4oêŒGÕl‘¦¢5s˜šJºÝdg«:7[¨ÏT¯[ ãÑy`•r Œ»IŒ"©*¼e}ЂD‰s˜:IÜp3¥)Pç{|/¹lT§Óé’8N9ŸàÉP)äœQJ²,~Ô,s:öÊege¥ÆM±³Ó:w®”RDPJ…aÒj =/"„\¿¾âûñÑQwy¹Y¦jÆh§ãú~Ü998Ž1† U¥œ[[›¹reñƒ¶Žû«« J‰ç…››Ç†ÁwvŽ[­¾ãXå²Ój ïÞ=”R-/×{í¶ûµ¯mAlz§ãJ©ðè¨wr2lµ†”ÒK—æÏŸ_RœôoßÞi——j¿û»W¿d˜âW›¦3¬OpP$¦’ e5BÓÓÈpLªTÚ÷Še=ÁKNÛ¨®«‚VUî€i˜´6î”Q$±˜·P]·Ã*;28É-¼NÈ‹•JnfæB‹Ì€Rªá0€—_Þ‚xv¶L)Ùßï,,”5à ê:ÿÎw®QJ3˜^–s†rùò"PJ²#«Y>ÆH¥Açrf–Ì’R’%þ-‡=•FÁºO\'„r€bàw½ˆåŒ2Šœ®[HÞ±]¿”´k°“%¬<7œØkËÎ/̂סܤºeÖ×Óp¨’p½0ÜF’òÙçia^1ÓÊÍ$wvޱ:‡Úv¢"Í*¢ä ¶©Ñ²”ÈEtÄó)QUÕˆa;\9eÚj|Ðà(„âºÑÇ;„@»=¬Õ Žë8!äw÷™VkEÉþ~·Rqƒ ÛÖïÝ;JSaY†eiQ”¾úêyÆØ'ŸìÕjù¹¹òÖÖ‰”j~¾ì8¥§}7MÍ:‹IürSyýFPq1­SsÎf”8 1§u]+jTål?ˆŒ­ÓXƒ›JgÄÉ—ÍÆ…Ôm¦Í» …2‹ÚÚ†nˆÞNؼ+ƒþ8.ÍÆõÃûye55Óâ­=×.©ç3§Ø‰´-W7ëD([)-Y°˜2K‡šÙ§t’²aéÇTi—™),«v¥âø~Ç¢Óq{ssåz½€ž%‰‚„1ÚëžÇqÇb0ž¾z|<ð¼(Mc¬Ûõòy‹rr2|ðàèÿðÆg©¿]´þ 4µˆM/h ±cÛd.8¨¼eJBë‡ ×#–¥+(7µÚºð;Q{PñÚšV9—D•0>‰—ŽQß%“æ§ v¶7–çžéø¼Ô0µùö®ÉYhÃÚâŽf†ySˤ,%4†cÖ)“8J÷’D*˜`Î8!4Ûõr9³^ŸBÎΖdÚ%}î¹Õì@<Æhš Æ("dggB®\YHSeY¼þúå̲²R+•ì³]¿¥_‘Èœ÷$º©úa EDe"¥3ì[áPÚ¦¯å6Ù{psûS­A¦ÑÞ{ å¼0+Ã> ¢še6.¿›ô÷À\¸–´7 ãéਔ·˜­û·žÉw˜îiëZ’„%¢<ÂJ¾û¢E:E×´\JSåè€ ¥™³Ì4-Ã$ óîû~üàÁÑÜ\io¯ãûq’¤Q”†Öíº/¼°V,Ú»Œm£xƒlIŸ›+ÏÍ}™±F›htdÆ”Citü‚¥‹º‰*•ìžP¦Hºço e¥ÁI­ß):b’‚•YEbÄà”$L·/~Û¨¬DÍOム¿~·e«Ø§VQýN¨µŸoøZzœÐ†Ôg:v­+Ôu鯖U±ŒÄ(>´-”òü°Û±óC! ÀåH²P%ãá“s²†Ã°Óqs9#;<5Måp"b&—.-LaŸÖ øä•)…ûL¶£Ó‹Ó)¨ ˜žþõÉgÿÎÑTlÿ™0Bv&é E!Lƒ$KVŽßÎŦœPÈ ³@¨ðÒ¢6¼ù=bäXiip÷*ñPª™ÄȧƒC”) ,‘#™˜@HhVgÿ ,µ4æ¹|µ¦#ˆLÉzu%êVâ8\X‰5-Ë‚”½œB ¥JáÌL±\æ†Á‹E{bƒÕ4ž7 a˜pÎt];ô{:É2›­¦±,ß}šJÇ1¤Tý~ i,KG)µ,MIæôtÝ1*„r#ŽSËÒÁuƒ PÔ鸈 iÌ04D•ðw¦,°gGGPˆG)iE¸®…$zÅʳagþð'Ø> ÔB¶ZCÓäž·ÛîµkËÕjÁuƒNÇ BBÀ÷cÆhv€h.gžœ òyk~¾Üízí¶«ë¼Ý Ýðú³«•JîÞ½ßOžþ\»=|÷ÝGŽcfg&U+ùçž[ÙÙiö¯\Y4 íÝw•Jv$†Á»]ï;ßy¶ÝÞ¿´¼\[Yi4›ý›7wëõü… ó¿ñÆå/ùBßåãv2 ðñg0~®bœo?Z¾«'iw.å&áF¸÷¡^_'ÜDéJ¿„¡˜Éñ½•Mì¡J£ƒ[rpxš?hÝŒBšt¸stóƒBë–¯­~Zi¤„è’#")”*Ò²†9œ:(`|ü!< !|?y÷ÝGRÊ$µZ¾ÓV«¹½½Îñqß÷Ãà¶­÷û ‡a–~÷µ×.@·ëù~ôñÇÍ0L9§ùÜI¥’KS…ˆ''ƒÌ↱mºÆ…ˆYªf ü ˆONÝ®73SÜÜ<BI)…PˆàûñÞ^[ÓX’ˆÃÃ~±hÇq’$éßÁÅlEžº2Ï4Ï â¦ÈâXóùˆÃIjUì&ÇTiLu[EÃ,7±"Ìã³^w=íZžaªþÞ(U>‰äŽ_/4W®„N^=ú™àiR½Òˆ£=ÓŽ cYÉCÂ$!ÝR%K0ñXnHJ)¡a”Õ‡ @>o~ã—t!‚m묬ÔÇÈb'…P‹‹Š¢ë<Š’BÁ)—œŸ/§iÞ÷ã8N—–jµZ^yéÒ|’È8NËåÜË/ç¥TË™ºÎ£çÎ5*•œ¦1DxýõK†¡)…™É—s6;[âœ:ŽyxØËç­ï|çšÒ¶RÉ&„ŽN@”QÌÌÇá×JJz~=Ž,I}J5-Kˆ8º‘œ1Ÿu‹BdÙÕ•”„Rgÿ²¤CD8sr8‚N°Æ”ï‹n(ªUÞ•t¦²­ ãõ®*z$¯i\ƒ:÷t*Í#¦Œ°ŒPêqt˜°KuçÈ—5 "cÔrÄsi-(]2L"$^'§º‡é9'Ž/ôoæ.JÕ!¡ ˜gudŽÑôÅ£˜c¬Íré±+RcC»æ§4—+´‘”#?Vq*RÚOXØmŸÚÅ êŽeI'º½|±Ü±òÝ1 ¬D·»åZ›Gs×γÛÈK¡vºÃ y¯$sáb¯Tí?Í a Ò…p¹V ¼²=Îê£ÔÈAÞl?úhg0ð ÙlmWʹååÚë¯_ºuk7ID†›¨VóõzááÃæææÉúú)ü:Š’fsÀ9Õ4v~Íž~õióá)j)žýõqW]xtÜ¿õIíÕ—dQ]öö½Í­`÷@¯”Ì™ ~=ì}ØÁ¯§rã¹tèz›Ûé`hÍÏ©8Þ{Ð}ÿCgy) -I]ÏßÙk|ëZ.ì&½Õu”Ê^XPiwºÃ;÷…ç—ŸÖßÝ£ºåëÏ蕲VÈÃߘ;¢WNï™i_/åÉ-Ï”´cE˜gæzá‚2´ƒb¥ Axˆ¼TÌÙE׉¶sÒësÈ0f9BZƸ³P*É–£zÃD‰óT3 ZRïPÏv=¸ÉèšùY-×rJêa¢¹CU+˜l2¨¥’sñâ¼að……Jµš_]­ë:+mBÈÊJ=Œ")°^/ÌÏ—mÛÈçÍ‹ç3øõÆÆ,¥t0GÏÔˆBÁž™)fPl]ÿÂá×çRs¦BäÖVUçέεb‘r¦åólÆ2jÕè¤Í,çz©hÖk̲ÒáFã׌z P¥—p†RR]CTZÞÑòŽQ¯ÎÕu­P¨¼ô<Õ4½T2jUªk2Šx>óœCþ¦‘œê@2µ¯ƒ$”çÌWsø¯|­‡” ü‡œ·á™"–ÓvìØ×BAò’ \ÇväÐ%ÜL%Ìål«P*ìÌ-.÷Á½¶Ø,ßH$qÊeoèF½ÃrÚ4xª@]Í·X ›Úå–ÿ¬4 !-Ã*§q©QMr¹‘v9:üÁ²ôgžYÊ$’ §ðëêÔHÀ) ;s€móóåÏ`Ž/~­SÃDî8…‹çñ±£QK×®f/ÌÇÉà×ÕªY«e·a³ÓœÀš››°/äίË@tέÓqE£Va¸zíoº=±áøŸlDaÛ°ŸÁôjžµû b„O|Ø Å9/ú®ž7Wl{ e;{T˻޵¡ s(¤‘î3ª›2‰æÈp6Ý œµdá¥å\qsºƒ¾aYçÔ.á^8·¬·LˆbpŽŠk¾i‘³ÍŸŒCô4 ‰Ä‰,Ó.ã†ß$øõÙ—NTjLïÇí¹ežÞLxâë”ùsbÅ'_úkoðé;O@“¤¬d”+-“äR*n{£÷C²Á•0ø‡• ­÷„(xá0 Ë9Ý&’3Êý°"¤ÉÒ™è–å÷uˆïóëaJöz¾P*qò%÷¨(›l)e„c úÂ>d¶¤tšÉ ) !MgB$ºÆ…5ÝòûTˆlwŸ¤)x ~ý+€¡?ÿ‘§çûü-äú¯@OLªä¼ŠÒ\ÎañóÂK”|"‚!¼p‹¤ßÑzʰ=?5­4fhåÀ­;Õ|QBŸ¤^›ÍÆ h¥cÃI¢8oP˜‹Ž=Èò¥i3‘Åá‘ëD©‰l¨+¹”†Ì4P&ñ ·W)IAËŒž9I,§J©Á (m]çJašŠ0Lƒ`f¦”’,:<³q(¥²óÞà·3H™2ÃjK©!ŒQÏ 5g'sDZÃx{»í8º”xñâÜo±¿ "ɧ„2†‚Ovùµ‚MW½«0mw\¡€¤ceôM_£m¹Q SIfm®tÊ8¡ŒYš+ °ÿ0¿dسP"ehÚaªÚ—5Z¶µpþrÏ?ÇS2ãmÒ4bùbº¾+òE-³\(•X¦¨”5))•¢>èÓŒ§¢Âø¸Â0„o¿s›RÒïû„o}ëêâbmg§ytÔ[\¬öz^‹ƒƒn¯ç¿üòz£QüÓ?ý˜RbYº”*IDFÏ=wîÁƒ¦¦±\ΔRe@ÙããÁ`DQ|ñâÂóÏŸëvÝ›7wNN†Fqo¯}éÒüÙ¥÷·ô¹DN7 ˆ6š&RC§¢ZšíÎ4Ä~„Í1ÎF"¾ãËz^³ÒÀ¹©ªÕ÷„B¡»“+Õ”tswÓ4zeF4 Gù|'Ÿ'iZjuż>÷¼ £ápSZ•rÑ´| „% u]GS›"4 –wÆóS·RÆôŒSÓÔ9'Ùù7®d'9² HƒPJl·ÝrÙÉå¬,ÃÅìl1’,¡ðÒÒB$†¡e0îBÁ^]­?xÐlµ†å²sáÂ\ÅLˆ1¶´T]_Ÿñ¼hv¶ôeÛo‘‘Ì?½êÆU¹V1ËíR±Bèlw˜ÍBŽÖáf¡à+²Óy-´‹–V*XAéz§’cûûN1aü€qˆ’” J)T ʉ¦!!a©¼_*£iã$Ò./)‘SbGžeÓ Ö4šp-µmn!)IMSRfÕ†‘ÅŸPDtóÛ¿û e4C^džÅÅêÌL1ËÍÙj *•JN×5¥Ô7¿y5—3”Â^Ïs3ŽÓ(J®][ i*†ÃвôgŸ]ºpa–s®ë\JÉ-íW_½À%²(óß.c¿¦SGýLÇ,ÖK$û„”·kµÕþà‘'fË&Æ7Ý̸[ºdiëQDìY(—Y(岦‘R„EHªi±Ä©À5Ûëû&¥&Hé]Ó2£d À%,`”U:œŸ©ö¶?, ì•Ê(e­Ýv‹…Ô´€ÌÛ 9Ý.‰ç|_ÓX–7ê7®ÌÏWÚûûÝì ÃÐ’D,B)ôý(û°0_éõ½ùùR§I"ÒTh: ‚Ä÷#McAt»žã bY†çE½žßízAôz~>o:Ž'É“‡6~qtz ß_é™/ÚÐòëWÉ)ö±ÔQŒ`%=\Ü>è3péÛeÇŽ¥¤Pv¼À õiÆà) @î “z‰œâôâØÓŒsŽ–³);NL?Ú×LJH! 5)"Ô²O¤J( „JEP!¡ ‰ãaÂ0€"eè8n¡€ô)ÃÍ•’™¡¬P°¾ýíkR*ËÒ9§J!Y]mÌΖ8gÓnƘ”RÓ¥äð°»±1sõêâ$âˆRš¦2;`š~Ñ †R¢”Ô0„çÇ'-kažúx(Æ–,BFæÖÉaÑYÝ•ŠZm½T¢Yƒñ°Áĺ–=8öß()!@éè¤@!çSà.Òþ€Y3Œ‘wb‰¹É™d)¿2›‘Ó¿ã·"ʪÜÍéªùàè0X¿`Â]w@n>_ˆ¢bš|£n}:©Â­ˆ|8ÇÀë”â°“Ëg`V.+11X”"Zè-Š$Lâ*eMÓŠX½‚Œsf™a¦îOÀÐYßRš>‘ÀF)¥ !||ò9ø~|ïîN¯ïe©Ô‡Ã°ZÍÛ¶¾¸XÝÝmïì´æçËI"Žz¥’Ï>»Üïo½õàÊ•…8šÆ†Ã€0F†ÃèÆs¥’óÅ.„ÐÞ­[ƒÛwVÿÙ?žç>Ü ›Çf½®ÒD ©ås<—3ëUos;é ŒzE†qÒíò|žj<a#>i>¹ë¬.¡R(¤JÓŒod•®?CumpûSB(a¦%|_/•d’È pV—y>×þÙ;ù‹q»kÎ4ŒZÅßÚ&œ‹ €´7Ыå¤Ó£ºf4jöâBÜn£þîžY¯9«Ë_€—s<‰p$eeØ‚·Óõ~eMÖç¢0RBµEâ1†a­à8‘Ø¡êN`?!\Uål¶^Qœå}?ÄëvÃ@Ãì ©iÊÑh§2«8ÏQ_J$”I¡GFI:S £Ðï÷³€J<¦Ù0kbjJQJ)!Ô&!q®E‰eéooŸ8޹ºZϘìãwz=²“Õ“D\¾¼@™›+é'vv:5³èsËÒ/_žÏxñ‹%n[z¥œ%$•¤Ô4¼Íí¤? /\¾hÔ*Áþa°w`ö(U:jEŸ2–ÛXJ͹ ”ÚpçaÒîË äù\áòPÊßÚ۞ϙ3¨yl// Ï3gI •Š<çû‡Âó©®ÕrÜêh¥‚p½¤ÛO‡Ãt0ôwö —ÎSÓÄø¤íoï†GÇìÅçþú­FD@òØzF ¨òŒ_»r¯¶D™C «ß?Š8vÀyÅ„«¶Ü 1*€ì{IŸË™£¤¨)©r91vݸR! B!ÀÔÛ¶”bŒhQšfC 6Ûp-eB  ÔÒl Cj5 žœSô´e…|ðÁ{–©/-¯I%’Ø3 nYz&R*Ι¦1Ãà¾GQšE‰¦ñ4•¥’RŽJÊÉaqœ‹ö¯EË6#BTœ¤žÇsÕ4„@aºN8~€B0ËD)U’f( -ŸG¥@!¥2‘hZ¶ÿjù¤®'\/ØÛÏ_§ºR"wB€hš CL…’’;6Õ5á ”’r”‘sLSf[@Õ4'©ëª81ggÈ_¯!ˆRDÓà‡?ü”ÌqlÃ0ž}öÂ_üàÍÍåÂÒ¶nJ @TjV$Z“a–?ŠBÎÒ?J¸ ´B%õºµJiÞÖ¡TPº†Jê”ùJùºýé aµÂ°à}/t ³ÁIX¯B¹ß«ZFÐ2BzHì0èÍÏŦI´Á #û<"!¾e¯--á(„D`”T«YzKÌr]OÐ8¶mL’¥µE@DB€Ž£„§ù5F€ƒ@ Ý0«Ù¼áùÜ)ÿðœ3 Ì>+B)LRåŽA˜Û´bA+¬ÅùÇ™i5¾‚ã·<ÉãêÕ¦ØþZžZ½4뺮iœ€;Ìà¦J1¥h.Ê„J+©3šjº¡•‘¦Œ¦‚;Ò8T–©×ûÜ “d‘’žiU†Ã@‰”±>’„Ða*5F©ž¦UNL$¦¡€˜I,(ó¢„G1•2aœºb,kašËÁY¥DSŠbLNø´é%ã› ¯œí½Ïp*?qÃçÜóÓ”àùô럓’ì©÷ü‚jŸ-í¶ñ‹í„̪ɹeåtMëõzB$¤¨é²j¿Sí¶LM¦Â„zm 2Š¥nÛ4"ÄÛRæ[£ Ë”ˆ 92ÌJg¥² ÄÉçc„Žd”Ìôz$Šz±X15;MšùB“ÄÐ4×óKI<"æû¦9a|õ”hš ,Sèi 2åê3‚•K_"M4TBHš¤®çìH)@Agó±_‰C' rù¼nYX^BËRö,Ç¡Ûz9y¢ÀPQ :ŠçÛí´ZiårB*d¼¢dK³6SØ—äÈ´ï ˆ}_pˆÂ²Ï-¦ ŠF>/9*àÓ¾M¢•P ô›À8hyˆâ”/ùBæý–>—&€Øi'9%$NƒTm;lÌ£H*¡¯ê5b$•@•oXI÷XˆÔÑøªF7†âã<£—IØ»âÒ²|¾â{VÒϧ)Íç»BP…h(Ñ~£A(%f (¦C7o[„1$ÄHÓb[¤ŒÄ\§”Æ#ÇOF)!„Jâ.|É+— ‚Ô‡üè…_¥O~K_!2}ATÇÍã^¿G aœ)y«•+%%P©0I$ã%Ý q…ÊëzÍ RaµÊ9ËIñJkçur»˜çÛî™2Ä?èœô™²U'm‡©òÙ…œQÎwSQ?:ŠòyÞï' 82K¥ýJ…p)1a´ì{±](2%g|ïÈÉQÄJ¿g—J<H)â(s—0lÔ€ê€)ð=Ú8‚B5±qB&GERÎ*’…ûLCûN‰žœ <Õƒ£|Žˆ(¥$$ BBHvìòä¶ñÑ2;c€e ÎDŸg€§ã†ÆFW8­üx¦/Žp2emÍJ%@Ɔ< ¨¤ÊªÁÆÒI–B‹1þYbî/ÍdÇD)"%èš±¼R>~ƒkZf¨J€Ð$©ø^Z,Ûî€8NBõb§eÑ Ã°n¥lºéXÃ0lèêe+}+b·\É ÞQTê“=¯¦áîy3è–¯ö¨jly/[b8ǨËY!ï„~X*¢RõvgP­ºžPª7›©‚¡:¥¢KY®ÓÑLëã L®öûýNg „Ã@IÅ}–$I±TÒC;¨¶0|à\ÛÚÜ$„´Ú­•••••ß÷‘ŠRÊîÏÍÍòJi³ÙôÿÙg¯Ÿ¦BJÁÛÙÙ½|ù2ËüH³ÙlµN}ßßÙÙ©×ë„PÏsã8–RU*åË—¯7›®ç;·EÑÖÖVÆÊëëišÞùôÓR¹¼´´ÄB Û±Ëå²RÙ@›–5²§PÊDšê†¡®k£d“\3t=Nb!Df2Bjœ§"K-ƒˆ¥$žïÕªµÌ‹xÜ<ž›;99‡Ýn·P(¤iº¶¶æ8!¤Ýj=xøðÂù ¶c÷ûý™™™3|ázyÐ35fÙN¯P €h†>gLÅ‚Ÿ;wý Óë‰+6¢<'Ãí!ùI—Ô-æÎ úiGV¸²9=FòöãÙnïóÆ`¦Ä¢Aáb£ñè¸øA`Û‚’D©lºF¦)MS(¥$ç¶”®c›” ËA}Ê$I67wÇé÷ú[[›NÎi6¿ùÍo6urrrò'ò'À0Í\.gYÖáÁÁâÂÒíÛ·þó·Úíöââb†¶mŸœœdý @Â0X___XXüñ|Ül¦yãÆ[·n-//†1És‘¦i’¤½^¿Ûí›7o‹Å0 «ÕJ³Ù”Rž;5…­V›1G cLH‘¦©çy‡GG­vûæÍ›š¦†ž a[ÎÄ•ŒˆÇÇ'BÈN»åär3×u«µj§ÓqÝ¡«•ʥ˗ß}÷½0 u]/äó¾ïû_­Ö¥\Ór¹œçºÏ\»Öít}?@Ä4M[­–í8Aöz}¥pkkÛ0 θiY„×uONZá[ÈçûƒÁ7ƒeša醮¤Tˆš¦EQlYf'ŒQFYG¶mEaÄ5 „†aDQd†t]ÂÐ0M¥„Œt¾œFÉL£*K$‘¡EÕr!ðû33¥ e>Ž‹ˆÃƒ#Ïrfý[‰§À ·À ¿”‹«&€7øY¬Ï8osW`,èæ=/½‘À…Ð{àwùG·}JJsa¶Ý¨³TD¤Ô­Õ1ÐÒT õzÁuóBÐñ¾À‘smiii0 È×_ÿ:¢”Òu=IâL VWW’$5 Ã0ŒëÏ=[* Åüõë×<ÏK’˜ªiÚÜlƒqލ8ׂÀwœÜûï¿«”Èr—/_ªÕÊår1I¢lyȶ-ßw%¢4MݲtË2„‹‹óFcii¤L«Õràû®;ð\7É8™²ÒuþÒK7úýžëºŒ‘$ ¥LU*’l%ÈvÒZ­|xx$dZ¯WkõÊpØ CQÎÍÍBºÝŽíXB$–eT«eÓ4ÇÙßßwr6£tyy‘"„Ðu]Ó¢¬ÖÊÅb1[ˆ•Lww·5MÓ4æ8–ãXJɹùÓ´!†¡ù¾ë8¥´R-…¡¿¸8?rq*0|0øÔõ®ÆžUß÷’$ur©T*Ç'Tb¤éDGj2Zn·übE× øºçëŒÙœ(ƒ°Üí1…owħµcEãM–òä/Z*’”Åû£úÑ[1D’,hlÞV›ž¼ë†k¹¨@“6Åž‘›…4F•w=ǽJ9¡ì4=ca±`Åq`šºë²0µä½÷Þ1-£Zi JJSMËh¶;îË/opN»]¯Óñ«¶[aÚáaoo¯£iÌ÷cÃàžehÛ8N«µüÚ¹)ÕÄå°µu’6­i R!)%J¡ah»»-ÇÑ …œÆ™çÇÇÇý,—̹s •Å"H)c­Ö°P°LSGÄ4•­Öpy¹–µ%æ¬c9ïô,³Ì­’ízÓ7L§£ÇSÛìç‡ð¬ñˆ Îáç?ÿ¢fFø/¿|ýÇo½÷n¤jT¯§4­"R–Dn®PÊ[ZÍ ÊaXŒ"HÒV îµü͈º¨]²e¤è£z‘J’*X° a2‹ÓݘÝH…˜"¡ÏéP` tÃRK6}iÆ05 –) £eÛ1ç‰mODZD0”\èõ’nW—â…Kç€!º¦ …Ngðþû›ËËÕ$/Ε˹»wÇTŠGï½÷ÉÜ\I×µ8N]7(•r¹œY.;÷îÁìl©ß*ç÷ÿù4•÷ïõzþpäóf©”»}{÷Ê•Å8Vßÿþ|ÞúûÿºïÇ5KåB«í 9ØÞîîï,ËÚÞn5›ýBÁºreq8ŒØp˜¹¹Ú›oÞMSrãÆÚÑQÏsÅövw02èQ©d#ÒÝÝ^¯ççóçt0ÊåÜáaïúõ•(ÂÝݶ¦õ––ªRª8Vûû½¯ýÂááÐuÃ{÷«Õ|·ëåófÄsså H:·V+(%®\Y~óÍ{®I©Ê/¾¸þ«Éï¿2!‚¦eÇCC.çbH!ƒcÛœeDÔÒ¹NAjGÒlŸ¬0èºC§çÞõÔÍvdšÆIÈglMÆê§=â%¢“²`âó ½¤n*w øûó|ÞÄ;ÙQZ7Lïz¸l¨Y“(Ä÷:é¼Mg抉i!]OuŒ4͵۾¦©|>1Œ#Ç©†¡NHªÆwü×ÿõÿݲ¬b±äyáûï?¸paªŒñJ%§i|só˜*„ºti1;¾$Ÿ·£¶mhB ‡ÑÚÚŒeéårna¡ªi¼^/Äqêû‰mšÆÒT†æy±eõzqn®’ÝÓï”Òùùj¥”²ùùŠç††¡»nT­æ+•ÜìlEÕj ³¡š¦Õjy¥@Y¯._^‚D)¤”†æº1!DÓ¸”*ŠÄêj£Ñ(v:®ã˜³³•?Ü*ì8N !¾Ÿ¬¯Ï./×ëõ¥4 SJ çܲŒBÁ™- ¡r9Ó²ôb1wrâv»ÞÜ\YÓ¸aèss•qº¿¹•¢„ÆÈÑѡ~϶­‹7¶¶wg—«¥B€ eÇr”¢Kºî¸þOO’·š~Ì’ÑÃuÜòd7Q”ëy5«É×J*§Ñ?oÁž¯X%„;n pÅ¡‰P y}NÇH‘¢†ä$?ç Ð4-Ô ÆH4-Ÿ¦ÅN7&€œ§¦)C¥´À¯ÚÎlµJ!ñÿ) ýF£.¥::êÖëÇ1ÔèOÈvLJ)@Ï)q¼MŒVþ0J,S£”(:FNý%“ÛÙ–:²þÈâ=)ÍŽ±'#q,%ºÆ³+€%G»¥$«[¶§gSdöd¥prdßÄ‘½{ŽcŠPˆ, 2$!J©‘*G ˜¤BÓD$©È9fvì7!”Ÿá2Ò`ÉD€zêáêdêÄʳ%™dQNÅb¦ëÒ‡þÖÉ`?‚}F¡Ÿ¸ ÑMHC—ouÀb´j(p  A+å©Â7C•*(iJ=m]ÉŽ€-O^/Ðo5Ø#ïõâ^¬) ѵÅZ e𦆮+Ä1Ô8Pš2¦úi.Œ¯`:Ö̼ŽxšBalÐÇáp†a¿ß/•JÙ™†§f}Tc‘3»¤”BT8½•g?*…‘"ðÂ\Ôz¨`špÄxûgÔ©É,© §7ȳ¿‡9§Ýéú'ÝVµbȈp>$hy.òzT£ "AY‘ O“躺% ËYóÙòµkÃ;õƒœ[>á&RÓiÙtSåó5¥fü ÑæyyǰQ4}ß0D«~/ª×bÎÇI)¥¨¶ k''¡D+ e”¾}·v $ЧD©Žàûʸ€¢Î¡z‰‚ñÎíËi¬íÓéߨˆƒ•)®êÒEž7ø›Éß#'V£‚HbC$¥"PŠZ¿Ÿ‹‰ãÈÉa_6;=Îd¡_J™RÊqœ\.?ÅgØóÌœ™ 6?Ÿˆp ’ LeL·Eo@¡—ú•çÝP´¶÷8g~Þ©…¾îùGv1aÜ¢âzâ‡A“ê7¹’Wd˜Ä8$)V‹¥yK?2ÍašØ”˜¯Ôf÷ýh‹Ys*­èôˆ`^ŠF02L}È´¸Rž?fë’CשRÖ`V«1%yw˜ )åÐíö}q§ŸHÊ›0 sShpù0d5ƒ>òÉ ¡„¨éü§¡Pqº;Ò_‹C ÿ±EoTùŒÎ~Ú‘^"›‰²8ýãCùBÐÙ˜Ëy– IÊ+%Å: aÈ,kdŒý²ÙéóZGÆu&,Ã+—ˈ¸»»«iOOJEF')?&<~öj8Jà(’LìLúûÜ© ¯ €Ñ¥Å#{ö8V ’FµÈ¸lu>âÖ€r(˜ÄŽIfã„I4å…üa3íÛ¹…¾¥K)[„æŽÛÒó$#daŽú‰ì1­AÒdyÉ w‘Ç”!ç+E)Í¢3Ÿ¬®R?£Êže“ÁE=B¢RÊ D›(8'JQÆ$•"ƒ)}5™ )ñ´—fŠõÆ úžÎ£ûÆ–§ÏÖlò…J¿°BQ))MÎ@Á9¯Ž eJÓ“$!RJ PÎå9ÿe¢>õYJ)ÒTJ B @¨—œ_¾(8[T’Ä€™’„RJÓ4 ÓüŠBÄ0s]W)õÕd2òDBY2½f²ç‰&ž)ç3o›ê‘_¦B6ݽs' £••å.//ë[ߢõØe¥ÔüÿQ×õƒƒý .Bÿ÷¿P(üUu|BÈ|ðî»ï:޽´¼Ünµ¥¿ÿûÿ SºÿªEmoo¿õö[€/ä5M;:<|ãonllü Eyž÷¿ýoÿZJ5;;kšÆñññW“ÉF’Õø„ø”òñ8뉧ù¯o£™™™‰Âº¼¼ @êõú4¦ò—'BH­VCTW®\¹|ùr†×°¬_ñ(Ùb±X¯×ªÕÚóÏ=ÿèÑ#¥¤mÛ¿ZQŽã¬,¯PB––—ƒ È9¹r¹ü+”Œ±õõ Ïóž{î¹8Ž Ã$ï½÷Þ_¯ÿ„?ÿùÏ …B½Þ8µx(¥ÚíöÕ«W¥”;;;õzíá£ÍõõÌ #¿ít:ÓOQ7›ÍóçÏ¿ú꫹\î¯RÅ_m‹ü(ê±Ã¬¾À¢¾Š+"H%áŒbx øž2À>Ý„ø‘äþ:ôf„ü õë«ÒW‘É`äðœÎk=â3)ÅÞÞ^I’0Ʀ̊d¢‹ž¶t¤7|]§è+Êdcš–÷3Ü®­­!âÖÖ&ç|’ît¡B?ƒxj˜…qÌËéßßÒß}•™ §Eý  !¥RJu:’/ˆœ…LšH¤”ÇÇÇæ¯¤–ÿ–þ:ôe2<ÍR1¹@ÆqÜëõ3mb˜Í0jäqÑ)îY)u÷îÝ/»eé+Êd”Ò'65€J¥ªiÚÊÊŠa˜ï‹E]×`JKÓtjÌ8gÕjÕ0 øBÕº_L§aœ§é+ÊdJ©)rD„€ã8ív{²X …áÐ}òññS£¿š¦kšÇñ—ݬ¿£ôUd²l{K’4MÓQüÏø‡‰ÎøT“Ä/T"ÇñD“d¿xjâ§¥"H]ƒÉ÷qDøS~!³N!ÁäÉ ŒoÊ >§Úðy^ØÏ†2ãã·áTâã.•ÇÓpÑ ªùé}2ݽ0­â!_Myv¬ðööÖÑáácñÔýg ¢=i6NµÇ¹žúÈé…Óþúxø8½ÁéÛ¦§rœ-„LŠÂ 1ny¬ “ÏOTåÔ|8l1ýÞÇXø©ÙÁë±ÉCøYmâ§INqóÍä-„¯¦Åÿ´G¾ì*ü–¾ú*®dú­Aëoýö܆ßÒ¯þÿŽ–v×™(Û.zTXtcreate-datexÚ320°Ô54Ò54 14±24´22Ö50±20A} p±{ã.zTXtmodify-datexÚ320°Ô54Ò54 14±24´22Ö50±20A} ‰Œ3zTXtSignaturexÚ3±LK´LNJ5610101MN667KI4O4H²0IM³´”ùñ9OªIEND®B`‚gri-2.12.23/doc/screenshots/gri-screenshot-4.png000644 000767 000024 00000164443 11310756313 022020 0ustar00kelleystaff000000 000000 ‰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åK4kN^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-2.12.23/doc/resources/bottom_banner.gri000644 000767 000024 00000000572 11310756313 021213 0ustar00kelleystaff000000 000000 set 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-2.12.23/doc/resources/Makefile.am000644 000767 000024 00000000773 11310756313 017716 0ustar00kelleystaff000000 000000 ## 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-2.12.23/doc/resources/Makefile.in000644 000767 000024 00000021122 11605066212 017715 0ustar00kelleystaff000000 000000 # Makefile.in generated by automake 1.10 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in 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) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) VPATH = @srcdir@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CXXFLAGS = @AM_CXXFLAGS@ 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_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@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ # gri: doc/resources/Makefile.am srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ 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 \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/resources/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/resources/Makefile .PRECIOUS: 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 tags: TAGS TAGS: ctags: CTAGS CTAGS: 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-am info-am: install-data-am: install-dvi: install-dvi-am 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 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 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 uninstall uninstall-am 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-2.12.23/doc/resources/math_symbols.gif000644 000767 000024 00000041106 11310756313 021045 0ustar00kelleystaff000000 000000 GIF87aÄ ðÿÿÿ,Ä þŒ©Ëí£œ´Ú‹³Þ¼û†â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-2.12.23/doc/resources/pixel.gif000644 000767 000024 00000000052 11310756313 017460 0ustar00kelleystaff000000 000000 GIF89a€ÿÀÀÀ!ù,2;gri-2.12.23/doc/resources/sm_bg.gif000644 000767 000024 00000000721 11310756313 017431 0ustar00kelleystaff000000 000000 GIF89aÄ ‘ÿÿÿÿúúúíííÞÞÞ,Ä ÿœ©Ëí£œ”‰²Þ¼û†â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-2.12.23/doc/resources/symbols.gif000644 000767 000024 00000004611 11310756313 020034 0ustar00kelleystaff000000 000000 GIF89aó ðÿÿÿ!þ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-2.12.23/doc/resources/top_banner.gif000644 000767 000024 00000001372 11310756313 020474 0ustar00kelleystaff000000 000000 GIF89aZñ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-2.12.23/doc/resources/top_banner.gri000644 000767 000024 00000000572 11310756313 020511 0ustar00kelleystaff000000 000000 set 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-2.12.23/doc/examples/example1.dat000644 000767 000024 00000000425 11310756313 017666 0ustar00kelleystaff000000 000000 0.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-2.12.23/doc/examples/example1.gri000644 000767 000024 00000000311 11310756313 017671 0ustar00kelleystaff000000 000000 # 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-2.12.23/doc/examples/example1.ps000644 000767 000024 00000042120 11477466154 017555 0ustar00kelleystaff000000 000000 %!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-2.12.23/doc/examples/example1.txt000644 000767 000024 00000000015 11310756313 017730 0ustar00kelleystaff000000 000000 example1.gri gri-2.12.23/doc/examples/example10.dat000644 000767 000024 00000024216 11310756313 017752 0ustar00kelleystaff000000 000000 0.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-2.12.23/doc/examples/example10.gri000644 000767 000024 00000001445 11310756313 017762 0ustar00kelleystaff000000 000000 # 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-2.12.23/doc/examples/example10.ps000644 000767 000024 00000337414 11310756313 017633 0ustar00kelleystaff000000 000000 %!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-2.12.23/doc/examples/example10.txt000644 000767 000024 00000000016 11310756313 020011 0ustar00kelleystaff000000 000000 example10.gri gri-2.12.23/doc/examples/example10color.gri000644 000767 000024 00000003433 11310756313 021020 0ustar00kelleystaff000000 000000 # 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-2.12.23/doc/examples/example10color.ps000644 000767 000024 00000540236 11310756313 020670 0ustar00kelleystaff000000 000000 %!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-2.12.23/doc/examples/example10color.txt000644 000767 000024 00000000023 11310756313 021046 0ustar00kelleystaff000000 000000 example10color.gri gri-2.12.23/doc/examples/example11.dat000644 000767 000024 00000022746 11310756313 017761 0ustar00kelleystaff000000 000000 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-2.12.23/doc/examples/example11.gri000644 000767 000024 00000007434 11310756313 017767 0ustar00kelleystaff000000 000000 # 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-2.12.23/doc/examples/example11.ps000644 000767 000024 00000112731 11310756313 017625 0ustar00kelleystaff000000 000000 %!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-2.12.23/doc/examples/example11.txt000644 000767 000024 00000000016 11310756313 020012 0ustar00kelleystaff000000 000000 example11.gri gri-2.12.23/doc/examples/example12.dat000644 000767 000024 00000000104 11310756313 017742 0ustar00kelleystaff000000 000000 800 .0 .2 .3 .4 850 .2 .3 .4 .5 900 .22 .33 .44 .55 950 .6 .7 .8 .9 gri-2.12.23/doc/examples/example12.gri000644 000767 000024 00000004131 11310756313 017757 0ustar00kelleystaff000000 000000 # 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-2.12.23/doc/examples/example12.ps000644 000767 000024 00000050700 11310756313 017623 0ustar00kelleystaff000000 000000 %!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-2.12.23/doc/examples/example12.txt000644 000767 000024 00000000016 11310756313 020013 0ustar00kelleystaff000000 000000 example12.gri gri-2.12.23/doc/examples/example13.dat000644 000767 000024 00000003014 11310756313 017746 0ustar00kelleystaff000000 000000 34.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-2.12.23/doc/examples/example13.gri000644 000767 000024 00000002361 11310756313 017763 0ustar00kelleystaff000000 000000 # 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-2.12.23/doc/examples/example13.ps000644 000767 000024 00000070567 11310756313 017641 0ustar00kelleystaff000000 000000 %!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-2.12.23/doc/examples/example13.txt000644 000767 000024 00000000016 11310756313 020014 0ustar00kelleystaff000000 000000 example13.gri gri-2.12.23/doc/examples/example2.gri000644 000767 000024 00000000276 11310756313 017704 0ustar00kelleystaff000000 000000 # 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-2.12.23/doc/examples/example2.ps000644 000767 000024 00000042146 11311207327 017544 0ustar00kelleystaff000000 000000 %!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-2.12.23/doc/examples/example2.txt000644 000767 000024 00000000015 11310756313 017731 0ustar00kelleystaff000000 000000 example2.gri gri-2.12.23/doc/examples/example3.gri000644 000767 000024 00000004274 11310756313 017707 0ustar00kelleystaff000000 000000 # 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-2.12.23/doc/examples/example3.ps000644 000767 000024 00000052050 11310756313 017543 0ustar00kelleystaff000000 000000 %!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-2.12.23/doc/examples/example3.txt000644 000767 000024 00000000015 11310756313 017732 0ustar00kelleystaff000000 000000 example3.gri gri-2.12.23/doc/examples/example4.gri000644 000767 000024 00000001173 11310756313 017703 0ustar00kelleystaff000000 000000 # 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-2.12.23/doc/examples/example4.ps000644 000767 000024 00000051772 11310756313 017556 0ustar00kelleystaff000000 000000 %!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-2.12.23/doc/examples/example4.txt000644 000767 000024 00000000015 11310756313 017733 0ustar00kelleystaff000000 000000 example4.gri gri-2.12.23/doc/examples/example5.dat000644 000767 000024 00000000662 11310756313 017675 0ustar00kelleystaff000000 000000 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-2.12.23/doc/examples/example5.gri000644 000767 000024 00000001055 11310756313 017703 0ustar00kelleystaff000000 000000 # 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-2.12.23/doc/examples/example5.ps000644 000767 000024 00000176132 11310756313 017555 0ustar00kelleystaff000000 000000 %!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-2.12.23/doc/examples/example5.txt000644 000767 000024 00000000015 11310756313 017734 0ustar00kelleystaff000000 000000 example5.gri gri-2.12.23/doc/examples/example6.gri000644 000767 000024 00000003205 11310756313 017703 0ustar00kelleystaff000000 000000 # 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-2.12.23/doc/examples/example6.ps000644 000767 000024 00000207166 11310756313 017560 0ustar00kelleystaff000000 000000 %!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-2.12.23/doc/examples/example6.txt000644 000767 000024 00000000015 11310756313 017735 0ustar00kelleystaff000000 000000 example6.gri gri-2.12.23/doc/examples/example6histogram.gri000644 000767 000024 00000002447 11310756313 021630 0ustar00kelleystaff000000 000000 # 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-2.12.23/doc/examples/example6histogram.ps000644 000767 000024 00000206411 11310756313 021466 0ustar00kelleystaff000000 000000 %!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-2.12.23/doc/examples/example6histogram.txt000644 000767 000024 00000000026 11310756313 021655 0ustar00kelleystaff000000 000000 example6histogram.gri gri-2.12.23/doc/examples/example6image.dat000644 000767 000024 00000040000 11310756313 020667 0ustar00kelleystaff000000 000000 %:% '"".+)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-2.12.23/doc/examples/example6mask.dat000644 000767 000024 00000040000 11310756313 020540 0ustar00kelleystaff000000 000000 gri-2.12.23/doc/examples/example7.gri000644 000767 000024 00000001633 11310756313 017707 0ustar00kelleystaff000000 000000 # 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-2.12.23/doc/examples/example7.ps000644 000767 000024 00000067635 11310756313 017566 0ustar00kelleystaff000000 000000 %!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-2.12.23/doc/examples/example7.txt000644 000767 000024 00000000015 11310756313 017736 0ustar00kelleystaff000000 000000 example7.gri gri-2.12.23/doc/examples/example7a.dat000644 000767 000024 00000001634 11310756313 020040 0ustar00kelleystaff000000 000000 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-2.12.23/doc/examples/example7b.dat000644 000767 000024 00000011113 11310756313 020032 0ustar00kelleystaff000000 000000 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-2.12.23/doc/examples/example7c.dat000644 000767 000024 00000007232 11310756313 020042 0ustar00kelleystaff000000 000000 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-2.12.23/doc/examples/example7d.dat000644 000767 000024 00000006017 11310756313 020043 0ustar00kelleystaff000000 000000 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-2.12.23/doc/examples/example7e.dat000644 000767 000024 00000005252 11310756313 020044 0ustar00kelleystaff000000 000000 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-2.12.23/doc/examples/example7f.dat000644 000767 000024 00000003614 11310756313 020045 0ustar00kelleystaff000000 000000 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-2.12.23/doc/examples/example7g.dat000644 000767 000024 00000001364 11310756313 020046 0ustar00kelleystaff000000 000000 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-2.12.23/doc/examples/example8.gri000644 000767 000024 00000005463 11310756313 017715 0ustar00kelleystaff000000 000000 # 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-2.12.23/doc/examples/example8.ps000644 000767 000024 00000116030 11310756313 017547 0ustar00kelleystaff000000 000000 %!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-2.12.23/doc/examples/example8.txt000644 000767 000024 00000000015 11310756313 017737 0ustar00kelleystaff000000 000000 example8.gri gri-2.12.23/doc/examples/example8a.dat000644 000767 000024 00000023256 11310756313 020045 0ustar00kelleystaff000000 000000 -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-2.12.23/doc/examples/example8b.dat000644 000767 000024 00000000076 11310756313 020041 0ustar00kelleystaff000000 000000 517.0 0.05 516.0 39.38 514.0 118.67 512.0 194.63 508.0 321.14 gri-2.12.23/doc/examples/example9.gri000644 000767 000024 00000003507 11310756313 017713 0ustar00kelleystaff000000 000000 # 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-2.12.23/doc/examples/example9.ps000644 000767 000024 00000350037 11354705702 017563 0ustar00kelleystaff000000 000000 %!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-2.12.23/doc/examples/example9.txt000644 000767 000024 00000000015 11310756313 017740 0ustar00kelleystaff000000 000000 example9.gri gri-2.12.23/doc/examples/example9a.dat000644 000767 000024 00000035572 11310756313 020052 0ustar00kelleystaff000000 000000 -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-2.12.23/doc/examples/example9b.dat000644 000767 000024 00000000076 11310756313 020042 0ustar00kelleystaff000000 000000 517.0 0.05 516.0 39.38 514.0 118.67 512.0 194.63 508.0 321.14 gri-2.12.23/doc/examples/FEM.gri000644 000767 000024 00000000364 11310756313 016574 0ustar00kelleystaff000000 000000 set 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-2.12.23/doc/examples/FEM.pl000755 000767 000024 00000003055 11310756313 016431 0ustar00kelleystaff000000 000000 #!/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-2.12.23/doc/examples/FEM.ps000644 000767 000024 00000043061 11310756313 016436 0ustar00kelleystaff000000 000000 %!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-2.12.23/doc/examples/FEM.txt000644 000767 000024 00000000010 11310756313 016616 0ustar00kelleystaff000000 000000 FEM.gri gri-2.12.23/doc/examples/logo.gri000644 000767 000024 00000001055 11310756313 017123 0ustar00kelleystaff000000 000000 set 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-2.12.23/doc/examples/logo.ps000644 000767 000024 00000044055 11310756313 016773 0ustar00kelleystaff000000 000000 %!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-2.12.23/doc/examples/Makefile.am000644 000767 000024 00000010427 11500152353 017512 0ustar00kelleystaff000000 000000 ## 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 $< $@ %-tiny.png : %.png -convert -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-2.12.23/doc/examples/Makefile.in000644 000767 000024 00000030573 11605066212 017533 0ustar00kelleystaff000000 000000 # Makefile.in generated by automake 1.10 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in 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) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) VPATH = @srcdir@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CXXFLAGS = @AM_CXXFLAGS@ 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_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@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ # gri/doc/examples/ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ 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 \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/examples/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/examples/Makefile .PRECIOUS: 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 tags: TAGS TAGS: ctags: CTAGS CTAGS: 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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: info: info-am info-am: install-data-am: install-dvi: install-dvi-am 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 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 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 uninstall uninstall-am %.svg : %.gri gri -output $@ $< %.txt : %.gri echo "$<" | cat >$@ chmod +w $@ %.eps : %.ps cp $< $@ chmod +w $@ %.png : %.ps -convert $< $@ %-tiny.png : %.png -convert -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-2.12.23/doc/examples/model.elements000644 000767 000024 00000000040 11310756313 020307 0ustar00kelleystaff000000 000000 1 1 2 3 2 2 5 3 3 2 4 5 4 3 5 6 gri-2.12.23/doc/examples/model.nodes000644 000767 000024 00000000050 11310756313 017604 0ustar00kelleystaff000000 000000 1 1 1 2 2 1 3 1 2 4 3 1.5 5 2 2 6 1.5 3 gri-2.12.23/debian/changelog000644 000767 000024 00000101350 11607300521 016163 0ustar00kelleystaff000000 000000 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-2.12.23/debian/compat000644 000767 000024 00000000002 11310756313 015514 0ustar00kelleystaff000000 000000 7 gri-2.12.23/debian/control000644 000767 000024 00000006033 11355100034 015713 0ustar00kelleystaff000000 000000 Source: gri Section: science Priority: optional Maintainer: Peter S Galbraith Build-Depends: debhelper (>= 7), libnetcdf-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, texinfo, imagemagick, info, ghostscript, gsfonts Homepage: http://gri.sourceforge.net/ Standards-Version: 3.8.4 Package: gri Section: science Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, dpkg (>= 1.15.4) | install-info 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 PostScript 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), emacs23 | 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} Replaces: 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-2.12.23/debian/control.unofficial000644 000767 000024 00000005052 11310756313 020041 0ustar00kelleystaff000000 000000 Source: 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-2.12.23/debian/copyright.template000644 000767 000024 00000001165 11310756313 020066 0ustar00kelleystaff000000 000000 This 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-2.12.23/debian/gri-el.emacsen-install000644 000767 000024 00000002414 11310756313 020477 0ustar00kelleystaff000000 000000 #!/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-2.12.23/debian/gri-el.emacsen-remove000644 000767 000024 00000001326 11310756313 020327 0ustar00kelleystaff000000 000000 #!/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-2.12.23/debian/gri-el.emacsen-startup000644 000767 000024 00000000656 11310756313 020541 0ustar00kelleystaff000000 000000 (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-2.12.23/debian/gri-html-doc.doc-base000644 000767 000024 00000000444 11310756313 020205 0ustar00kelleystaff000000 000000 Document: 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-2.12.23/debian/gri-html-doc.emacsen-startup000644 000767 000024 00000000310 11310756313 021633 0ustar00kelleystaff000000 000000 (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-2.12.23/debian/gri-html-doc.preinst000644 000767 000024 00000001215 11310756313 020211 0ustar00kelleystaff000000 000000 #!/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-2.12.23/debian/gri-pdf-doc.doc-base000644 000767 000024 00000000372 11355100034 020002 0ustar00kelleystaff000000 000000 Document: 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-2.12.23/debian/gri.doc-base000644 000767 000024 00000000423 11310756313 016475 0ustar00kelleystaff000000 000000 Document: 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-2.12.23/debian/gri.man000644 000767 000024 00000013074 11355100034 015571 0ustar00kelleystaff000000 000000 .TH GRI 1 .SH NAME gri \- scientific graphics language .SH SYNOPSIS .B gri [ .B OPTIONS ] [ .I CommandFile [ .I PostScriptFile ]] .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-ps-doc package is a .I PostScript 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-2.12.23/debian/gri.postinst000644 000767 000024 00000001757 11310756313 016716 0ustar00kelleystaff000000 000000 #!/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-2.12.23/debian/Makefile.am000644 000767 000024 00000000742 11403430371 016351 0ustar00kelleystaff000000 000000 ## 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-2.12.23/debian/Makefile.in000644 000767 000024 00000021120 11605066212 016356 0ustar00kelleystaff000000 000000 # Makefile.in generated by automake 1.10 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in 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) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CXXFLAGS = @AM_CXXFLAGS@ 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_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@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ 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 \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu debian/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu debian/Makefile .PRECIOUS: 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 tags: TAGS TAGS: ctags: CTAGS CTAGS: 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-am info-am: install-data-am: install-dvi: install-dvi-am 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 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 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 uninstall uninstall-am # 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-2.12.23/debian/README.Debian.template000644 000767 000024 00000004114 11403430371 020165 0ustar00kelleystaff000000 000000 gri 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-2.12.23/debian/README.Debian.unofficial000644 000767 000024 00000000605 11310756313 020476 0ustar00kelleystaff000000 000000 gri --- 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-2.12.23/debian/rules000755 000767 000024 00000013156 11403430371 015400 0ustar00kelleystaff000000 000000 #!/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/copyright gri cd doc; make refcard.ps cmdrefcard.ps 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 src/gri.cmd src/startup.msg-tmp mv doc/FAQ.html.KEEP doc/FAQ.html dh_clean rm -fR debian/gri-$(version)static rm -f debian/README.Debian debian/gri.1 debian/copyright 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/copyright: 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 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/copyright Makefile cd doc; make 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 cd doc; make gri.pdf install -m 644 doc/gri.pdf 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 doc/refcard.ps doc/cmdrefcard.ps 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 # This is a target that developers won't use. I use it to create # non-Debian Gri packages that contain a specific version of Gri for use # alongside other (newer) versions of Gri. # See README.Debian.unofficial binary-arch-unofficial: debian/copyright build-arch rm -f debian/*debhelper rm -rf debian/gri-$(version) debian/gri-$(version)static -cp debian/control debian/control.real sed -e 's/VSN/$(version)/g' debian/control.unofficial > debian/control -cp debian/README.Debian debian/README.Debian.real -cp debian/README.Debian.unofficial debian/README.Debian cd src; make install_linux_debian_grionly debian=../debian/gri-$(version) (cd debian/gri-$(version)/usr/share/gri/$(version) ; ln -s ../../common-licenses/GPL license.txt) cd src; mv gri gri.real -rm debian/substvars make LIBS="-lm -L/usr/lib/netcdf -lnetcdf -static" cd src; make install_linux_debian_grionly debian=../debian/gri-$(version)static (cd debian/gri-$(version)static/usr/share/gri/$(version) ; ln -s ../../common-licenses/GPL license.txt) cd src; mv gri.real gri dh_testdir -a dh_testroot -a dh_installdocs -a -A README debian/README.Debian install -d debian/gri-$(version)/usr/share/man/man1 install debian/gri.1 debian/gri-$(version)/usr/share/man/man1/gri-$(version).1 install -d debian/gri-$(version)static/usr/share/man/man1 install debian/gri.1 debian/gri-$(version)static/usr/share/man/man1/gri-$(version).1 # dh_installmanpages -a doc/gri*.1 debian/gri.1 # -rm debian/gri-$(version).1 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 -mv debian/control.real debian/control -mv debian/README.Debian.real debian/README.Debian 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-2.12.23/debian/source/000777 000767 000024 00000000000 11607310073 015620 5ustar00kelleystaff000000 000000 gri-2.12.23/debian/source/format000644 000767 000024 00000000014 11355126120 017020 0ustar00kelleystaff000000 000000 3.0 (quilt)