/********************************************************************** * * display.h -- Context sensitive macro language * Copyright (C) 1999 The New Zealand Digital Library Project * * A component of the Greenstone digital library software * from the New Zealand Digital Library Project at the * University of Waikato, New Zealand. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * *********************************************************************/ #ifndef DISPLAY_H #define DISPLAY_H #include "gsdlconf.h" #include "text_t.h" #if defined(GSDL_USE_OBJECTSPACE) # include # include # include # include # include #elif defined(GSDL_USE_STL_H) # include # include # include # include # if defined(GSDL_USE_ALGO_H) # include # else # include # endif #else # include # include # include # include # include #endif #if defined(GSDL_USE_OBJECTSPACE) # include # include #elif defined(GSDL_USE_IOS_H) # include # include #define unistream ifstream #else # include # include typedef std::basic_ifstream unistream; #endif // use the standard namespace #if defined(GSDL_USE_OBJECTSPACE) using namespace ospace::std; #elif !defined(GSDL_NAMESPACE_BROKEN) using namespace std; #endif // MAXRECURSIONDEPTH is a cutoff to catch // cyclic macros (a includes b and b includes a) #define MAXRECURSIONDEPTH 30 // class prototypes class parammacros_t; class currentmacros_t; // a few supporting types // fileelement isn't finished yet, I have to find out // more about getting information about files struct fileinfoelement { int otherinfo; }; // macro value structure struct mvalue { text_t filename; text_t value; }; inline bool operator==(const fileinfoelement &x, const fileinfoelement &y) { return (x.otherinfo==y.otherinfo); } inline bool operator<(const fileinfoelement &x, const fileinfoelement &y) { return (x.otherinfo fileinfomap; typedef map paramhashtype; void splitparams (const text_t ¶mstring, paramhashtype ¶mhash); struct paramspec { double spec; text_t param; }; inline bool operator==(const paramspec& x, const paramspec& y) { return ((x.spec == y.spec) && (x.param == y.param)); } inline bool operator!=(const paramspec& x, const paramspec& y) { return ((x.spec != y.spec) || (x.param != y.param)); } // note: paramspec is sorted by reverse spec and then param inline bool operator<(const paramspec& x, const paramspec& y) { return ((x.spec > y.spec) || ((x.spec == y.spec) && (x.param < y.param))); } inline bool operator>(const paramspec& x, const paramspec& y) { return ((x.spec < y.spec) || ((x.spec == y.spec) && (x.param > y.param))); } typedef vector paramspeclist; // NOTE: when macros are used within text they should have // underscores '_' on both sides, however, in calls to // setdefaultmacro and setmacro they should not have the // underscores. So you might have // // setmacro ("aname", "query", " some text "); // expandstring ("_aname_", expandedtext); // // because the input to expandstring is a block of text, not // a macroname class displayclass { public: static text_t defaultpackage; displayclass (); ~displayclass (); // isdefaultmacro sees if there is an entry in the list of // default macros with the given package and macro name // returns 0 if no macros in the package or in the global package // were found // 1 if no macros in the package were found but a macro // in the global package was found // 2 if a macro in the given package was found int isdefaultmacro (const text_t &package, const text_t ¯oname); // setdefaultmacro adds an entry to the list of default macros // returns 0 if there was no error, // -1 if it redefined a macro // -2 if it hid a Global macro // -3 if it redefined a macro and hid a Global macro // -4 if no macroname was supplied int setdefaultmacro (const text_t &package, const text_t ¯oname, const text_t ¶ms, const text_t ¯ovalue); // loads a default macro file (if it isn't already loaded) // returns 0 if didn't need to load the file (it was already loaded) // 1 if was (re)loaded // -1 an error occurred while trying to load the file int loaddefaultmacros (const text_t &thisfilename); // overrides (or sets) a macro for the current page. // returns 0 if there was no error, // -1 if it redefined a macro // -4 if no macroname was supplied int setcollectionmacro (const text_t &package, const text_t ¯oname, text_t params, const text_t ¯ovalue); // loads a collection specific macro file // returns 0 if didn't need to load the file (it was already loaded) // 1 if was (re)loaded // -1 an error occurred while trying to load the file int loadcollectionmacros (const text_t &thisfilename); // unloads all default macros void unloaddefaultmacros (); // unloads all collection specific macros void unloadcollectionmacros (); // prepares to create a page: deletes all macros set with // 'setmacro', checks all the default macro files to see // if any need reloading, and sets the page parameters. void openpage (const text_t &thispageparams, const text_t &thisprecedence); // changes the parameters for the current page. void setpageparams (text_t thispageparams, text_t thisprecedence); // overrides (or sets) a macro for the current page. // returns 0 if there was no error, // -1 if it redefined a macro // -4 if no macroname was supplied int setmacro (const text_t ¯oname, const text_t &package, const text_t ¯ovalue); // havemacro sees if there is an entry in the list of macros or // default macros with the given package and macro name // returns 0 if no macros in the package or in the global package // were found // 1 if no macros in the package were found but a macro // in the global package was found // 2 if a macro in the given package was found // 4 if no macros in the package were found but a macro // in the global package was found in default macros // 8 if a macro in the given package was found in default int havemacro(const text_t &package, const text_t ¯oname); int setmacroif (const text_t ¯o_to_set_and_test, const text_t ¯o_to_set_if_macro_not_set, const text_t ¯oname, const text_t& package); inline void expandstring (const text_t &inputtext, text_t &outputtext) { expandstring(defaultpackage, inputtext, outputtext); } void expandstring (const text_t &package, const text_t &inputtext, text_t &outputtext, int recursiondepth = 0); // these functions are not ment to be used directly, they are used to permit // concise stream output like: // cout << text_t2ascii << display << "_amacro_" << "_anothermacro_"; void setconvertclass (outconvertclass *theoutc) {outc = theoutc;} outconvertclass *getconvertclass () {return outc;} // say where any error logging goes, this can be NULL // if no error logging is desired - returns previous value ostream *displayclass::setlogout (ostream *thelogout); // debug stuff void printdefaultmacros (); void printallparams (); protected: // special variables to permit trickly output outconvertclass *outc; // general variables text_tset allparams; // possible parameter combinations parammacros_t *defaultmacros; parammacros_t *collectionmacros; fileinfomap *defaultfiles; // variables to do with a page expansion text_t params; text_t precedence; paramspeclist *orderparamlist; // ordered by specificness currentmacros_t *currentmacros; // only macros set by setmacro // logging variable ostream *logout; // reloads any default macro files which have changed // returns 0 no errors occurred // -1 an error occurred while trying to load one of the files int checkdefaultmacrofiles (); int loadparammacros (parammacros_t* macrotable, const text_t &thisfilename); int setparammacro (parammacros_t* macrotable, const text_t &package, const text_t ¯oname, text_t params, const text_t &filename, const text_t ¯ovalue); int setdefaultmacro (const text_t &package, const text_t ¯oname, text_t params, const text_t &filename, const text_t ¯ovalue); int setcollectionmacro(const text_t &package, const text_t ¯oname, text_t params, const text_t &filename, const text_t ¯ovalue); // evaluates a boolean expression bool boolexpr (const text_t &package, const text_t &expr, int recursiondepth); mvalue* macro_find (parammacros_t* macrotable, const text_t &packagename, const text_t ¯oname); // (recursively) expand out a macro // returns true if the macro was found // false if the macro was not found bool macro (const text_t ¯oname, const text_t ¯opackage, const text_t ¯oparam, text_t &outputtext, int recursiondepth); }; displayclass &operator<< (outconvertclass &theoutc, displayclass &display); displayclass &operator<< (displayclass &display, const text_t &t); #endif