// This file is part of TagSoup and is Copyright 2002-2008 by John Cowan. // // TagSoup is licensed under the Apache License, // Version 2.0. You may obtain a copy of this license at // http://www.apache.org/licenses/LICENSE-2.0 . You may also have // additional legal rights not granted by this license. // // TagSoup is distributed in the hope that it will be useful, but // unless required by applicable law or agreed to in writing, TagSoup // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS // OF ANY KIND, either express or implied; not even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // // // PYX Writer // FIXME: does not do escapes in attribute values // FIXME: outputs entities as bare '&' character package org.ccil.cowan.tagsoup; import java.io.*; import org.xml.sax.*; import org.xml.sax.ext.LexicalHandler; /** A ContentHandler that generates PYX format instead of XML. Primarily useful for debugging. **/ public class PYXWriter implements ScanHandler, ContentHandler, LexicalHandler { private PrintWriter theWriter; // where we write to private static char[] dummy = new char[1]; private String attrName; // saved attribute name // ScanHandler implementation public void adup(char[] buff, int offset, int length) throws SAXException { theWriter.println(attrName); attrName = null; } public void aname(char[] buff, int offset, int length) throws SAXException { theWriter.print('A'); theWriter.write(buff, offset, length); theWriter.print(' '); attrName = new String(buff, offset, length); } public void aval(char[] buff, int offset, int length) throws SAXException { theWriter.write(buff, offset, length); theWriter.println(); attrName = null; } public void cmnt(char [] buff, int offset, int length) throws SAXException { // theWriter.print('!'); // theWriter.write(buff, offset, length); // theWriter.println(); } public void entity(char[] buff, int offset, int length) throws SAXException { } public int getEntity() { return 0; } public void eof(char[] buff, int offset, int length) throws SAXException { theWriter.close(); } public void etag(char[] buff, int offset, int length) throws SAXException { theWriter.print(')'); theWriter.write(buff, offset, length); theWriter.println(); } public void decl(char[] buff, int offset, int length) throws SAXException { } public void gi(char[] buff, int offset, int length) throws SAXException { theWriter.print('('); theWriter.write(buff, offset, length); theWriter.println(); } public void cdsect(char[] buff, int offset, int length) throws SAXException { pcdata(buff, offset, length); } public void pcdata(char[] buff, int offset, int length) throws SAXException { if (length == 0) return; // nothing to do boolean inProgress = false; length += offset; for (int i = offset; i < length; i++) { if (buff[i] == '\n') { if (inProgress) { theWriter.println(); } theWriter.println("-\\n"); inProgress = false; } else { if (!inProgress) { theWriter.print('-'); } switch(buff[i]) { case '\t': theWriter.print("\\t"); break; case '\\': theWriter.print("\\\\"); break; default: theWriter.print(buff[i]); } inProgress = true; } } if (inProgress) { theWriter.println(); } } public void pitarget(char[] buff, int offset, int length) throws SAXException { theWriter.print('?'); theWriter.write(buff, offset, length); theWriter.write(' '); } public void pi(char[] buff, int offset, int length) throws SAXException { theWriter.write(buff, offset, length); theWriter.println(); } public void stagc(char[] buff, int offset, int length) throws SAXException { // theWriter.println("!"); // FIXME } public void stage(char[] buff, int offset, int length) throws SAXException { theWriter.println("!"); // FIXME } // SAX ContentHandler implementation public void characters(char[] buff, int offset, int length) throws SAXException { pcdata(buff, offset, length); } public void endDocument() throws SAXException { theWriter.close(); } public void endElement(String uri, String localname, String qname) throws SAXException { if (qname.length() == 0) qname = localname; theWriter.print(')'); theWriter.println(qname); } public void endPrefixMapping(String prefix) throws SAXException { } public void ignorableWhitespace(char[] buff, int offset, int length) throws SAXException { characters(buff, offset, length); } public void processingInstruction(String target, String data) throws SAXException { theWriter.print('?'); theWriter.print(target); theWriter.print(' '); theWriter.println(data); } public void setDocumentLocator(Locator locator) { } public void skippedEntity(String name) throws SAXException { } public void startDocument() throws SAXException { } public void startElement(String uri, String localname, String qname, Attributes atts) throws SAXException { if (qname.length() == 0) qname=localname; theWriter.print('('); theWriter.println(qname); int length = atts.getLength(); for (int i = 0; i < length; i++) { qname = atts.getQName(i); if (qname.length() == 0) qname = atts.getLocalName(i); theWriter.print('A'); // theWriter.print(atts.getType(i)); // DEBUG theWriter.print(qname); theWriter.print(' '); theWriter.println(atts.getValue(i)); } } public void startPrefixMapping(String prefix, String uri) throws SAXException { } // Default LexicalHandler implementation public void comment(char[] ch, int start, int length) throws SAXException { cmnt(ch, start, length); } public void endCDATA() throws SAXException { } public void endDTD() throws SAXException { } public void endEntity(String name) throws SAXException { } public void startCDATA() throws SAXException { } public void startDTD(String name, String publicId, String systemId) throws SAXException { } public void startEntity(String name) throws SAXException { } // Constructor public PYXWriter(Writer w) { if (w instanceof PrintWriter) { theWriter = (PrintWriter)w; } else { theWriter = new PrintWriter(w); } } }