Methods for Justifying text output in TCL

29 views
Skip to first unread message

Thane Reaver

unread,
Jun 15, 2001, 11:44:17 AM6/15/01
to
I am interested in finding some methods for producing fully justified text
output in TCL, not in TK. The problem is simple. I have a standard list of
words of varying lengths and I need to output that list in lines with
specific lenghts. This of course was not too difficult, I was able to
format the output to lines of 40 characters or less, ending at the last
complete word fully contained within that 40 character limit. So now what I
want is to make it more aesthetically pleasing and add some nice right
justification to thisblock of text output. I am having a surprisingly
difficult time digging up any algorithms or scripts designed for this
purpose. I was, after quite some time spent searching, able to find a copy
of a TK script for producing fully justified text within a canvas widget by
DKF. This peice of code can be found here.
http://www.cs.man.ac.uk/~fellowsd/tcl/wordwrap.tcl

This is, of course, not what I need, as I am after something that works in
TCL, not in TK, and as this script is made to check many things such as font
size and then output the text to a window. All I want to do is split apart
a list of words by "leftover" spaces in an evenly distributed manner, like
your word processor would do, but just for standard TCL text output. One
character is one space, line length of 40 would be a line of 40 or less
characters.

Does anybody have some standard methods for justifying standard text output,
or can someone give me a quick and easy algorithm that would work
efficiently? I'm sure I could technically dig it out of DKF's code at some
point if I have to, but I'd rather find something more suited for what I'm
after.


Phil Ehrens

unread,
Jun 15, 2001, 12:18:57 PM6/15/01
to
Thane Reaver wrote:
> I am interested in finding some methods for producing fully justified text
> output in TCL, not in TK. The problem is simple.

The usual way of doing this is to prepend a space to each word
starting with the LAST word in the line, and NOT to prepend a space
to words of less than 2 or 3 characters. Additional padding can be
added after [,.!?], and extra spaces can be prepended to words
that are longer than, say 9 characters. This is the simpleminded
way which assumes that the lines in the inital input are within
a few characters in length of each other.

And you don't generally want to overjustify the last line in the
paragraph.

Like that.

Phil

Thane Reaver

unread,
Jun 15, 2001, 9:27:30 PM6/15/01
to
Thanks
I'll give it a try


lvi...@yahoo.com

unread,
Jun 16, 2001, 12:46:21 PM6/16/01
to

According to Phil Ehrens <-@->:
:And you don't generally want to overjustify the last line in the
:paragraph.

By overjustify, I suspect one could use some kind of algorithm like
"if line is less than 75% of the total full justification size, don't
modify". Of course, the percentage could vary to suit your preference.

--
--
"See, he's not just anyone ... he's my son." Mark Schultz
<URL: mailto:lvi...@cas.org> <URL: http://www.purl.org/NET/lvirden/>
Even if explicitly stated to the contrary, nothing in this posting

Donal K. Fellows

unread,
Jun 16, 2001, 3:05:39 PM6/16/01
to
In article <9gdchh$q...@gap.cco.caltech.edu>, Phil Ehrens <pehrens@nospam
.ligo.caltech.edu> writes

>Thane Reaver wrote:
>> I am interested in finding some methods for producing fully justified text
>> output in TCL, not in TK. The problem is simple.
>
>The usual way of doing this is to prepend a space to each word
>starting with the LAST word in the line, and NOT to prepend a space
>to words of less than 2 or 3 characters.

I tend to use a different technique based on the idea of trying to
distribute the extra spaces as evenly over the line as possible. It
seems to work fairly well...

I attach a demo.

Donal.
------------ BEGIN JUSTIFY.TCL ------------

# Calculate the indices into the paragraph where words start.
# Assumes no leading spaces (or tabs) and breaks over hyphens too.
proc getWordIndices {text {extraBreakChars ""}} {
set indices [list 0]
set words [split $text " -$extraBreakChars"]
set index [string length [lindex $words 0]]
foreach word [lrange $words 1 end] {
incr index
if {![string length $word]} {continue}
lappend indices $index
incr index [string length $word]
}
return $indices
}

