Index < Previous     Next >
Macro expansion [ ^ ]
Macro declaration
@MACRO MNAME(arg1, arg2, ...)@
...
@ENDMACRO@
Declare MNAME as a new macro. Notice that the valid charset for the name and the arguments is the same of the variables (A-Z,0-9,_).
Macro calling
@MNAME("arg1", "arg2", ...)@
Calls MNAME. If you use the char '"' within a macro argument you should excape it by prepending a '\' char.

Source file
<!-- macro declaration -->
@MACRO MY_MACRO(NAME, HREF)@
<A HREF="@HREF@">@NAME@</A>
@ENDMACRO@

<!-- macro called with args containing string constants -->
@MY_MACRO("Test", "test.html")@

<!-- macro called with args containing variables -->
@MY_MACRO(@FILENAME@, "@FILENAME@.html")@

<!-- example of splitted macro call -->
@MY_MACRO("\"@FILENAME@\" is the source",\
    "@FILENAME@.html")@

Notes & Restrictions [ ^ ]
You cannot declare a macro from inside another macro.

Macros can be called within other macros (but pay attention to recursive calls!), variables assignments or macro aguments.

Sometimes can be useful surrounding a macro declaration with an IF block. By testing the macro's name you can prevent multiple declarations of the same macro.

Overloading [ ^ ]
Macros overloading is now supported. You can declare the same macro with different number of parameters.

Macros Overloading Example
<!-- be sure that we aren't redefining it -->
@IF !HTML_LINK@

<!-- macro #1 declaration -->
@MACRO HTML_LINK(NAME, HREF)@
<A HREF="@HREF@">@NAME@</A>
@ENDMACRO@

<!-- macro #2 declaration -->
@MACRO HTML_LINK(HREF)@
@HTML_LINK("unnamed link (@HREF@)", "@HREF@")@
@ENDMACRO@

@ENDIF@

Built-in macros [ ^ ]
Built-in macros are predefined macros allowing particular operations, you can use them as normal macros.
Usually if a built-in macro reads data from a file, this file will be included into the dependencies list (see the --depend switch).
Macros working on images
Allowed file formats are GIF, JPEG and PNG.
Macro Expanded to (XHTML output)
@HTML_IMAGE(img)@
<img
  src="img"
  width="(image width)"
  height="(image height)" />
@HTML_IMAGE(img, alt)@
<img
  srg="img"
  width="(image width)"
  height="(image height)"
  alt="alt" />
@HTML_IMAGE(img, alt, extra)@
<img
  src="img"
  width="(image width)"  height="(image height)"
  alt="alt"  extra />
@HTML_IMAGE_SIZE(img)@
src="img"
width="(image width)"
height="(image height)"
@HTML_IMAGE_SIZEO(img)@
width="(image width)"
height="(image height)"
@HTML_IMAGE_WIDTH(img)@
width="(image width)"
@HTML_IMAGE_HEIGHT(img)@
height="(image height)"
@IMAGE_WIDTH(img)@
Image width.
@IMAGE_HEIGHT(img)@
Image height.
Example:
Source file
@HTML_IMAGE("index.jpg", "my logo",\
  "border=\"0\" hspace=\"10\"")@
HTML file (HTML Output)
<IMG SRC="index.jpg" WIDTH="100" HEIGHT="200" ALT="my logo" border="0" hspace="10" >
HTML file (XHTML Output)
<img src="index.jpg" width="100" height="200" alt="my logo" border="0" hspace="10" />
Macros working on image maps
These macros read a server side imagemap and are expanded into a converted HTML client side version.
In the map files the ALT field is taken from the comment line before the area definition.
Macro Expanded to (XHTML output)
@CERN2HTML(mapfile)@
@NCSA2HTML(mapfile)@
<map name="mapfile" id="mapfile">
<area shape="..."
  href="..." coords="..." alt="..." />
</map>
@CERN2HTML(mapfile, mapname)@
@NCSA2HTML(mapfile, mapname)@
<map name="mapname" id="mapname">
<area shape="..."
  href="..." coords="..." alt="..." />
</map>
@CERN2HTML(mapfile, mapname, mapid)@
@NCSA2HTML(mapfile, mapname, mapid)@
<map name="mapname" id="mapid">
<area shape="..."
  href="..." coords="..." alt="..." />
</map>
Example:
Source file
@NCSA2HTML("index.map", "myindex")@

<A HREF="index.map"><IMG SRC="menu.gif" WIDTH="600" HEIGHT="50"
  ISMAP USEMAP="#myindex"></A>
