1// This file is part of TagSoup and is Copyright 2002-2008 by John Cowan. 2// 3// TagSoup is licensed under the Apache License, 4// Version 2.0. You may obtain a copy of this license at 5// http://www.apache.org/licenses/LICENSE-2.0 . You may also have 6// additional legal rights not granted by this license. 7// 8// TagSoup is distributed in the hope that it will be useful, but 9// unless required by applicable law or agreed to in writing, TagSoup 10// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 11// OF ANY KIND, either express or implied; not even the implied warranty 12// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13// 14// 15// PYX Writer 16// FIXME: does not do escapes in attribute values 17// FIXME: outputs entities as bare '&' character 18 19package org.ccil.cowan.tagsoup; 20import java.io.*; 21import org.xml.sax.*; 22import org.xml.sax.ext.LexicalHandler; 23 24/** 25A ContentHandler that generates PYX format instead of XML. 26Primarily useful for debugging. 27**/ 28public class PYXWriter 29 implements ScanHandler, ContentHandler, LexicalHandler { 30 31 private PrintWriter theWriter; // where we write to 32 private static char[] dummy = new char[1]; 33 private String attrName; // saved attribute name 34 35 // ScanHandler implementation 36 37 public void adup(char[] buff, int offset, int length) throws SAXException { 38 theWriter.println(attrName); 39 attrName = null; 40 } 41 42 public void aname(char[] buff, int offset, int length) throws SAXException { 43 theWriter.print('A'); 44 theWriter.write(buff, offset, length); 45 theWriter.print(' '); 46 attrName = new String(buff, offset, length); 47 } 48 49 public void aval(char[] buff, int offset, int length) throws SAXException { 50 theWriter.write(buff, offset, length); 51 theWriter.println(); 52 attrName = null; 53 } 54 55 public void cmnt(char [] buff, int offset, int length) throws SAXException { 56// theWriter.print('!'); 57// theWriter.write(buff, offset, length); 58// theWriter.println(); 59 } 60 61 public void entity(char[] buff, int offset, int length) throws SAXException { } 62 63 public int getEntity() { return 0; } 64 65 public void eof(char[] buff, int offset, int length) throws SAXException { 66 theWriter.close(); 67 } 68 69 public void etag(char[] buff, int offset, int length) throws SAXException { 70 theWriter.print(')'); 71 theWriter.write(buff, offset, length); 72 theWriter.println(); 73 } 74 75 public void decl(char[] buff, int offset, int length) throws SAXException { 76 } 77 78 public void gi(char[] buff, int offset, int length) throws SAXException { 79 theWriter.print('('); 80 theWriter.write(buff, offset, length); 81 theWriter.println(); 82 } 83 84 public void cdsect(char[] buff, int offset, int length) throws SAXException { 85 pcdata(buff, offset, length); 86 } 87 88 public void pcdata(char[] buff, int offset, int length) throws SAXException { 89 if (length == 0) return; // nothing to do 90 boolean inProgress = false; 91 length += offset; 92 for (int i = offset; i < length; i++) { 93 if (buff[i] == '\n') { 94 if (inProgress) { 95 theWriter.println(); 96 } 97 theWriter.println("-\\n"); 98 inProgress = false; 99 } 100 else { 101 if (!inProgress) { 102 theWriter.print('-'); 103 } 104 switch(buff[i]) { 105 case '\t': 106 theWriter.print("\\t"); 107 break; 108 case '\\': 109 theWriter.print("\\\\"); 110 break; 111 default: 112 theWriter.print(buff[i]); 113 } 114 inProgress = true; 115 } 116 } 117 if (inProgress) { 118 theWriter.println(); 119 } 120 } 121 122 public void pitarget(char[] buff, int offset, int length) throws SAXException { 123 theWriter.print('?'); 124 theWriter.write(buff, offset, length); 125 theWriter.write(' '); 126 } 127 128 public void pi(char[] buff, int offset, int length) throws SAXException { 129 theWriter.write(buff, offset, length); 130 theWriter.println(); 131 } 132 133 public void stagc(char[] buff, int offset, int length) throws SAXException { 134// theWriter.println("!"); // FIXME 135 } 136 137 public void stage(char[] buff, int offset, int length) throws SAXException { 138 theWriter.println("!"); // FIXME 139 } 140 141 // SAX ContentHandler implementation 142 143 public void characters(char[] buff, int offset, int length) throws SAXException { 144 pcdata(buff, offset, length); 145 } 146 147 public void endDocument() throws SAXException { 148 theWriter.close(); 149 } 150 151 public void endElement(String uri, String localname, String qname) throws SAXException { 152 if (qname.length() == 0) qname = localname; 153 theWriter.print(')'); 154 theWriter.println(qname); 155 } 156 157 public void endPrefixMapping(String prefix) throws SAXException { } 158 159 public void ignorableWhitespace(char[] buff, int offset, int length) throws SAXException { 160 characters(buff, offset, length); 161 } 162 163 public void processingInstruction(String target, String data) throws SAXException { 164 theWriter.print('?'); 165 theWriter.print(target); 166 theWriter.print(' '); 167 theWriter.println(data); 168 } 169 170 public void setDocumentLocator(Locator locator) { } 171 172 public void skippedEntity(String name) throws SAXException { } 173 174 public void startDocument() throws SAXException { } 175 176 public void startElement(String uri, String localname, String qname, 177 Attributes atts) throws SAXException { 178 if (qname.length() == 0) qname=localname; 179 theWriter.print('('); 180 theWriter.println(qname); 181 int length = atts.getLength(); 182 for (int i = 0; i < length; i++) { 183 qname = atts.getQName(i); 184 if (qname.length() == 0) qname = atts.getLocalName(i); 185 theWriter.print('A'); 186// theWriter.print(atts.getType(i)); // DEBUG 187 theWriter.print(qname); 188 theWriter.print(' '); 189 theWriter.println(atts.getValue(i)); 190 } 191 } 192 193 public void startPrefixMapping(String prefix, String uri) throws SAXException { } 194 195 // Default LexicalHandler implementation 196 197 public void comment(char[] ch, int start, int length) throws SAXException { 198 cmnt(ch, start, length); 199 } 200 public void endCDATA() throws SAXException { } 201 public void endDTD() throws SAXException { } 202 public void endEntity(String name) throws SAXException { } 203 public void startCDATA() throws SAXException { } 204 public void startDTD(String name, String publicId, String systemId) throws SAXException { } 205 public void startEntity(String name) throws SAXException { } 206 207 // Constructor 208 209 public PYXWriter(Writer w) { 210 if (w instanceof PrintWriter) { 211 theWriter = (PrintWriter)w; 212 } 213 else { 214 theWriter = new PrintWriter(w); 215 } 216 } 217 } 218