Submitted by Alaa on Thu, 10/06/2004 - 11:30.
<?php // -*-php-*-
/*
* Original module by Alaa Abd El Fatah.
* Mohammed Sameer: My Modifications Copyright (c) 2004 Mohammed Sameer,
* under the GNU GPL v2 or later.
* Mohammed Sameer: 2004 10 30
* * Ported to drupal 4.5 API.
*
* 04/04/2005 Ported to drupal 4.6 API by Amr Mostafa
*/
setlocale(LC_ALL, "ar_EG.UTF-8");
/**
* Implementation of hook_help()
*/
function bidi_help($section) {
$output = "";
switch ($section) {
case 'admin/modules#description':
$output = t("Automaticaly sets line direction");
break;
}
return $output;
}
/**
* Implementation of hook_filter_tips()
*/
function bidi_filter_tips($delta, $format, $long = false) {
if ($long) {
return t("You may write mixed Arabic and English freely, line direction will be computed automaticaly");
}
else {
return t("You may write mixed Arabic and English freely, line direction will be computed automaticaly");
}
}
/**
* Implementation of hook_filter()
*/
function bidi_filter($op, $delta = 0, $format = -1, $text = "") {
switch ($op) {
case 'list':
return array(0 => t('BiDi'));
case 'description':
return t("Bidi filter");
case "process":
return _bidi_filter_process($text);
default:
return $text;
}
}
/**
* Determine text language (arabic or english).
* This function needs to be split into a single include file so it can be used on theme and other places.
*
* @param $text
* The text needs to be.
* @return
* right2left or left2right depending on the detected language.
*/
function _get_dir($text) {
$text = strtolower($text);
$len = strlen($text);
$arabic = 0;
$english = 0;
// constants
$a = ord('a');
$z = ord('z');
// arabic UTF-8 letters have one of these values in the 1st byte
$ar1 = 0xd8;
$ar2 = 0xd9;
// this calculates the dominant language in the text, most bidi implementations just use the first letter (which may be more efficient)
for ($i = 0; $i < $len; ++$i) {
$bin = ord($text[$i]);
if ($bin == $ar1 || $bin == $ar2) {
++$arabic;
++$i;
}
else if ($bin >= $a && $bin <= $z) {
++$english;
}
}
// should this return a bool instead?
if ($english || $arabic) {
if ($english > $arabic)
return ' dir="LTR" ';
else
return ' dir="RTL" ';
}
else {
return "";
}
}
/**
* Sets HTML text line directions (rtl or ltr) as needed.
*
* @param $text
* The HTML text needs to be processed.
*
* @return
* The processed result, with line directions are set using css
* classes "righ2left" and "left2right".
*/
function _bidi_filter_process($text) {
$output = "";
$len = strlen($text);
$i = 0;
while ($i < $len) {
// find next tag
$e = strpos(substr($text, $i), "<");
if ($e === FALSE) {
break;
}
$output .= substr($text, $i, $e);
$i += $e;
// find end of next tag
$e = strcspn(substr($text, $i), "/> ");
$tag = substr($text, $i+1, $e-1);
$output .= substr($text, $i, $e);
$i += $e;
switch ($tag) {
// single tag entity
case "img":
case "br":
case "hr":
continue;
break;
//nested cases
case "ul":
case "ol":
case "dl":
case "div":
$e = 0;
// stack counter
$j = 1;
// if $j = 0 then stack is empty
while ($j > 0) {
$e += strpos(substr($text, $i+$e) , $tag);
// yeah I know I'm assuming certain sizes for tags, sue me
// new nested block
if ($text[$i+$e-1] == '<') {
++$j;
}
// end of block
else if ($text[$i+$e-1] == '/') {
--$j;
}
// skip current tag
$e += 2;
}
$content = substr($text, $i+1, $e);
$output .= _get_dir(strip_tags($content));
$e += strlen($tag);
$output.= substr($text, $i, $e);
$i += $e;
break;
// block elements these get out attention
case "p":
case "blockquote":
case "pre":
case "h1":
case "h2":
case "h3":
case "h4":
case "h5":
case "h6":
// nested lists are proken better think of a fix
case "li":
$close_tag = "</".$tag.">";
// breaks on extra whitespaces, maybe I should use regexps instead
$e = strpos(substr($text, $i), $close_tag);
$content = substr($text, $i+1, $e-1);
// calculate directions
$output.= _get_dir(strip_tags($content));
$e += strlen($close_tag);
$output.= substr($text, $i, $e);
$i += $e;
break;
// non block tags we are not handeling
default:
$close_tag = "</".$tag.">";
$e = strpos(substr($text, $i), $close_tag) + strlen($close_tag);
$output.= substr($text, $i, $e);
$i += $e;
}
}
// any missing content
$output .= substr($text, $i);
return $output;
}
?>
- Printer-friendly version
- Login or register to post comments
- 1697 reads

