Register Guidelines E-Books Search Today's Posts Mark Forums Read

Go Back   MobileRead Forums > E-Book Readers > Amazon Kindle > Kindle Developer's Corner

Notices

Reply
 
Thread Tools Search this Thread
Old 03-27-2012, 12:56 PM   #46
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Quote:
Originally Posted by kaminkatze View Post
I feel like I'm not ready for a cross-compiled language (besides I never really used C).

This is how far I got (with the eips calls, thus same update speed) .

Run it with gameoflife savegame.png
The image is loaded via eips -g. The topmost row and leftmost column indicate the field position.
I am thinking about breaking my individual functions (line, circle, etc.) into individual script files instead of a monolithic (one file) script.

Also, I am considering writing a replacement for eips that lets you do partial updates (specifying the corner coordinates of the update area). I was thinking I should call it "eoops".

That way, I can replace individual scripts with compiled C versions that are identical in function (but a lot faster). The first scripts to update to C should be the line and circle functions. That way, existing scripts will not need any changes to run faster (other than removing the embedded functions and adding my "graphics library" folder to the search PATH env var).

Thanks for the source code. I will check it out later when I have more time. I like the nice anti-aliased splash screen. Personally, I like mapped memory calls instead of fread and fseek -- you can just treat the framebuffer as a large memory array. There is some sample code posted somewhere here...

Last edited by geekmaster; 03-27-2012 at 01:03 PM.
geekmaster is offline   Reply With Quote
Old 03-28-2012, 01:31 AM   #47
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Quote:
Originally Posted by kaminkatze View Post
echo ${v:1:1} returns -sh: syntax error: Bad substitution on my K3, and expr substr $v 1 1 is even slower than hexdump.

Here is a ev[ia]l array style version.
eval "v=\$A${x}x$y".
...
See how the "cut" method for K3 substrings compares to your other methods. I used it here:
geekmaster is offline   Reply With Quote
Old 04-01-2012, 03:56 PM   #48
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Arrow titty - tiny tty

UPDATE: v1.4 tested and works great on DX, DXG, K3, K4, and Touch!



titty

titty - tiny tty (display tiny text on eink display)

requirements: titty.png.

usage:
"titty" cat self
"
ls -al|titty -" cat STDIN (from "ls" in this example)
"
titty /etc/shadow" PWN!

hint: This runs at TTY speed.
PHP Code:
#!/bin/sh
#=============================
# titty - tiny tty (v1.4)
# display tiny text on eink
# requirements: titty.png.
# usage:
#   titty
#     cat self
#   titty [x y] [-k] [--] -|STRING|-f FILE
#     displays "STDIN", "echo STRING" or "cat FILE"
#       [x y]  initialize cursor at x y
#       [-k]   clear lines
#       [--]   treat as string
#   titty -s Y H S
#     move H-S lines S lines up, beginning with line Y+S
#   titty -mx|-my
#     return maximal x y coordinates
#   titty -v
#     return version
# hint: This runs at TTY speed.
#------------------------------
# Copyright (C) 2012 geekmaster
# MIT License: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#------------------------------
# Revision History (last change first):
# =ver= =date===== =author===== =description============================
# 1.4   2012-04-05 geekmaster   fix "end of page" bug
# 1.3   2012-04-05 kaminkatze   scrolling and options
# 1.2   2012-04-04 kaminkatze   k3 support and per line hexdump
# 1.1   2012-04-01 geekmaster   first release

# WARNING: If you don't stop using titty, you will go blind! :D

#===========================
# initvar - init global vars
#---------------------------
initvar() {
  
V=1.4 # version
  
eips -"$0.png" # char map image
  
DN=/dev/null DF=/dev/fb0 # devices
  
set $(eips -i|grep res:); FW=$2 FH=$# fb0 width, height
  
set $(eips -i|grep line); FS=$# fb0 stride
  
CW=$((4*FS/FW)) CH=6 LH=# char width, height, line height
  
LM=2 TM=$((CH*2)) # left, top margin px
  
MX=$((FW*FS/FW-CW)) MY=$((FH-LH)) # max X, Y
  
CX=$LM CY=$TM # cursor coords
  
DD="dd if=$DF of=$DF bs=1 count=$CW# ddblit
  
DL="dd if=$DF of=$DF bs=1 count=$((FS*CH)) skip=$((FS*CH))" # clear line
  
Q=false # quit flag
  
K=false # clear line flag
  
JFS=$IFS # normal field separator
}

#====================
# usage: scroll y h s
#--------------------
scroll() {
  
dd if=$DF of=$DF bs=1 count=$((FS*LH*($2-$3))) \
    
skip=$((FS*(LH*($1+$3)+TM))) seek=$((FS*(LH*$1+TM))) 2>$DN
  eips 
''
}

