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.