/**
  * Copy lines from reader to output
  *
  * @param codeReader line reader
  * @param range range of lines to copy
  */
 private void copyLines(final BufferedReader codeReader, final Range range)
     throws IOException, SAXException {
   boolean first = true;
   String line = codeReader.readLine();
   for (int i = 0; line != null; i++) {
     if (i >= range.start && i <= range.end) {
       if (first) {
         first = false;
       } else {
         super.characters(XML_NEWLINE, 0, XML_NEWLINE.length);
       }
       final char[] ch = line.toCharArray();
       super.characters(ch, 0, ch.length);
     }
     line = codeReader.readLine();
   }
 }
  @Override
  public void endElement(final String uri, final String localName, final String name)
      throws SAXException {
    if (ignoreDepth > 0) {
      ignoreDepth--;
      return;
    }

    super.endElement(uri, localName, name);
  }
  @Override
  public void startElement(
      final String uri, final String localName, final String name, final Attributes atts)
      throws SAXException {
    if (ignoreDepth > 0) {
      ignoreDepth++;
      return;
    }

    if (PR_D_CODEREF.matches(atts)) {
      ignoreDepth++;
      try {
        final URI hrefValue = toURI(atts.getValue(ATTRIBUTE_NAME_HREF));
        if (hrefValue != null) {
          File codeFile = toFile(stripFragment(currentFile.resolve(hrefValue))).getAbsoluteFile();
          if (!codeFile.exists()) {
            final URI rel = job.tempDir.toURI().relativize(codeFile.toURI());
            final Job.FileInfo fi = job.getFileInfo(rel);
            if (fi != null && fi.src.getScheme().equals("file")) {
              codeFile = new File(fi.src);
            }
          }
          if (codeFile.exists()) {
            logger.debug("Resolve coderef " + codeFile);
            final Charset charset = getCharset(atts.getValue(ATTRIBUTE_NAME_FORMAT));
            try (BufferedReader codeReader =
                new BufferedReader(new InputStreamReader(new FileInputStream(codeFile), charset))) {
              copyLines(codeReader, new Range(hrefValue));
            } catch (final Exception e) {
              logger.error("Failed to process code reference " + codeFile, e);
            }
          } else {
            logger.warn(
                MessageUtils.getInstance()
                    .getMessage("DOTJ051E", hrefValue.toString())
                    .setLocation(atts)
                    .toString());
          }
        } else {
          // logger.logDebug("Code reference target not defined");
        }
      } catch (final Exception e) {
        logger.error(e.getMessage(), e);
      }
    } else {
      super.startElement(uri, localName, name, atts);
    }
  }
 @Override
 public void write(final File filename) throws DITAOTException {
   assert filename.isAbsolute();
   setCurrentFile(filename.toURI());
   super.write(filename);
 }