#=================
# titty - tiny tty
# displays STDIN
#------------------
titty() {
  
until $Q ;do IFS='\n'read L || Q=trueIFS=$JFS
    
for A in $(echo -"$Lhexdump -ve '/1 "%d\n"'); do
      if [[ 
$A -ne 32 ]]; then
        RO
=$(((A-32)*CW)) FO=$((CY*FS+CX))
        for 
y in $(seq 1 $CH);do
          
$DD skip=$RO seek=$FO 2>$DNRO=$((RO+FS)) FO=$((FO+FS))
        
done
      fi
CX=$((CX+CW)); [[ $((CX%64)) -eq $LM ]] && eips ''
      
if [[ $CX -gt $MX ]]; then CX=$LM CY=$((CY+LH))
        [[ 
$CY -gt $MY ]] && CY=$TM CX=$LM
        $K 
&& $DL seek=$((CY*FS)) 2>$DNfi
    done
eips ''
    
CX=$LM CY=$((CY+LH)); [[ $CY -gt $MY ]] && break
    
$K && $DL seek=$((CY*FS)) 2>$DN
  done
}

# Do stuff!  :-)
initvar
if [[ "$1" == "" ]]; then cat "$0"|titty
else while [[ "$1" ]]; do
  case 
"$1" in
    
-sscroll $$$4shift;shift;shift;shift;;
    -
mx) echo $((FS/CW-CW)); shift;;
    -
my) echo $MLshift;;
    -
fcat "$2"|tittyshift;shift;;
    -) 
tittyshift;;
    -
k) if [[ $CX -eq $LM ]]; then $DL seek=$((CY*FS)) 2>$DN
        
else for y in $(seq 0 $((CH-1))); do
          
dd if=$DF of=$DF bs=1 count=$((FS-CX)) \
            
skip=$((FS*CH)) seek=$(((CY+y)*FS+CX)) 2>$DN
        done
fiK=trueshift;;
    --) echo -
"$2"|tittyshift;shift;;
    -
v) echo $Vshift;;
    *) if [[ -
"$3" ]]
       
then CX=$((LM+$1*CW)) CY=$((TM+$2*LH)); shift;shift
       
else echo -"$1"|tittyshift
       fi
;;
  
esac
done
fi 
This script requires the "titty.png" file shown below, and included in the download file along with the script. This image contains a complete set of 128 ASCII characters, used to display text on the eink display. This is a VERY TINY font, just to show that we CAN do this. I also have a version with an 8 pt Courier font, which I will release later.

WARNING: As shown below, the text is REALLY TINY, and even near-sighted people may need magnifying reading glasses to see it clearly on a real eink display, where it is a LOT smaller than on a typical LCD panel where you may be viewing this. Reading text at that size is a difficult task for eyes. (But think of all the text you could cram onto a screensaver image using this script, such as crib notes for an exam, with no batteries needed .) And it is cool watching it too, ESPECIALLY considering that it is all being done with just some clever little /bin/sh kung fu mojo and a few built-in linux commands, IMHO...

titty.png:
(The tiny low-resolution characters shown above actually look a lot better on the smaller kindle eink display, or from a distance on a large LCD display, due to visual perception properties.)

Here are some screen captures
from a kindle touch eink display
showing "titty" in action:
Spoiler:
./titty

Spoiler:
./titty /etc/upstart/functions

Spoiler:
ls -al /etc/upstart|./titty -


....FAQ:
Spoiler:
Q1) Why is this called "titty"?
A1) "Titty" is short for "(ti)ny (TTY)". It is a tiny script, it displays tiny characters, and watching it is like watching a teletype (TTY). It is quite a bit faster than a *real* TTY though (I have an ASR-33).

Q2) Why is this in the "algorithmic art" thread?
A2) It displays a PNG file, and it uses algorithms, and using it is sort of an "artistic statement ". Do we really need a separate thread just for "titty"?

Q3) Does this work on the Kindle 3?
A3) It can with a few little adjustments. Either do it yourself (a great learning experience) or wait for somebody else to do it for you.

Q4) If you look at tiny titty on the eink display too much, can you go blind?
A4) Yes! Just like your mother warned you when you were a teenager and she caught you!

Enjoy, and learn!


Ongoing optimization
investigation updates:

Spoiler:
EDIT: I just had a simple idea how to make this faster. It is now calling "hexdump" for every single character on the input line, to convert it from a character to a number used to offset into the onscreen character image map. Instead, we could call "hexdump" once with the entire line and then process the numeric values on the lines of hex numbers that it returns. Unfortunately, after stripping this subset of my code base to its essential simplicity for publication, it would start growing again as we add optimizations and features.