# Convert text (in a *single* font) into a list of words, required
# space, and widths of words (with and without required space added.)
# Used to drive the line-breaking algorithm.
proc getLengths {text font} {
set wis [getWordIndices $text]
set words {}
for {set i 0} {$i+1<[llength $wis]} {} {
lappend words [string range $text [lindex $wis $i] \
[expr {[lindex $wis [incr i]]-1}]]
}
set lengths {}
set m [string length $font]
foreach word [lappend words \
[string range $text [lindex $wis end] end]] {
set st [string trim $word]
if {$m} {
lappend lengths $st \
[string range $word [string length $st] end]\
[font measure $font $word] [font measure $font $st]
} else {
lappend lengths $st \
[string range $word [string length $st] end]\
[string length $word] [string length $st]
}
}
return $lengths
}

# Convert the output of [getLengths] into a list of line-widths and
# lines, where each line consists of a list of words (including required
# spaces when not at the end of the line) and widths of those words.
# Recombines hyphenated words when these are not broken across lines.
proc getBrokenLines {lengths widthmap} {
set linenumber 0
set linewidth [eval $widthmap [list $linenumber]]
set lines {}
set curline {}
set curwidth 0
set lastspc {}
set lastword {}
set lastgap 0
set lastswidth 0
set lasttwidth 0
foreach {word space swidth twidth} $lengths {
if {$curwidth+$lastgap+$twidth > $linewidth} {
lappend curline $lastword $lasttwidth
lappend lines $curline
set curline {}
set linewidth [eval $widthmap [list [incr linenumber]]]
set curwidth 0
} elseif {$lasttwidth} {
lappend curline $lastword$lastspc $lastswidth
}
set curwidth [expr {$curwidth+$lastgap+$twidth}]
set lastgap [expr {$swidth-$twidth}]
set lastspc $space
set lastswidth $swidth
set lasttwidth $twidth
set lastword $word
}
lappend lines [lappend curline $lastword $lasttwidth]
set clines {}
foreach line $lines {
set oc {}
set ow 0
set combined {}
set tw 0
foreach {chunk w} $line {
if {[string compare $chunk [string trim $chunk]]} {
lappend combined $oc$chunk [expr {$w+$ow}]
set oc {}
set ow 0
} else {
append oc $chunk
set ow [expr {$ow+$w}]
}
set tw [expr {$tw+$w}]
}
if {$ow} {lappend combined $oc $ow}
lappend clines $tw $combined
}
set clines
}

proc simpleWidthMap {mainwidth firstwidth linenumber} {
expr {$linenumber>0||$firstwidth==0 ? $mainwidth : $firstwidth}
}

# Takes the text of a paragraph to justify and a width in characters,
# and produces the justified paragraph (with spaces and newlines
# inserted so as to make each line except the last contain exactly
# $width characters with each containing the maximum number of words.)
proc justify {string width} {
set info [getBrokenLines [getLengths $string {}] \
[list simpleWidthMap $width 0]]
set numlines [expr {[llength $info] / 2}]
set ln 0
set output {}
foreach {lw ld} $info {
if {[incr ln] == $numlines} {
foreach {s w} $ld {
append output $s
}
continue
}
set diff [expr {$width-$lw}]
set each [expr {double($diff)/$lw}]
set cur 0.0
set line {}
set done 0
foreach {s w} [lrange $ld 0 [expr {[llength $ld]-3}]] {
append line $s
set cur [expr {$cur + ($each*$w) + $w}]
incr done $w
while {($cur-$done) > 1.0} {
append line " "
incr done
}
}
append output $line [lindex $ld [expr {[llength $ld]-2}]] "\n"
}
return $output
}

# Some text from a message by Phil Ehrens
# <peh...@nospam.ligo.caltech.edu> though this algorithm doesn't break
# lines in quite the same places as he did in the original message. Not
# sure why.
set text {The usual way of doing this is to prepend a space to each\


word starting with the LAST word in the line, and NOT to\
prepend a space to words of less than 2 or 3 characters.\
Additional padding can be added after [,.!?], and extra spaces\
can be prepended to words that are longer than, say 9\
characters. This is the simpleminded way which assumes that the\
lines in the inital input are within a few characters in length\
of each other.}

