What was said was never done
Don't panic, it's not really worth your while
(Blur, "Bang")

# Special Tags

`Hsc` adds several special tags to process macros, handle conditionals, include files and lots of other things.

## List Of Special Tags

- `<* comment *>`—insert comments
- `<$content>`—insert content of container macro
- `<$defent>`,`<$deficon>`,`<$deftag>`,`<$defstyle>`,`<$varlist>`—define entities, icon-entities, tags, styles and attribute-list shotcuts
- `<$define>`—define new (global) attribute
- `<$depend>`—add dependency
- `<$exec>`—execute shell-command
- `<$if>`, `<$else>`, `<$elseif>`—conditionals
- `<$include>`—include a file
- `<$let>`—update attribute value
- `<$macro>`—define macro-tag
- `<$match>`—perform pattern matching and capture subpatterns.
- `<$message>`—display user message
- `<$stripws>`—strip previous/next white space
- `<$export>`—export data to a file
- `<( expression )>`—insert expression
- `<| verbatim data |>`—insert verbatim data

## <* ... *> - Comments

One of the basic concepts of every computer language is that the user should be able to add comments. The machine will ignore them, but they usually help the programmer to understand his intention when looking at his source code later.

As yet another proof of the incompetence of the HTML creators, there is no reasonable way to add comments to your source code. Early versions of HTML did not offer any possibility to do that at all. Later ones support comments comparable to sgml. But as the way sgml handles comments is so messy and weird, nearly no one knows how they are really supposed to work (including myself and - more remarkable - most developers of w3-browsers).

In general, there is no way to use sgml-comments so they will work with all browsers. Many browsers are unable to find out when a comment ends, independent of whether you did it right or wrong.

Furthermore, such comments also waste bandwidth, as usually the reader will not see them (except he views the document source). And internal notes of w3-authors are usually not interesting for the public...

It is really remarkable that they managed to fuck up such a simple and usually strait forward concept like comments; even most assembler languages are smarter with this.

Anyway, with `hsc` you can insert a comment like

    <* This is a <* nested *> hsc-comment *>

As you can see, such comments can also be nested - yes, this is a documented behaviour.

And you can comment out sections of HTML source without any problems for the browser. This simply is possible because comments in the hsc-source are not written to the HTML object. So they also will not waste bandwidth.

Of course, if you need the standard comments, you can still use

    <!-- This is an HTML/sgml-comment -->

as usual. But think twice before doing so.

## <$content> - Insert Content

The tag `<$content>` can be only used inside a container macro and inserts the content the user specified inside the start and end tag for the macro.

## <$if> - Conditionals

Conditionals are used to decide whether some part of the text should be processed or not. As there is a lot to tell about them, there exists a whole chapter dealing with conditionals.

## <$depend> - Add Dependencies

If your source should not only be updated if an included file has been modified, you can use the tag `<$depend>` to add an additional dependency which will be noted in the project data.

Possible attributes:

`ON:string`
  URI to depend on (relative to destination directory)
`FILE:bool`
  If this attribute is set, `ON` is no more interpreted as an URI, but as a local filename relative to the source directory.

Example:

    <$depend ON="work:dings.dat" FILE>
    <$exec COMMAND="convdings FROM work:dings.dat" INCLUDE TEMPORARY>

In this example, dings.dat contains some data maintained by an external application. A script called `convdings` converts dings.dat to legal HTML data end send them to `stdout`, which are inserted into the current document.

Obviously, dings.dat is not maintained or included by hsc, so the current document does not depend on it. But by specifying the above `<$depend>`, the current source will be updated if dings.dat has been modified.

## <$include> - Include File

Text files can be included using `<$include>`.

Possible attributes:

`FILE:string/required`
  This specifies the input file to be included
`SOURCE:bool`
  By default, include files are interpreted as normal *.hsc files. Therefor, they may defines macros or contain HTML tags to render the text. But if you for example want to include an excerpt of a source code, it is handy if a less-than character (```<`'') is not interpreted as an escape character, but converted to an entity.
  This attribute enables such a conversion for less than, greater than and ampersand (```&`'').
`PRE:bool`
  The included data will be enclosed inside a `<PRE>` ... `</PRE>`, and the whole section will be rendered as pre-formatted.