EDIT: I realized that because "dd" can "blit" as many horizontal pixels as you want with a single call, and because text characters are tall and narrow, we could use "dd" much more efficiently by drawing characters with the longest dimension (vertical) in the fastest direction that "dd" can draw (horizontal). In other words, because we start with a blank screen, we can "pretend" that it is in landscape mode. This will make character blitting about 50-percent faster for the character set used here. So, for text blitting using "dd", landscape mode is the way to go, and we can display two pages of 100-character lines side-by-side. Progress is an evolutionary process.

EDIT: I thought of another possible speed improvement for portrait mode (normal) text. This exploits the fact that "dd" call overhead is such that it can copy an entire line in about the same amount of time it takes to copy a single character. I have worked a lot with custom data compression for high-speed in-memory data transfer. Due to multi-level memory cache heirarchy on modern CPUs, LZ decompression is many times faster than direct memory transfers of uncompressed data because typically 90% of the data is copied from earlier in the output buffer (which is in high speed memory cache), and only 10% does not match and gets copied literally from the input buffer (which may still be streaming in from much slower DRAM, or even slower mmc). What I realized is that the decompression algorithm that tells how far back in the output buffer to copy a run of duplicate data from, would also tell how far back to find the same run of already rendered text character images, and we could "ddblit" the entire run (split by right page margin) from the rendered page instead of individual characters from the character map image. With the typical 10x compression for normal text (like ascii ebooks), we should also see a 10x speedup on the "dd" calls (and 10x text rendering speed). This program could become sort of like an eink zcat instead of cat (but using simple and fast byte-mode LZ compression). Cool, huh?

EDIT: Of course, the GREATEST speed improvement will come from converting this to a compiled language such as C, which can directly access the pixels with no "dd" call overhead, and can do partial screen updates using ioctl system calls. For eink, partial screen updates make a HUGE difference for small changes such as individual characters like we are doing here. I still have a few more shell script code snippets I plan to use as teaching tools (and useful little script-only utilities), before I switch to C in these tutorials.


What, no feedback? Are you guys even READING this stuff? Please leave some feedback. Thanks.


Attached Files
File Type: gz titty-1.1.tar.gz (2.0 KB, 218 views)
File Type: gz titty-1.4.tar.gz (2.6 KB, 284 views)

Last edited by geekmaster; 04-11-2012 at 12:49 PM.
geekmaster is offline   Reply With Quote
Old 04-03-2012, 01:30 PM   #49
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Arrow "TTY speed" explanation (with video)

Quote:
Originally Posted by geekmaster View Post
titty - tiny tty (display tiny text on eink display)
...
hint: This runs at TTY speed.
For those too young to remember what "TTY speed" was, teletypes ran at "110 baud", or 10 characters per second. I could type faster than that, so I could not press the next key until the teletype mechanism would allow the key I was pressing to "go down" first. I still own an ASR-33 teletype.

When "glass teletypes" (CRT terminals) were available, they were able to do an "amazingly fast" 30 characters per second (3 times as fast). This was all the faster an accoustic-coupled modem could go, for online access. Back then, it was not legal to connect directly to telephone lines, and using an accoustic coupler was the ONLY way, so this 300bps was the maximum speed. Some BBS systems measured the width of bits you send when you press the Enter key to get a login message. I was able to adust my terminal software to get a fairly reliable local telephone connection at up to about 500bps, but at 600bps there were way too many bad characters getting corrupted over the connection. Because XMODEM protocol used by most BBS systems had built-in error-detection and packet resending, using these faster connections allowed much faster downloads (only 30 minutes to download a crude low-resolution picture of a naked chick.)

Modems that used compression were not available until "MNP-5" compression was introduced in the MultiTech 2400baud modem after the law was changed to allow direct connections to the telephone system. I still have my beta MultiTech MNP-5 modem that I purchased for the cheap wholesale price of $600 USD (back in the days when that was enough money to buy a very nice used automobile).

Even in the olden days before the Internet was open to the public (only universities, government and military), I had access via one of seven BBS systems that were connected to the Internet (for news and email). I had a real Internet email address even back then, long before the World Wide Web was invented. Later, when they opened the Internet to the public, state-of-the-art modem speeds had advanced to 14.4Kbps, and the WWW had a total of 250 web sites (but no search engines like Google, so you had to buy "Internet Guide Books" printed on paper).

Because the "300baud days" were before modem compression, that 300bps really was only 30 characters per second. To give you an idea of what this "amazingly fast" (at the time) online experience was like, just watch this video:


As you can see, the script-based text output from the "titty" program is much faster than the text displayed in that video.


Last edited by geekmaster; 04-03-2012 at 06:11 PM.
geekmaster is offline   Reply With Quote
Old 04-04-2012, 11:50 AM   #50
kaminkatze
Member
kaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with others
 
Posts: 17
Karma: 2600
Join Date: Mar 2012
Device: Kindle 3
K3 (and hopefully K4/K5) single (per line) hexdump titty.

