3.6 KiB
toad.md
the pro toad and superb owl comic generator
about
This program reads a script file and interpolates its contents with some ascii art, and then writes the result to stdout.
The end goal is automating the creation of Pro Toad and Superb Owl comics.
usage
$ retro toad.md path/to/script.txt > comic.txt
components
the components of the program are:
-
IO - open the text file, read it line by line, close the file, write to stdout
-
input parser - there are 2 line types in the script file:
- a text line, and
- a separator line: a special
---
line to separate panels.
-
comic builder - build the first panel, the second panel (no input needed, just output tanel 2), and the 3rd panel (repeat steps needed for 1st panel)
-
panel builder - for as long as art array has length, and as long as the current input line has length or until the input parser hits the separator line or the end of the file, call the line builder with the next line of the art array (if there is one) and the input line.
If the input line has no length, and the next line is not the separator, have the line builder insert a "blank line" and get a new input line.
-
line builder - given two strings, build a new string containing the first, and appending words from the second up to a total of ~80 cols.
argument validation
print a helpful message if the script is called without an argument
TODO: is script:get-argument
an array? check to see if length equal zero
'ARGS s:put nl
script:get-argument a:length n:put
panels
okay let's go
There are two panels: one where toad speaks, and one where owl speaks. Let's save each to an array, one string per line.
Here's toad (panels 1 & 3):
'toad var
{
'_(@)(@)_____{0,0}__
'_(~~~~)____./)_)___
'_(>vv<)______"_"___
'___________________
'_____\_____________
} !toad
Here's owl (panel 2):
'owl var
{
'_(@)(@)_____{0,0}__--_Hoo?
'_(~~~~)____./)_)__________
'_(>vv<)______"_"__________
} !owl
Also here are some code fences, because we'll need those too:
:fences '``` s:put nl ;
Input/output
open the file for reading and save the file handle to file
save the file fize. we'll use this to check for end of file.
'handle var
'size var
#0 script:get-argument
file:open-for-reading !handle !size
:get-line @handle file:read-line ;
Input Parser
TODO: this isn't tested or used anywhere yet.
{{
:end-of-file? (-) @handle file:tell @size gteq? ;
:separator? (m-f) '--- eq? ;
---reveal---
:end-of-section? (-f) separator? end-of-file? or ;
}}
Line wrapping
Here's a line wrapping module.
{{
#0 'displayed var-n
#40 'wrap-at var-n
:wrap? dup @displayed + @wrap-at gt? ;
:display [ nl !displayed ] [ displayed v:inc-by ] choose s:put sp ;
---reveal---
:s:put-wrapped (s-) ASCII:SPACE s:tokenize
[ dup s:length wrap? display ] a:for-each
#0 !displayed ;
}}
src:
https://github.com/crcx/retroforth/blob/master/example/wordwrap.retro
Panel 1
print out the first panel
ascii art:
fences
@toad [ s:put nl ] a:for-each
text:
[
get-line
dup s:put-wrapped
'--- s:eq? not
dup [ nl nl ] if
] while
nl fences nl nl
TODO: don't print ---
line.
Panel 2
fences
@owl [ s:put nl ] a:for-each
fences nl nl
Panel 3
print the ascii:
fences
@toad [ s:put nl ] a:for-each
print the text:
[
get-line dup s:put-wrapped
#0
dup [ nl nl ] if
] while
nl fences
drop
TODO: loop till end of file
Conclusion
That's all! That's the end