Macros

Macros are a powerful feature which enables you to create shortcuts for often used text. As you can also pass arguments to macros, it is even possible to create templates for whole pages.

General Syntax

Macros can be defined like
<$macro MacroName [ modifiers ] [ attributes ] >

...macro text...

</$macro>
Here are some examples of macro definitions:

Use As Shortcuts

You can define a macro called Hugo-Address that only is a shortcut for your email-address like
<$macro Hugo-Address>
hugo@some.where
</$macro>
So every time, you insert the macro-tag <Hugo-Address> in your hsc-source, it will be replaced by
hugo@some.where
in the HTML-object.

Container Macros

Container macros allow you to create a macros with a text before and after the content. While the preceding/succeeding text is specified with the macro declaration, the content is assigned during the macro call.

To declare a macro as container, you have to specify the modifier ``/CLOSE''. To insert the contents, use the special tag <$content>. Alternatively, you can access the content with the special attribute HSC.Content.

You can use <$content> multiple times inside the same macro, too.

To call a container macro, act the same as with the simple macro you have seen in the above example. But different to before, now also a end-tag has to show up. Everything between the corresponding start- and end-tag will be interpreted as content.

You should be aware of the fact that hsc, when scanning for the end-tag for the macro, does not in process other macros or <$include>-tags, but only looks at the text. Therefore, the end-tag has to show up within the same input file as the start-tag.

Ok, that was a bit much. Probably a good time for an example...

Declare Your Own Logical Styles

One of the most laughable stories about HTML is the one about physical and logical styles: It is possible to render text in bold or italic letters using tags like <B> or <I>, which are known as physical styles. Furthermore, you can also use some logical styles like <CODE> or <KBD>, which should be used to mark sequences of code or user input. Both are usually rendered same as the physical style <TT> (typewriter font).

As everyone with a brain implemented could have told from the beginning, the number of physical styles increased with every new HTML release. In the draft to (never released) HTML-3.0 tags appeared to render names of authors, acronyms, persons etc. The lack behind these concepts became that obvious that even w3c found out it sucks. And so, probably only soon before tags like <Tim-Berners-Lee-s-favourite-tag-to-render-his-name> made it into the specifications, this concepts has been abandoned.

However, it has not been replaced by anything more useful, and this has not changed much until today; except that many people are waiting for a new holy cow called Style Sheets to be implemented in a functioning way in at least some of the available browsers.

So it makes sense to use container macros as substitute for logical styles, which will do nothing but enclose the content in a physical style. Below a macro <FILE> will be created, which can be used to render filenames:

<$macro FILE /Close><I><$content></I></$macro>
Your new style can be used like all other styles:
  ..open the file <file>hugo.txt</file> and..
In this case, filenames will be rendered italic:
..open the file hugo.txt and..

It should be rather obvious how this one works: When calling the macro using <FILE>hugo.txt</FILE>, hsc will scan the input until it reaches a </FILE>. Anything between the corresponding start and end tag will be used as content, in this case ``hugo.txt''.

Now the macro text will be interpreted: The first part is easy, a simple <I> will be inserted. After that, a <$content> shows up, and the content read before will be inserted. In this case, this is a simple plain text, but of course you could also use tags or even other (container) macros. At the end of the macro, a closing </I> is appended, and the macro call exits.

Nesting Container Macros

You should be aware that the macro content (the text specified between the corresponding start and end macro tag) can not access attributes which have been declared for the macro text (the text which is assigned to the macro while declaring it using <$macro>).

For example:
<$macro sepp /close hugo:string>
sepp   : hugo=<(hugo)>
<$content>
sepp   : hugo=<(hugo)>
</$macro>

<$define hugo:string="content's hugo">

<sepp hugo="sepp's hugo">
content: hugo=<(hugo)>
</sepp>
will result in

sepp   : hugo=sepp's hugo

content: hugo=content's hugo
sepp   : hugo=content's hugo
The line
content: hugo=<(hugo)>

does not - as some might have expected - access the attribute hugo passed to the container macro <sepp> just before, but still reads the attribute hugo declared above using <$define>.

The reason for this shows up soon when you start using container macros inside container macros: every time a <$content> shows up while just processing a <$content>, it does not make much sense to include the same content as just before. Instead, the parser uses the content passed to the previous but one container macro. For example:
<$macro hinz /close>
hinz=( <$content> )
</$macro>

<$macro kunz /close>
kunz=( <$content> )
</$macro>

<hinz><kunz>...some text...</kunz></hinz>
will result in

hinz=( kunz=( ...some text... ) )

Macros With Attributes

Take a look at this example:
<$macro Button.Next NxtRef:uri>
<A HREF=(NxtRef)><IMG SRC=":image/next.png" ALT="Next"></A>
</$macro>
This defines a macro that defines a button that references to the next page. As every page has its own next page, you can set one attribute for this macro: NXTREF, which is the URI that should be referenced as the ``next'' page.

So an example usage of this macro would be:

  <button.next NXTREF=":features/rplcent.html">
which will give the button seen below:

Next

Note that the value of NXTREF is passed to the HREF attribute within the <A> tag when the macro is extracted.

If you wonder, what HREF=(NxtRef) (see above) should mean: This sets HREF with the value stored in NxtRef. For details, read the section about expressions.

Macros Inside Macros

Currently, locale macros are not supported. If you declare a macro inside a macro, the inner macro will be declared when the outer macro is called. For example:
<$macro outer-sepp>
  now in outer sepp

  <* define inner-sepp *>
  <$macro inner-sepp>
    now in inner sepp
  </$macro>

  <* use inner-sepp *>
  <inner-sepp>
</$macro>

<outer-sepp>
will result in
  now in outer sepp

    
        now in inner sepp

At the moment you can call <inner-sepp> even outside of <outer-sepp>, as it is defined globally. When calling <outer-sepp> another time, you will receive a message #59, as this tries to redefine <inner-sepp>.

Obviously this behaviour doesn't make sense, but local macros are not supported in this release.