Today is
84 | ; Warning: Inactive or undefined CL-Markdown function TODAY
85 | ; While executing: #
86 | . It is
87 | ; Warning: Inactive or undefined CL-Markdown function NOW
88 | ; While executing: #
89 | .
90 |
91 | As you can see, the functions weren't ones that CL-Markdown was ready
92 | to recognize, so we got warnings and no text was generated. If we
93 | tell CL-Markdown that `today` and `now` should be treated as
94 | functions, then we see a far prettier picture:
95 |
96 | ? (let ((*render-active-functions*
97 | (append '(today now) *render-active-functions*)))
98 | (markdown "Today is {today}. It is {now}."
99 | :format :html :stream t))
100 | Today is 1 August 2006. It is 11:36.
101 |
102 | By now, we've seen how to include function calls in CL-Markdown
103 | documents and how to generate those documents with CL-Markdown. The
104 | final piece of the puzzle is actually writing the extensions.
105 |
106 |
107 | #### Writing Cl-Markdown extensions
108 |
109 | There are several ways to write extensions. {footnote
110 | Extensions beg for a little {abbrev DSL Domain Specific
111 | Language} but those macros are still to be written.} The
112 | easiest is one is to write functions active during rendering
113 | that return the text that you wish to be included in the
114 | document. For example:
115 |
116 | (defun today (phase arguments result)
117 | (declare (ignore phase arguments result))
118 | (format-date "%e %B %Y" (get-universal-time)))
119 |
120 | The format-date command is part of [metatilities-base][]; it
121 | returns a string of the date using the C library inspired
122 | date format. This string is placed in the document whereever
123 | the function call (\{today\}) is found.
124 |
125 | [metatilities]:
126 |
127 | Alternately, one can use the `*output-stream*` variable to
128 | insert more complicated text. This would look like:
129 |
130 | (defun now (phase arguments result)
131 | (declare (ignore phase arguments result))
132 | (format *output-stream* "~a"
133 | (format-date "%H:%M" (get-universal-time)))
134 | nil)
135 |
136 | (Note that `now` returns `nil` so that the date isn't inserted
137 | twice!).
138 |
139 | The other alternative is to use your function calls to alter
140 | the structure of the CL-Markdown document and then let
141 | Markdown deal with some or all of the rest. The `anchor`
142 | extension provides an example of this:
143 |
144 | (defun anchor (phase &rest args)
145 | (ecase phase
146 | (:parse
147 | (let ((name (caar args))
148 | (title (cadar args)))
149 | (setf (item-at (link-info *current-document*) name)
150 | (make-instance 'link-info
151 | :id name :url (format nil "#~a" name)
152 | :title (or title "")))))
153 | (:render (let ((name (caar args)))
154 | (format nil "Now is the time for all good men to come to
82 | the aid of their country. This is just a
83 | regular paragraph.
84 |
85 | The quick brown fox jumped over the lazy
86 | dog's back.
87 |
88 | ` tags for the
168 | list item text. You can create multi-paragraph list items by indenting
169 | the paragraphs by 4 spaces or 1 tab:
170 |
171 | * A list item.
172 |
173 | With multiple paragraphs.
174 |
175 | * Another item in the list.
176 |
177 | Output:
178 |
179 |