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
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>