What are the essential parts of the referent mechanism?
referents-allowed accepts referents, buffering all input until the referent values are resolved. output referent into such a stream. set referent, open ... as referent, or using output as referent action. These three requirements already describe our interface. First, we need a markup sink filter to play the role of the referents-allowed modifier:
export markup sink function resolve-referents into value markup sink destination
The input of resolve-referents consists of plain text, markup, and referents. Its task is to replace each referent by its resolved value and output the resulting markup stream into destination.
For the next piece of the puzzle, if the aim is to replicate the built-in OmniMark syntax as closely as possible, we'd like the equivalent of the following interface that uses the word referent both for emitting a referent and for setting its value:
export markup source function referent value string referent-name export markup sink function referent value string referent-name
This interface supports both emitting a referent with output referent, and setting a referent's value with using output as referent. The two function definitions would unfortunately not be allowed in OmniMark, but we can achieve the same effect by having the function referent return an intermediate type which then gets converted to the desired result type by a conversion-function:
export markup-referent-buffer function referent value string referent-name export markup source conversion-function value markup-referent-buffer b export markup sink conversion-function value markup-referent-buffer b