Version 3 of iRead: a Gutenberg eBook reader

Updated 2003-04-22 09:18:40

if 0 {Richard Suchenwirth 2003-04-18 - Very much literature is available for free download from Project Gutenberg , mostly as plain text files (.txt), but with some quirks - a lengthy legal notice header, as well as extra line breaks between each two lines of text. I used part of this Easter weekend to write a little Gutenberg reader that runs on a PocketPC, and displays such a file (taking "The First Men in the Moon" by H.G.Wells as test case) reasonably well in a scrolled text widget on the little screen. It is interesting to note that the text widget in this tiny Tcl script can well handle 400K of input, while PocketWord, originally associated with .txt files, errors out - can it be that simple is better?

I haven�t tried to paginate the text flow. With <Up> and <Down> keys you can scroll a screenful, which roughly amounts to a page. As additional feature, you can let the text scroll automatically by lines - <Right> for more speed, <Left> for less.

With the short script below, I was able to read the whole Wells book - and enjoy it. The text widget could hold all the text. Page scrolling was sometimes unreliable - the best way was to use timed line scrolling, and to click inside the visible text before stopping it. In general, it is pretty amazing that some 40 lines of code make a feasible eText reader. The legal and introductory header is only displayed when you click on the About... "link" at top. }

 scrollbar .y -command ".t yview"
 text .t -yscrollc ".y set" -wrap word -font {Tahoma 8} -padx 2 -pady 3 -borderwidth 0 -takefocus 0
 pack .y -side right -fill y
 pack .t -side right -fill both -expand 1
 .t tag config bold -font [concat [.t cget -font] bold]
 .t tag config about -foreground blue -underline 1
 .t tag bind about <1> {.t insert 1.0 $about}
 bind . <Up> {.t yview scroll -1 page}
 bind . <Down> {.t yview scroll 1 page}
 wm geometry . 238x268+0+0
 set fn ""
 while {$fn==""} {
 set fn [tk_getOpenFile -filetypes {{TXT .txt} {{All files} *}}]
 set fp [open $fn]
 set inbody 0
 set nl 0
 set speed 0
 bind . <Left> {incr speed -1}
 bind . <Right> {incr speed 1}
 proc every {ms body} {
    eval $body
    after $ms [info level 0]
 every 1800 {.t yview scroll $::speed units}
 .t insert 1.0 About... about
 while {[gets $fp line]>=0} {
    if $inbody {
       if [string length $line] {
           if {$nl>1} {.t insert end \n\n}
           if [regexp {^Chapter} $line] {
              set tag bold
           } else {set tag ""}
           .t insert end "$line " $tag
           set nl 0
       } else {incr nl}
    } else {
       if {$line==""} {set line \n}
       append about $line
    if [regexp {\*END\*} $line] {
       incr inbody

Update: a second test case ("The Club of Queer Trades" by Gilbert K. Chesterton) promptly proved to have no interspersed newlines - so a format decider will have to be added. Soon here...