Spoiler:

Code:
#!/bin/sh
#=============================
# titty - tiny tty (v1.2)
# display tiny text on eink
# requirements: titty.png.
# usage:
#  "titty" cat self
#  "ls -al|titty -" cat STDIN
#  "titty /etc/shadow" PWN! :D
# hint: This runs at TTY speed.
#------------------------------
# Copyright (C) 2012 geekmaster
# MIT License: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# WARNING: If you don't stop using titty, you will go blind! :D

#===========================
# initvar - init global vars
#---------------------------
initvar() {
  eips -c; eips -f; eips -g "$0.png" # char map image
  DN=/dev/null DF=/dev/fb0 # devices
  set $(eips -i|grep res:); FW=$2 FH=$4 # fb0 width, height
  set $(eips -i|grep line); FS=$4 # fb0 stride
  CW=$((4*FS/FW)) CH=6 LH=7 # char width, height, line height
  LM=2 TM=12 # left, top margin px
  MX=$((FW*FS/FW-CW)) ML=$((FH/LH)); MS=$((ML+FS)) # max X, line, stride
  CX=$LM CY=$TM # cursor coords
  DD="dd if=$DF of=$DF bs=1 count=$CW" # ddblit
  Q=false # quit flag
  JFS=$IFS # normal field separator
}

#=================
# titty - tiny tty
# displays STDIN
#-----------------
titty() {
  until $Q ;do IFS='\n'; read L || Q=true; IFS=$JFS
    for A in $(echo -n "$L" | hexdump -ve '/1 "%d\n"'); do
      if [[ $A -ne 32 ]];then
        RO=$(((A-32)*CW)) FO=$((CY*FS+CX))
        for y in $(seq 1 1 $CH);do
          $DD skip=$RO seek=$FO 2>$DN; RO=$((RO+FS)) FO=$((FO+FS))
        done
      fi; CX=$((CX+CW)); [[ $((CX%64)) -eq $LM ]]&& eips ''
      if [[ $CX -gt $MX ]];then CX=$LM CY=$((CY+LH))
        [[ $CY -gt $MS ]]&& CY=$TM CX=$LM; fi
    done; eips ''
    CX=$LM CY=$((CY+LH)); [[ $CY -gt $MS ]]&& break
  done
}

# Do stuff!  :-)
initvar
if [[ "$1" == "-" ]];then titty
elif [[ "$1" == "" ]];then cat "$0"|titty
else cat "$1"|titty
fi
kaminkatze is offline   Reply With Quote
Old 04-04-2012, 12:10 PM   #51
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Quote:
Originally Posted by kaminkatze View Post
K3 (and hopefully K4/K5) single (per line) hexdump titty.
Thanks! It is nice to see that somebody who has some time to spare for this project is actually reading (and implementing!) some of my potential optimization ideas.

I do not have time right now. I want to do a speed comparison test to see how much this speeds it up.

I also want to integrate it with the K3 tiny terminal script that does eips text output now (with its severely limited character set). You are welcome to do that if you wish.

Now that this includes your code, I think you should add a compact revision history (including your name and mine) like the one in my touchpaint script here:



Last edited by geekmaster; 04-04-2012 at 12:26 PM.
geekmaster is offline   Reply With Quote
Old 04-05-2012, 12:49 PM   #52
kaminkatze
Member
kaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with others
 
Posts: 17
Karma: 2600
Join Date: Mar 2012
Device: Kindle 3
Quote:
Originally Posted by geekmaster View Post
I also want to integrate it with the K3 tiny terminal script that does eips text output now (with its severely limited character set). You are welcome to do that if you wish.
I have a tinysh version that uses titty calls (initvar/eips -g for every key press). I guess with "to integrate it" you mean to merge both codes?

Scrolling and some other things that might be useful.

Spoiler:

Code:
#!/bin/sh
#=============================
# titty - tiny tty (v1.3)
# display tiny text on eink
# requirements: titty.png.
# usage:
#   titty
#     cat self
#   titty [x y] [-k] [--] -|STRING|-f FILE
#     displays "STDIN", "echo STRING" or "cat FILE"
#       [x y]  initialize cursor at x y
#       [-k]   clear lines
#       [--]   treat as string
#   titty -s Y H S
#     move H-S lines S lines up, beginning with line Y+S
#   titty -mx|-my
#     return maximal x y coordinates
#   titty -v
#     return version
# hint: This runs at TTY speed.
#------------------------------
# Copyright (C) 2012 geekmaster
# MIT License: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#------------------------------
# Revision History (last change first):
# =ver= =date===== =author===== =description============================
# 1.3   2012-04-05 kaminkatze   scrolling and options
# 1.2   2012-04-04 kaminkatze   k3 support and per line hexdump
# 1.1   2012-04-01 geekmaster   first release

