davidj has asked for the wisdom of the Perl Monks concerning the following question:

Hey fellow monks,

I'm the new mutli-media guy at my church. On Sunday afternoons we have a service that is done in Urdu. I was recently approached by the pastor of that service to train some of his people so that they can use the multi-media stuff for their service. Unfortunately, Urdu is written right to left, so I thought I would write a rudimentary application to accomodate that, and then they could just cut-and-paste. Easier said than done. My efforts to find a right to left widget or find some ideas on how to implement the functionality have been fruitless.
If any of you monks out there know of such a widget or have any ideas of how I could use the standard widgets to accomplish the task, I would much appreciate your wisdom.

As always, many thanks in advance for your input,


Replies are listed 'Best First'.
Re: right to left Tk text widget
by gaal (Parson) on Dec 04, 2004 at 09:34 UTC
      Isn't that a function of the OS, under linux Tk should check the LANG setting and then handle text based on those rules.
      Windows should do the samething if you have the language pack installed and switch to a R to L language.
      I only have us-eng installed on my linux box so I can't change languages to test.
        It's a function several pieces of software: the font / font renderer and the toolkit the edit widget came from, and sadly the particular application. That's why there are often inconsistencies across systems and softwares. In Windows, the consistency issue at least is better, because one vendor is responsible for more things.

        On your linux box where you "only have us-eng installed", you might in fact get BiDi anyway in certain cases (say, for example, in a browser). And to get it *everywhere*, you might have to work very hard.

Re: right to left Tk text widget
by zentara (Archbishop) on Dec 04, 2004 at 12:29 UTC
    I'm not sure what Urdu actually looks like, but can't you just reverse the text, line by line, before inserting it into the text widget?
    #!/usr/bin/perl use warnings; use strict; my $a1= "I sit here and think ?"; print "$a1\n"; my $b1 = reverse $a1; print "$b1\n";

    I'm not really a human, but I play one on earth. flash japh
Re: right to left Tk text widget
by zakzebrowski (Curate) on Dec 04, 2004 at 21:35 UTC
    In theory, you should be able to use a web browser,ensure that the a web page with urdu text is encoded, encode the web page in reverse, display the web page in reverse, and use ie's full screen to make it look like an application instead of a web page, and have a next button or a page down button to move to the next slide. (Opera has a nice presentation mode, btw.)

    Zak - the office
Re: right to left Tk text widget
by Courage (Parson) on Dec 04, 2004 at 12:51 UTC
    <quote> "...Unfortunately, Urdu is written right to left...." </quote>

    let me assure you, that right-to-left writing are so in a quite fortunate way.

    May be a bit unfortunate a fact that it is a bit more complicated to process in a simple hello-world program, but this is another question...

    Best regards,
    Courage, the Cowardly Dog

      I suspect that the OP meant that it was unfortunate for him/her that Urdu is not written in the same direction that the Tk widget set works in, with no slight intended towards RTL languages.

      And I'd also like to second the suggestion (below) to use a browser as the renderer. Search the monastery for links on using translation and Template::Toolkit together, and you're off to a good start.

      Spring: Forces, Coiled Again!
Re: right to left Tk text widget
by wolfger (Deacon) on Dec 07, 2004 at 15:43 UTC
    Okay, I think this will satisfy your needs. Backspace and delete still work in their standard left-to-right fashion, but otherwise I don't think there will be any problems.
    #!/usr/bin/perl #, written by Mike Foster # feel free to reuse, modify, redistribute, # bend, fold, staple, or mutilate. use strict; use warnings; use Tk; my $lastlength=1; my $lastdepth=1; my $mw = MainWindow->new( -background=>"darkviolet" ); $mw->title('Right-to-left text entry'); my $t1 = $mw->Text( -background=>"navy", -foreground=>"white", -height=>35, -width=>80, -wrap=>"word", -selectbackground=>"blueviolet" )->pack; $t1->bind("<Key>" => \&rtl); sub rtl { #gets end position my $depth = $t1->index('end'); #reduces to line $depth =~ s/\..*$//; #converts back to an integer $depth--; if ($lastdepth < $depth) { $t1->SetCursor('insert - 1 lines lineend'); } #remember where we were $lastdepth = $depth; #gets end of current line my $length = $t1->index('insert lineend'); #reduces to character number $length =~ s/^.*\.//; #converts back to integer $length++; if ($lastlength < $length) { $t1->SetCursor('insert - 1 chars'); } #remember where we were $lastlength = $length; } MainLoop;

    Linux, sci-fi, and Nat Torkington, all at Penguicon 3.0

      Thanks for the code. It is pretty much what I am looking for. I modified it to 1) have only 1 line of text (because they will copy/paste), 2) have a simple menu, and 3) use an Udru font.

