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