Next: Using foreign definitions   Previous: Parsing hooks   Contents: Contents

Post-parsing hooks

You are right. The previous section mentioned anchor reference checks several times but did not show how to perform them. Well, for an obvious reason. If I want to check a link via an anchor collection object in a parsing hook, I might fail even if the link is valid, because the hook is invoked at parsing time and the link might not have been parsed before the tag but may follow it somewhere. To check a reference, one needs to know the complete source first. To solve problems like this, another type of tag hooks is available.

Post-parsing hooks are invoked when parsing is successfully completed and a possibly installed parsing hook was called successfully. (So if a hook function returned an error code, the related post-parsing hook will be ignored.)

These hooks are defined via the finish key. Here's an example from an implementation of \REF.


  finish =>  sub
              {
               # declare and init variable
               my $ok=PARSING_OK;

               # take parameters
               my ($options, $anchors)=@_;

               # try to find an alternative, if possible
               if (exists $options->{alt} and not $anchors->query($options->{name}))
                 {
                  foreach my $alternative (split(/s*,s*/, $options->{alt}))
                    {
                     if ($anchors->query($alternative))
                       {
                        warn qq(nn[Info] Unknown link address "$options->{name}" is replaced by alternative "$alternative".n);
                        $options->{name}=$alternative;
                        last;
                       }
                    }
                 }

               # check link for being valid - finally
               unless ($anchors->query($options->{name}))
                 {
                  # allowed case?
                  if (exists $options->{occasion} and $options->{occasion})
                    {
                     $ok=PARSING_IGNORE;
                     warn qq(nn[Info] Unknown link address "$options->{name}": REF tag ignored.n);
                    }
                  else
                    {
                     $ok=PARSING_FAILED;
                     warn qq(nn[Error] Unknown link address "$options->{name}".n);
                    }
                 }
               else
                 {
                  # link ok, get value
                  $options->{__value__}=$anchors->query($options->{name})->{$options->{name}};
                 }

                # supply status
               $ok;
              },

This hook uses the anchor collection to verify several passed links. If everything is ok, it extracts the value of the finally chosen anchor and stores it in an internal "option" slot (remember the tag option conventions). To do so, it modifies the tag options.

The interface is quite similar to parsing hooks, except for data that cannot be provided after parsing, like source line number or the body contents. So a post-parsing hook receives the options hash (which it can modify as is wishes) and the anchor collection object and should return one of the follwing values:

return codedescription
PARSING_ERASEThe tag and all its contents will disappear (which means that these parts will not be presented to the backend).
PARSING_ERRORA semantic error occurred.
PARSING_IGNOREThe tag will disappear. The result is just the body (if any).
PARSING_OKAll right.

Use of another PARSING_ constant is not recommended because it makes no sense in its original meaning, but it will be automatically treated as something very close: PARSING_COMPLETE is evaluated like PARSING_OK, while PARSING_FAILED is translated into PARSING_ERROR.

Next: Using foreign definitions   Previous: Parsing hooks   Contents: Contents