Glyph - Using Placeholders

Sometimes you may need to access some data that will not be available until the entire document has been fully parsed and analyzed. For example, in order to be able to validate internal links, it is necessary to know in advance if the bookmark ID referenced in the link exists or not, either before (that’s easy) or even after the link.

Here’s the source code of the link macro:

 1macro :link do
 2  min_parameters 1
 3  max_parameters 2
 4  target = param 0 
 5  title = param 1 
 6  if target.match /^#/ then
 7    @node[:document].links << target 
 8    anchor = target.gsub /^#/, ''
 9    bmk = bookmark? anchor
10    if !bmk then
11      placeholder do |document|
12        bmk = document.bookmark?(anchor)
13        macro_error "Bookmark '#{anchor}' does not exist" unless bmk
14        bmk_title = title
15        bmk_title = bmk.title if bmk_title.blank?
16        @data[:target] = bmk.link(@source_file)
17        @data[:title] = bmk_title
18        render
19      end
20    else
21      bmk_title = title
22      bmk_title = bmk.title if bmk_title.blank?
23      @data[:target] = bmk.link(@source_file)
24      @data[:title] = bmk_title
25      render
26    end
27  else
28    # Code omitted...
29  end
30end

If there’s already a bookmark stored in the current document, then it is possible to retrieve its title and use it as link text. Otherwise, it is necessary to wait until the entire document has been fully processed and then check if the bookmark exists. To do so, use the placeholder method. When called, this method returns an unique placeholder, which is then substituted with the value of the block, right before the document is finalized.

Within the placeholder block, the document parameter is, by all means, the fully analyzed document.