You are using a browser which doesn't fully support Cascading Style Sheets. This site will look much better in a browser that supports web standards, but its content is accessible to any browser or Internet device.

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 it wishes) and the anchor collection object and should return one of the follwing values:

return code description
PARSING_ERASE The tag and all its contents will disappear (which means that these parts will not be presented to the backend).
PARSING_ERROR A semantic error occurred.
PARSING_IGNORE The tag will disappear. The result is just the body (if any).
PARSING_OK All 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.