if {$tcl_platform(platform) != "unix"} {
console show
console eval {.console configure -font {Courier 10}}
}
puts [justify $text 67]
--
Donal K. Fellows (at home)
--
FOOLED you! Absorb EGO SHATTERING impulse rays, polyester poltroon!!
(WARNING: There is precisely one error in this message.)

Thane Reaver

unread,
Jun 18, 2001, 9:04:52 PM6/18/01
to
Thanks DKF
=)


Jeff Hobbs

unread,
Jun 18, 2001, 10:31:56 PM6/18/01
to Donal K. Fellows
"Donal K. Fellows" wrote:
> In article <9gdchh$q...@gap.cco.caltech.edu>, Phil Ehrens <pehrens@nospam
> .ligo.caltech.edu> writes
...

> >The usual way of doing this is to prepend a space to each word
> >starting with the LAST word in the line, and NOT to prepend a space
> >to words of less than 2 or 3 characters.
>
> I tend to use a different technique based on the idea of trying to
> distribute the extra spaces as evenly over the line as possible. It
> seems to work fairly well...
>
> I attach a demo.

Very cool, master Fellows. Care to put it in tcllib? I wonder
how hard it would be to make the algorithm customize to Phil's
method as well.

--
Jeff Hobbs The Tcl Guy
Senior Developer http://www.ActiveState.com/
Tcl Support and Productivity Solutions

Donal K. Fellows

unread,
Jun 19, 2001, 6:03:27 AM6/19/01
to
Jeff Hobbs wrote:
> Very cool, master Fellows. Care to put it in tcllib? I wonder
> how hard it would be to make the algorithm customize to Phil's
> method as well.

I'm a little busy right now, but you can snarf it out of

http://www.cs.man.ac.uk/~fellowsd/tcl/wordwrap.tcl

where I combined it with the code I posted around last Christmas to
produce justified text in [text] and [canvas] widgets. The version
there also has the benefit of having fewer bugs...

Donal.
--
Donal K. Fellows http://www.cs.man.ac.uk/~fellowsd/ fell...@cs.man.ac.uk
-- A large ASCII art .sig is the Usenet equivalent of walking around in
public with your asscrack sticking out past the top of your sweatpants.
You be the judge. -- Mike Hoye <mh...@prince.carleton.ca>

Phil Ehrens

unread,
Jun 19, 2001, 12:40:52 PM6/19/01
to
Jeff Hobbs wrote:
> "Donal K. Fellows" wrote:
>> In article <9gdchh$q...@gap.cco.caltech.edu>, Phil Ehrens <pehrens@nospam
>> .ligo.caltech.edu> writes
> ...
>> >The usual way of doing this is to prepend a space to each word
>> >starting with the LAST word in the line, and NOT to prepend a space
>> >to words of less than 2 or 3 characters.
>>
>> I tend to use a different technique based on the idea of trying to
>> distribute the extra spaces as evenly over the line as possible. It
>> seems to work fairly well...
>>
>> I attach a demo.
>
> Very cool, master Fellows. Care to put it in tcllib? I wonder
> how hard it would be to make the algorithm customize to Phil's
> method as well.

I think my method is based on an incorrect memory of the methods
described by Donald Knuth somewhere. Probably in the TeX source.
I think if Donal does find the time to work this problem over he
would find the venerable Knuth's observations useful. TeX, of
course, manages the job to perfection.

Phil

Juan C. Gil

unread,
Jun 20, 2001, 5:28:07 AM6/20/01
to
peh...@nospam.ligo.caltech.edu (Phil Ehrens) wrote in message news:<9gnvak$p...@gap.cco.caltech.edu>...

> I think my method is based on an incorrect memory of the methods
> described by Donald Knuth somewhere. Probably in the TeX source.
> I think if Donal does find the time to work this problem over he
> would find the venerable Knuth's observations useful. TeX, of
> course, manages the job to perfection.
>
> Phil

