livetext 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (8) hide show
  1. checksums.yaml +7 -0
  2. data/README.html +960 -0
  3. data/README.ltx +342 -0
  4. data/README.md +965 -0
  5. data/dlt +1 -0
  6. data/livetext.gemspec +12 -0
  7. data/notes.txt +146 -0
  8. metadata +50 -0
data/README.ltx ADDED
@@ -0,0 +1,342 @@
1
+ .mixin lib/tutorial
2
+ .title Livetext: A smart processor for text
3
+
4
+ .p Livetext is simply a tool for transforming text from one format into another. The source file
5
+ has commands embedded in it, and the output is dependent on those commands.
6
+
7
+ .p Why is this special? It's very flexible, very extensible, and it's extensible _(in Ruby).
8
+
9
+ .section Why Livetext?
10
+
11
+ .p Livetext grew out of several motivations. One was a desire for a markup language that would permit
12
+ me to write articles (and even books) in my own way and on my own terms. I've done this more
13
+ than once (and I know others who have, as well).
14
+
15
+ .p I liked Softcover, but I found it to be very complex. I never liked Markdown much -- it is very
16
+ dumb and not extensible at all.
17
+
18
+ .p I wanted something that had the basic functionality of all my ad hoc solutions but allowed
19
+ extensions. Then my old solutions would be like subsets of the new format. This was a generalization
20
+ similar to the way we began several years ago to view HTML as a subset of XML.
21
+
22
+ .section What is Livetext really?
23
+
24
+ .p Here goes:
25
+ .list
26
+ It's a text transformer
27
+ It's Ruby-based (later on, more language agnostic)
28
+ It's (potentially) agnostic about output format
29
+ It's designed to be flexible, extensible, and easy
30
+ It's designed to be "plugin" oriented
31
+ It's like an old-fashioned text formatter (but extensible)
32
+ It's like a macro processor (but not)
33
+ It's like markdown and others (but not)
34
+ It's like erb or HAML (but not)
35
+ It's powerful but not too dangerous
36
+ It's not necesarily a markdown replacement
37
+ It's definitely not a softcover replacement
38
+ It could possibly augment markdown, softcover, others
39
+ .end
40
+
41
+ .section How does it work?
42
+
43
+ .p A Livetext file is simply a text file which may have commands interspersed. A command is
44
+ simply a period followed by a name and optional parameters (at the beginning of a line).
45
+
46
+ .p The period is configurable if you want to use another character. The names are (for now)
47
+ actual Ruby method names, so names such as `to_s and `inspect are currently not allowed.
48
+
49
+ .p Currently I am mostly emitting "dumb HTML" or Markdown as output. In theory, you can write
50
+ code (or use someone else's) to manipulate text in any way and output any format. Technically,
51
+ you could even emit PDF, PNG, or SVG formats.
52
+
53
+ . Idea: Make an RMagick DSL as an example.
54
+
55
+ .p It's possible to embed comments in the text, or even to pass them through to the output
56
+ in commented form.
57
+
58
+ .p The command `.end is special, marking the end of a body of text. Some commands may operate on
59
+ a block of lines rather than just a few parameters. (A text block is like a here-document.)
60
+ There is no method name corresponding to the `.end command.
61
+
62
+ .p The file extension I've chosen is `.lt (though this may change). *Note: The source for this
63
+ README is a `.lt file which uses its own little _(ad hoc) library (called `(readme.rb)). Refer to
64
+ the repo to see these.
65
+
66
+ .section Syntax, comments, and more
67
+
68
+ .p At first, my idea was to provide predefined commands and allow user-defined commands (to be
69
+ distinguished by a leading `. or `.. markers). So the single and double dots are both legal.
70
+
71
+ However, my concept at present is that the double dots (currently unused) will be used for
72
+ subcommmands.
73
+
74
+ .p User-defined commands may be added to the standard namespace marked with a period. They may
75
+ also be preceded by a specified character other than the period and thus stored in their own
76
+ namespace. More on that later.
77
+
78
+ .p When a leading period (or double period) is followed by a space, that line is a comment.
79
+ When it is follwed by a name, that name is typically understood to be a method name. Any
80
+ remaining text on the line is treated as a parameter list to be accessed by that method.
81
+ Some methods accept multiple lines of text, terminated by a `.end tag.
82
+
83
+ .section Boldface and italics
84
+
85
+ .p Very commonly we want to format short words or phrases in italics, boldface, or a monospaced
86
+ (fixed width) font. The Markdown spec provides ways to do this that are fairly intuitive; but I
87
+ personally don't like them. My own notation works a different way.
88
+
89
+ .p First of all, note that these don't work across source lines; they're strictly intra-line.
90
+ You may need (for example) an italicized phrase that spans across a newline; at present, you'll
91
+ need a workaround for that.
92
+
93
+ .p I find that most short items I want to format are single tokens. Therefore I use a prefixed
94
+ character in front of such a token: Underscore for italics, asterisk for boldface, and backtick
95
+ for "code font." The formatting ends when the first blank space is encountered, without any
96
+ kind of suffixed character. (This behavior may change to include certain punctuation marks as
97
+ terminators.)
98
+
99
+ .p Of course, there are cases where this won't work; a formatted string may contain spaces, or it
100
+ may exclude characters before the blank space. In this case, we can use an opening parenthesis
101
+ after the prefix and a closing parenthesis at the end of the string.
102
+
103
+ .p This means that it can be difficult to include a left paren inside a formatted token. I'm thinking
104
+ about that. It also means that a "literal" prefix character must be escaped.
105
+
106
+ .p This is all summarized in this example (taken from one of the testcases):
107
+
108
+ .testcase basic_formatting
109
+
110
+ .section Standard methods
111
+
112
+ .p The module `Livetext::Standard contains the set of standard or predefined methods. Their
113
+ names are essentially the same as the names of the dot-commands, with occasional exceptions.
114
+ (For example, it is impractical to use the name `def as a method name, so we use `_def instead.)
115
+ Here is the current list:
116
+
117
+ .dlist
118
+ `comment ~~ Start a comment block
119
+ `errout ~~ Write an error message to STDERR
120
+ `sigil ~~ Change the default sigil from `. to some other character
121
+ `_def ~~ Define a new method inline
122
+ `set ~~ Assign values to variables for later interpolation
123
+ `include ~~ Include an outside text file (to be interpreted as Livetext)
124
+ `mixin ~~ Mix this file of Ruby methods into the standard namespace
125
+ `copy ~~ Copy this input file verbatim (no interpretation)
126
+ `r ~~ Pass a single line through without processing
127
+ `raw ~~ Pass this special text block (terminated with `(__EOF__)) directly into output without processing
128
+ .end
129
+
130
+ .section Examples from the tests
131
+
132
+ Here are some tests from the suite. The file name reflects the general purpose of the test.
133
+
134
+ .testcase hello_world
135
+ .testcase comments_ignored_1
136
+ .testcase sigil_can_change
137
+ .testcase block_comment
138
+ .testcase def_method
139
+ .testcase simple_vars
140
+ .testcase simple_include
141
+ .testcase simple_mixin
142
+ .testcase simple_copy
143
+ .testcase copy_is_raw
144
+ .testcase raw_text_block
145
+
146
+ .section Writing custom methods
147
+
148
+ .p Suppose you wanted to write a method called `chapter that would simply
149
+ output a chapter number and title with certain heading tags and a
150
+ horizontal rule following. There is more than one way to do this.
151
+
152
+ .p The simplest way is just to define a method inline with the rest of
153
+ the text. Here's an example.
154
+
155
+ .code
156
+ .comment
157
+ This example shows how to define
158
+ a simple method "chapter" inline
159
+ .end
160
+
161
+ . This is also a comment, by the way.
162
+ .def chapter
163
+ params = _args
164
+ raise "chapter: expecting at least two args" unless params.size > 1
165
+ num, *title = params # Chapter number + title
166
+ title = title.join(" ") # Join all words into one string
167
+ text = <<-HTML
168
+ <h3>Chapter #{num}</h3>
169
+ <h2>#{title}</h2>
170
+ <hr>
171
+ HTML
172
+ _puts text
173
+ .end
174
+ . Now let's invoke it...
175
+ .chapter 1 Why I Went to the Woods
176
+ It was the best of times, and you can call me Ishmael. The clocks
177
+ were striking thirteen.
178
+ .end
179
+
180
+ .p What can we see from this example? First of all, notice that the part
181
+ between `.def and `.end (the body of the method) really is just Ruby
182
+ code. The method takes no parameters because parameter passing is
183
+ handled inside the Livetext engine and the instance variable `@_args is
184
+ initialized to the contents of this array. We usually refer to the
185
+ `@_args array only through the method `_args which returns it.
186
+
187
+ The `_args method is also an iterator. If a block is attached, that block
188
+ will be called for every argument.
189
+
190
+ .p We then create a string using these parameters and call it using the
191
+ `_puts method. This really does do a `puts call, but it applies it to
192
+ wherever the output is currently being sent (defaulting to STDOUT).
193
+
194
+ .p All the "helper" methods start with an underscore so as to avoid name
195
+ collisions. These are all stored in the `Livetext::Helpers module
196
+ (which also has some methods you will never use).
197
+
198
+ .p Here is the HTML output of the previous example:
199
+
200
+ .code
201
+ <h3>Chapter 1</h3>
202
+ <h2>Why I Went to the Woods</h2>
203
+ <hr>
204
+ It was the best of times, and you can call me Ishmael. The clocks
205
+ were striking thirteen.
206
+ .end
207
+
208
+ .p What are some other helper methods? Here's a list.
209
+
210
+ .dlist
211
+ `_args ~~ Returns an array of arguments for the method (or an enumerator for that array)
212
+ `_data ~~ A single "unsplit" string of all arguments in raw form
213
+ `_body ~~ Returns a string (or enumerator) giving access to the text block (preceding `(.end))
214
+ `_puts ~~ Write a line to output (STDOUT or wherever)
215
+ `_print ~~ Write a line to output (STDOUT or wherever) without a newline
216
+ `_formatting ~~ A function transforming boldface, italics, and monospace (Livetext conventions)
217
+ `_var_substitution ~~ Substitute variables into a string
218
+ `_passthru ~~ Feed a line directly into output after transforming and substituting
219
+ .end
220
+
221
+ .p Note that the last three methods are typically _not called in your own code. They could be,
222
+ but it remains to be seen whether something that advanced is useful.
223
+
224
+ .section More examples
225
+
226
+ .p Suppose you wanted to take a list of words, more than one per line, and alphabetize them.
227
+ Let's write a method called `alpha for that. This exercise and the next one are implemented
228
+ in the test suite.
229
+
230
+ .testcase example_alpha
231
+
232
+ .p I'll let that code stand on its own. Now suppose you wanted to allow columnar output. Let's
233
+ have the user specify a number of columns (from 1 to 5, defaulting to 1).
234
+
235
+ .testcase example_alpha2
236
+
237
+ .p What if we wanted to store the code outside the text file? There is more than one way to
238
+ do this.
239
+
240
+ .p Let's assume we have a file called `mylib.rb in the same directory as the file we're processing.
241
+ (Issues such as paths and security have not been addressed yet.) We'll stick the actual Ruby code
242
+ in here (and nothing else).
243
+
244
+ .code
245
+ # File: mylib.rb
246
+
247
+ def alpha
248
+ cols = _args.first
249
+ cols = "1" if cols == ""
250
+ cols = cols.to_i
251
+ raise "Columns must be 1-5" unless cols.between?(1,5)
252
+ text = _body.join
253
+ text.gsub!(/\n/, " ")
254
+ words = text.split.sort
255
+ words.each_slice(cols) do |row|
256
+ row.each {|w| _print '%-15s' % w }
257
+ _puts
258
+ end
259
+ end
260
+ .end
261
+
262
+ .p Now the `.lt file can be written this way:
263
+
264
+ .code
265
+ .mixin mylib
266
+ Here is an alphabetized list:
267
+
268
+ .alpha 3
269
+ fishmonger anarchist aardvark glyph gryphon
270
+ halcyon zymurgy mataeotechny zootrope
271
+ pareidolia manicotti quark bellicose anamorphic
272
+ cytology fusillade ectomorph
273
+ .end
274
+
275
+ I hope that worked a second time.
276
+ .end
277
+
278
+ .p The output, of course, is the same.
279
+
280
+ .p There is an important feature that has not yet been implemented (the
281
+ `require method). Like Ruby's `(require), it will grab Ruby code and
282
+ load it; however, unlike `(mixin), it will load it into a customized
283
+ object and associate a new sigil with it. So for example, the command
284
+ `.foobar would refer to a method in the `Livetext::Standard class
285
+ (whether predefined or user-defined). If we did a `require on a file
286
+ and associated the sigil `# with it, then `#foobar would be a method
287
+ on that new custom object. I will implement this soon.
288
+
289
+ .section Issues, open questions, and to-do items
290
+
291
+ .p This list is not prioritized yet.
292
+
293
+ .nlist
294
+ Add versioning information
295
+ Clean up code structure
296
+ Add RDoc
297
+ Think about command line executable
298
+ Write as pure library in addition to executable
299
+ Package as gem
300
+ Document: `require `include `copy `mixin `errout and others
301
+ Need much better error checking and corresponding tests
302
+ Worry about nesting of elements (probably mostly disallow)
303
+ Think about UTF-8
304
+ Document API fully
305
+ Add `_raw_args and let `_args honor quotes
306
+ Support quotes in `.set values
307
+ Support "namespaced" variables (`(.set code.font="whatever"))
308
+ Support functions (`($$func)) including namespacing
309
+ Create predefined variables and functions (e.g., `($_source_file), `$(_line), `($$_today))
310
+ Support markdown-style bold/italics? (`_markdown replaces `_formatting method)
311
+ Allow turning on/off: formatting, variable interpolation, function interpolation?
312
+ `.require with file and sigil parameters
313
+ Investigate "common intermediate format" - output renderers all read it
314
+ Comments passed through (e.g. as HTML comments)
315
+ `.run to execute arbitrary Ruby code inline?
316
+ Concept of `.proc (guaranteed to return no value, produce no output)?
317
+ Exceptions??
318
+ Ruby `$SAFE levels?
319
+ Warn when overriding existing names?
320
+ Think about passing data in (erb replacement)
321
+ Allow custom ending tag on `raw method
322
+ Ignore first blank line after `(.end)? (and after raw-tag?)
323
+ Allow/encourage custom `passthru method?
324
+ Must have sane support for CSS
325
+ Support for Pygments and/or other code processors
326
+ Support for gists? arbitrary links? other remote resouces?
327
+ Small libraries for special purposes (books? special Softcover support? blogs? PDF? RMagick?)
328
+ Experiment with idea of special libraries having pluggable output formats (via Ruby mixin?)
329
+ Imagining a lib that can run/test code fragments as part of document generation
330
+ Create vim (emacs?) syntax files
331
+ Someday: Support other languages (Elixir, Python, ...)
332
+ `.pry method?
333
+ `.irb method?
334
+ Other debugging features
335
+ Feature to "break" to EOF?
336
+ `.meth? method ending in `? takes a block that may be processed or thrown away (`(.else) perhaps?)
337
+ `.dump to dump all variables and their values
338
+ `.if and `(.else)?
339
+ Make any/all delimiters configurable
340
+ HTML helper? (in their own library?)
341
+ .end
342
+
data/README.md ADDED
@@ -0,0 +1,965 @@
1
+ <center><h2>Livetext: A smart processor for text</h2></center>
2
+
3
+ Livetext is simply a tool for transforming text from one format into another. The source file
4
+ has commands embedded in it, and the output is dependent on those commands.
5
+
6
+ Why is this special? It's very flexible, very extensible, and it's extensible <i>in Ruby</i>.
7
+
8
+ <br><br><b><font size=+1>Why Livetext?</font></b><br>
9
+
10
+ Livetext grew out of several motivations. One was a desire for a markup language that would permit
11
+ me to write articles (and even books) in my own way and on my own terms. I've done this more
12
+ than once (and I know others who have, as well).
13
+
14
+ I liked Softcover, but I found it to be very complex. I never liked Markdown much -- it is very
15
+ dumb and not extensible at all.
16
+
17
+ I wanted something that had the basic functionality of all my ad hoc solutions but allowed
18
+ extensions. Then my old solutions would be like subsets of the new format. This was a generalization
19
+ similar to the way we began several years ago to view HTML as a subset of XML.
20
+
21
+ <br><br><b><font size=+1>What is Livetext really?</font></b><br>
22
+
23
+ Here goes:
24
+ <ul>
25
+ <li>It's a text transformer
26
+ </li>
27
+ <li>It's Ruby-based (later on, more language agnostic)
28
+ </li>
29
+ <li>It's (potentially) agnostic about output format
30
+ </li>
31
+ <li>It's designed to be flexible, extensible, and easy
32
+ </li>
33
+ <li>It's designed to be "plugin" oriented
34
+ </li>
35
+ <li>It's like an old-fashioned text formatter (but extensible)
36
+ </li>
37
+ <li>It's like a macro processor (but not)
38
+ </li>
39
+ <li>It's like markdown and others (but not)
40
+ </li>
41
+ <li>It's like erb or HAML (but not)
42
+ </li>
43
+ <li>It's powerful but not too dangerous
44
+ </li>
45
+ <li>It's not necesarily a markdown replacement
46
+ </li>
47
+ <li>It's definitely not a softcover replacement
48
+ </li>
49
+ <li>It could possibly augment markdown, softcover, others
50
+ </li>
51
+ </ul>
52
+
53
+ <br><br><b><font size=+1>How does it work?</font></b><br>
54
+
55
+ A Livetext file is simply a text file which may have commands interspersed. A command is
56
+ simply a period followed by a name and optional parameters (at the beginning of a line).
57
+
58
+ The period is configurable if you want to use another character. The names are (for now)
59
+ actual Ruby method names, so names such as <tt>to_s</tt> and <tt>inspect</tt> are currently not allowed.
60
+
61
+ Currently I am mostly emitting "dumb HTML" or Markdown as output. In theory, you can write
62
+ code (or use someone else's) to manipulate text in any way and output any format. Technically,
63
+ you could even emit PDF, PNG, or SVG formats.
64
+
65
+
66
+ It's possible to embed comments in the text, or even to pass them through to the output
67
+ in commented form.
68
+
69
+ The command <tt>.end</tt> is special, marking the end of a body of text. Some commands may operate on
70
+ a block of lines rather than just a few parameters. (A text block is like a here-document.)
71
+ There is no method name corresponding to the <tt>.end</tt> command.
72
+
73
+ The file extension I've chosen is <tt>.lt</tt> (though this may change). <b>Note:</b> The source for this
74
+ README is a <tt>.lt</tt> file which uses its own little <i>ad hoc</i> library (called <tt>readme.rb</tt>). Refer to
75
+ the repo to see these.
76
+
77
+ <br><br><b><font size=+1>Syntax, comments, and more</font></b><br>
78
+
79
+ At first, my idea was to provide predefined commands and allow user-defined commands (to be
80
+ distinguished by a leading <tt>.</tt> or <tt>..</tt> markers). So the single and double dots are both legal.
81
+
82
+ However, my concept at present is that the double dots (currently unused) will be used for
83
+ subcommmands.
84
+
85
+ User-defined commands may be added to the standard namespace marked with a period. They may
86
+ also be preceded by a specified character other than the period and thus stored in their own
87
+ namespace. More on that later.
88
+
89
+ When a leading period (or double period) is followed by a space, that line is a comment.
90
+ When it is follwed by a name, that name is typically understood to be a method name. Any
91
+ remaining text on the line is treated as a parameter list to be accessed by that method.
92
+ Some methods accept multiple lines of text, terminated by a <tt>.end</tt> tag.
93
+
94
+ <br><br><b><font size=+1>Boldface and italics</font></b><br>
95
+
96
+ Very commonly we want to format short words or phrases in italics, boldface, or a monospaced
97
+ (fixed width) font. The Markdown spec provides ways to do this that are fairly intuitive; but I
98
+ personally don't like them. My own notation works a different way.
99
+
100
+ First of all, note that these don't work across source lines; they're strictly intra-line.
101
+ You may need (for example) an italicized phrase that spans across a newline; at present, you'll
102
+ need a workaround for that.
103
+
104
+ I find that most short items I want to format are single tokens. Therefore I use a prefixed
105
+ character in front of such a token: Underscore for italics, asterisk for boldface, and backtick
106
+ for "code font." The formatting ends when the first blank space is encountered, without any
107
+ kind of suffixed character. (This behavior may change to include certain punctuation marks as
108
+ terminators.)
109
+
110
+ Of course, there are cases where this won't work; a formatted string may contain spaces, or it
111
+ may exclude characters before the blank space. In this case, we can use an opening parenthesis
112
+ after the prefix and a closing parenthesis at the end of the string.
113
+
114
+ This means that it can be difficult to include a left paren inside a formatted token. I'm thinking
115
+ about that. It also means that a "literal" prefix character must be escaped.
116
+
117
+ This is all summarized in this example (taken from one of the testcases):
118
+
119
+
120
+ <b>Test: <tt>015\_basic\_formatting</tt></b><br>
121
+ <center>
122
+ <table width=80% cellpadding=4>
123
+ <tr>
124
+ <td width=50%><b>Input</b></td>
125
+ <td width=50%><b>Output</b></td>
126
+ </tr>
127
+ <tr>
128
+ <td width=50% bgcolor=#fec0fe valign=top>
129
+ <pre> Here are examples of *boldface and \_italics and `code
130
+ as well as *(more complex) examples of \_(italicized text)
131
+ and `(code font).
132
+
133
+ Here are some random punctuation marks:
134
+ # . @ * \_ ` : ; % ^ & $
135
+
136
+ Oops, forgot to escape these: \* \\_ \`
137
+ </pre>
138
+ </td>
139
+ <td width=50% bgcolor=lightgray valign=top>
140
+ <pre> Here are examples of <b>boldface</b> and <i>italics</i> and <tt>code</tt>
141
+ as well as <b>more complex</b> examples of <i>italicized text</i>
142
+ and <tt>code font</tt>.
143
+
144
+ Here are some random punctuation marks:
145
+ # . @ * \_ ` : ; % ^ & $
146
+
147
+ Oops, forgot to escape these: * \_ `
148
+ </pre>
149
+ </td>
150
+ </tr>
151
+ </table>
152
+ </center>
153
+
154
+ <br><br><b><font size=+1>Standard methods</font></b><br>
155
+
156
+ The module <tt>Livetext::Standard</tt> contains the set of standard or predefined methods. Their
157
+ names are essentially the same as the names of the dot-commands, with occasional exceptions.
158
+ (For example, it is impractical to use the name <tt>def</tt> as a method name, so we use <tt>_def</tt> instead.)
159
+ Here is the current list:
160
+
161
+ <table>
162
+ <tr>
163
+ <td width=3%><td width=10%> <tt>comment</tt> </td><td> Start a comment block
164
+ </td>
165
+ </tr>
166
+ <tr>
167
+ <td width=3%><td width=10%> <tt>errout</tt> </td><td> Write an error message to STDERR
168
+ </td>
169
+ </tr>
170
+ <tr>
171
+ <td width=3%><td width=10%> <tt>sigil</tt> </td><td> Change the default sigil from <tt>.</tt> to some other character
172
+ </td>
173
+ </tr>
174
+ <tr>
175
+ <td width=3%><td width=10%> <tt>_def</tt> </td><td> Define a new method inline
176
+ </td>
177
+ </tr>
178
+ <tr>
179
+ <td width=3%><td width=10%> <tt>set</tt> </td><td> Assign values to variables for later interpolation
180
+ </td>
181
+ </tr>
182
+ <tr>
183
+ <td width=3%><td width=10%> <tt>include</tt> </td><td> Include an outside text file (to be interpreted as Livetext)
184
+ </td>
185
+ </tr>
186
+ <tr>
187
+ <td width=3%><td width=10%> <tt>mixin</tt> </td><td> Mix this file of Ruby methods into the standard namespace
188
+ </td>
189
+ </tr>
190
+ <tr>
191
+ <td width=3%><td width=10%> <tt>copy</tt> </td><td> Copy this input file verbatim (no interpretation)
192
+ </td>
193
+ </tr>
194
+ <tr>
195
+ <td width=3%><td width=10%> <tt>r</tt> </td><td> Pass a single line through without processing
196
+ </td>
197
+ </tr>
198
+ <tr>
199
+ <td width=3%><td width=10%> <tt>raw</tt> </td><td> Pass this special text block (terminated with <tt>__EOF__</tt>) directly into output without processing
200
+ </td>
201
+ </tr>
202
+ </table>
203
+
204
+ <br><br><b><font size=+1>Examples from the tests</font></b><br>
205
+
206
+ Here are some tests from the suite. The file name reflects the general purpose of the test.
207
+
208
+
209
+ <b>Test: <tt>001\_hello\_world</tt></b><br>
210
+ <center>
211
+ <table width=80% cellpadding=4>
212
+ <tr>
213
+ <td width=50%><b>Input</b></td>
214
+ <td width=50%><b>Output</b></td>
215
+ </tr>
216
+ <tr>
217
+ <td width=50% bgcolor=#fec0fe valign=top>
218
+ <pre> Hello,
219
+ world!
220
+ </pre>
221
+ </td>
222
+ <td width=50% bgcolor=lightgray valign=top>
223
+ <pre> Hello,
224
+ world!
225
+ </pre>
226
+ </td>
227
+ </tr>
228
+ </table>
229
+ </center>
230
+
231
+ <b>Test: <tt>002\_comments\_ignored\_1</tt></b><br>
232
+ <center>
233
+ <table width=80% cellpadding=4>
234
+ <tr>
235
+ <td width=50%><b>Input</b></td>
236
+ <td width=50%><b>Output</b></td>
237
+ </tr>
238
+ <tr>
239
+ <td width=50% bgcolor=#fec0fe valign=top>
240
+ <pre> . Comments are ignored
241
+ abc 123
242
+ this is a test
243
+ . whether at beginning, middle, or
244
+ more stuff
245
+ still more stuff
246
+ . end of the file
247
+ </pre>
248
+ </td>
249
+ <td width=50% bgcolor=lightgray valign=top>
250
+ <pre> abc 123
251
+ this is a test
252
+ more stuff
253
+ still more stuff
254
+ </pre>
255
+ </td>
256
+ </tr>
257
+ </table>
258
+ </center>
259
+
260
+ <b>Test: <tt>003\_comments\_ignored\_2</tt></b><br>
261
+ <center>
262
+ <table width=80% cellpadding=4>
263
+ <tr>
264
+ <td width=50%><b>Input</b></td>
265
+ <td width=50%><b>Output</b></td>
266
+ </tr>
267
+ <tr>
268
+ <td width=50% bgcolor=#fec0fe valign=top>
269
+ <pre> .. Comments (with a double-dot) are ignored
270
+ abc 123
271
+ this is a test
272
+ .. whether at beginning, middle, or
273
+ more stuff
274
+ still more stuff
275
+ .. end of the file
276
+ </pre>
277
+ </td>
278
+ <td width=50% bgcolor=lightgray valign=top>
279
+ <pre> abc 123
280
+ this is a test
281
+ more stuff
282
+ still more stuff
283
+ </pre>
284
+ </td>
285
+ </tr>
286
+ </table>
287
+ </center>
288
+
289
+ <b>Test: <tt>004\_sigil\_can\_change</tt></b><br>
290
+ <center>
291
+ <table width=80% cellpadding=4>
292
+ <tr>
293
+ <td width=50%><b>Input</b></td>
294
+ <td width=50%><b>Output</b></td>
295
+ </tr>
296
+ <tr>
297
+ <td width=50% bgcolor=#fec0fe valign=top>
298
+ <pre> . This is a comment
299
+ .sigil #
300
+ # Comments are ignored
301
+ abc 123
302
+ this is a test
303
+ . this is not a comment
304
+ # whether at beginning, middle, or
305
+ more stuff
306
+ .this means nothing
307
+ still more stuff
308
+ # end of the file
309
+ </pre>
310
+ </td>
311
+ <td width=50% bgcolor=lightgray valign=top>
312
+ <pre> abc 123
313
+ this is a test
314
+ . this is not a comment
315
+ more stuff
316
+ .this means nothing
317
+ still more stuff
318
+ </pre>
319
+ </td>
320
+ </tr>
321
+ </table>
322
+ </center>
323
+
324
+ <b>Test: <tt>005\_block\_comment</tt></b><br>
325
+ <center>
326
+ <table width=80% cellpadding=4>
327
+ <tr>
328
+ <td width=50%><b>Input</b></td>
329
+ <td width=50%><b>Output</b></td>
330
+ </tr>
331
+ <tr>
332
+ <td width=50% bgcolor=#fec0fe valign=top>
333
+ <pre> .comment
334
+ This is
335
+ a comment
336
+ .end
337
+ abc 123
338
+ xyz
339
+ .comment
340
+ And so is this.
341
+ .end
342
+
343
+ one
344
+ more
345
+ time
346
+ .comment
347
+ And so
348
+ is
349
+ this
350
+ .end
351
+ </pre>
352
+ </td>
353
+ <td width=50% bgcolor=lightgray valign=top>
354
+ <pre> abc 123
355
+ xyz
356
+
357
+ one
358
+ more
359
+ time
360
+ </pre>
361
+ </td>
362
+ </tr>
363
+ </table>
364
+ </center>
365
+
366
+ <b>Test: <tt>006\_def\_method</tt></b><br>
367
+ <center>
368
+ <table width=80% cellpadding=4>
369
+ <tr>
370
+ <td width=50%><b>Input</b></td>
371
+ <td width=50%><b>Output</b></td>
372
+ </tr>
373
+ <tr>
374
+ <td width=50% bgcolor=#fec0fe valign=top>
375
+ <pre> abc
376
+ 123
377
+ .def foobar
378
+ ::STDERR.puts "This is the"
379
+ ::STDERR.puts "foobar method"
380
+ .end
381
+ xyz
382
+ .foobar
383
+ xyzzy
384
+ 123
385
+ </pre>
386
+ </td>
387
+ <td width=50% bgcolor=lightgray valign=top>
388
+ <pre> abc
389
+ 123
390
+ xyz
391
+ xyzzy
392
+ 123
393
+ </pre>
394
+ </td>
395
+ </tr>
396
+ </table>
397
+ </center>
398
+
399
+ <b>Test: <tt>007\_simple\_vars</tt></b><br>
400
+ <center>
401
+ <table width=80% cellpadding=4>
402
+ <tr>
403
+ <td width=50%><b>Input</b></td>
404
+ <td width=50%><b>Output</b></td>
405
+ </tr>
406
+ <tr>
407
+ <td width=50% bgcolor=#fec0fe valign=top>
408
+ <pre> Just
409
+ some text.
410
+ .set name=GulliverFoyle,nation=Terra
411
+ Hi, there.
412
+ $name is my name, and $nation is my nation.
413
+ I'm $name, from $nation.
414
+ That's all.
415
+ </pre>
416
+ </td>
417
+ <td width=50% bgcolor=lightgray valign=top>
418
+ <pre> Just
419
+ some text.
420
+ Hi, there.
421
+ GulliverFoyle is my name, and Terra is my nation.
422
+ I'm GulliverFoyle, from Terra.
423
+ That's all.
424
+ </pre>
425
+ </td>
426
+ </tr>
427
+ </table>
428
+ </center>
429
+
430
+ <b>Test: <tt>008\_simple\_include</tt></b><br>
431
+ <center>
432
+ <table width=80% cellpadding=4>
433
+ <tr>
434
+ <td width=50%><b>Input</b></td>
435
+ <td width=50%><b>Output</b></td>
436
+ </tr>
437
+ <tr>
438
+ <td width=50% bgcolor=#fec0fe valign=top>
439
+ <pre> Here I am
440
+ trying to
441
+ include
442
+ .include simplefile.inc
443
+ I hope that
444
+ worked.
445
+ </pre>
446
+ </td>
447
+ <td width=50% bgcolor=lightgray valign=top>
448
+ <pre> Here I am
449
+ trying to
450
+ include
451
+ a simple
452
+ include file.
453
+ I hope that
454
+ worked.
455
+ </pre>
456
+ </td>
457
+ </tr>
458
+ </table>
459
+ </center>
460
+
461
+ <b>Test: <tt>009\_simple\_mixin</tt></b><br>
462
+ <center>
463
+ <table width=80% cellpadding=4>
464
+ <tr>
465
+ <td width=50%><b>Input</b></td>
466
+ <td width=50%><b>Output</b></td>
467
+ </tr>
468
+ <tr>
469
+ <td width=50% bgcolor=#fec0fe valign=top>
470
+ <pre> Here I am
471
+ testing a simple mixin
472
+ .mixin simple\_mixin
473
+ Now call it:
474
+ .hello\_world
475
+ That's all.
476
+ </pre>
477
+ </td>
478
+ <td width=50% bgcolor=lightgray valign=top>
479
+ <pre> Here I am
480
+ testing a simple mixin
481
+ Now call it:
482
+ Hello, world.
483
+ That's all.
484
+ </pre>
485
+ </td>
486
+ </tr>
487
+ </table>
488
+ </center>
489
+
490
+ <b>Test: <tt>010\_simple\_copy</tt></b><br>
491
+ <center>
492
+ <table width=80% cellpadding=4>
493
+ <tr>
494
+ <td width=50%><b>Input</b></td>
495
+ <td width=50%><b>Output</b></td>
496
+ </tr>
497
+ <tr>
498
+ <td width=50% bgcolor=#fec0fe valign=top>
499
+ <pre> The copy command
500
+ copies any file
501
+ without interpretation,
502
+ such as:
503
+ .copy simplefile.inc
504
+ That is all.
505
+ </pre>
506
+ </td>
507
+ <td width=50% bgcolor=lightgray valign=top>
508
+ <pre> The copy command
509
+ copies any file
510
+ without interpretation,
511
+ such as:
512
+ a simple
513
+ include file.
514
+ That is all.
515
+ </pre>
516
+ </td>
517
+ </tr>
518
+ </table>
519
+ </center>
520
+
521
+ <b>Test: <tt>011\_copy\_is\_raw</tt></b><br>
522
+ <center>
523
+ <table width=80% cellpadding=4>
524
+ <tr>
525
+ <td width=50%><b>Input</b></td>
526
+ <td width=50%><b>Output</b></td>
527
+ </tr>
528
+ <tr>
529
+ <td width=50% bgcolor=#fec0fe valign=top>
530
+ <pre> A copy command
531
+ does not interpret its input:
532
+ .copy rawtext.inc
533
+ That's all.
534
+ </pre>
535
+ </td>
536
+ <td width=50% bgcolor=lightgray valign=top>
537
+ <pre> A copy command
538
+ does not interpret its input:
539
+ This is not a comment:
540
+ .comment woohoo!
541
+ This is not a method:
542
+ .no\_such\_method
543
+ That's all.
544
+ </pre>
545
+ </td>
546
+ </tr>
547
+ </table>
548
+ </center>
549
+
550
+ <b>Test: <tt>012\_raw\_text\_block</tt></b><br>
551
+ <center>
552
+ <table width=80% cellpadding=4>
553
+ <tr>
554
+ <td width=50%><b>Input</b></td>
555
+ <td width=50%><b>Output</b></td>
556
+ </tr>
557
+ <tr>
558
+ <td width=50% bgcolor=#fec0fe valign=top>
559
+ <pre> This text block will be passed thru
560
+ with no interpretation or processing:
561
+ .raw
562
+ .comment
563
+ This isn't a
564
+ real comment.
565
+ .end This isn't picked up.
566
+
567
+ .not\_a\_method
568
+
569
+ And this stuff won't be munged: `alpha \_beta *gamma
570
+ Or this: `(alpha male) \_(beta max) *(gamma rays)
571
+ \_\_EOF\_\_
572
+
573
+ I hope that worked.
574
+ </pre>
575
+ </td>
576
+ <td width=50% bgcolor=lightgray valign=top>
577
+ <pre> This text block will be passed thru
578
+ with no interpretation or processing:
579
+ .comment
580
+ This isn't a
581
+ real comment.
582
+ .end This isn't picked up.
583
+
584
+ .not\_a\_method
585
+
586
+ And this stuff won't be munged: `alpha \_beta *gamma
587
+ Or this: `(alpha male) \_(beta max) *(gamma rays)
588
+
589
+ I hope that worked.
590
+ </pre>
591
+ </td>
592
+ </tr>
593
+ </table>
594
+ </center>
595
+
596
+ <br><br><b><font size=+1>Writing custom methods</font></b><br>
597
+
598
+ Suppose you wanted to write a method called <tt>chapter</tt> that would simply
599
+ output a chapter number and title with certain heading tags and a
600
+ horizontal rule following. There is more than one way to do this.
601
+
602
+ The simplest way is just to define a method inline with the rest of
603
+ the text. Here's an example.
604
+
605
+ <pre>
606
+ .comment
607
+ This example shows how to define
608
+ a simple method &quot;chapter&quot; inline
609
+ .end
610
+
611
+ . This is also a comment, by the way.
612
+ .def chapter
613
+ params = _args
614
+ raise &quot;chapter: expecting at least two args&quot; unless params.size &gt; 1
615
+ num, *title = params # Chapter number + title
616
+ title = title.join(&quot; &quot;) # Join all words into one string
617
+ text = &lt;&lt;-HTML
618
+ &lt;h3&gt;Chapter #{num}&lt;/h3&gt;
619
+ &lt;h2&gt;#{title}&lt;/h2&gt;
620
+ &lt;hr&gt;
621
+ HTML
622
+ _puts text
623
+ .end
624
+ . Now let&#39;s invoke it...
625
+ .chapter 1 Why I Went to the Woods
626
+ It was the best of times, and you can call me Ishmael. The clocks
627
+ were striking thirteen.
628
+ </pre>
629
+
630
+ What can we see from this example? First of all, notice that the part
631
+ between <tt>.def</tt> and <tt>.end</tt> (the body of the method) really is just Ruby
632
+ code. The method takes no parameters because parameter passing is
633
+ handled inside the Livetext engine and the instance variable <tt>@_args</tt> is
634
+ initialized to the contents of this array. We usually refer to the
635
+ <tt>@_args</tt> array only through the method <tt>_args</tt> which returns it.
636
+
637
+ The <tt>_args</tt> method is also an iterator. If a block is attached, that block
638
+ will be called for every argument.
639
+
640
+ We then create a string using these parameters and call it using the
641
+ <tt>_puts</tt> method. This really does do a <tt>puts</tt> call, but it applies it to
642
+ wherever the output is currently being sent (defaulting to STDOUT).
643
+
644
+ All the "helper" methods start with an underscore so as to avoid name
645
+ collisions. These are all stored in the <tt>Livetext::Helpers</tt> module
646
+ (which also has some methods you will never use).
647
+
648
+ Here is the HTML output of the previous example:
649
+
650
+ <pre>
651
+ &lt;h3&gt;Chapter 1&lt;/h3&gt;
652
+ &lt;h2&gt;Why I Went to the Woods&lt;/h2&gt;
653
+ &lt;hr&gt;
654
+ It was the best of times, and you can call me Ishmael. The clocks
655
+ were striking thirteen.
656
+ </pre>
657
+
658
+ What are some other helper methods? Here's a list.
659
+
660
+ <table>
661
+ <tr>
662
+ <td width=3%><td width=10%><tt>_args</tt> </td><td> Returns an array of arguments for the method (or an enumerator for that array)
663
+ </td>
664
+ </tr>
665
+ <tr>
666
+ <td width=3%><td width=10%><tt>_data</tt> </td><td> A single "unsplit" string of all arguments in raw form
667
+ </td>
668
+ </tr>
669
+ <tr>
670
+ <td width=3%><td width=10%><tt>_body</tt> </td><td> Returns a string (or enumerator) giving access to the text block (preceding <tt>.end</tt>)
671
+ </td>
672
+ </tr>
673
+ <tr>
674
+ <td width=3%><td width=10%><tt>_puts</tt> </td><td> Write a line to output (STDOUT or wherever)
675
+ </td>
676
+ </tr>
677
+ <tr>
678
+ <td width=3%><td width=10%><tt>_print</tt> </td><td> Write a line to output (STDOUT or wherever) without a newline
679
+ </td>
680
+ </tr>
681
+ <tr>
682
+ <td width=3%><td width=10%><tt>_formatting</tt> </td><td> A function transforming boldface, italics, and monospace (Livetext conventions)
683
+ </td>
684
+ </tr>
685
+ <tr>
686
+ <td width=3%><td width=10%><tt>_var_substitution</tt> </td><td> Substitute variables into a string
687
+ </td>
688
+ </tr>
689
+ <tr>
690
+ <td width=3%><td width=10%><tt>_passthru</tt> </td><td> Feed a line directly into output after transforming and substituting
691
+ </td>
692
+ </tr>
693
+ </table>
694
+
695
+ Note that the last three methods are typically <i>not</i> called in your own code. They could be,
696
+ but it remains to be seen whether something that advanced is useful.
697
+
698
+ <br><br><b><font size=+1>More examples</font></b><br>
699
+
700
+ Suppose you wanted to take a list of words, more than one per line, and alphabetize them.
701
+ Let's write a method called <tt>alpha</tt> for that. This exercise and the next one are implemented
702
+ in the test suite.
703
+
704
+
705
+ <b>Test: <tt>013\_example\_alpha</tt></b><br>
706
+ <center>
707
+ <table width=80% cellpadding=4>
708
+ <tr>
709
+ <td width=50%><b>Input</b></td>
710
+ <td width=50%><b>Output</b></td>
711
+ </tr>
712
+ <tr>
713
+ <td width=50% bgcolor=#fec0fe valign=top>
714
+ <pre> .def alpha
715
+ text = \_body.join
716
+ text.gsub!(/\n/, " ")
717
+ words = text.split.sort
718
+ words.each {|w| \_puts " #{w}" }
719
+ .end
720
+ Here is an alphabetized list:
721
+
722
+ .alpha
723
+ fishmonger anarchist aardvark glyph gryphon
724
+ halcyon zymurgy mataeotechny zootrope
725
+ pareidolia manicotti quark bellicose anamorphic
726
+ cytology fusillade ectomorph
727
+ .end
728
+
729
+ I hope that worked.
730
+ </pre>
731
+ </td>
732
+ <td width=50% bgcolor=lightgray valign=top>
733
+ <pre> Here is an alphabetized list:
734
+
735
+ aardvark
736
+ anamorphic
737
+ anarchist
738
+ bellicose
739
+ cytology
740
+ ectomorph
741
+ fishmonger
742
+ fusillade
743
+ glyph
744
+ gryphon
745
+ halcyon
746
+ manicotti
747
+ mataeotechny
748
+ pareidolia
749
+ quark
750
+ zootrope
751
+ zymurgy
752
+
753
+ I hope that worked.
754
+ </pre>
755
+ </td>
756
+ </tr>
757
+ </table>
758
+ </center>
759
+
760
+ I'll let that code stand on its own. Now suppose you wanted to allow columnar output. Let's
761
+ have the user specify a number of columns (from 1 to 5, defaulting to 1).
762
+
763
+
764
+ <b>Test: <tt>014\_example\_alpha2</tt></b><br>
765
+ <center>
766
+ <table width=80% cellpadding=4>
767
+ <tr>
768
+ <td width=50%><b>Input</b></td>
769
+ <td width=50%><b>Output</b></td>
770
+ </tr>
771
+ <tr>
772
+ <td width=50% bgcolor=#fec0fe valign=top>
773
+ <pre> .def alpha
774
+ cols = \_args.first
775
+ cols = "1" if cols == ""
776
+ cols = cols.to\_i
777
+ raise "Columns must be 1-5" unless cols.between?(1,5)
778
+ text = \_body.join
779
+ text.gsub!(/\n/, " ")
780
+ words = text.split.sort
781
+ words.each\_slice(cols) do |row|
782
+ row.each {|w| \_print '%-15s' % w }
783
+ \_puts
784
+ end
785
+ .end
786
+ Here is an alphabetized list:
787
+
788
+ .alpha 3
789
+ fishmonger anarchist aardvark glyph gryphon
790
+ halcyon zymurgy mataeotechny zootrope
791
+ pareidolia manicotti quark bellicose anamorphic
792
+ cytology fusillade ectomorph
793
+ .end
794
+
795
+ I hope that worked a second time.
796
+ </pre>
797
+ </td>
798
+ <td width=50% bgcolor=lightgray valign=top>
799
+ <pre> Here is an alphabetized list:
800
+
801
+ aardvark anamorphic anarchist
802
+ bellicose cytology ectomorph
803
+ fishmonger fusillade glyph
804
+ gryphon halcyon manicotti
805
+ mataeotechny pareidolia quark
806
+ zootrope zymurgy
807
+
808
+ I hope that worked a second time.
809
+ </pre>
810
+ </td>
811
+ </tr>
812
+ </table>
813
+ </center>
814
+
815
+ What if we wanted to store the code outside the text file? There is more than one way to
816
+ do this.
817
+
818
+ Let's assume we have a file called <tt>mylib.rb</tt> in the same directory as the file we're processing.
819
+ (Issues such as paths and security have not been addressed yet.) We'll stick the actual Ruby code
820
+ in here (and nothing else).
821
+
822
+ <pre>
823
+ # File: mylib.rb
824
+
825
+ def alpha
826
+ cols = _args.first
827
+ cols = &quot;1&quot; if cols == &quot;&quot;
828
+ cols = cols.to_i
829
+ raise &quot;Columns must be 1-5&quot; unless cols.between?(1,5)
830
+ text = _body.join
831
+ text.gsub!(/\n/, &quot; &quot;)
832
+ words = text.split.sort
833
+ words.each_slice(cols) do |row|
834
+ row.each {|w| _print &#39;%-15s&#39; % w }
835
+ _puts
836
+ end
837
+ end
838
+ </pre>
839
+
840
+ Now the <tt>.lt</tt> file can be written this way:
841
+
842
+ <pre>
843
+ .mixin mylib
844
+ Here is an alphabetized list:
845
+
846
+ .alpha 3
847
+ fishmonger anarchist aardvark glyph gryphon
848
+ halcyon zymurgy mataeotechny zootrope
849
+ pareidolia manicotti quark bellicose anamorphic
850
+ cytology fusillade ectomorph
851
+ .end
852
+
853
+ I hope that worked a second time.
854
+ </pre>
855
+
856
+ The output, of course, is the same.
857
+
858
+ There is an important feature that has not yet been implemented (the
859
+ <tt>require</tt> method). Like Ruby's <tt>require</tt>, it will grab Ruby code and
860
+ load it; however, unlike <tt>mixin</tt>, it will load it into a customized
861
+ object and associate a new sigil with it. So for example, the command
862
+ <tt>.foobar</tt> would refer to a method in the <tt>Livetext::Standard</tt> class
863
+ (whether predefined or user-defined). If we did a <tt>require</tt> on a file
864
+ and associated the sigil <tt>#</tt> with it, then <tt>#foobar</tt> would be a method
865
+ on that new custom object. I will implement this soon.
866
+
867
+ <br><br><b><font size=+1>Issues, open questions, and to-do items</font></b><br>
868
+
869
+ This list is not prioritized yet.
870
+
871
+ <ol>
872
+ <li>Add versioning information
873
+ </li>
874
+ <li>Clean up code structure
875
+ </li>
876
+ <li>Add RDoc
877
+ </li>
878
+ <li>Think about command line executable
879
+ </li>
880
+ <li>Write as pure library in addition to executable
881
+ </li>
882
+ <li>Package as gem
883
+ </li>
884
+ <li>Document: <tt>require</tt> `include <tt>copy</tt> `mixin <tt>errout</tt> and others
885
+ </li>
886
+ <li>Need much better error checking and corresponding tests
887
+ </li>
888
+ <li>Worry about nesting of elements (probably mostly disallow)
889
+ </li>
890
+ <li>Think about UTF-8
891
+ </li>
892
+ <li>Document API fully
893
+ </li>
894
+ <li>Add <tt>_raw_args</tt> and let <tt>_args</tt> honor quotes
895
+ </li>
896
+ <li>Support quotes in <tt>.set</tt> values
897
+ </li>
898
+ <li>Support "namespaced" variables (`(.set code.font="whatever"))
899
+ </li>
900
+ <li>Support functions (`($$func)) including namespacing
901
+ </li>
902
+ <li>Create predefined variables and functions (e.g., <tt>$_source_file</tt>, <tt>$(_line),</tt> <tt>$$_today</tt>)
903
+ </li>
904
+ <li>Support markdown-style bold/italics? (`_markdown replaces <tt>_formatting</tt> method)
905
+ </li>
906
+ <li>Allow turning on/off: formatting, variable interpolation, function interpolation?
907
+ </li>
908
+ <li><tt>.require</tt> with file and sigil parameters
909
+ </li>
910
+ <li>Comments passed through (e.g. as HTML comments)
911
+ </li>
912
+ <li><tt>.run</tt> to execute arbitrary Ruby code inline?
913
+ </li>
914
+ <li>Concept of <tt>.proc</tt> (guaranteed to return no value, produce no output)?
915
+ </li>
916
+ <li>Exceptions??
917
+ </li>
918
+ <li>Ruby <tt>$SAFE</tt> levels?
919
+ </li>
920
+ <li>Warn when overriding existing names?
921
+ </li>
922
+ <li>Think about passing data in (erb replacement)
923
+ </li>
924
+ <li>Allow custom ending tag on <tt>raw</tt> method
925
+ </li>
926
+ <li>Ignore first blank line after <tt>.end</tt>? (and after raw-tag?)
927
+ </li>
928
+ <li>Allow/encourage custom <tt>passthru</tt> method?
929
+ </li>
930
+ <li>Must have sane support for CSS
931
+ </li>
932
+ <li>Support for Pygments and/or other code processors
933
+ </li>
934
+ <li>Support for gists? arbitrary links? other remote resouces?
935
+ </li>
936
+ <li>Small libraries for special purposes (books? special Softcover support? blogs? PDF? RMagick?)
937
+ </li>
938
+ <li>Experiment with idea of special libraries having pluggable output formats (via Ruby mixin?)
939
+ </li>
940
+ <li>Imagining a lib that can run/test code fragments as part of document generation
941
+ </li>
942
+ <li>Create vim (emacs?) syntax files
943
+ </li>
944
+ <li>Someday: Support other languages (Elixir, Python, ...)
945
+ </li>
946
+ <li><tt>.pry</tt> method?
947
+ </li>
948
+ <li><tt>.irb</tt> method?
949
+ </li>
950
+ <li>Other debugging features
951
+ </li>
952
+ <li>Feature to "break" to EOF?
953
+ </li>
954
+ <li><tt>.meth?</tt> method ending in <tt>?</tt> takes a block that may be processed or thrown away (`(.else) perhaps?)
955
+ </li>
956
+ <li><tt>.dump</tt> to dump all variables and their values
957
+ </li>
958
+ <li><tt>.if</tt> and <tt>.else</tt>?
959
+ </li>
960
+ <li>Make any/all delimiters configurable
961
+ </li>
962
+ <li>HTML helper? (in their own library?)
963
+ </li>
964
+ </ol>
965
+