2011-09-15 12:19:24 +00:00
( *
The function to_braille from this unit translates a string from UTF8 chars to Braille chars.
The dictionaries were taken from http: //www.ibc.gov.br/?catid=110&blogid=1&itemid=479
and from http: //www.braillevirtual.fe.usp.br/pt/Portugues/braille.html
Copyright 2 0 1 1
2011-09-15 01:20:50 +00:00
* )
2011-09-15 13:26:03 +00:00
unit mod_braille;
2011-09-15 12:19:24 +00:00
interface
{$mode objfpc} {$H+}
uses
browsermodules, lclproc;
type
{ TBrailleBrowserModule }
TBrailleBrowserModule = class( TBrowserModule)
public
constructor Create; override ;
function HandleOnPageLoad( AInput: string ; out AOutput: string ) : Boolean ; override ;
end ;
function ConvertUTF8TextToBraille( Line: string ) : string ;
function ConvertUTF8HtmlTextToBraille( AInput: string ) : string ;
implementation
type
2011-11-10 18:23:42 +00:00
dictionary = array [ 1 .. 3 2 ] of string ;
2011-09-15 12:19:24 +00:00
const
number_signal = chr( $e2 ) + chr( $a0 ) + chr( $bc ) ;
caps_signal = chr( $e2 ) + chr( $a0 ) + chr( $a8 ) ;
2011-11-10 18:23:42 +00:00
d1: dictionary = ( {!} chr( $96 ) , {"} chr( $a6 ) , {# TODO} chr( $80 ) , {(*$*)} chr( $b0 ) ,
2011-09-15 12:19:24 +00:00
{%} chr( $b8 ) + chr( $e2 ) + chr( $a0 ) + chr( $b4 ) , {&} chr( $af ) , {'} chr( $84 ) ,
{(} chr( $a3 ) + chr( $e2 ) + chr( $a0 ) + chr( $84 ) , {)} chr( $a0 ) + chr( $e2 ) + chr( $a0 ) + chr( $9c ) ,
{*} chr( $94 ) , {+} chr( $96 ) , {,} chr( $82 ) , {-} chr( $a4 ) , {.} chr( $84 ) ,
{/} chr( $90 ) + chr( $e2 ) + chr( $a0 ) + chr( $b2 ) , {0} chr( $9a ) , {1} chr( $81 ) ,
{2} chr( $83 ) , {3} chr( $89 ) , {4} chr( $99 ) , {5} chr( $91 ) , {6} chr( $8b ) ,
{7} chr( $9b ) , {8} chr( $93 ) , {9} chr( $8a ) , {:} chr( $92 ) , {;} chr( $86 ) ,
2011-11-10 18:23:42 +00:00
{<} chr( $aa ) , {=} chr( $b6 ) , {>} chr( $95 ) , {?} chr( $a2 ) , {@ TODO} chr( $80 ) ) ;
2011-09-15 12:19:24 +00:00
d2: dictionary = ( {a} chr( $81 ) , {b} chr( $83 ) , {c} chr( $89 ) , {d} chr( $99 ) ,
{e} chr( $91 ) , {f} chr( $8b ) , {g} chr( $9b ) , {h} chr( $93 ) , {i} chr( $8a ) ,
{j} chr( $9a ) , {k} chr( $85 ) , {l} chr( $87 ) , {m} chr( $8d ) , {n} chr( $9d ) ,
{o} chr( $95 ) , {p} chr( $8f ) , {q} chr( $9f ) , {r} chr( $97 ) , {s} chr( $8e ) ,
{t} chr( $9e ) , {u} chr( $a5 ) , {v} chr( $a7 ) , {w} chr( $ba ) , {x} chr( $ad ) ,
2011-11-10 18:23:42 +00:00
{y} chr( $bd ) , {z} chr( $b5 ) , '' , '' , '' , '' , '' , '' ) ;
2011-09-15 12:19:24 +00:00
d3: dictionary = ( {a + grave} chr( $ab ) , {a + acute} chr( $b7 ) ,
2011-11-10 18:23:42 +00:00
{a + circumflex} chr( $a1 ) , {a + tilde} chr( $9c ) , {a + diaeresis TODO} chr( $80 ) ,
{a + ring above TODO} chr( $80 ) , {ae TODO} chr( $80 ) , {c + cedilla} chr( $af ) ,
2011-09-15 12:19:24 +00:00
{e + grave} chr( $ae ) , {e + acute} chr( $bf ) , {e + circumflex} chr( $a3 ) ,
2011-11-10 18:23:42 +00:00
{e + diaeresis TODO} chr( $80 ) , {i + grave} chr( $a9 ) , {i + acute} chr( $8c ) ,
{i + circumflex TODO} chr( $80 ) , {i + diaeresis} chr( $bb ) , {eth TODO} chr( $80 ) ,
{n + tilde TODO} chr( $80 ) , {o + grave} chr( $ba ) , {o + acute} chr( $ac ) ,
{o + circumflex} chr( $b9 ) , {o + tilde} chr( $aa ) , {o + diaeresis TODO} chr( $80 ) ,
{division sign TODO} chr( $80 ) , {o + stroke TODO} chr( $80 ) , {u + grave} chr( $b1 ) ,
{u + acute} chr( $be ) , {u + circumflex TODO} chr( $80 ) , {u + diaeresis} chr( $b3 ) ,
{y + acute TODO} chr( $80 ) , {thorn TODO} chr( $80 ) , {y + diaeresis TODO} chr( $80 ) ) ;
2011-09-15 13:43:59 +00:00
2011-09-15 12:19:24 +00:00
function ConvertUTF8TextToBraille( Line: string ) : string ;
var
2011-10-01 19:25:25 +00:00
lCharSize, count, n, next_n, len: integer ;
Braille_string: string ;
Pline: Pchar ;
num, caps: boolean ;
2011-09-15 12:19:24 +00:00
begin
Braille_string : = '' ;
num : = False ;
2011-10-01 19:25:25 +00:00
caps : = False ;
count : = 1 ;
2011-09-15 12:19:24 +00:00
if Line = '' then Result : = '' ;
2011-10-01 19:25:25 +00:00
len : = length( Line) ;
Pline : = PChar( Line) ;
2011-09-15 12:19:24 +00:00
2011-10-01 19:25:25 +00:00
while count < = len do
2011-09-15 12:19:24 +00:00
begin
2011-10-01 19:25:25 +00:00
lCharSize : = LCLProc. UTF8CharacterLength( PLine) ;
if ( lCharSize = 1 ) then
2011-09-15 12:19:24 +00:00
begin
2011-10-01 19:25:25 +00:00
n : = Ord( Line[ count] ) ;
if ( n = 9 ) then Braille_string : = Braille_string + #9
else
if ( n = 1 0 ) then Braille_string : = Braille_string + #10
2011-11-10 18:23:42 +00:00
else
if ( n = 3 2 ) then Braille_string : = Braille_string + #32
2011-10-01 19:25:25 +00:00
else
2011-09-15 12:19:24 +00:00
begin
2011-10-01 19:25:25 +00:00
if ( ( n > = 9 7 ) and ( n < = 1 2 2 ) ) then {a lower case letter}
Braille_string : = Braille_string + chr( $e2 ) + chr( $a0 ) + d2[ n - 9 6 ]
2011-09-15 12:19:24 +00:00
2011-10-01 19:25:25 +00:00
else
begin
2011-09-15 12:19:24 +00:00
2011-10-01 19:25:25 +00:00
if ( ( n > = 6 5 ) and ( n < = 9 0 ) ) then {an upper case letter}
2011-09-15 12:19:24 +00:00
begin
2011-10-01 19:25:25 +00:00
if not caps then
begin
Braille_string : = Braille_string + caps_signal;
if ( count + 2 < length( Line) ) then
begin
next_n : = Ord( Line[ count + 1 ] ) ;
if ( ( next_n > = 6 5 ) and ( next_n < = 9 0 ) ) or ( ( next_n = 1 9 5 ) and ( ( Ord( Line[ count + 2 ] ) > = 1 2 8 ) and ( Ord( Line[ count + 2 ] ) < = 1 5 9 ) ) ) then {if the next char is also upper case, add another caps signal}
begin
Braille_string : = Braille_string + caps_signal;
caps : = True ;
end ;
end ;
end ;
2011-11-10 18:23:42 +00:00
Braille_string : = Braille_string + chr( $e2 ) + chr( $a0 ) + d2[ n - 6 4 ] ;
2011-10-01 19:25:25 +00:00
if ( count + 1 < = length( Line) ) then
begin
next_n : = Ord( Line[ count + 1 ] ) ;
if not( ( ( next_n > = 6 5 ) and ( next_n < = 9 0 ) ) or ( ( next_n = 1 9 5 ) and ( ( Ord( Line[ count + 2 ] ) > = 1 2 8 ) and ( Ord( Line[ count + 2 ] ) < = 1 5 9 ) ) ) ) then caps : = False ; {if the next char is not upper case, unflag <caps>}
end ;
end
else
2011-09-15 12:19:24 +00:00
begin
2011-10-01 19:25:25 +00:00
if ( n > = 4 8 ) and ( n < = 5 7 ) then {a number}
begin
if not num then Braille_string : = Braille_string + number_signal; {first algarism of a number, add a number signal}
num : = True ;
Braille_string : = Braille_string + chr( $e2 ) + chr( $a0 ) + d1[ n - 3 1 ] ;
if ( count + 1 < = length( Line) ) then
begin
next_n : = Ord( Line[ count + 1 ] ) ;
if not ( ( next_n > = 4 8 ) and ( next_n < = 5 7 ) or ( next_n = 4 4 ) or ( next_n = 4 6 ) ) then num : = False ; {the next char is not a number, nor ',', nor '.', then unflag <num>}
end ;
end
2011-09-15 12:19:24 +00:00
else
2011-10-01 19:25:25 +00:00
begin
2011-09-15 12:19:24 +00:00
2011-11-10 18:23:42 +00:00
if ( n > = 3 3 ) and ( n < = 6 4 ) then {a char from the first dictionary}
2011-10-01 19:25:25 +00:00
begin
2011-11-10 18:23:42 +00:00
Braille_string : = Braille_string + chr( $e2 ) + chr( $a0 ) + d1[ n - 3 2 ] ;
2011-10-01 19:25:25 +00:00
if ( count + 1 < = length( Line) ) then
begin
next_n : = Ord( Line[ count + 1 ] ) ;
if ( ( n = 4 4 ) or ( n = 4 6 ) ) and not ( ( next_n > = 4 8 ) and ( next_n < = 5 7 ) ) then num : = False ; {if the char is a ',' or a '.' but the next is not a number, unflag <num>}
end ;
end ;
end ;
end ;
end ;
end ;
end
2011-09-15 12:19:24 +00:00
2011-10-01 19:25:25 +00:00
else
2011-09-15 12:19:24 +00:00
begin
2011-10-01 19:25:25 +00:00
if ( lCharSize = 2 ) then
begin
n : = Ord( Line[ count] ) ;
if ( n = 1 9 5 ) then
begin
n : = Ord( Line[ count + 1 ] ) ;
if ( n > = 1 2 8 ) and ( n < = 1 5 9 ) then {upper case accented char}
begin
if not caps then
begin
Braille_string : = Braille_string + caps_signal;
if ( count + 2 < = length( Line) ) then
begin
next_n : = Ord( Line[ count + 2 ] ) ;
if ( ( next_n > = 6 5 ) and ( next_n < = 9 0 ) ) or ( ( next_n = 1 9 5 ) and ( ( Ord( Line[ count + 2 ] ) > = 1 2 8 ) and ( Ord( Line[ count + 2 ] ) < = 1 5 9 ) ) ) then {if the next char is also upper case, add another caps signal}
begin
Braille_string : = Braille_string + caps_signal;
caps : = True ;
end ;
end ;
end ;
Braille_string : = Braille_string + chr( $e2 ) + chr( $a0 ) + d3[ n - 1 2 7 ] ;
if ( count + 3 < = length( Line) ) then
begin
next_n : = Ord( Line[ count + 2 ] ) ;
if not( ( ( next_n > = 6 5 ) and ( next_n < = 9 0 ) ) or ( ( next_n = 1 9 5 ) and ( ( Ord( Line[ count + 3 ] ) > = 1 2 8 ) and ( Ord( Line[ count + 3 ] ) < = 1 5 9 ) ) ) ) then {if the next char is not upper case, unflag <caps>}
caps : = False ;
end ;
end
else
if ( n > = 1 6 0 ) and ( n < = 1 9 1 ) then Braille_string : = Braille_string + chr( $e2 ) + chr( $a0 ) + d3[ n - 1 5 9 ] ; {lower case accented letter}
end ;
end ;
end ;
count : = count + lCharSize;
Inc( Pline, lCharSize) ;
2011-09-15 12:19:24 +00:00
end ;
Result : = Braille_string;
end ;
function ConvertUTF8HtmlTextToBraille( AInput: string ) : string ;
2011-09-15 13:10:18 +00:00
var
2011-10-19 18:00:31 +00:00
i, lCharSize: integer ;
2011-10-01 19:25:25 +00:00
output, aux_string, end_string: string ;
2011-09-15 13:10:18 +00:00
is_text: boolean ;
2011-10-01 19:25:25 +00:00
Pline : PChar ;
2011-09-15 12:19:24 +00:00
begin
2011-09-15 13:10:18 +00:00
i : = 1 ;
output : = '' ;
aux_string : = '' ;
2011-10-01 19:25:25 +00:00
is_text : = False ;
Pline : = PChar( AInput) ;
2011-09-15 13:10:18 +00:00
2011-10-01 19:25:25 +00:00
while i < = length( AInput) do
2011-09-15 13:10:18 +00:00
begin
2011-10-01 19:25:25 +00:00
end_string : = '' ;
while is_text and ( i < = length( AInput) ) do
2011-09-15 13:10:18 +00:00
begin
2011-10-19 18:00:31 +00:00
if ( AInput[ i] = '<' ) then { an instruction comes next }
2011-09-15 13:10:18 +00:00
begin
is_text : = False ;
2011-10-01 19:25:25 +00:00
i : = i + 1 ;
Inc( Pline, 1 ) ;
end_string : = '<' ;
2011-10-19 18:00:31 +00:00
if ( copy( AInput, i, 6 ) = 'script' ) then { if it' s a script, go through it and
keep reading the text }
begin
i : = i + 6 ;
Inc( Pline, 6 ) ;
end_string : = end_string + 'script' ;
while ( copy( AInput, i, 9 ) < > '</script>' ) do
begin
end_string : = end_string + AInput[ i] ;
i : = i + 1 ;
Inc( Pline, 1 ) ;
end ;
is_text : = True ;
end ;
2011-10-01 19:25:25 +00:00
break;
2011-09-15 13:10:18 +00:00
end ;
2011-10-01 19:25:25 +00:00
2011-10-19 18:00:31 +00:00
{ Read the next UTF8 character add it to aux_string }
2011-10-01 19:25:25 +00:00
lCharSize : = LCLProc. UTF8CharacterLength( Pline) ;
2011-10-19 18:00:31 +00:00
aux_string : = aux_string + copy( AInput, i, lCharSize) ;
2011-10-01 19:25:25 +00:00
i : = i + lCharSize;
Inc( Pline, lCharSize) ;
2011-09-15 13:10:18 +00:00
end ;
2011-10-19 18:00:31 +00:00
{ Translate aux_string to Braille and add it to output }
2011-10-01 19:25:25 +00:00
output : = output + ConvertUTF8TextToBraille( aux_string) + end_string;
aux_string : = '' ;
2011-09-15 13:10:18 +00:00
2011-10-01 19:25:25 +00:00
while ( not is_text) and ( i < = length( AInput) ) do
2011-09-15 13:10:18 +00:00
begin
2011-10-19 18:00:31 +00:00
if ( AInput[ i] = '>' ) then { End of instruction }
2011-09-15 13:10:18 +00:00
begin
is_text : = True ;
i : = i + 1 ;
2011-10-01 19:25:25 +00:00
Inc( Pline, 1 ) ;
2011-09-15 13:10:18 +00:00
output : = output + '>' ;
break
end ;
2011-10-19 18:00:31 +00:00
{ Add the next UTF8 character straight to output, without translating it }
2011-10-01 19:25:25 +00:00
lCharSize : = LCLProc. UTF8CharacterLength( Pline) ;
2011-10-19 18:00:31 +00:00
output : = output + copy( AInput, i, lCharSize) ;
2011-10-01 19:25:25 +00:00
i : = i + lCharSize;
Inc( Pline, lCharSize) ;
2011-09-15 13:10:18 +00:00
end ;
end ;
ConvertUTF8HtmlTextToBraille : = output;
2011-09-15 12:19:24 +00:00
end ;
{ TBrailleBrowserModule }
constructor TBrailleBrowserModule. Create;
begin
inherited Create;
ShortDescription : = 'Braille Module' ;
end ;
function TBrailleBrowserModule. HandleOnPageLoad( AInput: string ; out
AOutput: string ) : Boolean ;
begin
AOutput : = ConvertUTF8HtmlTextToBraille( AInput) ;
2011-11-10 18:23:42 +00:00
Result : = True ;
2011-09-15 12:19:24 +00:00
end ;
initialization
RegisterBrowserModule( TBrailleBrowserModule. Create( ) ) ;
end .