# WARNING: If you don't stop using titty, you will go blind! :D

#===========================
# initvar - init global vars
#---------------------------
initvar() {
  V=1.3 # version
  eips -g "$0.png" # char map image
  DN=/dev/null DF=/dev/fb0 # devices
  set $(eips -i|grep res:); FW=$2 FH=$4 # fb0 width, height
  set $(eips -i|grep line); FS=$4 # fb0 stride
  CW=$((4*FS/FW)) CH=6 LH=7 # char width, height, line height
  LM=2 TM=$((CH*2)) # left, top margin px
  MX=$((FW*FS/FW-CW)) ML=$(((FH-TM)/LH-1)); MS=$((ML+FS)) # max X, line, stride
  CX=$LM CY=$TM # cursor coords
  DD="dd if=$DF of=$DF bs=1 count=$CW" # ddblit
  DL="dd if=$DF of=$DF bs=1 count=$((FS*CH)) skip=$((FS*CH))" # clear line
  Q=false # quit flag
  K=false # clear line flag
  JFS=$IFS # normal field separator
}

#====================
# usage: scroll y h s
#--------------------
scroll() {
  dd if=$DF of=$DF bs=1 count=$((FS*LH*($2-$3))) \
    skip=$((FS*(LH*($1+$3)+TM))) seek=$((FS*(LH*$1+TM))) 2>$DN
  eips ''
}

#=================
# titty - tiny tty
# displays STDIN
#------------------
titty() {
  until $Q ;do IFS='\n'; read L || Q=true; IFS=$JFS
    $K && [[ $CX -eq $LM ]] && $DL seek=$((CY*FS)) 2>$DN
    for A in $(echo -n "$L" | hexdump -ve '/1 "%d\n"'); do
      if [[ $A -ne 32 ]]; then
        RO=$(((A-32)*CW)) FO=$((CY*FS+CX))
        for y in $(seq 1 $CH);do
          $DD skip=$RO seek=$FO 2>$DN; RO=$((RO+FS)) FO=$((FO+FS))
        done
      fi; CX=$((CX+CW)); [[ $((CX%64)) -eq $LM ]] && eips ''
      if [[ $CX -gt $MX ]]; then CX=$LM CY=$((CY+LH))
        [[ $CY -gt $MS ]] && CY=$TM CX=$LM
        $K && $DL seek=$((CY*FS)) 2>$DN; fi
    done; eips ''
    CX=$LM CY=$((CY+LH)); [[ $CY -gt $MS ]] && break
  done
}

# Do stuff!  :-)
initvar
if [[ "$1" == "" ]]; then cat "$0"|titty
else while [[ "$1" ]]; do
  case "$1" in
    -s) scroll $2 $3 $4; shift;shift;shift;shift;;
    -mx) echo $((FS/CW-CW)); shift;;
    -my) echo $ML; shift;;
    -f) cat "$2"|titty; shift;shift;;
    -) titty; shift;;
    -k) if [[ $CX -gt $LM ]]; then
          for y in $(seq 0 $((CH-1))); do
            dd if=$DF of=$DF bs=1 count=$((FS-CX)) \
              skip=$((FS*CH)) seek=$(((CY+y)*FS+CX)) 2>$DN
          done
        fi; K=true; shift;;
    --) echo -n "$2"|titty; shift;shift;;
    -v) echo $V; shift;;
    *) if [[ -n "$3" ]]
       then CX=$((LM+$1*CW)) CY=$((TM+$2*LH)); shift;shift
       else echo -n "$1"|titty; shift
       fi;;
  esac
done; fi

Last edited by kaminkatze; 04-05-2012 at 05:22 PM.
kaminkatze is offline   Reply With Quote
Old 04-05-2012, 04:00 PM   #53
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Arrow kittycon 1.0 - kindle tty console

Quote:
Originally Posted by kaminkatze View Post
I have a tinysh version that uses titty calls (initvar/eips -g for every key press). I guess with "to integrate it" you mean to merge both codes?

Scrolling and some other things that might be useful.
That code looks well done (and very interesting). I am anxious to use it as soon as I get some spare time.

By "integrate" I did mean to merge them. Although the linux philosophy is to have a bunch of small tools and pipe them together (which I *do* use for prototyping), keeping all the functions in one file prevents missing pieces or mixing wrong versions together. Scripts are "source code" anyway, so you can just cut and paste functions from a "master library" (or source the library, like how the kindle startup scripts source a "functions" file). But sourcing can lead to version conflicts too, and there is plenty of storage space for (complete) monolithic scripts.

BTW, I static link my C programs too (all libraries embedded in the executable), to prevent loadable library version conflicts between different kindle models. That works MUCH better for portable programs, to prevent missing or "wrong library version" errors when you run them on a different kindle model.

