/[drupal]/contributions/sandbox/alaa/bidi.module
ViewVC logotype

Contents of /contributions/sandbox/alaa/bidi.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.4 - (hide annotations) (download) (as text)
Sat Jun 9 22:16:45 2007 UTC (2 years, 5 months ago) by alaa
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +3 -33 lines
File MIME type: text/x-php
fixed major bug in bidi
1 alaa 1.1 <?php // -*-php-*-
2     /*
3     * Original module by Alaa Abd El Fatah.
4     * Mohammed Sameer: My Modifications Copyright (c) 2004 Mohammed Sameer,
5     * under the GNU GPL v2 or later.
6     * Mohammed Sameer: 2004 10 30
7     * * Ported to drupal 4.5 API.
8 alaa 1.2 *
9     * 04/04/2005 Ported to drupal 4.6 API by Amr Mostafa
10 alaa 1.1 */
11    
12     setlocale(LC_ALL, "ar_EG.UTF-8");
13    
14 alaa 1.2
15     /**
16     * Implementation of hook_help()
17     */
18 alaa 1.1 function bidi_help($section) {
19     $output = "";
20    
21     switch ($section) {
22     case 'admin/modules#description':
23     $output = t("Automaticaly sets line direction");
24     break;
25     }
26    
27     return $output;
28     }
29    
30 alaa 1.2 /**
31     * Implementation of hook_filter_tips()
32     */
33     function bidi_filter_tips($delta, $format, $long = false) {
34     if ($long) {
35     return t("You may write mixed Arabic and English freely, line direction will be computed automaticaly");
36     }
37     else {
38     return t("You may write mixed Arabic and English freely, line direction will be computed automaticaly");
39     }
40     }
41 alaa 1.1
42 alaa 1.2 /**
43     * Implementation of hook_filter()
44     */
45 alaa 1.1 function bidi_filter($op, $delta = 0, $format = -1, $text = "") {
46     switch ($op) {
47 alaa 1.2 case 'list':
48     return array(0 => t('BiDi'));
49     case 'description':
50     return t("Bidi filter");
51     case "process":
52     return _bidi_filter_process($text);
53     default:
54     return $text;
55 alaa 1.1 }
56     }
57    
58 alaa 1.2 /**
59     * Determine text language (arabic or english).
60     * This function needs to be split into a single include file so it can be used on theme and other places.
61     *
62     * @param $text
63     * The text needs to be.
64     * @return
65     * right2left or left2right depending on the detected language.
66     */
67 alaa 1.1 function _get_dir($text) {
68     $text = strtolower($text);
69     $len = strlen($text);
70 alaa 1.2
71 alaa 1.1 $arabic = 0;
72     $english = 0;
73    
74 alaa 1.2 // constants
75 alaa 1.1 $a = ord('a');
76     $z = ord('z');
77    
78 alaa 1.2 // arabic UTF-8 letters have one of these values in the 1st byte
79 alaa 1.1 $ar1 = 0xd8;
80     $ar2 = 0xd9;
81 alaa 1.2
82 alaa 1.1 // this calculates the dominant language in the text, most bidi implementations just use the first letter (which may be more efficient)
83     for ($i = 0; $i < $len; ++$i) {
84     $bin = ord($text[$i]);
85 alaa 1.2
86 alaa 1.1 if ($bin == $ar1 || $bin == $ar2) {
87     ++$arabic;
88     ++$i;
89 alaa 1.2 }
90     else if ($bin >= $a && $bin <= $z) {
91 alaa 1.1 ++$english;
92     }
93     }
94 alaa 1.2
95     // should this return a bool instead?
96 alaa 1.1 if ($english || $arabic) {
97     if ($english > $arabic)
98 alaa 1.3 return ' dir="LTR" ';
99 alaa 1.1 else
100 alaa 1.3 return ' dir="RTL" ';
101 alaa 1.2 }
102     else {
103 alaa 1.1 return "";
104     }
105     }
106    
107 alaa 1.2 /**
108     * Sets HTML text line directions (rtl or ltr) as needed.
109     *
110     * @param $text
111     * The HTML text needs to be processed.
112     *
113     * @return
114     * The processed result, with line directions are set using css
115     * classes "righ2left" and "left2right".
116     */
117 alaa 1.1 function _bidi_filter_process($text) {
118     $output = "";
119 alaa 1.2
120 alaa 1.1 $len = strlen($text);
121     $i = 0;
122    
123     while ($i < $len) {
124 alaa 1.2 // find next tag
125 alaa 1.1 $e = strpos(substr($text, $i), "<");
126 alaa 1.2 if ($e === FALSE) {
127     break;
128     }
129 alaa 1.1
130 alaa 1.2 $output .= substr($text, $i, $e);
131 alaa 1.1
132     $i += $e;
133    
134 alaa 1.2 // find end of next tag
135     $e = strcspn(substr($text, $i), "/> ");
136 alaa 1.1 $tag = substr($text, $i+1, $e-1);
137 alaa 1.2
138     $output .= substr($text, $i, $e);
139 alaa 1.1 $i += $e;
140    
141     switch ($tag) {
142 alaa 1.2 // single tag entity
143     case "img":
144     case "br":
145     case "hr":
146     continue;
147     break;
148    
149 alaa 1.4
150     // block elements these get out attention
151     case "p":
152 alaa 1.2 case "ul":
153     case "ol":
154     case "dl":
155     case "pre":
156     case "h1":
157     case "h2":
158     case "h3":
159     case "h4":
160     case "h5":
161     case "h6":
162 alaa 1.1
163 alaa 1.2 // nested lists are proken better think of a fix
164     case "li":
165     $close_tag = "</".$tag.">";
166     // breaks on extra whitespaces, maybe I should use regexps instead
167     $e = strpos(substr($text, $i), $close_tag);
168     $content = substr($text, $i+1, $e-1);
169     // calculate directions
170     $output.= _get_dir(strip_tags($content));
171     $e += strlen($close_tag);
172     $output.= substr($text, $i, $e);
173     $i += $e;
174     break;
175 alaa 1.1
176 alaa 1.2 // non block tags we are not handeling
177     default:
178     $close_tag = "</".$tag.">";
179     $e = strpos(substr($text, $i), $close_tag) + strlen($close_tag);
180     $output.= substr($text, $i, $e);
181     $i += $e;
182     }
183 alaa 1.1 }
184 alaa 1.2
185     // any missing content
186 alaa 1.1 $output .= substr($text, $i);
187    
188 alaa 1.2 return $output;
189 alaa 1.1 }
190    
191     ?>

  ViewVC Help
Powered by ViewVC 1.1.2