File Coverage

blib/lib/App/Brl2Brl.pm
Criterion Covered Total %
statement 84 92 91.3
branch 24 34 70.5
condition 0 6 0.0
subroutine 11 11 100.0
pod 4 4 100.0
total 123 147 83.6


line stmt bran cond sub pod time code
1             package App::Brl2Brl;
2              
3 2     2   144957 use 5.006;
  2         31  
4 2     2   10 use strict;
  2         4  
  2         69  
5 2     2   11 use warnings FATAL => 'all';
  2         5  
  2         77  
6 2     2   628 use utf8;
  2         16  
  2         15  
7 2     2   75 use Exporter qw(import);
  2         4  
  2         69  
8 2     2   12 use Carp;
  2         3  
  2         148  
9 2     2   1099 use File::ShareDir qw(dist_dir);
  2         58952  
  2         2115  
10              
11             our @EXPORT_OK = qw(parse_dis Conv switch_brl_char_map new);
12              
13             =encoding utf8
14              
15             =head1 NAME
16              
17             App::Brl2Brl - Convert between braille display tables defined in Liblouis.
18              
19             =head1 VERSION
20              
21             Version 0.05
22              
23             =cut
24              
25             our $VERSION = '0.05';
26              
27              
28             =head1 SYNOPSIS
29              
30             This module is useful if you have a text coded for one braille character set and need to convert it to another, e.g. you have a text in North American ASCII or Eurobraille and you need it in Unicode braille.
31              
32             use App::Brl2Brl;
33              
34             my $brl_obj = App::Brl2Brl->new({ # to read in the specified files and store the characters/dots in hashes
35             from_table_file => 'en-us-brf.dis', # or another display table
36             to_table_file => 'unicode.dis', # or another display table
37             warn => 1, # if you want to be warned if a char isn't defined in table
38             });
39             my $out = $brl_obj->switch_brl_char_map('ABC123'); # switch from BRF to Unicode braille
40             print "$out\n";
41              
42             Or you may do:
43              
44             use App::Brl2Brl;
45              
46             my $from_table_file = 'en-us-brf.dis';
47             my $to_table_file = 'unicode.dis';
48              
49             my %from_table = parse_dis( "$from_table_file" );
50             my %to_table = parse_dis( "$to_table_file" );
51             while( <> ){
52             my $out = Conv( \%from_table, \%to_table, $_);
53             print "$out\n";
54             };
55              
56              
57             =head1 EXPORT
58              
59             parse_dis - Parses a given display table
60              
61             Conv - Convert from one display table to another.
62              
63             =head1 SUBROUTINES/METHODS
64              
65             =head2 new
66              
67             Takes the following parameters:
68              
69             path => '/usr/share/liblouis/tables', # path to liblouis tables
70             from_table_file => 'en-us-brf.dis', # or another display table
71             to_table_file => 'unicode.dis', # or another display table
72             warn => 1, # if you want to be warned if a char isn't defined in table
73              
74             The path is optional. App::Brl2Brl comes with a copy of the data files
75             and knows where to find them. Only provide this if you want to use a
76             different set of data files, perhaps a more recent one. As with most
77             liblouis software you can also set C in your environment.
78              
79             The order of precedence is that the value in a C argument will be used,
80             falling back to C, falling back to using the data bundled with
81             the module.
82              
83             =cut
84              
85             sub new {
86 3     3 1 1482 my ($class,$args) = @_;
87              
88             # figure out which path to use
89 3 100       11 if(!exists($args->{path})) {
90 2 100       7 if(exists($ENV{LOUIS_TABLEPATH})) {
91 1         3 $args->{path} = $ENV{LOUIS_TABLEPATH};
92             } else {
93 1         6 $args->{path} = dist_dir('App-Brl2Brl');
94             }
95             }
96              
97             my $self = {
98             path => $args->{path},
99             from_table_file => $args->{from_table_file},
100             to_table_file => $args->{to_table_file},
101             warn => $args->{warn},
102 3         202 }; # $self
103 3         14 my $complete_from_filename = "$self->{path}/"."$self->{from_table_file}";
104 3         13 my $complete_to_filename = "$self->{path}/"."$self->{to_table_file}";
105 3         11 $self->{from_table} = { parse_dis( $complete_from_filename ) };
106 1         24 $self->{to_table} = { parse_dis( $complete_to_filename ) };
107            
108 1         6 bless( $self, $class );
109 1         7 return $self;
110             } # new
111              
112             =head2 switch_brl_char_map
113              
114             Switch a character or string of characters from one character set
115             to another, defined by from_table and to_table set in the new function.
116              
117             =cut
118              
119             sub switch_brl_char_map {
120 1     1 1 848 my $self = shift;
121 1         2 my $inputstr = shift;
122 1         3 my $warn = $self->{warn};
123 1         3 my $outputstr = Conv( $self->{from_table}, $self->{to_table}, $warn, $inputstr );
124 1         4 return $outputstr;
125             } # switch_brl_char_map
126              
127             =head2 parse_dis
128              
129             Parses a liblouis display table file (.dis) and return a hash with the
130             characters and dots respectively.
131              
132             =cut
133              
134             sub parse_dis {
135 4     4 1 7 my $fileName = shift;
136 4         7 my ($char, $dots, %table);
137 4 100       268 open( DIS, "<", $fileName) || croak "Error opening file $fileName;";
138 2         102 while( my $line = ) {
139 380         598 $char = '';
140 380         453 $dots = 0;
141 380 100       839 next unless( $line =~ /^display/i);
142 320         1176 ($char, $dots) = $line =~ /display\s+(\S+)\s+(\S+)/i;
143 320 100       677 if( $char =~ /\\s/ ){
144 1         3 $char = " ";
145             }
146 320 100       498 if( length($char) >=4 ){ # $char is a hex value, not a char.
147             #$charhex = "u";
148             #$charhex = sprintf '%2.2x', unpack('U0U*', $char);
149             #$charhex .= sprintf "%04x", ord Encode::decode("UTF-8", $char);
150 256         636 $char =~ s/\\x//i;
151 256         607 $char =~ s/(....)/ pack( 'U*', hex($1))/ie;
  256         748  
152             }
153 320 50       681 if( !defined($table{$char})) {
154 320 50       636 if( $dots =~ /^$/ ){
155 0         0 $dots = 0;
156             }
157 320         441 $char =~ s/^\\\\$/\\/;
158 320         1257 $table{$char} = $dots;
159             }
160             }
161 2         24 close( DIS );
162              
163 2         8 my( $chr, $dts );
164 2         11 while( ($chr, $dts) = each (%table) ){
165 122         166 $dts = $table{$chr};
166 122 100       281 next unless( $dts == 1 );
167 2         4 last;
168             } # while
169 2 100       20 if( $chr =~ /⠁/ ){ # if dot 1 is x2801
170 1         4 $table{"⠀"} = 0; # inject unicode brl space
171             } else {
172 1         4 $table{" "} = "0";
173             } # if
174              
175 2         214 return( %table );
176             } # parse_dis
177              
178             =head2 Conv
179              
180             Converts a string, character by character, from %from_table to %to_table.
181              
182             =cut
183              
184             sub Conv {
185 1     1 1 2 my %from_tab = %{shift()};
  1         121  
186 1         13 my %to_tab = %{shift()};
  1         30  
187 1 50       10 my $warn = shift unless $#_ == 0;
188 1         2 my $inputstr = shift;
189              
190 1         2 my( $dots, $outC, $outstr);
191 1         6 foreach my $inC (split( //, $inputstr )){
192 4 50       22 if( $inC =~ /([\r\n\f])/ ){
193 0         0 $outstr .= $inC;
194 0         0 next;
195             } # if
196 4 50       10 if( !exists $from_tab{$inC} ) {
197 0         0 $outstr .= $inC;
198 0 0 0     0 carp "Warning: Character $inC isn't defined in input table!\n" if( defined $warn && $warn != 0);
199 0         0 next;
200             }
201 4         6 $dots = 0;
202 4         6 $outC = '';
203 4         7 $dots = $from_tab{$inC};
204 4         27 for my $outkey (keys %to_tab) {
205 256 100       622 if( $to_tab{$outkey} =~ /^$dots$/ ){
206 4         7 $outC = $outkey;
207 4         8 $outstr .= $outC;
208             }
209             }
210 4 50       19 if( $outC =~ /^$/ ){
211 0         0 $outstr .= $inC;
212 0 0 0     0 carp "Warning: Dots $dots isn't defined in output table!\n" if( defined $warn && $warn != 0);
213             }
214             }
215 1         35 return $outstr;
216             } # Conv
217              
218             =head1 AUTHOR
219              
220             Lars Bjørndal, C<< >>
221              
222             =head1 BUGS
223              
224             Please report any bugs or feature requests to C, or through
225             the web interface at L. I will be notified, and then you'll
226             automatically be notified of progress on your bug as I make changes.
227              
228              
229              
230              
231             =head1 SUPPORT
232              
233             You can find documentation for this module with the perldoc command.
234              
235             perldoc App::Brl2Brl
236              
237             and
238              
239             perldoc brl2brl
240              
241             You can also look for information at:
242              
243             =over 4
244              
245             =item * RT: CPAN's request tracker (report bugs here)
246              
247             L
248              
249             =item * CPAN Ratings
250              
251             L
252              
253             =item * Search CPAN
254              
255             L
256              
257             =back
258              
259              
260             =head1 ACKNOWLEDGEMENTS
261              
262              
263             =head1 LICENSE AND COPYRIGHT
264              
265             This software is Copyright (c) 2023 by Lars Bjørndal.
266              
267             This is free software, licensed under:
268              
269             The Artistic License 2.0 (GPL Compatible)
270              
271             It includes data files in the C directory copied from
272             v3.26.0 of
273             L.
274             Liblouis is free software licensed under the
275             L
276             (see the file COPYING.LESSER).
277              
278             =cut
279              
280             1; # End of App::Brl2Brl