1   package org.daisy.pipeline.braille.dotify.calabash.impl;
2   
3   import javax.xml.namespace.QName;
4   
5   import org.daisy.dotify.api.table.BrailleConverter;
6   import org.daisy.dotify.api.table.Table;
7   import org.daisy.dotify.api.writer.MetaDataItem;
8   import org.daisy.dotify.api.writer.PagedMediaWriter;
9   import org.daisy.dotify.api.writer.Row;
10  
11  /**
12   * PEF writer that converts braille from specified character set to Unicode braille.
13   */
14  class PEFWriter extends PEFMediaWriter implements PagedMediaWriter {
15  
16  	private static final QName DP2_ASCII = new QName("http://www.daisy.org/ns/pipeline/", "ascii", "dp2");
17  
18  	private final BrailleConverter brailleCharset;
19  	private final Character space;
20  
21  	/**
22  	 * @param brailleCharset Braille character set of provided rows objects.
23  	 *                       <code>null</code> means the rows contain Unicode braille.
24  	 */
25  	PEFWriter(Table brailleCharset) {
26  		super();
27  		if (brailleCharset != null) {
28  			this.brailleCharset = brailleCharset.newBrailleConverter();
29  			this.space = this.brailleCharset.toText("\u2800").toCharArray()[0];
30  			// trick to add namespace nodes to "pef" element
31  			metadata.add(new MetaDataItem(new QName("http://www.w3.org/2000/xmlns/", DP2_ASCII.getPrefix(), "xmlns"),
32  			                              DP2_ASCII.getNamespaceURI()));
33  		} else {
34  			this.brailleCharset = null;
35  			this.space = '\u2800';
36  		}
37  	}
38  
39  	@Override
40  	public void newRow(Row row) {
41  		state.assertOpen();
42  		pst.print("<row");
43  		if (row.getRowSpacing() != null)
44  			pst.print(" rowgap=\"" + (int) Math.floor((row.getRowSpacing() - 1) * 4) + "\"");
45  		String chars = row.getChars();
46  		if (chars.length() > 0) {
47  			// HACK: because the Liblouis based translator always uses a space ('\s') to represent a
48  			// blank dot pattern, no matter which braille character set was specified, we replace
49  			// spaces with the correct representation here.
50  			if (space != ' ')
51  				chars = chars.replace(' ', space);
52  			// also replace '\u2800' just to be sure
53  			if (space != '\u2800')
54  				chars = chars.replace('\u2800', space);
55  			if (brailleCharset != null) {
56  				pst.print(" " + DP2_ASCII.getPrefix() + ":" + DP2_ASCII.getLocalPart() + "=\"" + chars.replace("&", "&amp;")
57  				                                                                                      .replace("\"", "&quot;")
58  				                                                                                      .replace("<", "&lt;")
59  				                                                                                      .replace(">", "&gt;")
60  				                                                                                      + "\"");
61  				try {
62  					chars = brailleCharset.toBraille(chars);
63  				} catch (RuntimeException e) {
64  					throw new RuntimeException("Braille character set '" + brailleCharset + "' does not contain character", e);
65  				}
66  			}
67  			pst.println(">" + chars + "</row>");
68  		} else
69  			pst.println("/>");
70  	}
71  }