/**
   * Parse using current settings
   *
   * @throws IOException
   */
  public void parse() throws IOException {
    if (date == null) {
      date = new Date();
    }
    FileInputStream is = new FileInputStream(input);
    PrintWriter pw = new PrintWriter(output, "utf-8");
    LineNumberReader lr =
        new LineNumberReader(new InputStreamReader(is, converter.getPreferredCharset()));
    // determine max rows/page and chars/row

    read(lr, null);

    // reset input
    is = new FileInputStream(input);
    lr = new LineNumberReader(new InputStreamReader(is, converter.getPreferredCharset()));

    pw.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    pw.println("<pef version=\"2008-1\" xmlns=\"http://www.daisy.org/ns/2008/pef\">");
    pw.println("	<head>");
    pw.println("		<meta xmlns:dc=\"http://purl.org/dc/elements/1.1/\">");
    if (!"".equals(title)) {
      pw.println("			<dc:title>" + title + "</dc:title>");
    }
    if (!"".equals(author)) {
      pw.println("			<dc:creator>" + author + "</dc:creator>");
    }
    if (!"".equals(language)) {
      pw.println("			<dc:language>" + language + "</dc:language>");
    }
    pw.println("			<dc:date>" + DATE_FORMAT.format(date) + "</dc:date>");
    pw.println("			<dc:format>application/x-pef+xml</dc:format>");
    if (!"".equals(identifier)) {
      pw.println("			<dc:identifier>" + identifier + "</dc:identifier>");
    }
    pw.println("		</meta>");
    pw.println("	</head>");
    pw.println("	<body>");
    pw.println(
        "		<volume cols=\""
            + maxCols
            + "\" rows=\""
            + maxRows
            + "\" rowgap=\"0\" duplex=\""
            + duplex
            + "\">");
    pw.println("			<section>");

    read(lr, pw);
    pw.println("			</section>");
    pw.println("		</volume>");
    pw.println("	</body>");
    pw.println("</pef>");
    pw.flush();
    pw.close();
  }
 private void read(LineNumberReader lr, PrintWriter pw) throws IOException {
   maxRows = 0;
   maxCols = 0;
   int cRows = 0;
   boolean pageClosed = true;
   int eofIndex = -1;
   cRows++;
   String line = lr.readLine();
   while (line != null) {
     eofIndex = line.indexOf(0x1A);
     if (eofIndex > -1) {
       line = line.substring(0, eofIndex); // remove trailing characters beyond eof-mark (CTRL+Z)
     }
     if ("\f"
         .equals(
             line)) { // if line consists of a single form feed character. Just close the page
                      // (don't add rows yet).
       // if page is already closed, this is an empty page
       if (pageClosed) {
         if (pw != null) {
           pw.println("				<page>");
         }
         pageClosed = false;
       }
       if (pw != null) {
         pw.println("				</page>");
       }
       pageClosed = true;
       cRows--; // don't count this row
       if (cRows > maxRows) {
         maxRows = cRows;
       }
       cRows = 0;
     } else {
       String[] pieces = line.split("\\f", -1); // split on form feed
       int i = 1;
       for (String p : pieces) {
         if (i > 1) { // there were form feeds
           if (pw != null) {
             pw.println("				</page>");
           }
           pageClosed = true;
           cRows--; // don't count this row
           if (cRows > maxRows) {
             maxRows = cRows;
           }
           cRows = 0;
         }
         if (pageClosed) {
           if (pw != null) {
             pw.println("				<page>");
           }
           pageClosed = false;
         }
         if (p.length() > maxCols) {
           maxCols = p.length();
         }
         // don't output if row contains form feeds and this segment equals ""
         if (!(pieces.length > 1 && (i == pieces.length || i == 1) && "".equals(p))) {
           if (pw != null) {
             pw.print("					<row>");
             pw.print(converter.toBraille(p));
             pw.println("</row>");
           }
         }
         i++;
       }
     }
     if (eofIndex > -1) {
       // End of file reached. Stop reading.
       line = null;
     } else {
       line = lr.readLine();
       cRows++;
     }
   }
   lr.close();
   if (!pageClosed) {
     if (pw != null) {
       pw.println("				</page>");
     }
     pageClosed = true;
     cRows--; // don't count this row
     if (cRows > maxRows) {
       maxRows = cRows;
     }
     cRows = 0;
   }
 }