`TEMPORARY:bool`
  Normally, `hsc` keeps track of all files included and stores the names in the project file. Later, they can be used by `hscdepp` to find out dependencies.
  But if a file that is to be removed after the conversion ends up in the dependency list of your Makefile, it can cause trouble for `make`. If the attribute is enabled, the input file will not be added to the dependency list.
  You should consider to enable this attribute, if invoking `make` returns something like
  `make: *** No rule to make target `hsc0x395bf7e0001.tmp', needed by `/html/hugo.html'.`

Example:

`<$include FILE="macro.hsc">`
  This can be used to include some macro definitions
`<$include FILE="hugo.mod" SOURCE PRE>`
  This is reasonable to include a source code that has been written using some programming language like Oberon, Pascal or E.

## <$define> - Define A New Attribute

You can create an attribute and pass a value to it via

> `<$define attribute-declaration>`

If you define an attribute using `<$define>` inside a macro, it is of local existence only and is removed after processing the macro. You can suppress this with the attribute modifier `/GLOBAL`: in this case, the attribute exists until the end of conversion.

You can use the modifier `/CONST` to make the attribute read-only. That means it can not be updated with `<$let>`.

For an example, see `<$let>`.

## <$let> - Update The Value Of An Attribute

The tag `<$let>` can be used to update an attribute with a new value. It has its own syntax and expects the name of the attribute and after an equal sign the new value, for instance:

    <$define hugo:string="hugo">       <* create hugo and set to "hugo" *>
    <$let hugo=(hugo+" ist doof.")>    <* update it to "hugo ist doof." *>

If you do not specify a value, the attribute will be unset (but still remains defined):

    <$let hugo>                        <* unset hugo *>

You can also use Conditional Assignments for updating:

    <$let hugo?=sepp>                  <* if sepp has any value, copy it to hugo *>

## <$macro> - Define Macro

Macros can be used to define your own short-cuts and templates. As there is a lot to tell about this feature, there exists a whole chapter dealing with macros.

## <$message> - Launch User Message

During conversion, messages might show up. But not only `hsc` creates messages, also the user is able to do so using `<$message>`. Messages created by means of this tag will always show up as message #39, but the user can set text and class of it.

For instance this can be useful, if he wants to perform some plausibility checks of macro arguments, or for debugging purpose (``still alive'' messages).

Possible attributes:

`TEXT:string/required`
  Specifies message text
`CLASS:enum("note|warning|error|fatal")='note'`
  Specifies message class

Example:

    <$message TEXT="shit happens..." CLASS="fatal">
    <$message TEXT="something's wrong" CLASS="warning">

## <$match> - Perform pattern matching

Perform pattern matching on a string and capture subpatterns, much like Perl's `m//` operator.

Possible attributes:

`RE:string/required`
  The regular experssion to match against. This uses the same syntax as the `MATCH`/`MATCHI` string operators, with the important addition that bracketed subpatterns do make sense here while the operators simply ignore them.
`S:string/required`
  The string to match against the regular expression specified as `RE`.
`NOCASE:bool`
  Perform case-insensitive matching.
`C0:string`
  Specifies a variable name in which the whole string matched by RE will be stored; equivalent to Perl's `$&` variable.
`C1, C2, C3, C4, C5, C6, C7, C8, C9`
  Same as `C0` but stores the corresponding bracketed subpattern; equivalent to Perl's `$1 .. $9`. If you need more fields, you have to match multiple times as the regex library used does not support more than 9 subexpressions. The variables specified in attributes of this tag need not exist; `hsc` will automatically create them if they were undefined before.

    <$match S="-rw-r--r--  1 mb users 15838 Mar 15 23:35 features/spctags.hsc"
            RE="^(...)(...)(...)" C1=puser C2=pgroup C2=pother>

The above will extract the user, group and other permission bits from a line of ``ls -l`' output and put them into the variables `puser`, `pgroup` and `pother` respectively.

## <$stripws> - Strip White Space

Possible attributes:

`TYPE:enum("both|prev|succ|none")="both"`
  This specifies which white space at the current location should be removed.
  `Prev` will remove all white spaces, which have occured between the previous word and the ```<`'' of this tag, `succ` will skip all blanks between the ```>`'' and the next text or visible tag.
  `Both` will act like if both `prev` and `succ` would have been specified, and `none` has no effect on your data.

Example:

    prev  <$stripws type=both>   succ
    prev  <$stripws type=prev>   succ
    prev  <$stripws type=succ>   succ
    prev  <$stripws type=none>   succ

results in

    prevsucc
    prev   succ
    prev  succ
    prev     succ

Note that the word ```prev`'' is succeeded by two blanks, whereas the word ```succ`'' is preceded by three spaces.

## <$export> - Export data to a file

Possible attributes:

`FILE:string/required`
  Name of file where to write output. If the file already exists, it will be overwritten without any warning.
`DATA:string/required`
  Data to store in the file
`APPEND:bool`
  If the output file already exists, the new data will be appended, leaving the old contents intact.

## <( ... )> - Insert Expression

The tag `<(expression)>` is used to insert data of attributes and expressions.
Example:

    <$define hugo:string="hugo">       <* create hugo and set it to "hugo" *>
    <(hugo+" ist doof.")>              <* insert text "hugo ist doof." *>

## <| ... |> - Insert Verbatim Data

If you created some perverted HTML code or use features `hsc` can't handle (which is theoretically impossible), you can keep `hsc` from parsing this section by surrounding it with `<| ... |>`. Of course, this is a dirty hide-out and should be used only for special cases. Example:

    <|<b>some &<> bull >> shit</b>|>

This can be useful when you want to use other HTML extensions together with `hsc`.