Being an "old-timer", I MUCH prefer larger programs and scripts that do not suffer "bit rot" as quickly as utilities that have external and version-specific dependencies.

EDIT: After integrating "tinysh" onscreen shell with "titty" tiny TTY, this new script should have a new name. I would name it something alliterative and easy to say and remember. I (strongly) suggest that we name it "kittycon" (kindle TTY console), and with a new name restart the version number. You can keep the history showing its parentage.

I plan to merge in GUI support from my other scripts (with buttons and stuff, and onscreen keyboard for touch and k4), so perhaps the name can later represent "kittycon - kindle tty control panel", making this name somewhat "future proof". I have been working on "gmcp - geekmaster control panel" occasionally for the past few months, but that name feels too egotistical, so I like kittycon "more better"...

Of course, we should keep the individual functions as independent scripts as well (just like you did above), for direct use by other simple scripts, and for prototyping more advanced scripts. As I said, I like it both ways, but I usually *publish* tutorial demo code that I have stripped down to its essence, containing everything it needs (monolithic) but nothing that it does not use.

P.S. Thank you kaminkatze for keeping this project alive and growing.


Last edited by geekmaster; 04-05-2012 at 04:35 PM.
geekmaster is offline   Reply With Quote
Old 04-05-2012, 06:21 PM   #54
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Porting this to the K3 shows a little bug in my original code. I did not notice it on the K4 and Touch because it gave a reasonable value for "max stride", but on the K3 it is obviously only half the screen. Fixing it actually made the code a little simpler and a little smaller. I like that! And the fact that it works on all the (tested) kindle models with NO CHANGES means that we did *something* right.

Change this line:

MX=$((FW*FS/FW-CW)) ML=$(((FH-TM)/LH-1)); MS=$((ML+FS)) # max X, line, stride

to this:

MX=$((FW-CW)) MY=$((FH-LH)) # max X, Y

and change the "last line" checks to use $MX instead of $MS.


EDIT: Tested and working on my DX, DXG, K3, K4, and Touch, using this command:

eips -c;hexdump -C /dev/urandom|./titty -

which fills all available lines on the screen with a hexdump of random data, and then quits. On the DXG, it stops after the last full line on the larger screen. And while displaying itself, the MIT license wraps at the larger screen right margin. It is nice when things actually work as designed without needing a lot of little bug fixes.

UPDATE: Original "titty" post updated to v1.4 (which includes above changes):
EDIT: Now I tested the scrolling with v1.4 (posted above) on my DX, and that works too. On a DX 824x1200 display, that is 206 columns of readable tiny text, or 300 columns wide if we used landscape mode. In DX landscape mode, we could display 4 side-by-side pages of 75-character lines, or 3 pages of 100-character lines. Cool. Now all we need is 3 or 4 open text console windows side-by-side. We could also split the screen in half along the other direction and get 6-up or 8-up text console windows on the DX display.


Last edited by geekmaster; 04-06-2012 at 12:26 AM.
geekmaster is offline   Reply With Quote
Old 04-06-2012, 02:55 AM   #55
aBP
Member
aBP began at the beginning.
 
Posts: 18
Karma: 10
Join Date: Feb 2012
Device: K4NT
Just ran this on my K4 with Kite. The text appeared as white on top of my home screen, also the script would not stop running! haha, I hit the home button, went to the settings page, but the script was still drawing tiny white characters on the screen I had to restart the kindle to get it back to normal. Just thought I'd give you some feedback, I am not sure if this is normal lol

EDIT>> Disregard my comment about the script not stopping, I must have accidentally started the script more than once. Also, I ended up running the script and then displaying a black png on the screen to get a clear view of the output. Here is what I found.



I am guessing the text is showing as white boxes because the letters are actually bits of a png image. Not sure if what I am sharing is helping at all but I thought I'd chime in.

Last edited by aBP; 04-06-2012 at 03:09 AM.
aBP is offline   Reply With Quote
Old 04-06-2012, 05:43 AM   #56
kaminkatze
Member
kaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with others
 
Posts: 17
Karma: 2600
Join Date: Mar 2012
Device: Kindle 3
Quote:
Originally Posted by aBP View Post
Just ran this on my K4 with Kite. The text appeared as white on top of my home screen, also the script would not stop running!
Ok, same here on the K3. The problem is that kite or the framework redraws the screen seconds after starting the script. This erases the already drawn font template.

Temporarily you could use this kite script.
Code:
usleep 2000000; titty &
kaminkatze is offline   Reply With Quote
Old 04-06-2012, 08:41 AM   #57
knc1
Going Viral
knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.
 
knc1's Avatar
 
