Mailinglist Archive: yast-devel (78 mails)

< Previous Next >
[yast-devel] RFC: fix for displaying bidirectional texts (e.g. mixed ASCII + Arabic)

Hi all,

I'm fixing bug https://bugzilla.novell.com/show_bug.cgi?id=583209
the problem is with displaying a bidirectional text.

The dialog label contains Arabic traslation of "Joystick Configuration" which is
written right-to-left (RTL) plus normal ASCII text with sound card model
(written in
LTR direction):

sformat(_("Joystick Configuration - %1 (snd-card-%2)"), cardname, card_id);

The problem is when the text is rendered on the screen the brackets are broken.
See the attached screen shots (there is English and Arabic version, the last
screenshot is fixed Arabic).

It's caused by the fact that punctuation characters in bidirectional text are
"weak".
I.e. their direction depends on the direction of the surrounding text
and that can cause troubles when one side is LTR and the other one is RTL.
(See http://en.wikipedia.org/wiki/Bi-directional_text#Unicode_support)

Fortunately Unicode has special controlling characters to explicitly set
direction
for one or more characters.


To fix the problem with the string above I have added new
String::ForceLTRPunctuation() function which forces LTR direction on some
punctuation
characters (,.()-) in the string using "LEFT-TO-RIGHT MARK" Unicode controlling
character. See the result in the last attached screenshot.


Another solution would be to directly fix the Arabic translation so it contains
the
LTR mark in it. But I'm not sure if it is possible to put binary values into
translated pot file via some escape sequence... And some strings might be read
from
an external source and might not be marked for translation, so we need to fix
them
on the fly with the above function anyway...



Because I'm not an I18N expert I'm asking here for review of this fix.
I think the fix cannot be applied generally to any displayed text, sometimes the
default direction might be desired and this would break it.

The patch is attached for review.


--

Ladislav Slez√°k
Appliance department / YaST Developer
Lihovarsk√° 1060/12
190 00 Prague 9 / Czech Republic
tel: +420 284 028 960
lslezak@xxxxxxxx
SUSE
Index: String.ycp
===================================================================
--- String.ycp (revision 66607)
+++ String.ycp (working copy)
@@ -1370,5 +1370,37 @@
return mergestring (splitstring (str, chars), glue);
}

+/*
+* Force punctuation symbols to be LTR
+*
+* Punctuation symbols are "weak" in bidirectional texts (their direction
+* depends on the direction of the surrounding text)
+*
+* Useful in bidirectional texts (e.g. mixed English and Arabic parts)
+* to fix broken formatting in some cases (punctuation between LTR and RTL
parts)
+*
+* See also
+* http://www.w3.org/International/questions/qa-bidi-controls.en.php
+* http://en.wikipedia.org/wiki/Left-to-right_mark
+* http://en.wikipedia.org/wiki/Bi-directional_text#Unicode_support and
+*
+* @param str input string
+* @return string the copy of the input but with forced LTR direction of
punctuation characters (.,-())
+*/
+global string ForceLTRPunctuation(string str)
+{
+ // Unicode "LEFT-TO-RIGHT MARK" (U+200E)
+ // explicitly changes the preceding character to LTR direction
+ const string LTRmark = "\342\200\216";
+
+ string ret = ReplaceWith(str, "(", "(" + LTRmark);
+ ret = ReplaceWith(ret, ")", ")" + LTRmark);
+ ret = ReplaceWith(ret, "-", "-" + LTRmark);
+ ret = ReplaceWith(ret, ".", "." + LTRmark);
+ ret = ReplaceWith(ret, ",", "," + LTRmark);
+
+ return ret;
+}
+
/* EOF */
}
Index: joy_dialog.ycp
===================================================================
--- joy_dialog.ycp (revision 66607)
+++ joy_dialog.ycp (working copy)
@@ -20,6 +20,7 @@
import "Package";
import "Label";
import "Popup";
+ import "String";

include "sound/joysticks.ycp";
include "sound/ui.ycp";
@@ -410,7 +411,7 @@
});

// dialog header - %1: card name (e.g "Soundblaster 16"), %2: card ID
(a number)
- string caption = sformat(_("Joystick Configuration - %1
(snd-card-%2)"), cardname, card_id);
+ string caption = String::ForceLTRPunctuation(sformat(_("Joystick
Configuration - %1 (snd-card-%2)"), cardname, card_id));

string helptext =
// help text for joystick configuration 1/4
< Previous Next >
List Navigation