First upload
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
# Textereo: ASCII stereogram generator in AWK
|
||||
# Usage: [busybox] awk -f textereo.awk map.txt
|
||||
# Map format:
|
||||
# First line: [desired width] [maxpattern length]
|
||||
# Second line: alphabet (allowed characters to generate patterns from)
|
||||
# Next H lines: depth map, W digits from 0 to 7 without spaces
|
||||
# You can insert single zeros or empty lines into the map to adjust height
|
||||
#
|
||||
# Created by Luxferre in 2023, released into public domain
|
||||
|
||||
function dchar(str, pos) { # delete a character from str at position pos
|
||||
if(!pos) return str
|
||||
else return substr(str, 1, pos - 1) substr(str, pos + 1)
|
||||
}
|
||||
|
||||
function ichar(str, pos, c) { # insert a character c into str at position pos
|
||||
return substr(str, 1, pos - 1) c substr(str, pos)
|
||||
}
|
||||
|
||||
BEGIN { # we use 95-character subset from ASCII by default
|
||||
"date +%N"|getline rseed;srand(rseed) # init the PRNG
|
||||
getline # read the first line from the file to parse parameters
|
||||
WIDTH = int($1) # desired width of the image to generate
|
||||
PATLEN = int($2) # generated pattern length (must be between 8 and W/2)
|
||||
getline # read the full character set
|
||||
CHARSET = $0
|
||||
CHRANGE = length(CHARSET)
|
||||
if(WIDTH == 0) WIDTH = 78
|
||||
if(PATLEN < 8 || PATLEN > (WIDTH/2)) PATLEN = 10 # 10 to 15 is optimal
|
||||
}
|
||||
|
||||
{ # process the map itself
|
||||
j = 0 # set the secondary counter to store previous value
|
||||
FREEBUF = CHARSET # start with the full charset
|
||||
PATBUF = "" # start with empty pattern buffer
|
||||
mapline = $0 # cache the map line
|
||||
RWIDTH = length(mapline); # real pattern width
|
||||
tlen = (WIDTH - RWIDTH) / 2 # trailer AND header length
|
||||
for(i=0;i<tlen;i++) mapline = "0" mapline "0" # grow the line to the width
|
||||
if(length(mapline) > WIDTH) mapline = substr(mapline, 1, WIDTH)
|
||||
for(i=0;i<PATLEN;i++) { # fill in the pattern buffer
|
||||
do # we can repeat the characters in the pattern but not immediately
|
||||
pbc = substr(CHARSET, 1+int(rand()*CHRANGE), 1)
|
||||
while(pbc == j || !length(pbc)) # don't allow empty or repeating chars
|
||||
PATBUF = PATBUF pbc # concatenate the character to the pattern
|
||||
j = pbc # save as the previous value to j
|
||||
# delete this character from the unused buffer
|
||||
FREEBUF = dchar(FREEBUF, index(FREEBUF, pbc))
|
||||
}
|
||||
j = 0 # reset the secondary counter
|
||||
prevlen = PATLEN # cache the previous pattern length
|
||||
maplen = length(mapline)
|
||||
patpos = 0 # track pattern position
|
||||
for(i=0;++i<=maplen;) { # iterate over every character
|
||||
curlen = PATLEN - int(substr(mapline, i, 1)) # extract depth value and length
|
||||
delta = curlen - prevlen
|
||||
if(delta > 0) # add unused characters if decreasing depth value
|
||||
for(j=0;j<delta;j++) {
|
||||
ri = 1+int(rand()*length(FREEBUF)) # get random index
|
||||
rc = substr(FREEBUF, ri, 1) # retrieve the character
|
||||
FREEBUF = dchar(FREEBUF, ri) # delete it from the buffer
|
||||
PATBUF = ichar(PATBUF, 1+patpos, rc) # insert it here
|
||||
}
|
||||
else if(delta < 0) # remove characters if increasing depth value
|
||||
for(j=0;j<-delta;j++)
|
||||
PATBUF = dchar(PATBUF, 1+patpos)
|
||||
prevlen = curlen # update the previous length
|
||||
# now, output the current pattern character
|
||||
printf("%c", substr(PATBUF, 1 + (patpos % curlen), 1))
|
||||
patpos = (patpos + 1) % curlen # update pattern position
|
||||
}
|
||||
printf("\n")
|
||||
}
|
||||
Reference in New Issue
Block a user