Posts: 17,212
Karma: 18210809
Join Date: Feb 2012
Location: Central Texas
Device: No K1, PW2, KV, KOA
Quote:
Originally Posted by aBP View Post
Just ran this on my K4 with Kite. The text appeared as white on top of my home screen, also the script would not stop running! haha, I hit the home button, went to the settings page, but the script was still drawing tiny white characters on the screen I had to restart the kindle to get it back to normal. Just thought I'd give you some feedback, I am not sure if this is normal lol

EDIT>> Disregard my comment about the script not stopping, I must have accidentally started the script more than once. Also, I ended up running the script and then displaying a black png on the screen to get a clear view of the output. Here is what I found.



I am guessing the text is showing as white boxes because the letters are actually bits of a png image. Not sure if what I am sharing is helping at all but I thought I'd chime in.
Looks great for printing Morse Code.
knc1 is offline   Reply With Quote
Old 04-06-2012, 10:46 AM   #58
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Quote:
Originally Posted by aBP View Post
Just ran this on my K4 with Kite. The text appeared as white on top of my home screen, also the script would not stop running! haha, I hit the home button, went to the settings page, but the script was still drawing tiny white characters on the screen I had to restart the kindle to get it back to normal. Just thought I'd give you some feedback, I am not sure if this is normal lol
...
I am guessing the text is showing as white boxes because the letters are actually bits of a png image. Not sure if what I am sharing is helping at all but I thought I'd chime in.
That happens because the first row of characters at the very top of the screen is where all other characters are copied FROM. When the status bar overwrites that, then we copy bits of the status bar instead of the original characters.

I prevented this in my earlier version by pausing (killall -stop) and resuming (killall -cont) the kindle framework. That code was removed when kaminkatze added updates, because he calls this from a parent script (that presumable does the framework pause and resume). You can download the v1.1 code above to see the differences.

I simplified this to use characters that were onscreen, for the simplest possible code (for a tutorial demo).

My original (unpublished) code used larger characters that required two rows in the PNG file, and more complicated code to handle splitting the character set into multiple rows. After displaying the character map image, it copied the top part of the framebuffer to to /tmp/chars.bin and cleared the screen. Then the main code did "dd" from the temp file instead of from the top of the screen. To make the published tutorial demo code as simple as possible, I switched to a smaller character set that could fit on one row, and used the onscreen copy with no temp files.

I plan to add support for multiple character sets in other languages (UTF-8 support?) and different font sizes, using temp files again, but I will create a long single line temp file (too big to display on the screen) from the multi-line PNG, during the initialization (initvar).

If UTF-8 is too complicated to do in a shell script, I may go with codepages instead. Ideas?

Again -- you need to disable the framework writing on top of the character set at the top of the screen, of the characters being printed will contain the wrong pixels (like your screenshot image). Of course, that will not be an issue after we go back to copying characters from a temp file instead of top of screen.
geekmaster is offline   Reply With Quote
Old 04-06-2012, 11:54 AM   #59
kaminkatze
Member
kaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with others
 
Posts: 17
Karma: 2600
Join Date: Mar 2012
Device: Kindle 3
Quote:
Originally Posted by geekmaster View Post
I prevented this in my earlier version by pausing (killall -stop) and resuming (killall -cont) the kindle framework. That code was removed when kaminkatze added updates, because he calls this from a parent script (that presumable does the framework pause and resume). You can download the v1.1 code above to see the differences.
Must have been in the unpublished v1.0. v1.1 linked in the original post has no killall. But yes, it's very likely that I would have removed it and forgotten to put it in again.

Added backslash duplicates so that a single '\' is preserved by read L.

New version uses IFS="" because IFS="\n" somehow removed 'n's at the end of a line.

Spoiler:

Code:
#!/bin/sh
#=============================
# titty - tiny tty (v1.5)
# display tiny text on eink
# requirements: titty.png.
# usage:
#   titty
#     cat self
#   titty [x y] [-k] [--] -|STRING|-f FILE
#     displays "STDIN", "echo STRING" or "cat FILE"
#       [x y]  initialize cursor at x y
#       [-k]   clear lines
#       [--]   treat as string
#   titty -s Y H S
#     move H-S lines S lines up, beginning with line Y+S
#   titty -mx|-my
#     return maximal x y coordinates
#   titty -v
#     return version
# hint: This runs at TTY speed.
#------------------------------
# Copyright (C) 2012 geekmaster
# MIT License: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#------------------------------
# Revision History (last change first):
# =ver= =date===== =author===== =description============================
# 1.5   2012-04-06 kaminkatze   fix IFS "end of line" and '\' bug
# 1.4   2012-04-05 geekmaster   fix "end of page" bug
# 1.3   2012-04-05 kaminkatze   scrolling and options
# 1.2   2012-04-04 kaminkatze   k3 support and per line hexdump
# 1.1   2012-04-01 geekmaster   first release

