#set, #setenv & #echo Directives
[posted 2004/09/07; revised 2004/09/22]
[Notes issued with the release of PIKT 1.17.0pre4, which introduced the new #set, #setenv & #echo directives, making possible a form of parameter passing to #include files.]
pikt-1.17.0pre4 introduces several new preprocessor directives--#set, #setenv, and #echo.
With #set, and its variant #setenv, you can set environment variables. You can then reference these environment variables in subsequent preprocessor directives, such as #exec, #include, #verbatim, and the new directive #echo.
So, for example, if you use
#set foo = "bar"
or the variant
#setenv foo "bar"
you could subsequently test the value of the $foo environment variable in an #exec directive to conditionally run some command
#exec [if test $foo = "bar"; then ...; fi]
You might use this to update an #include file, or mv an #include file in place, run some program, or do some other clever thing.
For example, you might have
#include [if test $foo = "bar"; then /bin/cat thisfile; else /bin/cat thatfile; fi]
Or you might just reference the environment variable in this way:
#include [/bin/echo "$foo"]
which would have the same effect as the line
bar
Alternatively, you could use the new #echo directive:
#echo "$foo"
What's the point?
At pikt.org, we maintain the web pages using PIKT of course. All web pages have a common format and layout, with more or less identical meta information, headers, footers, sidebars, etc. We say "more or less," because of course pages differ, not only in the main page content but also in other details, such as the page title, description, keywords, etc.
Noting the commonality across web pages, we had wanted to employ #include files of the common elements but were stymied by the slight differences in those common elements. With the new #set and #echo directives, we can achieve a form of crude parameter passing to #include files, allowing us to "templatize" our web pages to an extent previously impractical.
As an example, in the /pikt/lib/configs/files/pikt/doc_samples_files.cfg file, this is now how we specify the web page downage_alarms.cfg.html:
/////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// =piktwebdir/samples/downage_alarms.cfg.html mode 644 uid 0 gid 0 /////////////////////////////////////////////////////////////////////////////// #set cat = "Samples: downage_alarms.cfg" #set title = "PIKT Samples: downage_alarms.cfg, system and network downages" #set descr = "Sample downage_alarms.cfg, system and network downages," #set keywords = "system\, downage\, script\, down\, off\, network\, host\, systems\, report\, downages\, ping" /////////////////////////////////////////////////////////////////////////////// #indent #include <files/pikt/doc_page_top_files.cfg> <td width="100%"> <br> In this sample downage_alarms.cfg file, we monitor and report system and network downages. <br> <br> [... detail omitted ...] The alarm script follows. <br> <br> #verbatim <files/pikt/doc_downage_alarms.cfg_files.cfg> // <br> This is just one program example. You may use PIKT for similar things, such as: monitoring log files for signs of unexpected system reboots, removing /var/crash files, logging uptime data, etc. <br> <br> </td> #include <files/pikt/doc_page_bottom_files.cfg> #unindent /////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
In the #include'd files/pikt/doc_page_top_files.cfg file, we have the lines:
<head> #echo "<title>$title</title>" =meta_content_language =meta_content_type #echo "=meta_description(=pikt_description($descr))" #echo "=meta_keywords($keywords)" =meta_author(=pikt_author) =meta_copyright(=pikt_copyright) </head>
and further on:
<td width="0%"> =piktlogo </td> <td width="100%" align="center"> =pikttitle <p> #echo " =topcat($cat)" <p> </td> <td width="0%"> =piktad </td>
For the downage_alarms.cfg.html page, effectively it's as if we had directly specified:
<title>PIKT Samples: downage_alarms.cfg, system and network downages</title>
and:
=meta_description(=pikt_description(Sample downage_alarms.cfg, system and network downages,)) =meta_keywords(system\, downage\, script\, down\, off\, network\, host\, systems\, report\, downages\, ping)
and:
=topcat(Samples: downage_alarms.cfg)
Incidentally, this is how those lines would appear in the final, fully preprocessed downage_alarms.cfg.html file installed on the web server:
<title>PIKT Samples: downage_alarms.cfg, system and network downages</title>
and:
<meta name="description" content="Sample downage_alarms.cfg, system and network downages, for PIKT, a Unix/Linux toolkit to monitor and configure computer systems, report and fix problems, organize system security, format documents, schedule processes, install files, etc."> <meta name="keywords" content="system, downage, script, down, off, network, host, systems, report, downages, ping">
and:
<font size="6" color="#000080" style="font-weight: 700"> <b>Samples: downage_alarms.cfg</b></font>
Now, if you are really observant (and you know PIKT really well), you might be thinking why don't we just specify the web page title, description, etc. with ordinary PIKT macros?
=doc_page_top(Samples: downage_alarms.cfg, PIKT Samples: downage_alarms.cfg\, system and network downages, ...)
where doc_page_top is a macro (defined in the doc_macros.cfg file) with content much like the files/pikt/doc_page_top_files.cfg #include file but, instead of directives like
#echo "<title>$title</title>"
have lines referencing macro arguments like
<title>(TITLE)</title>
The reason is that PIKT macros eliminate all line and spacing layout, and you would wind up with ugly, run-together, hard-to-read HTML code in the actual installed web pages.
Apologies if this is all murky to you. You really need to be doing advanced PIKT preprocessing to understand the importance of #set, #setenv, #echo, and all the rest. But if you know what you're doing, they open up a whole new realm of possibilities. With these new directives, and this new functionality, we are achieving a modularization and conciseness of our web page specifications previously impractical.
PIKT has a growing list of preprocessor directives--the #if family, the #ifdef family, the #include family, the #exec family, #set, #echo, and so on. With these many options, all sorts of cleverness is possible. It will be interesting to discover new uses and techniques for these directives, and their interplay. Additional directives will be implemented if and when there is need for them.
As always, we welcome your suggestions and feedback.
For more examples, see Developer's Notes.