All about macros

All about macros

From GreenstoneWiki

What is a macro

  • Macros define either strings on the interface or variables utilized in C++ codes. By using macros, users can easily customize the user interface without changing any C++ code.

Where and how to define macros

  • Macros can be explicitly defined in a macro file which is a .dm file, in greenstone/macros
    • english.dm and english2.dm contain all the text strings of the interface, in English. french.dm, spanish.dm etc contain the same in other languages.
    • query.dm contains macros defining html utilized on the search pages.
  • Macros are grouped into packages in a macro file.
    • eg. package Global, package home in the english.dm file
  • One macro can include other macros.
  • Macros can be generated during the run time by C++ codes.

Reference a macro

_package:macroname_

eg. _home:textpagetitle_ The package name can be omitted if you are referencing a macro from the same package. Check a macro from the defined package. If this macro is not existing, a warning message "macro is not defined" is returned.

How macros work

  • Once an action (eg. a=p&p=home) is sent to cgi-bin/library, external macros used for all actions are firstly defined (eg. navigation bar). Then the internal macros of this paticular action is defined. All macros are stored in a kind of hash structure.
  • Set macro(macroname,package,content) when the action is executed.

OutputStream<<converter<<display<<"macros+text"

Finally disply results on the web page.

Macros used on a general page

  • _:header_
  • _:content_
  • optional dynamic content which is not set as macros, but output directly
  • _:footer_

Learn more about macros using the expand_macros.pl script

Thanks to Jens Wille

  • get a list of all macros and where they are defined (in order to have macros defined in the c++ source included as well, you may specify the path to your greenstone source directory; see the usage information of the script for details):
 expand_macros.pl -s '.*'
  • get definition of _query:pagescriptextra_
 expand_macros.pl _query:pagescriptextra_

output:

 *** macro: query:pagescriptextra ***

 * query:pagescriptextra [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 68)
   { _If_("_cgiargqt_" eq "1", _formpagescriptextra_, _selectpagescriptextra_) _If_("_cgiarghd_" ne "0",_historypagescriptextra_) } }
 
  • get macros that are used by _query:pagescriptextra_ ('-s' for short output, omit for display of definitions; '-d' for depth, increase to see more levels):
 expand_macros.pl -s -d 2 _query:pagescriptextra_

output:

 *** macro: query:pagescriptextra ***

 * query:pagescriptextra [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 68)
   * query:formpagescriptextra [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 76)
     * query:formfunctions [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 178)
     * query:searchfunctions [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 478)
     * preferences:standardfunctions [v=0] (/usr/local/gsdl/stable/macros/pref.dm, line 82)
     * query:standardfunctions [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 143)
   * query:historypagescriptextra [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 101)
   * query:selectpagescriptextra [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 71)
     * query:dummypagescriptextra [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 72)
     * query:formpagescriptextra [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 76)

  • get macros that use "any" _pagescriptextra_ ('-r' for reverse search):
 expand_macros.pl -r _pagescriptextra_

output:

 *** macro: pagescriptextra (reverse) ***

 * Style:globalscripts [v=0] (/usr/local/gsdl/stable/macros/style.dm, line 142)
   { <script> <!-- _imagescript_ _pagescriptextra_ // --> </script> } }

 * homepref:pagescriptextra [v=0] (/usr/local/gsdl/stable/macros/home.dm, line 198)
   { _preferences:pagescriptextra_} }
  • get macros whose definitions contain "blank.gif" (a search in the definition contents will be performed if the argument doesn't start, and end, with an underscore (actually, it's a bit more complicated, but that should suffice for the moment); is actually treated as full perl regular expression):
 expand_macros.pl "blank.gif"

output:

 *** query: blank.gif ***

 * collector:iconblank [v=0] (/usr/local/gsdl/stable/macros/collect.dm, line 42)
   { <img src="_httpimg_/blank.gif">} }
  • get a macro that is defined in the c++ code (you need to extract a greenstone source archive and point to its base location, either via the '--source' parameter or via a GSDLSOURCE environment variable):
 expand_macros.pl --source=/usr/local/gsdl/src/stable/ _collector:pagescriptextra_

