Do you think it will work for Linux? I would think that cross-platform differences would have been taken care of in Java native methods. John On Thu, Dec 16, 2010 at 03:59:09PM +0100, Bert Frees wrote: > The method for calling xml2brl is now in LiblouisXML.java: > https://odt2braille.svn.sourceforge.net/svnroot/odt2braille/Odt2Braille/src/be/docarch/odt2braille/LiblouisXML.java > It works for both Windows and Mac OS. > > Bert > > > On 16/12/2010 15:51, John J. Boyer wrote: > >First, my server is back up. We're tying up the loose ends. > > > >Below is the Odt2Braille.java class from the odt2braille plugin for > >OpenOffi e. It calls xml2brl with RunTime.exec We could easily modify it > >to call file2brl > > > >Because of the server problems I haven't yet read the tutorial that > >Susan suggested. What do you think of the following? Search for the word > >execute to find the method that does the actual work. > > > >---------------------- > > > >/** > > * odt2braille - Braille authoring in OpenOffice.org. > > * > > * Copyright (c) 2010 by DocArch<http://www.docarch.be>. > > * > > * This program is free software: you can redistribute it and/or modify > > * it under the terms of the GNU General Public License as published by > > * the Free Software Foundation, either version 3 of the License, or > > * (at your option) any later version. > > * > > * This program is distributed in the hope that it will be useful, > > * but WITHOUT ANY WARRANTY; without even the implied warranty of > > * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > * GNU General Public License for more details. > > * > > * You should have received a copy of the GNU General Public License > > * along with this program. If not, see<http://www.gnu.org/licenses/>. > > */ > > > >package be.docarch.odt2braille; > > > >import java.io.BufferedReader; > >import java.io.InputStream; > >import java.io.InputStreamReader; > >import java.io.BufferedWriter; > >import java.io.Writer; > >import java.io.FileWriter; > >import java.util.logging.Logger; > >import java.util.logging.Level; > >import java.io.File; > >import java.util.ArrayList; > >import javax.xml.parsers.DocumentBuilder; > >import javax.xml.parsers.DocumentBuilderFactory; > >import org.w3c.dom.Document; > >import org.w3c.dom.Node; > >import org.w3c.dom.Element; > >import org.w3c.dom.DOMImplementation; > >import org.w3c.dom.ProcessingInstruction; > >import java.io.FileInputStream; > >import org.apache.commons.io.IOUtils; > >import java.util.regex.Matcher; > >import java.util.regex.Pattern; > >import java.util.Locale; > >import java.util.ResourceBundle; > >import javax.xml.namespace.NamespaceContext; > >import net.sf.saxon.TransformerFactoryImpl; > >import javax.xml.transform.Transformer; > >import javax.xml.transform.stream.StreamResult; > >import javax.xml.transform.stream.StreamSource; > >import javax.xml.transform.OutputKeys; > > > >import javax.xml.parsers.ParserConfigurationException; > >import java.io.IOException; > >import org.xml.sax.SAXException; > >import javax.xml.transform.TransformerConfigurationException; > >import javax.xml.transform.TransformerException; > > > >import com.versusoft.packages.jodl.OdtUtils; > >import org_pef_text.AbstractTable; > >import org_pef_text.TableFactory; > >import org_pef_text.TableFactory.TableType; > > > > > >/** > > * This class provides a way to convert a flat .odt file to a > > *<a > > > > href="http://www.daisy.org/projects/braille/braille_workarea/pef.html";>.pef > > (portable embosser format)</a> file. > > * The conversion is done according to previously defined braille {@link > > Settings}. > > *<code>liblouisxml</code> is used for the actual transcription to > > braille. > > * A {@link Checker} checks the resulting braille document for possible > > accessibility issues. > > * > > * @see<a > > href="http://code.google.com/p/liblouisxml/";><code>liblouisxml</code></a> > > * @author Bert Frees > > */ > >public class Odt2Braille { > > > > private final static Logger logger = > > Logger.getLogger("be.docarch.odt2braille.addone"); > > private static NamespaceContext namespace = new > > Odt2BrailleNamespaceContext(); > > > > private final static boolean IS_WINDOWS = > > System.getProperty("os.name").toLowerCase().contains("windows"); > > private static final String LIBLOUIS_EXEC_NAME = "xml2brl"; > > private final static String LIBLOUIS_EXEC_EXT = IS_WINDOWS?".exe":""; > > > > private static final String TMP_NAME = "odt2braille"; > > private final static String DAISY_EXT = ".xml"; > > private final static String BRAILLE_EXT = ".txt"; > > private final static String CONFIG_EXT = ".cfg"; > > > > public enum TranscribersNote { IMAGES_NOT_REPRODUCED }; > > > > public enum VolumeType { NORMAL, > > PRELIMINARY, > > SUPPLEMENTARY, > > NONE }; > > > > private static String L10N_statusIndicatorStep = null; > > > > private String liblouisDirUrl = null; > > private String brailleUrl = null; > > private String daisyUrl = null; > > > > private File brailleFile = null; > > private File daisyFile = null; > > private File stylesFile = null; > > private File chardefsFile = null; > > private File tempChardefsFile = null; > > > > private Odt2Daisy odt2daisy; > > private Settings settings = null; > > private StatusIndicator statusIndicator = null; > > private Checker checker = null; > > > > private ArrayList configurationList = new ArrayList(); > > > > AbstractTable liblouisTable = new > > TableFactory().newTable(TableType.LIBLOUIS); > > > > /** > > * Creates a new<code>Odt2Braille</code> instance. > > * The {@link Locale} for the user interface is set to the default > > value. > > * > > * @param flatOdtFile The "flat XML" .odt file. > > * This single file is the concatenation of > > all XML files in a normal .odt file. > > * @param liblouisDirUrl The URL of the<code>liblouis</code> > > executable. > > * @param settings The<code>Settings</code> that determine > > how the conversion is done. > > * @param statusIndicator The<code>StatusIndicator</code> that > > will be used. > > * @param checker The<code>Checker</code> that will check > > the braille document for possible accessibility issues. > > * @param odtLocale The<code>Locale</code> for the document. > > */ > > public Odt2Braille(File flatOdtFile, > > String liblouisDirUrl, > > Settings settings, > > StatusIndicator statusIndicator, > > Checker checker, > > Locale odtLocale) > > throws IOException, > > ParserConfigurationException, > > SAXException, > > TransformerConfigurationException, > > TransformerException{ > > > > this(flatOdtFile, liblouisDirUrl, settings, statusIndicator, > > checker, odtLocale, Locale.getDefault()); > > > > } > > > > /** > > * Creates a new<code>Odt2Braille</code> instance. > > * > > * @param flatOdtFile The "flat XML" .odt file. > > * This single file is the concatenation of > > all XML files in a normal .odt file. > > * @param liblouisDirUrl The URL of the liblouis executable. > > liblouis is used for the actual transcription to braille. > > * @param statusIndicator The<code>StatusIndicator</code> that > > will be used. > > * @param settings The<code>Settings</code> that determine > > how the conversion is done. > > * @param checker The<code>Checker</code> that will check > > the braille document for possible accessibility issues. > > * @param odtLocale The<code>Locale</code> for the document. > > * @param oooLocale The<code>Locale</code> for the user > > interface. > > */ > > public Odt2Braille(File flatOdtFile, > > String liblouisDirUrl, > > Settings settings, > > StatusIndicator statusIndicator, > > Checker checker, > > Locale odtLocale, > > Locale oooLocale) > > throws IOException, > > ParserConfigurationException, > > SAXException, > > TransformerConfigurationException, > > TransformerException { > > > > logger.entering("Odt2Braille", "<init>"); > > > > this.settings = settings; > > this.liblouisDirUrl = liblouisDirUrl; > > this.statusIndicator = statusIndicator; > > this.checker = checker; > > > > L10N_statusIndicatorStep = > > ResourceBundle.getBundle("be/docarch/odt2braille/l10n/Bundle", > > oooLocale).getString("statusIndicatorStep"); > > > > // Request temporary liblouisxml braille file > > brailleFile = File.createTempFile(TMP_NAME,BRAILLE_EXT); > > brailleFile.deleteOnExit(); > > brailleUrl = brailleFile.getAbsolutePath(); > > > > // Request temporary daisy xml file > > daisyFile = File.createTempFile(TMP_NAME,DAISY_EXT); > > daisyFile.deleteOnExit(); > > daisyUrl = daisyFile.getAbsolutePath(); > > > > // Create odt2daisy > > odt2daisy = new Odt2Daisy(flatOdtFile, settings, > > this.statusIndicator, odtLocale, oooLocale); > > odt2daisy.preProcessing(); > > > > chardefsFile = new File(liblouisDirUrl + "share" + > > System.getProperty("file.separator") > > + "liblouis" + > > > > System.getProperty("file.separator") > > + "tables" + > > > > System.getProperty("file.separator") > > + "_chardefs.cti"); > > tempChardefsFile = File.createTempFile(TMP_NAME, ".xml"); > > tempChardefsFile.deleteOnExit(); > > stylesFile = File.createTempFile(TMP_NAME,CONFIG_EXT); > > stylesFile.deleteOnExit(); > > createStylesFile(); > > > > } > > > > private void createStylesFile() throws IOException { > > > > logger.entering("Odt2Braille", "createStylesFile"); > > > > // Create temporary styles file > > > > Writer bufferedWriter = new BufferedWriter(new > > FileWriter(stylesFile)); > > String sep = System.getProperty("line.separator"); > > String s = null; > > > > // Paragraphs > > > > s = "firstLineIndent " + > > (settings.getFirstLineMargin("paragraph") - > > settings.getRunoversMargin("paragraph")) + sep > > + "leftMargin " + settings.getRunoversMargin("paragraph") > > + sep > > + "linesBefore " + settings.getLinesAbove("paragraph") + sep > > + "linesAfter " + settings.getLinesBelow("paragraph") + sep > > + "format " + > > (settings.getCentered("paragraph")?"centered":"leftJustified") > > + sep; > > bufferedWriter.write("style para" + sep + s); > > > > // Headings > > > > for (int i=1;i<=4;i++) { > > s = "firstLineIndent " + > > (settings.getFirstLineMargin("heading" + i) - > > settings.getRunoversMargin("heading" + i)) + sep > > + "leftMargin " + settings.getRunoversMargin("heading" > > + i) + sep > > + "linesBefore " + 0 + sep > > + "linesAfter " + 0 + sep > > + "format " + (settings.getCentered("heading" + > > i)?"centered":"leftJustified") + sep; > > bufferedWriter.write("style heading" + i + sep + s); > > bufferedWriter.write("style dummyheading" + i + sep + s); > > s = "linesBefore " + settings.getLinesAbove("heading" + > > i) + sep > > + "linesAfter " + settings.getLinesBelow("heading" + > > i) + sep; > > bufferedWriter.write("style heading" + i + "container" + sep > > + s); > > } > > > > // Lists > > > > for (int i=1;i<=10;i++) { > > s = "linesBefore " + settings.getLinesAbove("list" + i) + > > sep > > + "linesAfter " + settings.getLinesBelow("list" + i) + > > sep; > > bufferedWriter.write("style list" + i + sep + s); > > s = "linesAfter " + settings.getLinesBetween("list" + i) > > + sep; > > bufferedWriter.write("style li" + i + sep + s); > > s = "firstLineIndent " + (settings.getFirstLineMargin("list" > > + i) - settings.getRunoversMargin("list" + i)) + sep > > + "leftMargin " + settings.getRunoversMargin("list" + > > i) + sep > > + "format " + (settings.getCentered("list" + > > i)?"centered":"leftJustified") + sep; > > bufferedWriter.write("style listitem" + i + sep + s); > > } > > > > for (int i=2;i<=10;i++) { > > s = "linesBefore " + settings.getLinesAbove("list" + i) + > > sep; > > bufferedWriter.write("style lastlist" + i + sep + s); > > } > > > > // Tables > > > > s = "linesBefore " + settings.getLinesAbove("table") + sep > > + "linesAfter " + settings.getLinesBelow("table") + sep; > > bufferedWriter.write("style tablenoborder" + sep + s); > > bufferedWriter.write("style lasttablerow" + sep); > > > > if (settings.stairstepTableIsEnabled()) { > > > > for (int i=1;i<=10;i++) { > > s = "firstLineIndent " + > > (settings.getFirstLineMargin("table" + i) - > > settings.getRunoversMargin("table" + i)) + sep > > + "leftMargin " + > > settings.getRunoversMargin("table" + i) + sep > > + "format " + (settings.getCentered("table" + > > i)?"centered":"leftJustified") + sep; > > bufferedWriter.write("style tablecolumn" + i + sep + s); > > } > > > > s = ""; > > } else { > > s = "firstLineIndent " + > > (settings.getFirstLineMargin("table") - > > settings.getRunoversMargin("table")) + sep > > + "leftMargin " + settings.getRunoversMargin("table") > > + sep > > + "format " + > > (settings.getCentered("table")?"centered":"leftJustified") > > + sep; > > bufferedWriter.write(s); > > } > > > > s += "linesAfter " + settings.getLinesBetween("table") + sep; > > bufferedWriter.write("style tablerow" + sep + s); > > > > // Pagenumbers > > > > bufferedWriter.write("style document" + sep + > > "braillePageNumberFormat " + > > (settings.getBraillePageNumbers()?"normal": > > "blank") + sep); > > bufferedWriter.write("style preliminary" + sep + > > "braillePageNumberFormat " + > > > > (settings.getBraillePageNumbers()?settings.getPreliminaryPageFormat():"blank") > > + sep); > > > > // Table of contents > > > > s = "firstLineIndent " + (settings.getFirstLineMargin("heading1") > > - settings.getRunoversMargin("heading1")) + sep > > + "leftMargin " + settings.getRunoversMargin("heading1") + > > sep > > + "linesBefore " + settings.getLinesAbove("heading1") + sep > > + "linesAfter " + settings.getLinesBelow("heading1") + sep > > + "format " + > > (settings.getCentered("heading1")?"centered":"leftJustified") + > > sep; > > bufferedWriter.write("style contentsheader" + sep + s); > > > > for (int i=1;i<=4;i++) { > > s = "firstLineIndent " + (settings.getFirstLineMargin("toc" + > > i) - settings.getRunoversMargin("toc" + i)) + sep > > + "leftMargin " + settings.getRunoversMargin("toc" + > > i) + sep > > /* + "linesAfter " + settings.getLinesBetween("toc") > > + sep */ > > + "format " + "contents" + sep; > > bufferedWriter.write("style contents" + i + sep + s); > > } > > > > bufferedWriter.close(); > > > > logger.exiting("Odt2Braille", "createStylesFile"); > > > > } > > > > private void createChardefsFile(File daisyFile) throws IOException, > > > > TransformerConfigurationException, > > > > TransformerException { > > > > logger.entering("Odt2Braille", "createChardefsFile"); > > > > File newChardefsFile = File.createTempFile(TMP_NAME, ".cti"); > > TransformerFactoryImpl tFactory = new > > net.sf.saxon.TransformerFactoryImpl(); > > Transformer unicodeBlocksTransformer = > > tFactory.newTransformer(new > > > > StreamSource(getClass().getResource("/be/docarch/odt2braille/unicodeblocks.xsl").toString())); > > Writer bufferedWriter = new BufferedWriter(new > > FileWriter(newChardefsFile)); > > > > unicodeBlocksTransformer.setOutputProperty(OutputKeys.ENCODING, > > "UTF-8"); > > unicodeBlocksTransformer.setOutputProperty(OutputKeys.METHOD, > > "xml"); > > unicodeBlocksTransformer.setOutputProperty(OutputKeys.INDENT, > > "yes"); > > > > unicodeBlocksTransformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount";, > > "3"); > > unicodeBlocksTransformer.transform(new StreamSource(daisyFile), > > new StreamResult(tempChardefsFile)); > > > > bufferedWriter.write("include > > _chardefs_unicode_BRAILLE_PATTERNS.cti" + > > System.getProperty("line.separator") // First table should be > > BRAILLE_PATTERNS > > + "include _chardefs_unicode_BASIC_LATIN.cti" > > + System.getProperty("line.separator") > > + "include > > _chardefs_unicode_LATIN_1_SUPPLEMENT.cti" + > > System.getProperty("line.separator") > > + "include > > _chardefs_unicode_PRIVATE_USE_AREA.cti" + > > System.getProperty("line.separator")); > > > > String s = null; > > for (int i=1; > > i<=XPathUtils.evaluateNumber(tempChardefsFile.toURL().openStream(), > > "count(/unicodeblocks/block)"); i++) { > > s = > > > > XPathUtils.evaluateString(tempChardefsFile.toURL().openStream(), > > "/unicodeblocks/block[" + i + "]/@name"); > > if (s != null) { > > s = "include _chardefs_unicode_" + s + ".cti"; > > bufferedWriter.write(s + > > System.getProperty("line.separator")); > > logger.log(Level.INFO, s); > > } > > } > > > > bufferedWriter.close(); > > if (chardefsFile.exists()) { chardefsFile.delete(); } > > newChardefsFile.renameTo(chardefsFile); > > > > logger.exiting("Odt2Braille", "createChardefsFile"); > > > > } > > > > /** > > * Converts the flat .odt filt to a .pef file according to the > > braille settings. > > * > > * This function > > *<ul> > > *<li>makes calls to {@link Odt2Daisy}.<code>convertAsDTBook</code> > > to convert the .odt file to multiple DAISY-like xml files,</li> > > *<li>uses<code>liblouisxml</code> to translate these files into > > braille, and</li> > > *<li>recombines these braille files into one single .pef file.</li> > > *</ul> > > * > > * First, the document<i>body</i> is processed and split in volumes, > > then the<i>page ranges</i> are calculated > > * and finally the<i>preliminary pages</i> of each volume are > > processed and inserted at the right places. > > * The checker checks the DAISY-like files and the volume lengths. > > * > > * When a multi-volume feature is added to liblouisxml, this > > procedure of pef-creation might be simplified a lot. > > * > > * @param pefUrl The URL of the .pef file. > > */ > > public boolean makePEF(String pefUrl) > > throws IOException, > > ParserConfigurationException, > > TransformerConfigurationException, > > TransformerException, > > InterruptedException, > > LiblouisException { > > > > logger.entering("Odt2Braille", "makePEF"); > > > > VolumeType[] volumeTypes = new > > VolumeType[(settings.preliminaryVolumeEnabled?1:0) + > > > > Math.max(1,settings.NUMBER_OF_VOLUMES) + > > > > settings.NUMBER_OF_SUPPLEMENTS]; > > ArrayList<SpecialSymbol> specialSymbolsList = > > settings.getSpecialSymbolsList(); > > > > DocumentBuilderFactory docFactory; > > DocumentBuilder docBuilder; > > Document document; > > Element headElement; > > Element dcElement; > > Element bodyElement; > > Element[] volumeElements = new Element[volumeTypes.length]; > > Element sectionElement; > > Element pageElement; > > Element rowElement; > > Node node; > > ProcessingInstruction pi; > > BufferedReader bufferedReader = null; > > FileInputStream fileInputStream = null; > > InputStreamReader inputStreamReader = null; > > String brfInput = null; > > String line = null; > > > > int lineCount; > > int pageCount; > > int volumeCount; > > boolean cont; > > Matcher matcher; > > char ch; > > > > int volumeNr; > > boolean extractpprangemode; > > boolean allVolumes; > > boolean body; > > boolean front; > > int beginPage; > > int endPage; > > int prelPages; > > > > int[] bodyPageCount = new int[volumeTypes.length]; > > int[] preliminaryPageCount = new int[volumeTypes.length]; > > String[] beginPrintPages = new String[volumeTypes.length]; > > String[] endPrintPages = new String[volumeTypes.length]; > > boolean[][] specialSymbolsPresent = new > > boolean[volumeTypes.length][specialSymbolsList.size()]; > > boolean[][] transcribersNotesEnabled = new > > boolean[volumeTypes.length][TranscribersNote.values().length]; > > > > // Initialization > > > > for (int i=1;i<=volumeTypes.length;i++) { > > if (i-(settings.preliminaryVolumeEnabled?1:0)==0) { > > volumeTypes[i-1] = VolumeType.PRELIMINARY; > > } else if (i-(settings.preliminaryVolumeEnabled?1:0)> > > Math.max(1,settings.NUMBER_OF_VOLUMES)) { > > volumeTypes[i-1] = VolumeType.SUPPLEMENTARY; > > } else { > > volumeTypes[i-1] = VolumeType.NORMAL; > > } > > bodyPageCount[i-1] = 0; > > preliminaryPageCount[i-1] = 0; > > for (int j=1;j<=specialSymbolsPresent[0].length;j++) { > > specialSymbolsPresent[i-1][j-1] = false; > > } > > for (int j=1;j<=TranscribersNote.values().length;j++) { > > transcribersNotesEnabled[i-1][j-1] = false; > > } > > } > > > > try { > > > > docFactory = DocumentBuilderFactory.newInstance(); > > docFactory.setValidating(false); > > docBuilder = docFactory.newDocumentBuilder(); > > DOMImplementation impl = docBuilder.getDOMImplementation(); > > > > document = > > impl.createDocument("http://www.daisy.org/ns/2008/pef";, > > "pef", null); > > Element root = document.getDocumentElement(); > > root.setAttributeNS(null,"version","2008-1"); > > > > headElement = > > > > document.createElementNS("http://www.daisy.org/ns/2008/pef","head";); > > headElement.setAttributeNS("http://www.w3.org/2000/xmlns/";, > > "xmlns:dc", "http://purl.org/dc/elements/1.1/";); > > dcElement = > > > > document.createElementNS("http://purl.org/dc/elements/1.1/","dc:identifier";); > > node = document.createTextNode("00001"); > > dcElement.appendChild(node); > > headElement.appendChild(dcElement); > > dcElement = > > > > document.createElementNS("http://purl.org/dc/elements/1.1/","dc:format";); > > node = document.createTextNode("application/x-pef+xml"); > > dcElement.appendChild(node); > > headElement.appendChild(dcElement); > > > > root.appendChild(headElement); > > > > // BODY: Split into volumes and extract page ranges > > > > allVolumes = true; // all volumes > > body = true; // only body > > front = false; // no front > > beginPage = 1; > > endPage = 0; // not relevant > > prelPages = 0; // not relevant > > volumeNr = 0; // not relevant > > extractpprangemode = false; > > > > if (!odt2daisy.convertAsDTBook(daisyUrl, allVolumes, > > volumeNr, VolumeType.NONE, body, front, beginPage, endPage, > > prelPages, null, null, null, null)) { > > return false; > > } > > checker.checkDaisyFile(daisyFile); > > configureLiblouisxml(extractpprangemode, beginPage); > > runLiblouisxml(); > > > > fileInputStream = new FileInputStream(brailleFile); > > inputStreamReader = new > > InputStreamReader(fileInputStream,"UTF-8"); > > bufferedReader = new BufferedReader(inputStreamReader); > > > > statusIndicator.setSteps(1 + > > (settings.PRELIMINARY_PAGES_PRESENT?volumeElements.length:0)); > > statusIndicator.reset(); > > statusIndicator.setStatus(L10N_statusIndicatorStep); > > > > for (volumeCount = 1;volumeCount<= > > volumeElements.length;volumeCount++) { > > > > logger.log(Level.INFO,"Processing body of volume " + > > volumeCount + "/" + volumeElements.length); > > > > volumeElements[volumeCount-1] = > > > > document.createElementNS("http://www.daisy.org/ns/2008/pef","volume";); > > > > volumeElements[volumeCount-1].setAttributeNS(null,"cols",String.valueOf(settings.getNumberOfCellsPerLine())); > > > > volumeElements[volumeCount-1].setAttributeNS(null,"rows",String.valueOf(settings.getNumberOfLinesPerPage())); > > > > volumeElements[volumeCount-1].setAttributeNS(null,"rowgap","0"); > > > > volumeElements[volumeCount-1].setAttributeNS(null,"duplex",settings.isDuplex()?"true":"false"); > > > > if (volumeTypes[volumeCount-1] == VolumeType.PRELIMINARY) > > { > > > > bodyPageCount[volumeCount-1] = 0; > > > > } else { > > > > sectionElement = > > > > document.createElementNS("http://www.daisy.org/ns/2008/pef","section";); > > > > cont = true; > > pageCount = 1; > > > > while (cont) { > > > > pageElement = > > > > document.createElementNS("http://www.daisy.org/ns/2008/pef","page";); > > > > lineCount = 1; > > > > while (lineCount<= > > settings.getNumberOfLinesPerPage()) { > > > > line = bufferedReader.readLine(); > > /* WINDOWS */ bufferedReader.readLine(); > > if (line.contains("\uE000")) { > > line = line.replaceAll("\uE000"," "); > > cont = false; > > bodyPageCount[volumeCount-1] = pageCount; > > } > > line = line.replaceAll("\u00a0", " "); > > rowElement = > > > > document.createElementNS("http://www.daisy.org/ns/2008/pef","row";); > > node = > > > > document.createTextNode(liblouisTable.toBraille(line)); > > rowElement.appendChild(node); > > pageElement.appendChild(rowElement); > > > > lineCount++; > > > > } > > sectionElement.appendChild(pageElement); > > bufferedReader.skip(1); // skip '\f' > > pageCount++; > > > > } > > > > volumeElements[volumeCount-1].appendChild(sectionElement); > > > > } > > } > > > > statusIndicator.increment(); > > > > if (bufferedReader != null) { > > bufferedReader.close(); > > inputStreamReader.close(); > > fileInputStream.close(); > > } > > > > // Print page ranges > > > > String s; > > volumeNr = 0; > > for (volumeCount = 1;volumeCount<= > > specialSymbolsPresent.length;volumeCount++) { > > if (volumeTypes[volumeCount-1]!=VolumeType.PRELIMINARY) { > > volumeNr++; > > > > if > > > > (XPathUtils.evaluateBoolean(daisyFile.toURL().openStream(), > > "//dtb:div[@class='volume'][" + > > volumeNr + > > "]/dtb:div[@class='not-in-volume']" > > + > > > > "/following::*[not(self::dtb:pagebreak)][1][self::dtb:pagenum]", > > namespace)) { > > s = > > > > XPathUtils.evaluateString(daisyFile.toURL().openStream(), > > "//dtb:div[@class='volume'][" + > > volumeNr + > > "]/dtb:div[@class='not-in-volume']" > > + > > > > "/following::*[not(self::dtb:pagebreak)][1][self::dtb:pagenum]", namespace); > > } else { > > s = > > > > XPathUtils.evaluateString(daisyFile.toURL().openStream(), > > "//dtb:div[@class='volume'][" + > > volumeNr + > > "]/dtb:div[@class='not-in-volume']" > > + > > > > "/following::*[1]/preceding::dtb:pagenum[1]", namespace); > > } > > if (s.equals("")){ > > if (settings.mergeUnnumberedPages) { > > s = > > > > XPathUtils.evaluateString(daisyFile.toURL().openStream(), > > "//dtb:div[@class='volume'][" + > > volumeNr + > > "]/dtb:div[@class='not-in-volume']" > > + > > > > "/following::*[1]/preceding::dtb:pagenum[text()][1]", namespace); > > } else { > > s = > > > > XPathUtils.evaluateString(daisyFile.toURL().openStream(), > > "//dtb:div[@class='volume'][" + > > volumeNr + "]" + > > "//dtb:pagenum[text() and > > > > not(ancestor::dtb:div[@class='not-in-volume'])][1]", namespace); > > } > > } > > if (!s.equals("")){ > > beginPrintPages[volumeCount-1] = s; > > s = > > > > XPathUtils.evaluateString(daisyFile.toURL().openStream(), > > "//dtb:div[@class='volume'][" + > > volumeNr + "]" + > > "//dtb:pagenum[text() and > > > > not(ancestor::dtb:div[@class='not-in-volume'])][last()]", namespace); > > if (!(s.equals("") || > > s.equals(beginPrintPages[volumeCount-1]))) { > > endPrintPages[volumeCount-1] = s; > > } > > } > > } > > } > > > > // LIST OF SPECIAL SYMBOLS: Determine which symbols to display > > > > if (settings.specialSymbolsListEnabled) { > > > > volumeNr = 0; > > for (volumeCount = 1;volumeCount<= > > specialSymbolsPresent.length;volumeCount++) { > > if > > (volumeTypes[volumeCount-1]!=VolumeType.PRELIMINARY) > > { volumeNr++; } > > for (int > > i=0;i<specialSymbolsPresent[volumeCount-1].length;i++) { > > switch (specialSymbolsList.get(i).getMode()) { > > case NEVER: > > break; > > case ALWAYS: > > specialSymbolsPresent[volumeCount-1][i] = > > true; > > break; > > case FIRST_VOLUME: > > if (volumeCount == 1) { > > specialSymbolsPresent[volumeCount-1][i] = > > true; } > > break; > > case IF_PRESENT_IN_VOLUME: > > if > > > > (volumeTypes[volumeCount-1]!=VolumeType.PRELIMINARY) { > > switch > > (specialSymbolsList.get(i).getType()) > > { > > case NOTE_REFERENCE_INDICATOR: > > > > specialSymbolsPresent[volumeCount-1][i] = > > XPathUtils.evaluateBoolean(daisyFile.toURL().openStream(), > > > > "//dtb:div[@class='volume'][" + volumeNr + "]//dtb:note[@class='footnote' > > or @class='endnote']",namespace); > > break; > > case TRANSCRIBERS_NOTE_INDICATOR: > > > > specialSymbolsPresent[volumeCount-1][i] = > > XPathUtils.evaluateBoolean(daisyFile.toURL().openStream(), > > > > "//dtb:div[@class='volume'][" + volumeNr + > > "]//dtb:div[@class='tn']/dtb:note",namespace); > > break; > > case ITALIC_INDICATOR: > > > > specialSymbolsPresent[volumeCount-1][i] = > > XPathUtils.evaluateBoolean(daisyFile.toURL().openStream(), > > > > "//dtb:div[@class='volume'][" + volumeNr + > > "]//dtb:em[not(@class='reset')]",namespace); > > break; > > case BOLDFACE_INDICATOR: > > > > specialSymbolsPresent[volumeCount-1][i] = > > XPathUtils.evaluateBoolean(daisyFile.toURL().openStream(), > > > > "//dtb:div[@class='volume'][" + volumeNr + > > "]//dtb:strong[not(@class='reset')]",namespace); > > break; > > case ELLIPSIS: > > > > specialSymbolsPresent[volumeCount-1][i] = > > XPathUtils.evaluateBoolean(daisyFile.toURL().openStream(), > > > > "//dtb:div[@class='volume'][" + volumeNr + > > "]//dtb:flag[@class='ellipsis']",namespace); > > break; > > case DOUBLE_DASH: > > > > specialSymbolsPresent[volumeCount-1][i] = > > XPathUtils.evaluateBoolean(daisyFile.toURL().openStream(), > > > > "//dtb:div[@class='volume'][" + volumeNr + > > "]//dtb:flag[@class='double-dash']",namespace); > > break; > > default: > > } > > } > > break; > > } > > } > > } > > } > > > > // TRANSCRIBER'S NOTE PAGES: Determine which notes to display > > > > if (settings.transcribersNotesPageEnabled) { > > > > for (volumeCount = 1;volumeCount<= > > transcribersNotesEnabled.length;volumeCount++) { > > > > TranscribersNote[] transcribersNoteValues = > > TranscribersNote.values(); > > > > if > > (volumeTypes[volumeCount-1]!=VolumeType.PRELIMINARY) { > > for (int i=0;i<transcribersNoteValues.length;i++) > > { > > switch (transcribersNoteValues[i]) { > > > > case IMAGES_NOT_REPRODUCED: > > > > transcribersNotesEnabled[volumeCount-1][i] = > > XPathUtils.evaluateBoolean(daisyFile.toURL().openStream(), > > "//dtb:div[@class='volume'][" + > > volumeCount + > > > > "]//dtb:div[@class='image']",namespace); > > break; > > default: > > > > transcribersNotesEnabled[volumeCount-1][i] = false; > > } > > } > > } > > } > > } > > > > // PRELIMINARY PAGES: Insert PP sections before body of > > volumes 1,2,3,... > > > > if (settings.PRELIMINARY_PAGES_PRESENT) { > > > > beginPage = 0; > > endPage = 0; > > > > for (volumeCount = 1;volumeCount<= > > volumeElements.length;volumeCount++) { > > > > logger.log(Level.INFO,"Processing preliminary pages > > of volume " + volumeCount + "/" + > > volumeElements.length); > > > > sectionElement = > > > > document.createElementNS("http://www.daisy.org/ns/2008/pef","section";); > > > > if (volumeCount> 1&& > > volumeTypes[volumeCount-1]==volumeTypes[volumeCount-2]) > > { > > volumeNr ++; > > } else { > > volumeNr = 1; > > } > > > > allVolumes = false; > > front = true; > > body = (settings.tableOfContentEnabled&& > > volumeTypes[volumeCount-1]!=VolumeType.SUPPLEMENTARY); > > beginPage = endPage+1; > > endPage = endPage + bodyPageCount[volumeCount-1]; > > > > // Determine page range > > > > extractpprangemode = true; > > prelPages = 0; // not relevant > > > > if (!odt2daisy.convertAsDTBook(daisyUrl, allVolumes, > > volumeNr, volumeTypes[volumeCount-1], body, front, > > beginPage, endPage, prelPages, > > > > beginPrintPages[volumeCount-1], endPrintPages[volumeCount-1], > > > > specialSymbolsPresent[volumeCount-1],transcribersNotesEnabled[volumeCount-1])) > > { > > return false; > > } > > configureLiblouisxml(extractpprangemode, > > body?beginPage:1); > > runLiblouisxml(); > > > > fileInputStream = new FileInputStream(brailleFile); > > inputStreamReader = new > > InputStreamReader(fileInputStream,"UTF-8"); > > brfInput = IOUtils.toString(inputStreamReader); > > > > matcher = > > Pattern.compile("(\f|\uE000)").matcher(brfInput); > > pageCount = 1; > > > > while (matcher.find()) { > > ch = brfInput.charAt(matcher.start()); > > if (ch=='\f') { > > pageCount ++; > > } else { > > if (settings.tableOfContentEnabled&& > > > > volumeTypes[volumeCount-1]!=VolumeType.SUPPLEMENTARY) { > > pageCount --; > > } > > break; > > } > > } > > > > if (inputStreamReader != null) { > > inputStreamReader.close(); > > fileInputStream.close(); > > } > > > > // Extract preliminary pages > > > > extractpprangemode = false; > > prelPages = pageCount; > > preliminaryPageCount[volumeCount-1] = prelPages; > > > > if (!odt2daisy.convertAsDTBook(daisyUrl, allVolumes, > > volumeNr, volumeTypes[volumeCount-1], body, front, > > beginPage, endPage, prelPages, > > > > beginPrintPages[volumeCount-1], endPrintPages[volumeCount-1], > > > > specialSymbolsPresent[volumeCount-1],transcribersNotesEnabled[volumeCount-1])) > > { > > return false; > > } > > checker.checkDaisyFile(daisyFile); > > configureLiblouisxml(extractpprangemode, > > body?beginPage:1); > > runLiblouisxml(); > > > > fileInputStream = new FileInputStream(brailleFile); > > inputStreamReader = new > > InputStreamReader(fileInputStream,"UTF-8"); > > bufferedReader = new > > BufferedReader(inputStreamReader); > > > > pageCount = 1; > > while (pageCount<= prelPages) { > > > > pageElement = > > > > document.createElementNS("http://www.daisy.org/ns/2008/pef","page";); > > > > lineCount = 1; > > > > while (lineCount<= > > settings.getNumberOfLinesPerPage()) { > > > > line = bufferedReader.readLine(); > > /* WINDOWS */ bufferedReader.readLine(); > > line = line.replaceAll("\u00a0", " "); > > rowElement = > > > > document.createElementNS("http://www.daisy.org/ns/2008/pef","row";); > > node = > > > > document.createTextNode(liblouisTable.toBraille(line)); > > rowElement.appendChild(node); > > pageElement.appendChild(rowElement); > > > > lineCount++; > > > > } > > sectionElement.appendChild(pageElement); > > bufferedReader.skip(1); > > pageCount ++; > > } > > > > > > volumeElements[volumeCount-1].insertBefore(sectionElement, > > volumeElements[volumeCount-1].getFirstChild()); > > > > if ((!settings.tableOfContentEnabled || > > volumeTypes[volumeCount-1]==VolumeType.SUPPLEMENTARY)&& > > !settings.volumeInfoEnabled&& volumeCount>1) { > > for > > > > (volumeCount=volumeCount+1;volumeCount<=volumeElements.length;volumeCount++) > > { > > > > volumeElements[volumeCount-1].insertBefore(sectionElement.cloneNode(true), > > volumeElements[volumeCount-1].getFirstChild()); > > } > > break; > > } > > > > statusIndicator.increment(); > > > > if (bufferedReader != null) { > > bufferedReader.close(); > > inputStreamReader.close(); > > fileInputStream.close(); > > } > > } > > > > statusIndicator.finish(true); > > > > } > > > > checker.checkVolumeLengths(bodyPageCount, > > preliminaryPageCount, volumeTypes); > > > > bodyElement = > > > > document.createElementNS("http://www.daisy.org/ns/2008/pef","body";); > > > > for (volumeCount = > > 1;volumeCount<=volumeElements.length;volumeCount++) { > > bodyElement.appendChild(volumeElements[volumeCount-1]); > > } > > > > root.appendChild(bodyElement); > > > > pi = > > (ProcessingInstruction)document.createProcessingInstruction( > > "xml-stylesheet","type='text/css' href='pef.css'"); > > document.insertBefore(pi, document.getFirstChild()); > > > > OdtUtils.saveDOM(document, pefUrl); > > > > logger.exiting("Odt2Braille","makePEF"); > > > > return true; > > > > } finally { > > statusIndicator.finish(false); > > if (bufferedReader != null) { > > bufferedReader.close(); > > inputStreamReader.close(); > > fileInputStream.close(); > > } > > } > > > > } > > > > /** > > * Execute the<code>xml2brl</code> program. > > * An xml-file is translated to a braille file. > > * Before executing,<code>liblouisxml</code> has to be configured. > > * > > * @see<a > > > > href="http://code.google.com/p/liblouisxml/";><code>liblouisxml</code></a> > > */ > > private void runLiblouisxml() throws IOException, > > InterruptedException, > > LiblouisException { > > > > logger.entering("Odt2Braille","runLiblouisxml"); > > > > Process process; > > Runtime runtime = Runtime.getRuntime(); > > String exec_cmd[] = new String[configurationList.size()]; > > > > configurationList.toArray(exec_cmd); > > > > int i; > > String message = null; > > String line = null; > > String errors = ""; > > > > message = "liblouis: "; > > for (i=0;i<exec_cmd.length;i++) { > > message += "\n " + exec_cmd[i]; > > } > > > > logger.log(Level.INFO,message); > > > > process = runtime.exec(exec_cmd); > > if (process.waitFor() != 0) { > > throw new LiblouisException("liblouisxml did not terminate > > correctly"); > > } > > InputStream stderr = process.getErrorStream(); > > InputStreamReader isr = new InputStreamReader(stderr); > > BufferedReader br = new BufferedReader(isr); > > > > while ((line = br.readLine()) != null) { > > errors += line + "\n"; > > } > > > > if (isr != null) { > > isr.close(); > > stderr.close(); > > } > > > > logger.exiting("Odt2Braille","runLiblouisxml"); > > > > if (!errors.equals("")) { > > throw new LiblouisException("liblouisxml error: " + errors); > > } > > > > } > > > > /** > > * Configure the<code>xml2brl</code> program. > > * @see<a > > > > href="http://code.google.com/p/liblouisxml/";><code>liblouisxml</code></a> > > *<ul> > > > > *<li><code>literaryTextTable</code>,<code>printPages</code>,<code>cellsPerLine</code> > > and<code>linesPerPage</code> > > * are set according to the braille settings.</li> > > *<li>Depending on<code>extractpprangemode</code>, an additional > > semantic-action file is added to<code>semanticFiles</code>.</li> > > *<li><code>beginningPageNumber</code> is set > > to<code>beginPage</code>.</li> > > *</ul> > > * > > * @param extractpprangemode<code>true</code> if the braille > > output will be used to extract the page range of the preliminary > > section. > > * @param beginPage The first braille page number after > > this table of contents. > > * If no table of contents is > > rendered,<code>beginPage</code> is just the first braille page > > number. > > */ > > private void configureLiblouisxml(boolean extractpprangemode, > > int beginPage) > > throws TransformerConfigurationException, > > TransformerException, > > IOException { > > > > logger.entering("Odt2Braille","configureLiblouisxml"); > > > > configurationList.clear(); > > > > String math = settings.getMath().name().toLowerCase(); > > > > String translationTable = "__" + > > settings.getTranslationTable(settings.getMainLanguage()) + "-g" + > > settings.getGrade(settings.getMainLanguage()) + ".ctb"; > > String configFiles = stylesFile.getAbsolutePath() + "," + > > "_config.cfg," + > > "_styles.cfg"; > > String semanticFiles = "_main.sem," + > > > > (extractpprangemode?"_extractpprangemode.sem,":"") + > > > > (settings.stairstepTableIsEnabled()?"_stairsteptable.sem,":"") + > > "_" + math + ".sem"; > > String mathTable = "__" + math + ".ctb"; > > String editTables = "_edit_" + math + ".ctb"; > > > > configurationList.add("\"" + liblouisDirUrl + "bin" + > > System.getProperty("file.separator") + LIBLOUIS_EXEC_NAME + > > LIBLOUIS_EXEC_EXT + "\""); > > configurationList.add("-f"); > > configurationList.add(configFiles); > > > > configurationList.add("-C" + "literaryTextTable=" + > > translationTable); > > configurationList.add("-C" + "semanticFiles=" + > > semanticFiles); > > configurationList.add("-C" + "mathtextTable=" + > > translationTable); > > configurationList.add("-C" + "mathexprTable=" + > > mathTable); > > configurationList.add("-C" + "editTable=" + > > editTables); > > configurationList.add("-C" + "lineFill=" + > > liblouisTable.toText(settings.getLineFillSymbol())); > > configurationList.add("-C" + "beginningPageNumber=" + > > beginPage); > > configurationList.add("-C" + "cellsPerLine=" + > > Integer.toString(settings.getNumberOfCellsPerLine())); > > configurationList.add("-C" + "linesPerPage=" + > > Integer.toString(settings.getNumberOfLinesPerPage())); > > configurationList.add("-C" + "hyphenate=" + > > (settings.getHyphenate()?"yes":"no")); > > configurationList.add("-C" + "printPages=" + > > (settings.getPrintPageNumbers()?"yes":"no")); > > configurationList.add("-C" + "pageSeparator=" + > > (settings.getPageSeparator()?"yes":"no")); > > configurationList.add("-C" + "pageSeparatorNumber=" + > > (settings.getPageSeparatorNumber()?"yes":"no")); > > configurationList.add("-C" + "ignoreEmptyPages=" + > > (settings.getIgnoreEmptyPages()?"yes":"no")); > > configurationList.add("-C" + "continuePages=" + > > (settings.getContinuePages()?"yes":"no")); > > configurationList.add("-C" + "mergeUnnumberedPages=" + > > (settings.getMergeUnnumberedPages()?"yes":"no")); > > configurationList.add("-C" + "pageNumberTopSeparateLine=" + > > (settings.getPageNumberAtTopOnSeparateLine()?"yes":"no")); > > configurationList.add("-C" + "pageNumberBottomSeparateLine=" + > > (settings.getPageNumberAtBottomOnSeparateLine()?"yes":"no")); > > configurationList.add("-C" + "printPageNumberRange=" + > > (settings.getPrintPageNumberRange()?"yes":"no")); > > configurationList.add("-C" + "printPageNumberAt=" + > > settings.getPrintPageNumberAt()); > > configurationList.add("-C" + "braillePageNumberAt=" + > > settings.getBraillePageNumberAt()); > > > > configurationList.add("\"" + daisyUrl + "\""); > > configurationList.add("\"" + brailleUrl + "\""); > > > > createChardefsFile(daisyFile); > > > > logger.exiting("Odt2Braille","configureLiblouisxml"); > > > > } > >} > > > -- John J. Boyer, Executive Director GodTouches Digital Ministry, Inc. http://www.godtouches.org Madison, Wisconsin, USA Peace, Love, Service