livetext 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
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
+