1   package nl.dedicon.pipeline.braille.step;
2   
3   import nl.dedicon.pipeline.braille.step.Utils;
4   import java.io.StringWriter;
5   import java.util.HashMap;
6   import java.util.Map;
7   import nl.dedicon.pipeline.braille.calabash.impl.SymbolsListStep;
8   import org.slf4j.Logger;
9   import org.slf4j.LoggerFactory;
10  
11  /**
12   * Dedicon BRL
13   * Maps BRL characters to Unicode Braille characters
14   * 
15   * Based on Wim Berden's dediconbrl.php
16   * Modifications:
17   *   - added missing characters so that all uppercase/lowercase combinations are present
18   *   - reordered so that an uppercase character always precedes the lowercase variant
19   *   - changed Ú mapping from 0x2839 to 0x283E
20   * 
21   * @author Paul Rambags
22   */
23  public class DediconBrl {
24  
25      private static final Map<Character, Character> brlToUnicodeMap = new HashMap<>();
26      private static final Logger logger = LoggerFactory.getLogger(SymbolsListStep.class);
27  
28      private static void map (char brlChar, int unicodeChar) {
29          brlToUnicodeMap.put(brlChar, (char)unicodeChar);
30      }
31      
32      static {
33          map(' ', 0x2800);
34          map('1', 0x2801);
35          map('A', 0x2801);
36          map('a', 0x2801);	
37          map(',', 0x2802);
38          map('2', 0x2803);
39          map('B', 0x2803);
40          map('b', 0x2803);
41          map('\'', 0x2804);
42          map('K', 0x2805);
43          map('k', 0x2805);
44          map(';', 0x2806);
45          map('L', 0x2807);
46          map('l', 0x2807);
47          map('&', 0x2808);
48          map('3', 0x2809);
49          map('C', 0x2809);
50          map('c', 0x2809);
51          map('9', 0x280A);
52          map('I', 0x280A);
53          map('i', 0x280A);
54          map('6', 0x280B);
55          map('F', 0x280B);
56          map('f', 0x280B);
57          map('/', 0x280C);
58          map('ì', 0x280C);
59          map('í', 0x280C);
60          map('M', 0x280D);
61          map('m', 0x280D);
62          map('S', 0x280E);
63          map('s', 0x280E);
64          map('P', 0x280F);
65          map('p', 0x280F);
66          map('|', 0x2810);
67          map('5', 0x2811);
68          map('E', 0x2811);
69          map('e', 0x2811);
70          map(':', 0x2812);
71          map('8', 0x2813);
72          map('H', 0x2813);
73          map('h', 0x2813);
74          map('*', 0x2814);
75          map('O', 0x2815);
76          map('o', 0x2815);
77          map('!', 0x2816);
78          map('+', 0x2816);
79          map('¡', 0x2816);
80          map('R', 0x2817);
81          map('r', 0x2817);
82          map(']', 0x2818);
83          map('4', 0x2819);
84          map('D', 0x2819);
85          map('d', 0x2819);
86          map('0', 0x281A);
87          map('J', 0x281A);
88          map('j', 0x281A);
89          map('7', 0x281B);
90          map('G', 0x281B);
91          map('g', 0x281B);
92          map('Ä', 0x281C);
93          map('ä', 0x281C);
94          map('Å', 0x281C);
95          map('å', 0x281C);
96          map('N', 0x281D);
97          map('n', 0x281D);
98          map('T', 0x281E);
99          map('t', 0x281E);
100         map('Q', 0x281F);
101         map('q', 0x281F);
102         map('@', 0x2820);
103         map('\\', 0x2821);
104         map('Â', 0x2821);
105         map('â', 0x2821);
106         map('?', 0x2822);
107         map('¿', 0x2822);
108         map('Ê', 0x2823);
109         map('ê', 0x2823);
110         map('-', 0x2824);
111         map('U', 0x2825);
112         map('u', 0x2825);
113         map('<', 0x2826);
114         map('}', 0x2826);
115         map('V', 0x2827);
116         map('v', 0x2827);
117         map('{', 0x2828);
118         map('Î', 0x2829);
119         map('î', 0x2829);
120         map('Ö', 0x282A);
121         map('ö', 0x282A);
122         map('Ë', 0x282B);
123         map('ë', 0x282B);
124         map('Ò', 0x282C);
125         map('ò', 0x282C);
126         map('Ó', 0x282C);
127         map('ó', 0x282C);
128         map('X', 0x282D);
129         map('x', 0x282D);
130         map('È', 0x282E);
131         map('è', 0x282E);
132         map('ß', 0x282E);
133         map('#', 0x282F);
134         map('Ç', 0x282F);
135         map('ç', 0x282F);
136         map('~', 0x2830);
137         map('Û', 0x2831);
138         map('û', 0x2831);
139         map('$', 0x2832);
140         map('.', 0x2832);
141         map('Ü', 0x2833);
142         map('ü', 0x2833);
143         map('"', 0x2834);
144         map('>', 0x2834);
145         map('Z', 0x2835);
146         map('z', 0x2835);
147         map('(', 0x2836);
148         map(')', 0x2836);
149         map('=', 0x2836);
150         map('À', 0x2837);
151         map('à', 0x2837);
152         map('Á', 0x2837);
153         map('á', 0x2837);
154         map('[', 0x2838);
155         map('Ô', 0x2839);
156         map('ô', 0x2839);
157         map('W', 0x283A);
158         map('w', 0x283A);
159         map('Ï', 0x283B);
160         map('ï', 0x283B);
161         map('Ñ', 0x283B);
162         map('ñ', 0x283B);
163         map('%', 0x283C);
164         map('Y', 0x283D);
165         map('y', 0x283D);
166         map('Ù', 0x283E);
167         map('ù', 0x283E);
168         map('Ú', 0x283E);
169         map('ú', 0x283E);
170         map('É', 0x283F);
171         map('é', 0x283F);
172     }
173 
174     /**
175      * Convert BRL characters to unicode braille, if necessary.
176      * 
177      * Sometimes a BRL character must be converted to a unicode braille character.
178      * For instance, the pipeline would convert BRL character ~ to (5 26) but it should be converted to (56) according to the table above. 
179      * Case information gets lost when converting to unicode braille.
180      * Therefore, as much as possible we let the pipeline take care of the conversion to unicode braille.
181      * 
182      * @param braille Symbol replacement
183      * @return certain BRL characters replaced by Unicode braille characters
184      */
185     public static String convert(String braille) {
186         StringWriter result = new StringWriter();
187         for (int i = 0; i < braille.length(); i++) {
188             char brailleChar = braille.charAt(i);
189             if (Character.isLetterOrDigit(brailleChar)) {
190                 // let the pipeline convert this BRL character to unicode braille
191                 // and take care of capitalization
192                 result.append(brailleChar);
193             } else {
194                 Character unicodeChar = brlToUnicodeMap.get(brailleChar);
195                 if (unicodeChar != null) {
196                     result.append(unicodeChar);
197                 } else {
198                     result.append(brailleChar);
199                     if (!Utils.isBraille(brailleChar)) {
200                         logger.warn("Unknown BRL character: '{}'", brailleChar);
201                     }
202                 }
203             }
204         }
205         return result.toString();
206     }
207 }