output:

 *** macro: collector:pagescriptextra ***

 * collector:pagescriptextra [v=0] (SERVER: /usr/local/gsdl/src/stable/src/src/recpt/collectoraction.cpp, line 1058)
   { "_" + collector_page + "scriptextra_" }

  • additionally, you can use expand_macros.pl to explore macros interactively ('-i' or '-b' for "interactive", or "browse", mode)
 expand_macros.pl -i

output:

 entered 'expand_macros.pl' in ***interactive browse mode*** (v0.22)
 [you can get help at any time by typing '.h', '.?', or '.help']

 enter macro name (without package specification) [leave empty to quit]
 > pagescriptextra
   
 select package for macro 'pagescriptextra' [leave empty to return]
   [1]    Style
   [2]    browse
   [3]    collector
   [4]    homepref
   [5]    preferences
   [6]    query
 > 6

 * query:pagescriptextra [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 68)
 { _If_("_cgiargqt_" eq "1", _formpagescriptextra_, _selectpagescriptextra_)
 _If_("_cgiarghd_" ne "0",_historypagescriptextra_) } }

 [press key to continue]

 select macro [leave empty to return]
   [1]    formpagescriptextra
   [2]    historypagescriptextra
   [3]    selectpagescriptextra
 > 1

 select package for macro 'formpagescriptextra' [leave empty to return]
  [1]    query 
 > 1

 * query:formpagescriptextra [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 76)
 { // query scripts generated by \\_query:pagescriptextra\\_
 _standardfunctions_
 _formfunctions_
 _searchfunctions_
 function getsearchargs () \\{
   var args="";
   args = "&fqa=0&fqv="+argfqv+"&fqf="+argfqf;
  _If_(_cgiargqf_,args += "&fqk="+argfqk+"&fqs="+argfqs+"&fqc="+argfqc;)
 return args;
 \\}
 function getqueryargs () \\{
   return "&fqa=1"+"&q="+argq+"&fqv="+argfqv+"&fqf="+argfqf+
     "&fqk="+argfqk+"&fqs="+argfqs+"&fqc="+argfqc ;
 \\}
 } }

 [press key to continue]

 select macro [leave empty to return]
  [1]    formfunctions
  [2]    searchfunctions
  [3]    standardfunctions
 >

 select package for macro 'formpagescriptextra' [leave empty to return]
  [1]    query
 >

 select macro [leave empty to return]
  [1]    formpagescriptextra
  [2]    historypagescriptextra
  [3]    selectpagescriptextra
 >

 select package for macro 'pagescriptextra' [leave empty to return]
  [1]    Style
  [2]    browse
  [3]    collector
  [4]    homepref
  [5]    preferences
  [6]    query
 >

 enter macro name (without package specification) [leave empty to quit]
 >

Miscellaneous things

  • macro IF statement syntax
_If_(_cgiargs_,_trueStatement_,_falseStatement_)
  • String comparison: (eq,ne,lt,gt,sw,ew)

eg. _cgiargc_ eq "demo" (the collection is demo)

  • Numeric comparison (!=,==,<,>,>=,<=)
  • Edit main.cfg file to load a new macro file
  • macroprecedence"c,v,l"

[more...?]

  • Frequently used macros:

_gwcgi_("/cgi-bin/library")

_httpprefix_("/gsdl")

_httpimg_("/images")

_gsdlhome_

_navigationbar_

_homeextra_

_thisOID_

_compressedoptions_

_cgiargc_

[more...?]

'I'm feeling lucky' facility

There is a _useifeellucky_ macro in query.dm;

    • if you set this to "_ifeellucky_" then there will be an "I'm feeling lucky" checkbox in the search form.
    • If you tick this then "&ifl=1" goes into the search URL, and code in the C++ redirects you to the first matching document rather than the normal search results page.

(Thanks Michael)