Amen!. Have a look at

The Pursuit of Quality
How can automated typesetting achieve the highest
standards of craft typography?
Frank Mittelbach and Chris Rowley
November, 1991

http://www.ntg.nl/maps/pdf/9_14.pdf

The TeX alghorithm aims towards ensuring a similar grey (the
distribution of ink and white) value over the whole
paragraph, avoiding 'rivers' of white space flowing vertically
through a paragraph, distributing white space between words non-
uniformly depending on the boundary characters, ...

Juan Carlos---

Will Duquette

unread,
Jun 20, 2001, 11:02:29 AM6/20/01
to
On 19 Jun 2001 16:40:52 GMT, peh...@nospam.ligo.caltech.edu (Phil
Ehrens) wrote:

>
>I think my method is based on an incorrect memory of the methods
>described by Donald Knuth somewhere. Probably in the TeX source.
>I think if Donal does find the time to work this problem over he
>would find the venerable Knuth's observations useful. TeX, of
>course, manages the job to perfection.

We had an assignment to write an algorithm to do this
in my long ago Data Structures and
Algorithms class. The important point was that you get better results
if you split the text into lines so as to minimize the total amount of
padding needed over the whole paragraph. I remember in particular
that wrapping and padding lines one at a time from the beginning of
the paragraph to the end (the so-called "greedy" algorithm) yields
suboptimal results.

I also recall that I didn't do very well on that particular
assignment. :-)

Larry Smith

unread,
Jun 20, 2001, 12:25:15 PM6/20/01
to

> >> >The usual way of doing this is to prepend a space to each word
> >> >starting with the LAST word in the line, and NOT to prepend a space
> >> >to words of less than 2 or 3 characters.

Actually, a much better algorithm is to do the above
on odd lines and the opposite on even lines - that is,
you distribute the extra spaces needed at alternate
ends. This help keep the right side of the paragraph
from looking lighter than the left.

