1textutil::expander(Tne)xt and string utilities, macro processtienxgtutil::expander(n)
2
3
4
5______________________________________________________________________________
6

NAME

8       textutil::expander - Procedures to process templates and expand text.
9

SYNOPSIS

11       package require Tcl  8.2
12
13       package require textutil::expander  ?1.3.1?
14
15       ::textutil::expander expanderName
16
17       expanderName cappend text
18
19       expanderName cget varname
20
21       expanderName cis cname
22
23       expanderName cname
24
25       expanderName cpop cname
26
27       expanderName ctopandclear
28
29       expanderName cpush cname
30
31       expanderName cset varname value
32
33       expanderName cvar varname
34
35       expanderName errmode newErrmode
36
37       expanderName evalcmd ?newEvalCmd?
38
39       expanderName expand string ?brackets?
40
41       expanderName lb ?newbracket?
42
43       expanderName rb ?newbracket?
44
45       expanderName reset
46
47       expanderName setbrackets lbrack rbrack
48
49       expanderName textcmd ?newTextCmd?
50
51       expanderName where
52
53______________________________________________________________________________
54

DESCRIPTION

56       The  Tcl subst command is often used to support a kind of template pro‐
57       cessing. Given a string with  embedded  variables  or  function  calls,
58       subst  will interpolate the variable and function values, returning the
59       new string:
60
61                  % set greeting "Howdy"
62                  Howdy
63                  % proc place {} {return "World"}
64                  % subst {$greeting, [place]!}
65                  Howdy, World!
66                  %
67
68
69       By defining a suitable set of Tcl commands, subst can be used to imple‐
70       ment a markup language similar to HTML.
71
72       The  subst  command  is  efficient, but it has three drawbacks for this
73       kind of template processing:
74
75       •      There's no way to identify and process the  plain  text  between
76              two  embedded  Tcl  commands;  that makes it difficult to handle
77              plain text in a context-sensitive way.
78
79       •      Embedded commands are necessarily bracketed by  [  and  ];  it's
80              convenient  to  be  able to choose different brackets in special
81              cases.  Someone producing web pages that include a  large  quan‐
82              tity  of  Tcl code examples might easily prefer to use << and >>
83              as the embedded code delimiters instead.
84
85       •      There's no easy way to handle incremental input,  as  one  might
86              wish to do when reading data from a socket.
87
88       At  present, expander solves the first two problems; eventually it will
89       solve the third problem as well.
90
91       The following section describes the command API to the  expander;  this
92       is followed by the tutorial sections, see TUTORIAL.
93

EXPANDER API

95       The textutil::expander package provides only one command, described be‐
96       low. The rest of the section is taken by a description of  the  methods
97       for the expander objects created by this command.
98
99       ::textutil::expander expanderName
100              The command creates a new expander object with an associated Tcl
101              command whose name is expanderName. This command may be used  to
102              invoke  various  operations on the graph. If the expanderName is
103              not fully qualified it is interpreted as relative to the current
104              namespace.  The command has the following general form:
105
106
107              expanderName option ?arg arg ...?
108
109
110              Option and the args determine the exact behavior of the command.
111
112       The following commands are possible for expander objects:
113
114       expanderName cappend text
115              Appends  a  string  to  the output in the current context.  This
116              command should rarely be used by macros or application code.
117
118       expanderName cget varname
119              Retrieves the value of variable varname, defined in the  current
120              context.
121
122       expanderName cis cname
123              Determines  whether  or  not  the name of the current context is
124              cname.
125
126       expanderName cname
127              Returns the name of the current context.
128
129       expanderName cpop cname
130              Pops a context from the context stack, returning all accumulated
131              output  in that context.  The context must be named cname, or an
132              error results.
133
134       expanderName ctopandclear
135              Returns the output currently captured in the topmost context and
136              clears  that  buffer.  This  is similar to a combination of cpop
137              followed by cpush, except that internal state (brackets) is pre‐
138              served here.
139
140       expanderName cpush cname
141              Pushes  a  context named cname onto the context stack.  The con‐
142              text must be popped by cpop before expansion ends  or  an  error
143              results.
144
145       expanderName cset varname value
146              Sets variable varname to value in the current context.
147
148       expanderName cvar varname
149              Retrieves  the  internal  variable name of context variable var‐
150              name; this allows the variable to be  passed  to  commands  like
151              lappend.
152
153       expanderName errmode newErrmode
154              Sets  the  macro  expansion error mode to one of nothing, macro,
155              error, or fail; the default value is fail.  The value determines
156              what  the expander does if an error is detected during expansion
157              of a macro.
158
159              fail   The error propagates normally and can be  caught  or  ig‐
160                     nored by the application.
161
162              error  The  macro expands into a detailed error message, and ex‐
163                     pansion continues.
164
165              macro  The macro expands to itself; that is, it is passed  along
166                     to the output unchanged.
167
168              nothing
169                     The macro expands to the empty string, and is effectively
170                     ignored.
171
172
173       expanderName evalcmd ?newEvalCmd?
174              Returns the current evaluation command, which  defaults  to  up‐
175              level #0.  If specified, newEvalCmd will be saved for future use
176              and then returned; it must be a Tcl command expecting one  addi‐
177              tional argument: the macro to evaluate.
178
179       expanderName expand string ?brackets?
180              Expands  the  input string, replacing embedded macros with their
181              expanded values, and returns the expanded string.
182
183              Note that this method pushes a new (empty) context on the  stack
184              of contexts while it is running, and removes it on return.
185
186              If  brackets  is  given,  it  must be a list of two strings; the
187              items will be used as the left and right macro expansion bracket
188              sequences for this expansion only.
189
190       expanderName lb ?newbracket?
191              Returns  the  current value of the left macro expansion bracket;
192              this is for use as or within a macro, when the bracket needs  to
193              be  included in the output text.  If newbracket is specified, it
194              becomes the new bracket, and is returned.
195
196       expanderName rb ?newbracket?
197              Returns the current value of the right macro expansion  bracket;
198              this  is for use as or within a macro, when the bracket needs to
199              be included in the output text.  If newbracket is specified,  it
200              becomes the new bracket, and is returned.
201
202       expanderName reset
203              Resets  all  expander settings to their initial values.  Unusual
204              results are likely if this command is called from within a  call
205              to expand.
206
207       expanderName setbrackets lbrack rbrack
208              Sets  the left and right macro expansion brackets.  This command
209              is for use as or within a macro, or to  permanently  change  the
210              bracket  definitions.  By default, the brackets are [ and ], but
211              any non-empty string can be used; for example, < and > or (* and
212              *) or even Hello, and World!.
213
214       expanderName textcmd ?newTextCmd?
215              Returns the current command for processing plain text, which de‐
216              faults to the empty string, meaning identity. If specified, new‐
217              TextCmd  will be saved for future use and then returned; it must
218              be a Tcl command expecting one additional argument: the text  to
219              process.  The  expander  object  will this command for all plain
220              text it encounters, giving the user of the object the ability to
221              process all plain text in some standard way before writing it to
222              the output. The object expects that the command returns the pro‐
223              cessed plain text.
224
225              Note  that the combination of "textcmd plaintext" is run through
226              the evalcmd for the  actual  evaluation.  In  other  words,  the
227              textcmd is treated as a special macro implicitly surrounding all
228              plain text in the template.
229
230       expanderName where
231              Returns a three-element list containing  the  current  character
232              position,  line, and column the expander is at in the processing
233              of the current input string.
234

