Home | History | Annotate | Download | only in tagsoup
      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 
     19 package org.ccil.cowan.tagsoup;
     20 import java.io.*;
     21 import org.xml.sax.*;
     22 import org.xml.sax.ext.LexicalHandler;
     23 
     24 /**
     25 A ContentHandler that generates PYX format instead of XML.
     26 Primarily useful for debugging.
     27 **/
     28 public 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