/[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 - (show 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 <?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 *
9 * 04/04/2005 Ported to drupal 4.6 API by Amr Mostafa
10 */
11
12 setlocale(LC_ALL, "ar_EG.UTF-8");
13
14
15 /**
16 * Implementation of hook_help()
17 */
18 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 /**
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
42 /**
43 * Implementation of hook_filter()
44 */
45 function bidi_filter($op, $delta = 0, $format = -1, $text = "") {
46 switch ($op) {
47 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 }
56 }
57
58 /**
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 function _get_dir($text) {
68 $text = strtolower($text);
69 $len = strlen($text);
70
71 $arabic = 0;
72 $english = 0;
73
74 // constants
75 $a = ord('a');
76 $z = ord('z');
77
78 // arabic UTF-8 letters have one of these values in the 1st byte
79 $ar1 = 0xd8;
80 $ar2 = 0xd9;
81
82 // 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
86 if ($bin == $ar1 || $bin == $ar2) {
87 ++$arabic;
88 ++$i;
89 }
90 else if ($bin >= $a && $bin <= $z) {
91 ++$english;
92 }
93 }
94
95 // should this return a bool instead?
96 if ($english || $arabic) {
97 if ($english > $arabic)
98 return ' dir="LTR" ';
99 else
100 return ' dir="RTL" ';
101 }
102 else {
103 return "";
104 }
105 }
106
107 /**
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 function _bidi_filter_process($text) {
118 $output = "";
119
120 $len = strlen($text);
121 $i = 0;
122
123 while ($i < $len) {
124 // find next tag
125 $e = strpos(substr($text, $i), "<");
126 if ($e === FALSE) {
127 break;
128 }
129
130 $output .= substr($text, $i, $e);
131
132 $i += $e;
133
134 // find end of next tag
135 $e = strcspn(substr($text, $i), "/> ");
136 $tag = substr($text, $i+1, $e-1);
137
138 $output .= substr($text, $i, $e);
139 $i += $e;
140
141 switch ($tag) {
142 // single tag entity
143 case "img":
144 case "br":
145 case "hr":
146 continue;
147 break;
148
149
150 // block elements these get out attention
151 case "p":
152 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
163 // 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
176 // 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 }
184
185 // any missing content
186 $output .= substr($text, $i);
187
188 return $output;
189 }
190
191 ?>

  ViewVC Help
Powered by ViewVC 1.1.2