iRead: a Gutenberg eBook reader

 if 0 {<<br>>

Richard Suchenwirth 2003-04-18 - Very much literature is available for free download from Project Gutenberg http://promo.net/pg/ , mostly as plain text ASCII files (.txt), but with some quirks - a lengthy legal notice header, as well as occasionally extra line breaks between each two lines of text ("doublespaced"). 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?

WikiDbImage iread.jpg WikiDbImage iRead_cn.jpg

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]
proc doublespaced fp {
    #-- Check for double-spacing in first few lines
    set nNL 0
    foreach i {1 2 3 4 5 6 7 8 9 0} {
        incr nNL [expr {[gets $fp line]==0}]
    }
    seek $fp 0
    expr {$nNL > 5}
}
set doublespaced [doublespaced $fp]
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 [namespace code [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 > $doublespaced} {.t insert end \n\n}
            if {!$nl && [string match " *" $line]} {.t insert end \n} ;#(1)
            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 ;# (2)
    }
    if [regexp {\*END\*} $line] {
        incr inbody
    }
   update
}

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 was added with proc doublespace, which returns 1 if the first 10 lines of the file contain more than 5 lines of length zero, else 0; test for line insertion compares with the doublespace result instead of a constant. The modified code displays both test cases well. - The line marked (1) above handles another format variety: indents for list entries, or paragraph beginnings), come on a new line even if not double-spaced.


AK: Ha. Now pack the reader and the file into a starkit (or starpack) and we have really nice eBooks. Or maybe more than one file. Extract the titles, allow selection, carry your library with you :) - RS: I do that now, with MSReader and LIT eBooks, but wanted to tap the Gutenberg potential too. However, up to now there is no Tclkit for Windows/CE.. An advantage would be that the texts are zipped, which saves storage space. - AMucha: see Tclkit Mobile


Chinese eBook: Gutenberg offers the Confucian Analects (lun-yü) as eText [L1 ] . Adding, behind the line marked (2) above, the codelet

if [regexp "Character Set: Big 5" $line] {
    fconfigure $fp -encoding big5
    .t config -font {{Bitstream Cyberbit} 12}
}

makes it possible to read that too - provided you have a font like Bitstream Cyberbit around. Hip hip hooray for Tcl's encoding support!


French eBook: Less spectacular, but for French (e.g. Jules Verne, "De la terre à la lune" [L2 ] you need many accented letters... Just Works. RS