article: SAM Recipes

    SAM is an abstract markup language, otherwise known as a meta-language. This means that it is intended, like XML,
    defining your own markup languages. Unlike XML, however, SAM pre-defines a basic set of structures.
    SAMs predefined structures provide a simple clear syntax of common text structures, but they don't cover
    everything you might need. The following recipes are suggestions on how to handle some common markup
    problems in SAM. But remember, these involve you defining markup for yourself and require you to handle that
    markup in the application layer.

    recipe: Footnotes

        SAM does not have an predefined markup for footnotes, but it does have support for IDs and citations,
        which provide a reference mechanism for footnotes. The suggested recipe for footnotes is to create a
        footnote block with an id, and use a citation to reference that id:

        ```(sam)
            This paragraph reqires a footnote.[*1]

            footnote:(*1)
                This is a footnote.

        The footnote structure can be anywhere in the document, but it makes sense to place it immediately
        after the paragraph in which the reference occurs. You can move it to the bottom of the page or the
        of the chapter or book in the publishing process.

        Note that the footnote structure is not a child of the paragraph but a sibling at the same
        level of indentation. Paragraphs cannot have block children.

    recipe: Terminal sessions

        There is no support for SAM markup in the body of a codeblock. This works for code, since it
        requires no escaping, regardless of language. It does not work so well for terminal sessions
        if you want to markup the prompt, input, and output. If you need this kind of terminal session
        support, the suggested recipe is to create a terminal session block and use fields for
        the sequence of prompt, input, and response. This reads quite clearly and you can easily
        use it to construct a formatted terminal session illustration when publishing.

        ```(sam)
            terminal:
                prompt: $
                input: dir
                response: Empty directory.

    recipe: Semantic lists

        Sometimes you have semantic lists. That is, the list and its items are of a specific type. For
        example:

        ```(sam)
            filmography:
                film: Rio Bravo
                film: The Shootist

        If you don't want to have to repeat the item name over and over, you can use a recordset
        with a single field.

        ```(sam)
            filmography:: film
                Rio Bravo
                The Shootish

        Notice that while these two constructions capture the same data and the same semantics,
        they are not the same structure, and therefore not to interchangeable. You have to decide
        which one you want in your markup language and provide processing for it accordingly.

        Also note the the XML representation of the two forms is different. The first outputs this:

        ```(xml)
             <filmography>
             <film>Rio Bravo</film>
             <film>The Shootist</film>
             </filmography>

        The second outputs this:

        ```(xml)
             <filmography>
             <row>
             <film>Rio Bravo</film>
             </row>
             <row>
             <film>The Shootist</film>
             </row>
             </filmography>

        Of course, it is easy enough to transform the second output into the first in post-processing.

    recipe: Subscripts and superscripts
        SAM does not have predefined support for superscripts and subscripts. If you need then, you
        need to define a tagging language the provides them. You would do this with annotations:

        ```(sam)
            H{2}(super)S0{4}(super)

    recipe: Conditional paragraphs
        You can't apply attributes to a paragraph. If you want to make paragraphs conditional,
        support fragments in your tagging language and put the conditions on the fragments.

        ```(sam)
            ~~~(?novice)
                Be very careful and ask for help if you need it.

            Push the big red button and run.

    recipe: Use a lookup file to make annotations easier
        SAM allows you to omit the annotations on a phrase after you have annotated it the first
        time in a file. When the parser sees a phrase with no annotation or citation, it looks
        back through the file an finds the last instance of that phrase and copies its annotation.

        This is a time saver. If you have a set of phrases that are commonly annotated
        the same way across a number of documents, you can create a lookup file in which those
        phrases are annotated and import it into each document. You with then not need to
        annotate any of those phrases in the document. Just mark them up as phrases using
        curly braces and the parser will fill in the annotations.

        You need to make sure that the contents of the lookup file do not become part of the
        published document. To do this, simply create a structure in the lookup file to hold
        the list of annotations and suppress that structure in the application layer.

        ```(sam)
            dont-publish-this:
                {Enter}(key)
                {the Duke}(actor "John Wayne" (SAG))

    recipe: Complex labeled lists
        SAM provides a simple labeled list format that allows only one paragraph attached to a
        label. For anything more complex than this, construct a labeled list structured with
        blocks and fields.

        ```(sam)
            ll:
                li:
                    lable: Item label
                    item:
                        The text of the item, including:

                        * paragraphs
                        * lists
                        * etc

    recipe: Single sourcing via attribute substitution
        You can provide single sourcing support via attribute chaining. That is, you can provide but an
        HTTP link and a subject annotation. But if you use the trick of importing a file of
        annotation definitions and relying on annotation lookup to add them to the content, you
        can also substitute in different annotation lookup sets for different media (or different
        anything else). This will get easier when we add catalog support.

    recipe: Index markers

        There are a number of ways to implement index markers in SAM. The first it to avoid the
        use of explict index marker altogether and to generate an index based on semantic annotation.

        ```(sam)
            {The Duke}(actor "John Wayne") plays an ex-Union colonel.

        In this case you could generate an index entry for `John Wayne`, and a categorized entry
        for `Actor:John Wayne` from this annotation.


        Note that you don't have to generate an index entry for every instance of
        and annotated phrase. You can choose to generate an entry only for the first occurrence of
        an annotated phrase in a section or chapter, for instance.

        To implement explicit index markers, you can use annotations with a type `index`:

        ```(sam)
            {The Duke}(index "John Wayne; Actor:John Wayne") plays an ex-Union colonel.

        To implement index markers that span a passage, you can use a field on a block:

        ```(sam)
            bio: John Wayne
                index: John Wayne; Actor:John Wayne

                John Wayne was an actor known for his roles in westerns.

        To implement index markers that span an arbitrary passage within a block, you
        can use a field on a fragment:

        ```(sam)
            ~~~
                index: John Wayne; Actor:John Wayne

                Jimmy Stewart also made a number of films with John Wayne.
                ...

        Remember that these are suggestions as to how you might implement index markers
        in a tagging language based on SAM. SAM does not provide explicit support for
        index markers.

    recipe: Code callouts

        There is no way to insert markup into a regular codeblock. If you want to do callouts
        in code, you can use lines for the code and citations for the callouts. (The presumptive
        semantics for citations is that what they produce is base on the thing they refer to.)

        ```(sam)
        codesample:
            language: python
            code:
                | print("Hello World")[*c1]
                | print ("Goodbye, cruel World")[*c2]
            callouts:
                callout:(*c1) This prints "Hello World".
                callout:(*c2) This prints "Goodbye, cruel World".