# WARNING: If you don't stop using titty, you will go blind! :D

#===========================
# initvar - init global vars
#---------------------------
initvar() {
  V=1.5 # version
  eips -g "$0.png" # char map image
  DN=/dev/null DF=/dev/fb0 # devices
  set $(eips -i|grep res:); FW=$2 FH=$4 # fb0 width, height
  set $(eips -i|grep line); FS=$4 # fb0 stride
  CW=$((4*FS/FW)) CH=6 LH=7 # char width, height, line height
  LM=2 TM=$((LH*2)) # left, top margin px
  MX=$((FW*FS/FW-CW)) MY=$((FH-LH)) # max X, Y
  CX=$LM CY=$TM # cursor coords
  DD="dd if=$DF of=$DF bs=1 count=$CW" # ddblit
  DL="dd if=$DF of=$DF bs=1 count=$((FS*LH)) skip=$((FS*CH))" # clear line
  Q=false # quit flag
  K=false # clear line flag
  JFS=$IFS # normal field separator
}

#====================
# usage: scroll y h s
#--------------------
scroll() {
  dd if=$DF of=$DF bs=1 count=$((FS*LH*($2-$3))) \
    skip=$((FS*(LH*($1+$3)+TM))) seek=$((FS*(LH*$1+TM))) 2>$DN
  eips ''
}

#=================
# titty - tiny tty
# displays STDIN
#------------------
titty() {
  sed 's/\\/\\\\/g' | until $Q ; do IFS=''; read L || Q=true; IFS=$JFS
    $K && [[ $CX -eq $LM ]] && $DL seek=$((CY*FS)) 2>$DN
    for A in $(echo -n "$L" | hexdump -ve '/1 "%d\n"'); do
      if [[ $A -ne 32 ]]; then
        RO=$(((A-32)*CW)) FO=$((CY*FS+CX))
        for y in $(seq 1 $CH);do
          $DD skip=$RO seek=$FO 2>$DN; RO=$((RO+FS)) FO=$((FO+FS))
        done
      fi
      CX=$((CX+CW)); [[ $((CX%64)) -eq $LM ]] && eips ''
      if [[ $CX -gt $MX ]]; then CX=$LM CY=$((CY+LH))
        [[ $CY -gt $MY ]] && CY=$TM CX=$LM
        $K && $DL seek=$((CY*FS)) 2>$DN; fi
    done; eips ''
    CX=$LM CY=$((CY+LH)); [[ $CY -gt $MY ]] && break
  done
}

# Do stuff!  :-)
initvar
if [[ "$1" == "" ]]; then
  K=true; cat "$0" | titty
else while [[ "$1" ]]; do
  case "$1" in
    -s) scroll $2 $3 $4; shift;shift;shift;shift;;
    -mx) echo $((FS/CW-CW)); shift;;
    -my) echo $(((FH-TM)/LH-1)); shift;;
    -f) cat "$2"|titty; shift;shift;;
    -) titty; shift;;
    -k) if [[ $CX -gt $LM ]]; then
          for y in $(seq 0 $((LH-1))); do
            dd if=$DF of=$DF bs=1 count=$((FS-CX)) \
              skip=$((FS*CH)) seek=$(((CY+y)*FS+CX)) 2>$DN
          done
        fi; K=true; shift;;
    --) echo -n "$2"|titty; shift;shift;;
    -v) echo $V; shift;;
    *) if [[ -n "$3" ]]
       then CX=$((LM+$1*CW)) CY=$((TM+$2*LH)); shift;shift
       else echo -n "$1"|titty; shift
       fi;;
  esac
done; fi
kaminkatze is offline   Reply With Quote
Old 04-06-2012, 12:18 PM   #60
knc1
Going Viral
knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.
 
knc1's Avatar
 
Posts: 17,212
Karma: 18210809
Join Date: Feb 2012
Location: Central Texas
Device: No K1, PW2, KV, KOA
Quote:
Originally Posted by kaminkatze View Post

New version uses IFS="" because IFS="\n" somehow removed 'n's at the end of a line.
Not "somehow" but "required behavior" -

The character(s) in the Input Field Seperator (IFS) string are always removed.
Translation: IFS characters are never passed unless escaped or quoted.
knc1 is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Scripting with epub-meta averyml Calibre 20 11-17-2016 10:13 AM
Bunny + Scripting + Calibre = here tBunnyMan Introduce Yourself 4 02-06-2012 12:16 AM
Possible scripting engine for Sigil Valloric Sigil 48 10-17-2009 09:58 AM
Any NetNewsWire Scripting Pros out there? adinb Sony Reader 0 02-25-2007 01:44 AM


All times are GMT -4. The time now is 12:24 AM.


MobileRead.com is a privately owned, operated and funded community.