Re: right to left Tk text widget
by wolfger (Deacon) on Dec 06, 2004 at 20:45 UTC
    Tricky problem. I threw together some code that *almost* works. Feel free to expand on this. Current bugs I have noticed are:
    1) Backspace and delete should be re-mapped to one another (to account for the backwords nature of the writing).
    2) Sometime it just plain goofs, and doesn't print letters in the proper (reversed) order. This bug seems to have something to do with using the mouse to change cursor position, but I can't tell for sure.
    3) cursor keys will not navigate properly.
    #!/usr/bin/perl use strict; use warnings; use Tk; my $mw = MainWindow->new( -background=>"darkviolet" ); my $t1 = $mw->Text( -background=>"navy", -foreground=>"white", -height=>35, -width=>80, -wrap=>"word", -selectbackground=>"blueviolet" )->pack; $t1->bind("<KeyRelease>" => sub {$t1->SetCursor('current - 1 chars')}) +; MainLoop;

    edit: I think I figured bug 2 out... text is printed out of order if you hit a second key before the first key is released. Unfortunately, switching KeyRelease with KeyPress doesn't make everything work. Text is still sometimes out of order, for no apparant reason.

    Linux, sci-fi, and Nat Torkington, all at Penguicon 3.0
      Okay, I got it working better, but it's still buggy. I fixed the bug that prevented cursor keys from working. Also, delete and backspace function normally now (without causing undue cursor movement), although backspace still goes left rather than right, and vice versa. The proper text direction is more reliable, but still committing errors. When I type "This is a test.", I invariably wind up with " .tseta si sihT". The cursor fails to move left on the space following the "a" every single time I type that sentence. If somebody can figure this out, I'd be grateful, as I am now quite interested in solving this problem.
      #!/usr/bin/perl use strict; use warnings; use Tk; my $last=1.0; my $mw = MainWindow->new( -background=>"darkviolet" ); my $t1 = $mw->Text( -background=>"navy", -foreground=>"white", -height=>35, -width=>80, -wrap=>"word", -selectbackground=>"blueviolet" )->pack; $t1->bind("<Key>" => \&rtl); #$t1->bind("<KeyRelease>" => sub {$t1->SetCursor('insert - 1 chars')}) +; sub rtl { my $size = $t1->index('end - 1 chars'); if ($last < $size) { $t1->SetCursor('insert - 1 chars'); } $last = $size; } MainLoop;

      edit: Got it! This error occurs on the 10th character of the line, and repeats at the 100th. Our comparison is saying that 1.9 is not less than 1.10 and 1.99 is not less than 1.100. True for integers, but not for line.word count.

      Linux, sci-fi, and Nat Torkington, all at Penguicon 3.0
Re: right to left Tk text widget
by graff (Chancellor) on Dec 08, 2004 at 04:16 UTC
    Well, I'm sorry to be a kill-joy, but in addition to being right-to-left, Urdu actually uses Arabic script. This means it does not use discrete, invariable symbols for each "letter" (like Hebrew does). Instead, the appearance of each letter depends on its position in the word: e.g. the symbol for "meem" (letter representing the "m" sound) will appear one way in word-initial (right-most) position, another way in word-final (left-most) position, and yet another way in medial position, and similarly for most letters. And then there's the matter of the ligatures joining the characters in the word -- if the letters of a word are not properly connected, people will probably still be able to read the word, but it will be a strain. Much more of a strain if all the characters are shown invariably in their "initial" or "isolated" forms rather than their correct contextual forms.

    Obviously, there are ways of dealing with these issues; just bear in mind that it's more than just a simple matter of reversing the direction of text lines.

    Hopefully, Gtk will have what you need (though I've never used it with perl, and am not sure about its merits or deficiencies for rendering Arabic script). Let me know if you get anywhere with that...