TUTORIAL

236   BASICS
237       To begin, create an expander object:
238
239                  % package require textutil::expander
240                  1.2
241                  % ::textutil::expander myexp
242                  ::myexp
243                  %
244
245
246       The created ::myexp object can be used to expand text strings  contain‐
247       ing embedded Tcl commands.  By default, embedded commands are delimited
248       by square brackets.  Note that expander doesn't attempt to  interpolate
249       variables, since variables can be referenced by embedded commands:
250
251                  % set greeting "Howdy"
252                  Howdy
253                  % proc place {} {return "World"}
254                  % ::myexp expand {[set greeting], [place]!}
255                  Howdy, World!
256                  %
257
258
259   EMBEDDING MACROS
260       An expander macro is simply a Tcl script embedded within a text string.
261       Expander evaluates the script in the global context,  and  replaces  it
262       with its result string.  For example,
263
264                  % set greetings {Howdy Hi "What's up"}
265                  Howdy Hi "What's up"
266                  % ::myexp expand {There are many ways to say "Hello, World!":
267                  [set result {}
268                  foreach greeting $greetings {
269                append result "$greeting, World!\\n"
270                  }
271                  set result]
272                  And that's just a small sample!}
273                  There are many ways to say "Hello, World!":
274                  Howdy, World!
275                  Hi, World!
276                  What's up, World!
277
278                  And that's just a small sample!
279                  %
280
281
282   WRITING MACRO COMMANDS
283       More typically, macro commands are used to create a markup language.  A
284       macro command is just a Tcl command that returns an output string.  For
285       example, expand can be used to implement a generic document markup lan‐
286       guage that can be retargeted to HTML or any other output format:
287
288                  % proc bold {} {return "<b>"}
289                  % proc /bold {} {return "</b>"}
290                  % ::myexp expand {Some of this text is in [bold]boldface[/bold]}
291                  Some of this text is in <b>boldface</b>
292                  %
293
294
295       The above definitions of bold and /bold returns HTML, but such commands
296       can  be  as complicated as needed; they could, for example, decide what
297       to return based on the desired output format.
298
299   CHANGING THE EXPANSION BRACKETS
300       By default, embedded macros are enclosed in square brackets, [  and  ].
301       If  square  brackets  need  to be included in the output, the input can
302       contain the lb and rb commands.  Alternatively, or if  square  brackets
303       are  objectionable  for some other reason, the macro expansion brackets
304       can be changed to any pair of non-empty strings.
305
306       The setbrackets command changes the brackets permanently.  For example,
307       you can write pseudo-html by change them to < and >:
308
309                  % ::myexp setbrackets < >
310                  % ::myexp expand {<bold>This is boldface</bold>}
311                  <b>This is boldface</b>
312
313
314       Alternatively,  you  can  change  the expansion brackets temporarily by
315       passing the desired brackets to the expand command:
316
317                  % ::myexp setbrackets "\\[" "\\]"
318                  % ::myexp expand {<bold>This is boldface</bold>} {< >}
319                  <b>This is boldface</b>
320                  %
321
322
323   CUSTOMIZED MACRO EXPANSION
324       By default, macros are evaluated using the Tcl uplevel #0  command,  so
325       that the embedded code executes in the global context.  The application
326       can provide a different evaluation command using evalcmd;  this  allows
327       the  application  to  use  a  safe interpreter, for example, or even to
328       evaluated something other than Tcl code.  There is one  caveat:  to  be
329       recognized  as  valid, a macro must return 1 when passed to Tcl's "info
330       complete" command.
331
332       For example, the following code "evaluates" each macro by returning the
333       macro text itself.
334
335                  proc identity {macro} {return $macro}
336                  ::myexp evalcmd identity
337
338
339   USING THE CONTEXT STACK
340       Often  it's  desirable to define a pair of macros which operate in some
341       way on the plain text between them.   Consider  a  set  of  macros  for
342       adding footnotes to a web page: one could have implement something like
343       this:
344
345                  Dr. Pangloss, however, thinks that this is the best of all
346                  possible worlds.[footnote "See Candide, by Voltaire"]
347
348
349       The footnote macro would, presumably, assign a number to this  footnote
350       and  save the text to be formatted later on.  However, this solution is
351       ugly if the footnote text is long or should contain additional  markup.
352       Consider the following instead:
353
354                  Dr. Pangloss, however, thinks that this is the best of all
355                  possible worlds.[footnote]See [bookTitle "Candide"], by
356                  [authorsName "Voltaire"], for more information.[/footnote]
357
358
359       Here  the  footnote  text  is  contained between footnote and /footnote
360       macros, continues onto a second line, and contains  several  macros  of
361       its  own.   This  is  both clearer and more flexible; however, with the
362       features presented so far there's no easy way to  do  it.   That's  the
363       purpose of the context stack.
364
365       All  macro  expansion  takes  place in a particular context.  Here, the
366       footnote macro pushes a new context onto the context stack.  Then,  all
367       expanded  text gets placed in that new context.  /footnote retrieves it
368       by popping the context.  Here's a skeleton implementation of these  two
369       macros:
370
371                  proc footnote {} {
372                      ::myexp cpush footnote
373                  }
374
375                  proc /footnote {} {
376                      set footnoteText [::myexp cpop footnote]
377
378                      # Save the footnote text, and return an appropriate footnote
379                      # number and link.
380                  }
381
382
383       The  cpush command pushes a new context onto the stack; the argument is
384       the context's name.  It can be any string, but would typically  be  the
385       name of the macro itself.  Then, cpop verifies that the current context
386       has the expected name, pops it off of the stack, and returns the  accu‐
387       mulated text.
388
389       Expand provides several other tools related to the context stack.  Sup‐
390       pose the first macro in a context pair takes arguments or computes val‐
391       ues which the second macro in the pair needs.  After calling cpush, the
392       first macro can define one or more context variables; the second  macro
393       can  retrieve  their values any time before calling cpop.  For example,
394       suppose the document must specify the footnote number explicitly:
395
396                  proc footnote {footnoteNumber} {
397                      ::myexp cpush footnote
398                      ::myexp csave num $footnoteNumber
399                      # Return an appropriate link
400                  }
401
402                  proc /footnote {} {
403                      set footnoteNumber [::myexp cget num]
404                      set footnoteText [::myexp cpop footnote]
405
406                      # Save the footnote text and its footnoteNumber for future
407                      # output.
408                  }
409
410
411       At times, it might be desirable to define macros that  are  valid  only
412       within  a  particular context pair; such macros should verify that they
413       are only called within the correct context using either cis or cname.
414

HISTORY

416       expander was written by William H. Duquette; it is a repackaging of the
417       central algorithm of the expand macro processing tool.
418

BUGS, IDEAS, FEEDBACK

420       This  document,  and the package it describes, will undoubtedly contain
421       bugs and other problems.  Please report such in the  category  textutil
422       of  the Tcllib Trackers [http://core.tcl.tk/tcllib/reportlist].  Please
423       also report any ideas for enhancements you may have for either  package
424       and/or documentation.
425
426       When proposing code changes, please provide unified diffs, i.e the out‐
427       put of diff -u.
428
429       Note further that  attachments  are  strongly  preferred  over  inlined
430       patches.  Attachments  can  be  made  by  going to the Edit form of the
431       ticket immediately after its creation, and  then  using  the  left-most
432       button in the secondary navigation bar.
433

SEE ALSO

435       [uri, http://www.wjduquette.com/expand, regexp, split, string
436

KEYWORDS

438       string, template processing, text expansion
439

CATEGORY

441       Documentation tools
442
444       Copyright (c) William H. Duquette, http://www.wjduquette.com/expand
445
446
447
448
449tcllib                               1.3.1               textutil::expander(n)
Impressum