Macros working on files
Macro Expanded to
@FILE_SIZE(file)@
@FILE_SIZE(file, unit)@
File size in bytes. The unit can be 'b' (bytes, default), 'k' (kilobytes) , 'm' (megabytes) and 'g' (gigabytes).
@FILE_DATE(file)@
File modification date, according to DATE_FORMAT.
Misc macros
Macro Expanded to
@RURL(PATH)@
@RURL(PATH, NODEPS)@
Return the relativized path.
If NODEPS is defined (not an empty string) dependencies will not be generated.
@RANDOM()@
Random integer value taken from Perl's rand() value without the leading '0.'.
@RANDOM(to)@
Random integer value starting from 0 up to to.
@RANDOM(from, to)@
Random integer value starting from from up to to
@ENV(var)@
The value of the var environment variable.
@XHTML_OUTPUT(var)@
If var is a non zero value, built-in macros will generate xhtml compliant tags.
Extending WPP [ ^ ]
I've developed WPP by keeping in mind that it had to be easy to use, possibly faster than other solutions (i.e. writing a C or Perl program ad hoc) and flexible. I've added some basic features and provided few useful macros shipped with it. But in everyday work you may need extra features that WPP doesn't have or simply you need a way for doing something during the preprocessing and incorporating it's output.
The following built-in macros allows you to extend the capabilities of WPP by writing more flexible and powerful macros.
The SYSTEM macro
The SYSTEM macro was the first way for allowing more complex jobs within the preprocessing stage, the other way is through the EVAL macro.
This macro allows you calling other programs or shell commands and optionally parse the output through wpp.
Macro Expanded to
@SYSTEM(CMD)@
The output of 'CMD' command.
@SYSTEM(CMD, DOPP)@
@SYSTEM_PP(CMD)@
The command output postprocessed through WPP if 'DOPP' isn't an empty string. SYSTEM_PP is an alias for SYSTEM with postprocessed output.
The following example build a table with two lists obtained by the UNIX "ls" command. Each line is passed through "sed" in order to put it as argument for a RED macro. Please notice that in order to prevent the macro parsing before the SYSTEM execution I have replaced the beginning and ending '@' with the escaped version '@AT@'.
Source
@MACRO RED(TEXT)@
<span style="color: red;">@TEXT@</span>
@ENDMACRO@

@CMD=ls --color=no -1 / | sed 's|^|  @AT@RED("|; s|/||g; s|$|")@AT@|g'@

<table>
<tr>
  <td>
System #1:
<pre>
@SYSTEM("@CMD@")@
</pre>
  </td>
  <td>
System #2:
<pre>
@SYSTEM("@CMD@", "1")@
</pre>
  </td>
</tr>
</table>
And a sample output may look like that:
Output
System #1:
  @RED("bin")@
  @RED("boot")@
  @RED("dev")@
  @RED("etc")@
  @RED("home")@
  @RED("initrd")@
  @RED("lib")@
  @RED("lost+found")@
  @RED("misc")@
  @RED("mnt")@
  @RED("movies")@
  @RED("opt")@
  @RED("proc")@
  @RED("rar")@
  @RED("root")@
  @RED("sbin")@
  @RED("tftpboot")@
  @RED("tmp")@
  @RED("usr")@
  @RED("var")@
System #2:
  bin
  boot
  dev
  etc
  home
  initrd
  lib
  lost+found
  misc
  mnt
  movies
  opt
  proc
  rar
  root
  sbin
  tftpboot
  tmp
  usr
  var
The first call of SYSTEM isn't postprocessed while the second is, in fact the RED macro call was successfully expanded.
The INLINE directive
This directive behave exactly as the EVAL macro do, the main difference is that the code within INLINE and ENDINLINE shouldn't be escaped (except the '@' char that should be expanded into '@AT@').
Source
@VAR=some value@
...
@INLINE@
my $v;
my $f = '';

for ($v = 0; $v < 10; $v++) {
  $f .= ' ' . ($v * $v);
}

return "test code [$f @VAR@]";
@ENDINLINE@
...
Output