--
.-. .-. .---. .---. .-..-. | Do not mistake my cynicism
| |__ / | \| |-< | |-< > / | for dispair for deep inside
`----'`-^-'`-'`-'`-'`-' `-' | me is an optimist forever
http://www.smith-house.org/ | asking, "Why not?"

Donal K. Fellows

unread,
Jun 21, 2001, 6:33:55 AM6/21/01
to
Larry Smith wrote:
>>>>>The usual way of doing this is to prepend a space to each word
>>>>>starting with the LAST word in the line, and NOT to prepend a space
>>>>>to words of less than 2 or 3 characters.
>
> Actually, a much better algorithm is to do the above
> on odd lines and the opposite on even lines - that is,
> you distribute the extra spaces needed at alternate
> ends. This help keep the right side of the paragraph
> from looking lighter than the left.

My algorithm takes a very different route. It assumes that, by-and-large,
words are of essentially random length (but always a fair bit shorter than
the line) and that words of a particular length could be anywhere on the
line. Then it takes the space left over on the line and gives it out so
as to try to even out the space across the line but it measures according
to the width of the words so that long words tend to get more space around
them. The effect works very well with text and canvas widgets (where it
is possible to position characters with pixel-precision[*]) but still
seems aethetically pleasing when inserting spaces into monospace text. (I
did it this way when I noticed that my previous attempt tended to put too
much space around small words, marooning them in a sea of blankness in
some of my samples while cramming longer words together.)

It was either that or cleaning the house for Christmas. :^)

-- I'm curious; where does this statistic come from? Does its home, perchance,
ever see sunlight? -- Jason A Williams <jason+...@compsoc.man.ac.uk>

Thane Reaver

unread,
Jun 21, 2001, 9:20:41 PM6/21/01
to
> Very cool, master Fellows. Care to put it in tcllib? I wonder
> how hard it would be to make the algorithm customize to Phil's
> method as well.

I agree, it is very nice.
I had a bit of trouble, however, when trying to apply it to my application.
What I need to do is take a list of words or block of text (as opposed to a
structured paragraph of writing) and output it in a somewhat aesthetically
pleasing manner, ie right-justified.
This works fantastic, but as I played with it, I noticed a small bug/quirk
in the way it works. Allow me to demonstrate. For this, I will borrow a
portion of the dictionary in "A little spellchecker".

foreach i {
about above after all already also always am an another any and are as
at
be been before below between body both but by child children could
data different does doesn during each either empty
found for from fully given got happy happily
has have high his how however if in including into is isn it
just later legal low may maybe more must never next no none not
of on onto only or over perhaps same should since slow so some such
tcl than that the their them then there these they
this those three to too two under unless us using
was we were what whatever when where whether which while who whom whose
why with within would you zero automatic automatically
} { lappend list $i }

puts [justify $list 50] ;# perfect
puts [justify $list 62] ;# beautiful!
puts [justify $list 45] ;# hmm...

# that's not quite right. notice the trailing space at the end of the
# line after "child" and "zero". So we investigate a bit further.

puts [justify $list 47] ;# well, the first line
is correct
puts [justify $list 44] ;# this "bug" seems to
be getting bigger

# lets try something a bit different
puts [justify [info commands] 60] ;# ack!!


Thane Reaver

unread,
Jun 21, 2001, 9:25:56 PM6/21/01
to
By the way, I did use the tk console window rather than tclsh because it was
easier to work with as I am running windowsME on this particular box and the
pathetic dos window is practically useless with that incredibly limited
number of lines it allows.

Speaking of which, I don't suppose anybody knows of a solution to that
problem other than using wish or NOT using windowsME?


Jeff Hobbs

unread,
Jun 22, 2001, 1:20:52 AM6/22/01
to Thane Reaver

Well, I almost always use tkcon anyways (instead of tclsh or wish, see
http://tkcon.sourceforge.net/), but you can set the DOS console to
save a ton of lines by changing the properties in the system menu of
the DOS console (upper left-hand menu in the title bar).

Donal K. Fellows

unread,
Jun 22, 2001, 4:42:30 AM6/22/01
to
Thane Reaver wrote:
> I had a bit of trouble, however, when trying to apply it to my application.
> What I need to do is take a list of words or block of text (as opposed to a
> structured paragraph of writing) and output it in a somewhat aesthetically
> pleasing manner, ie right-justified.

Right-justified is not the same thing at all as what I'm doing (which is
fully-justified) and can be done quite simply with [format] applied to
each line.

> This works fantastic, but as I played with it, I noticed a small bug/quirk
> in the way it works. Allow me to demonstrate. For this, I will borrow a
> portion of the dictionary in "A little spellchecker".

I did discover a bug in it; the corrected code is on my website:
http://www.cs.man.ac.uk/~fellowsd/tcl/wordwrap.tcl

Note that the above code is not just a library; it also includes a demo
of the capabilities which you will need to remove to use it in with
anything else...

-- What's the reason of long discussions, if at the end someone says, "we have
not yet thought about it..." -- Andreas Leitgeb <a...@pc7499.gud.siemens.at>

Cameron Laird

unread,
Jun 22, 2001, 8:42:47 AM6/22/01
to
In article <3B3304F6...@cs.man.ac.uk>,
Donal K. Fellows <fell...@cs.man.ac.uk> wrote:
.
.

.
>I did discover a bug in it; the corrected code is on my website:
> http://www.cs.man.ac.uk/~fellowsd/tcl/wordwrap.tcl
>
>Note that the above code is not just a library; it also includes a demo
>of the capabilities which you will need to remove to use it in with
>anything else...
.
.
.
Or rewrite slightly.

I want to say a few words on this subject.

One of the best things about Perl is CPAN. One of the
best things about Java is JavaDoc. Notice here by "thing",
I'm not involving myself with typing semantics, or covari-
ance resolution, or similar technical linguistics. I'm
writing about cultural engineering conveniences that bring
pleasure to work in a particular language.

One of the best things about Python is that coders expect
to write self-testing source files. All Python programmers
with more than a couple days' experience recognize the
terminal fragment
if __name__ == "__main__":
main() # Or my_test(); you get the idea.
Pythoneers write source files that do something useful--perhaps
just exercise a test--when run standalone, and that also can
be re-used (as Tcl-ers, we think of [source] or [package require
...]) unchanged by larger programs.

Tcl can do the same, of course. I'd like to see more of it.

So: shall we continue a discussion in the abstract of why
this is a Good Thing, or shall I just dump some of my own
example usages into the Wiki?

Tip: feel free to ask me about other virtues of Python, and
how Tcl might cadge them.
--

Cameron Laird <cla...@NeoSoft.com>
Business: http://www.Phaseit.net
Personal: http://starbase.neosoft.com/~claird/home.html

Donal K. Fellows

unread,
Jun 22, 2001, 8:49:41 AM6/22/01
to
Cameron Laird wrote:
> One of the best things about Python is that coders expect
> to write self-testing source files. All Python programmers
> with more than a couple days' experience recognize the
> terminal fragment
> if __name__ == "__main__":
> main() # Or my_test(); you get the idea.

# Test for running stand-alone *or* in the plugin. Follow an idea
# through to its logical conclusion...
if {[string equal $::argv0 [info script]] || [array exists ::embed_args]} {
main

Richard.Suchenwirth

unread,
Jun 22, 2001, 9:50:27 AM6/22/01
to
"Donal K. Fellows" wrote:
>
> Cameron Laird wrote:
> > One of the best things about Python is that coders expect
> > to write self-testing source files. All Python programmers
> > with more than a couple days' experience recognize the
> > terminal fragment
> > if __name__ == "__main__":
> > main() # Or my_test(); you get the idea.
>
> # Test for running stand-alone *or* in the plugin. Follow an idea
> # through to its logical conclusion...
> if {[string equal $::argv0 [info script]] || [array exists ::embed_args]} {
> main
> }

Although I prefer Tcl over Python, I have to say that their formulation
is *way* clearer and pleasant to read...

The "Bag of algorithms" http://mini.net/cgi-bin/wikit/526.html
has a somehow similar, but wrapped thingy:

Self-test code: In a Tcl script that is sourced by other files, it's
nice to have some code for standalone testing (feeding only this file to
a tclsh/wish,
double-clicking on Windows, where you even get a free console for seeing
stdout ;-). Just brace the self-test code with

ifstandalone {#test what you want...}
proc ifstandalone body {
global argv0
if { [info exists argv0] && \
![string compare [file tail [info script]] [file tail
$argv0]] } {
catch {console show}
uplevel $body
}
}
--
Schoene Gruesse/best regards, Richard Suchenwirth - +49-7531-86 2703
Siemens Dematic AG, PA RC D2, Buecklestr.1-5, 78467 Konstanz,Germany
Personal opinions expressed only unless explicitly stated otherwise.

Bob Techentin

unread,
Jun 22, 2001, 10:48:55 AM6/22/01
to
"Richard.Suchenwirth" wrote:
>
> Although I prefer Tcl over Python, I have to say that their
> formulation is *way* clearer and pleasant to read...
>
> The "Bag of algorithms" http://mini.net/cgi-bin/wikit/526.html
> has a somehow similar, but wrapped thingy:
>
> Self-test code: In a Tcl script that is sourced by other files,
> it's nice to have some code for standalone testing ...

Nice idea. I think a language *should* encourage good programming by
offering facilities for better modularization, documentation, etc.

So, should we be suggesting a Tcl core proc named "self-test" or
"ifstandalone" which would *always* be available for programmers to add
a bit of self-test code to their modules?

Bob
--
Bob Techentin techenti...@mayo.edu
Mayo Foundation (507) 538-5495
200 First St. SW FAX (507) 284-9171
Rochester MN, 55901 USA http://www.mayo.edu/sppdg/

Donal K. Fellows

unread,
Jun 22, 2001, 11:15:47 AM6/22/01
to
"Richard.Suchenwirth" wrote:
> "Donal K. Fellows" wrote:
>> if {[string equal $::argv0 [info script]] || [array exists ::embed_args]} {
>> main
>> }
>
> Although I prefer Tcl over Python, I have to say that their formulation
> is *way* clearer and pleasant to read...

Under 8.4 and if I didn't care about the plugin, I'd use:

if {$argv0 eq [info script]} {
main
}

There are, of course, still some problems with this, but doing better
will need cooperation from the interpreter itself...

Jeff Hobbs

unread,
Jun 22, 2001, 3:25:59 PM6/22/01
to Cameron Laird
Cameron Laird wrote:
...

> One of the best things about Python is that coders expect
> to write self-testing source files. All Python programmers
> with more than a couple days' experience recognize the
> terminal fragment
> if __name__ == "__main__":
> main() # Or my_test(); you get the idea.
> Pythoneers write source files that do something useful--perhaps
> just exercise a test--when run standalone, and that also can
> be re-used (as Tcl-ers, we think of [source] or [package require
> ...]) unchanged by larger programs.
>
> Tcl can do the same, of course. I'd like to see more of it.

Errr... I fail to see the usefulness of this construct in
commercial applications. Tcl has a testing extension (tcltest)
that is very good for writing test suites independent of your
code.

Of course, I've used similar constructs to the above, but all
in minor side applications (like tkcon that can resource itself
- actually now it can reinstall itself, or several tclbench
scripts that run inside or outside of tclbench itself).
However, doing testing on a per-script basis doesn't get the
same effect as a real test suite.

Andreas Kupries

unread,
Jun 22, 2001, 12:26:12 PM6/22/01
to

cla...@starbase.neosoft.com (Cameron Laird) writes:

> One of the best things about Python is that coders expect to write
> self-testing source files.

> Tcl can do the same, of course. I'd like to see more of it.

> So: shall we continue a discussion in the abstract of why this is a
> Good Thing,

Not required for me, as I agree with that statement :)

> or shall I just dump some of my own example usages into the Wiki?

Please dump examples to the wiki.



> Tip: feel free to ask me about other virtues of Python, and
> how Tcl might cadge them.

Well, which other virtues can we pick up for Tcl too ?

--
Sincerely,
Andreas Kupries <a.ku...@westend.com>
Developer @ <http://www.activestate.com/>
Private <http://www.purl.org/NET/akupries/>
-------------------------------------------------------------------------------

Thane Reaver

unread,
Jun 22, 2001, 6:21:40 PM6/22/01
to
can't believe I never noticed that before. I'll take a look. Thanks


Thane Reaver

unread,
Jun 22, 2001, 6:33:36 PM6/22/01
to
> I did discover a bug in it; the corrected code is on my website:
> http://www.cs.man.ac.uk/~fellowsd/tcl/wordwrap.tcl
>
> Note that the above code is not just a library; it also includes a demo
> of the capabilities which you will need to remove to use it in with
> anything else...
>
> Donal.

I am familiar with the format command, although perhaps far from familiar
with it's syntax I am capapble of doing the basics with it. I think I may
be using the wrong term to describe what I mean, which is fully justified as
is what you're doing, but fully justified with the first character in the
start of each line beginning at point A and the last character in the last
word of each line at Point B.
example:

000 100 200 300 400 500 600 700 800 900
1000 2000 3000 4000 5000 6000 7000 8000 9000
00 05 10 15 20 25 30 35 40 50 60 70 80 90

something like that. note that lines up on the right if viewed in fixedsys
font or if counting characters.
heh
anyways, this is still giving me ideas and going in a helpful direction for
me, so whether or not your goal is exactly what I need, it's been extremely
helpful to me.
=)


Thane Reaver

unread,
Jun 23, 2001, 10:20:24 AM6/23/01
to
heh.
just tested your new code. you fixed the bug that I was trying to point
out, so whether that was the bug you "found" or not, thanks for help and the
nice script. Does exactly what I was looking for now and is just what I
needed.
Thanks!
=)
"Donal K. Fellows" <fell...@cs.man.ac.uk> wrote in message
news:3B3304F6...@cs.man.ac.uk...

Cameron Laird

unread,
Jun 25, 2001, 8:11:04 AM6/25/01
to
In article <873d8sz...@bluepeak.westend>,
Andreas Kupries <a.ku...@westend.com> wrote:
.
.

.
>> Tip: feel free to ask me about other virtues of Python, and
>> how Tcl might cadge them.
>
>Well, which other virtues can we pick up for Tcl too ?
.
.
.
docstrings. <URL:
http://www.onlamp.com/pub/a/python/2001/05/17/docstrings.html >
touches on only a fraction of their virtue.

One of the things I've been doing a lot lately is writing
variations on [proc] which also take or recognize an argument
which has more detailed information about the command signature,
usage, and so on.

Cameron Laird

unread,
Jun 25, 2001, 8:41:59 AM6/25/01
to
In article <3B339BC7...@ActiveState.com>,

Jeff Hobbs <Je...@ActiveState.com> wrote:
> ...
>> One of the best things about Python is that coders expect
>> to write self-testing source files. All Python programmers
>> with more than a couple days' experience recognize the
>> terminal fragment
>> if __name__ == "__main__":
>> main() # Or my_test(); you get the idea.
>> Pythoneers write source files that do something useful--perhaps
>> just exercise a test--when run standalone, and that also can
>> be re-used (as Tcl-ers, we think of [source] or [package require
>> ...]) unchanged by larger programs.
>>
>> Tcl can do the same, of course. I'd like to see more of it.
>
>Errr... I fail to see the usefulness of this construct in
>commercial applications. Tcl has a testing extension (tcltest)
>that is very good for writing test suites independent of your
>code.
>
>Of course, I've used similar constructs to the above, but all
>in minor side applications (like tkcon that can resource itself
>- actually now it can reinstall itself, or several tclbench
>scripts that run inside or outside of tclbench itself).
>However, doing testing on a per-script basis doesn't get the
>same effect as a real test suite.
.
.
.
There's a lot to what you say.

Yes, "real test suites" absolutely are different from
what I'm describing. Moreover, Tcl has plenty to be
proud of in its own history with real test suites, and
tcltest in particular.

"[C]ommercial applications", if I understand you cor-
rectly, are a small, small part of the world. Would
[history] be worth the bother, if that were our cri-
terion?

Anyway, whatever your answer to that (tangent: I've
got a long, involved argument that Java-style excep-
tion-handling is another construct that's formally
irrelevant to properly behaving "commercial applica-
tions"), I'm reporting that the Python culture is
really cool in this regard. Somebody says, "Here's
a do_wonders.tcl." You put a copy on your machine,
and launch it. Immediately, you see some level of
sanity. You [source] it into your own stuff, it does
you some good, you write to the author asking for an
enhancement, he sends an update, and, again, what he
sends is available immediately, without changes, both
for sanity check and for use in your own stuff. The
difference between that and Donal writing, "You have
to remove the last line before you use it in your own
code" is small but significant.

I take it as a mark of Donal's professionalism that
he has that last-line sanity check in what he writes,
by the way.

There's a footnote of another sort to this. There's
a sense in which Perl and Python aren't as "commer-
cial" as Tcl. This is a very curious situation.
Perl and, over the last year, Python are both
recognized as serious languages that support big
projects. However, I get considerably more of a feel
from the *Tcl* inner circle of attention to details
that matter for enterprise-class applications. I
want to say this carefully. Guido, for example, is
plenty smart, has the right passion about memory leaks,
and so on. However, the model coding situation that
the Python cabal has in mind when they're thinking
about source is of two engineers sitting at keyboards,
where one says to the other, "Look at *this*", and,
ideally, "this" is about forty lines of code. Python
is for "me and my friends".

TCT always sounds as though their Tcl applications
have a nuclear reactor connected on the far side.

I'm not saying anybody in this is good or bad--well,
actually, I'm saying there's a lot of good. I like
the scripting insiders, almost universally. It's
struck *me*, though, that there are differences in
style, and they're interesting ones.

Reply all
Reply to author
Forward
0 new messages