Design Overview
Terms and Abbreviations
  
    | Bidi | Bidirectional | 
  
    | LTR | Left to Right | 
  
    | RTL | Right to Left | 
  
    | LRM | Left-to-Right Mark | 
  
    | RLM | Right-to-Left Mark | 
  
    | LRE | Left-to-Right Embedding | 
  
    | RLE | Right-to-Left Embedding | 
   
    | PDF | Pop Directional Formatting | 
General Definitions, Terminology and Conventions
Every instance of bidi text has a base text direction. Bidi text in Arabic or
Hebrew has a RTL base direction, even if it includes numbers or Latin phrases
which are written from left to right. Bidi text in English or Greek has a LTR
base direction, even if it includes Arabic or Hebrew phrases which are written
from right to left.
Structured expressions also have a base text direction, which is often
determined by the type of structured expression, but may also be affected by the
content of the expression (whether it contains Arabic or Hebrew words).
This document addresses two groups of problematic cases:
  - Expressions with simple internal structure: this category
  regroups cases in which strings are concatenated together in simple ways
  using known separators. For example: variable names, "name = value"
  specifications, file path, etc...
 
- Expressions with complex internal structure: this category
  regroups structured text like regular expressions, XPath expressions and
  Java code. This category differs from the previous one since the expressions
  belonging to it have a unique syntax which cannot be described by
  concatenation of string segments using separators.
We will see that the same algorithms can handle both groups, with some
adaptations in the details.
In the examples appearing in this document, upper case Latin letters
represent Arabic or Hebrew text, lower case Latin letters represent English
text.
"@" represents an LRM, "&" represents an RLM.
Notations like LRE+LRM represent character LRE
immediately followed by character LRM.
Bidirectional Control Characters
When there are problems of wrong display of bidi text, it is often possible
to cure them by adding some bidi control characters at appropriate locations in
the text. There are 7 bidi control characters: LRM, RLM, LRE, RLE, LRO, RLO and
PDF. Since this design has no use for LRO and RLO (Left-to-Right and
Right-to-Left Override, respectively), the following paragraphs will describe
the effect of the 5 other characters.
  - LRM (Left-to-Right Mark): LRM is an invisible character which
  behaves like a letter in a Left to Right script such as Latin or Greek. It can
  be used when a segment of LTR text starts or ends with characters which are
  not intrinsically LTR and is displayed in a component with a RTL orientation.
  
 Example: assume in memory the string "\\myserver\myshare(mydirectory)". We
  want it displayed identically, but within a component with RTL
  orientation it would be displayed as "(myserver\myshare(mydirectory\\". Adding
  one LRM character at the beginning of the string will cause the leading
  backslashes to be displayed on the left side, and adding one LRM character
  at the end of the string will cause the trailing parenthesis to be displayed
  on the right side.
 
- RLM (Right-to-Left Mark): RLM is an invisible character which
  behaves like a letter in a Right to Left script like Hebrew. It can be used
  when a segment of RTL text starts or ends with characters which are not
  intrinsically RTL and is displayed in a component with a LTR
  orientation.
 Example: assume in memory the string "HELLO WORLD !". We want it displayed
  as "! DLROW OLLEH", but within a component with a LTR orientation it
  would be displayed as "DLROW OLLEH !" (exclamation mark on the right side).
  Adding one RLM character at the end of the string will cause the trailing
  exclamation mark to be displayed on the left side.
 
- LRE (Left-to-Right Embedding): LRE can be used to give a base
  LTR direction to a piece of text. It is most useful for mixed text which
  contains both LTR and RTL segments.
 Example: assume in memory the string "i love RACHEL and LEA" which should be
  displayed as "i love LEHCAR and AEL". However, within a component with RTL
  orientation, it would be displayed as "AEL and LEHCAR i love". Adding one
  LRE character at the beginning of the string and one PDF (see below)
  character at the end of the string will cause proper display.
 
- RLE (Right-to-Left Embedding): RLE can be used to give a base
  RTL direction to a piece of text.  It is most useful for mixed text which
  contains both LTR and RTL segments.
 Example: assume in memory the string "I LOVE london AND paris" which should
  be displayed as "paris DNA london EVOL I". However, within a component with
  LTR orientation, it would be displayed as "EVOL I london DNA paris".
  Adding one RLE character at the beginning of the string and adding one PDF
  (see below) character at the end of the string will cause proper display.
 
- PDF (Pop Directional Formatting): PDF may be used to limit the
  effect of a preceding LRE or RLE. It may be omitted if not followed by any
  text.
Note that pieces of text bracketed between LRE/PDF or RLE/PDF can be
contained within larger pieces of text themselves bracketed between LRE/PDF or
RLE/PDF. This is why the "E" of LRE and RLE means "embedding". This could happen
if we have for instance a Hebrew sentence containing an English phrase itself
containing an Arabic segment. In practice, such complex cases should be avoided
if possible. The present design does not use more than one level of LRE/PDF or
RLE/PDF, except possibly in regular expressions.
Bidi Classification
Characters can be classified according to their bidi type as described in the
Unicode Standard (see
Bidirectional_Character_Types for a full description of the bidi types). For
our purpose, we will distinguish the following types of characters:
  - "Strong" characters: those with a bidi type of L, R or AL
  (letters in LTR or RTL scripts);
- Numbers: European Numbers (type EN) or Arabic Numbers (type AN);
- Neutrals: all the rest.
Text Analysis
In all the structured expressions that we are addressing, we can see characters
with a special syntactical role that we will call "separators", and pieces of
text between separators that we will call "tokens". The separators vary
according to the type of structured expression. Often they are punctuation signs
like colon (:), backslash (\) and full stop (.), or mathematical signs like Plus
(+) or Equal (=).
Our objective is that the relative progression of the
tokens and separators for display should always follow the base text direction
of the text, while each token will go LTR or RTL depending on its content and
according to the UBA.
For this to happen, the following must be done:
  - Parse the expression to locate the separators and the tokens.
 
- While parsing, note the bidi classification of characters parsed.
 
- Depending on the bidi types of the characters before a token and in that
  token, a LRM or a RLM may have to be added. The algorithm for this is detailed below.
 
- If the expression has a LTR base direction and the component where
  it is displayed has a RTL orientation, add LRE+LRM at the beginning of
  the expression and LRM+PDF at its end.
 
- If the expression has a RTL base direction and the component where
  it is displayed has a LTR orientation, add RLE+RLM at the beginning of
  the expression and RLM+PDF at its end.
 
The original structured expression, before addition of directional formatting
characters, is called lean text.
The processed expression, after addition of directional formatting
characters, is called full text.
LRM Addition (structured text with LTR base text direction)
A LRM will be added before a token if the following conditions are satisfied:
  - The last strong character before the token has a bidi type equal to R or
  AL and the first non-neutral character in the token itself has a bidi type
  equal to R, AL, EN or AN.
Examples (strings in logical order where "@" represents where an LRM should
  be added):
   HEBREW @= ARABIC
   HEBREW @= 123
OR
  - The last non-neutral character before the token has a bidi type equal to
  AN and the first non-neutral character in the token has a bidi type equal to
  R, AL or AN.
Examples (strings in logical order where "@" represents where an LRM should
  be added):
   ARABIC NUMBER 123 @< MAX
   ARABIC NUMBER 123 @< 456
RLM Addition (structured text with RTL base text direction)
A RLM will be added before a token if the following conditions are satisfied:
  - The last strong character before the token has a bidi type equal 
to L and the first non-neutral character in the token itself has a bidi 
type
  equal to L or EN.
Example (string in logical order where "&" represents where an RLM should
  be added):
   my_pet &= dog