...
test code [ 0 1 4 9 16 25 36 49 64 81 some value]
...
INLINE perl code should be more readable than the equivalent EVAL version.
The EVAL macro
The EVAL macro was added in order to allow more sophisticated expansions and it was a way for adding loops and complex controls without implementing them directly (yeah, I'm a lazy boy!).
The argument string should be a valid Perl expression, otherwise wpp will warn you of syntax errors without stopping the parsing process.
Macro Expanded to
@EVAL(expr)@
The value returned by the Perl expression expr.
The following example shows a simple for loop (in Perl), it outputs a sequence of numbers starting from 0 up to 10. Please notice how the '"' char should be still escaped throgh '\"'.
Source
@EVAL(" \
  my $str = ''; \
  for(my $i = 0; $i < 11; $i++) { \
    $str .= $i . ' '; \
  } \
  return $str; \
")@
Output
0 1 2 3 4 5 6 7 8 9 10
The string passed as argument to the EVAL macro can contain wpp variables and macros, they will be expanded before evaluation through Perl's eval.
Source
@LIMIT=11@
@EVAL(" \
  my $str = ''; \
  for(my $i = 0; $i < @LIMIT@; $i++) { \
    $str .= \"@RANDOM()@ \"; \
  } \
  return $str; \
")@
Output
925896123251604 925896123251604 925896123251604 925896123251604 925896123251604 925896123251604 925896123251604 925896123251604 925896123251604 925896123251604 925896123251604
If you run the previous example you can notice that the RANDOM() output is always the same, that's because the evaluation of RANDOM() is done before the eval call.
Within a evaluated string you could call wpp parser by using the function WPP::call, which takes a macro name and it's arguments as input and returns the parsed string.
In the following example I've modified the previous one in order to use WPP::call.
Source
@LIMIT=11@
@EVAL(" \
  my $str = ''; \
  for(my $i = 0; $i < @LIMIT@; $i++) { \
    $str .= WPP::call('RANDOM') . ' '; \
  } \
  return $str; \
")@
Output
282702544575105 552693847483994 825954597827899 0348399899902532 0734755209571354 185688667196175 827332481085275 978426656426585 627908420295714 43169042916287 23026833623997
This is a bit more complex example, here I open and read a file (/etc/group), for each line of it I call the macro TEST that simply print it within square brackets.
Source
@MACRO TEST(TEXT)@
  [@TEXT@]
@ENDMACRO@

@F=/etc/group@

@EVAL(" \
  $str = ''; \
  open(FH, '@F@'); \
  while (<FH>) { \
    chomp; \
    $str .= WPP::call('TEST', $_) . \"\n\"; \
  }; \
  close(FH); \
  return $str; \
")@
Output
[root:x:0:root]
[bin:x:1:root,bin,daemon]
[daemon:x:2:root,bin,daemon]
[sys:x:3:root,bin,adm]
[adm:x:4:root,adm,daemon]
[tty:x:5:]
[disk:x:6:root]
Here you can see how to use EVAL for test conditions.
Source
@TVAL=@EVAL("1 != 1")@@
@IF !TVAL@
  EVAL ok!
@ENDIF@

@TVAL=@EVAL("1 == 1")@@
@IF TVAL@
  EVAL ok!
@ENDIF@
Output


  EVAL ok!




  EVAL ok!

EVAL returns the value returned by the Perl expression, however if you don't want return a value, just because you've already done it with a print or something similar inside the Perl expression, you have to return explicitly an empty string (tipically a "return '';").
Source
@EVAL("print 'TEST ' . (1 == 1); return '';")@

@EVAL("return 'TEST ' . (1 == 1);")@
The following and last example shows an invalid expression that raise an EVAL error, the parsing doesn't stop but a warning is printed by WPP.
test_eval_err.raw
@HEAD@
@TAIL@
$Date$
@EVAL("1+1'A'")@
And here is shown the output of wpp.
[ko]$ wpp - < test_eval_err.raw
W2: EVAL error 'String found where operator expected at (eval 2) line 1, near "1'A'"' (EVAL(v1):-:4)
W2: EVAL error
****
1+1'A'
****
W2: EVAL error '        (Missing operator before 'A'?)' (EVAL(v1):-:4)
W2: EVAL error
****
1+1'A'
****
W2: EVAL error 'syntax error at (eval 2) line 1, near "1'A'"' (EVAL(v1):-:4)
W2: EVAL error
****
1+1'A'
****
Methods available for INLINE/EVAL scripts
Method Description
WPP::eval(string)
Run wpp parser over a specified block of text, the parsed output is returned.
WPP::call(macroname, ...)
Calls the specified macro, the parsed output is returned.
This method is a cleaner way for calling a macro within inlined code without using WPP::eval and dealing with '@' chars escaping.
WPP::set(varname, value)
Sets the value value of a wpp variable varname.
WPP::get(varname)
Returns the value of the variable varname.
WPP::canonpath(path)
Return the canonicalized path.
WPP::debug(msg)
WPP::message(msg)
WPP::warning(msg)
WPP::error(msg)
Those methods are used for outputing log messages at different severity level.
WPP::current_file()
Returns the complete current file name where the expression is evaluated.
WPP::depend(file, ...)
Add the specified files to the dependencies for make.
^ Top < Previous     Next >