📄 pprint.java
字号:
/*
* @(#)PPrint.java 1.11 2000/08/16
*
*/
package org.w3c.tidy;
/**
*
* Pretty print parse tree
*
* (c) 1998-2000 (W3C) MIT, INRIA, Keio University
* See Tidy.java for the copyright notice.
* Derived from <a href="http://www.w3.org/People/Raggett/tidy">
* HTML Tidy Release 4 Aug 2000</a>
*
* @author Dave Raggett <dsr@w3.org>
* @author Andy Quick <ac.quick@sympatico.ca> (translation to Java)
* @version 1.0, 1999/05/22
* @version 1.0.1, 1999/05/29
* @version 1.1, 1999/06/18 Java Bean
* @version 1.2, 1999/07/10 Tidy Release 7 Jul 1999
* @version 1.3, 1999/07/30 Tidy Release 26 Jul 1999
* @version 1.4, 1999/09/04 DOM support
* @version 1.5, 1999/10/23 Tidy Release 27 Sep 1999
* @version 1.6, 1999/11/01 Tidy Release 22 Oct 1999
* @version 1.7, 1999/12/06 Tidy Release 30 Nov 1999
* @version 1.8, 2000/01/22 Tidy Release 13 Jan 2000
* @version 1.9, 2000/06/03 Tidy Release 30 Apr 2000
* @version 1.10, 2000/07/22 Tidy Release 8 Jul 2000
* @version 1.11, 2000/08/16 Tidy Release 4 Aug 2000
*/
/*
Block-level and unknown elements are printed on
new lines and their contents indented 2 spaces
Inline elements are printed inline.
Inline content is wrapped on spaces (except in
attribute values or preformatted text, after
start tags and before end tags
*/
import java.io.FileOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.FileNotFoundException;
public class PPrint {
/* page transition effects */
public static final short EFFECT_BLEND = -1;
public static final short EFFECT_BOX_IN = 0;
public static final short EFFECT_BOX_OUT = 1;
public static final short EFFECT_CIRCLE_IN = 2;
public static final short EFFECT_CIRCLE_OUT = 3;
public static final short EFFECT_WIPE_UP = 4;
public static final short EFFECT_WIPE_DOWN = 5;
public static final short EFFECT_WIPE_RIGHT = 6;
public static final short EFFECT_WIPE_LEFT = 7;
public static final short EFFECT_VERT_BLINDS = 8;
public static final short EFFECT_HORZ_BLINDS = 9;
public static final short EFFECT_CHK_ACROSS = 10;
public static final short EFFECT_CHK_DOWN = 11;
public static final short EFFECT_RND_DISSOLVE = 12;
public static final short EFFECT_SPLIT_VIRT_IN = 13;
public static final short EFFECT_SPLIT_VIRT_OUT = 14;
public static final short EFFECT_SPLIT_HORZ_IN = 15;
public static final short EFFECT_SPLIT_HORZ_OUT = 16;
public static final short EFFECT_STRIPS_LEFT_DOWN = 17;
public static final short EFFECT_STRIPS_LEFT_UP = 18;
public static final short EFFECT_STRIPS_RIGHT_DOWN = 19;
public static final short EFFECT_STRIPS_RIGHT_UP = 20;
public static final short EFFECT_RND_BARS_HORZ = 21;
public static final short EFFECT_RND_BARS_VERT = 22;
public static final short EFFECT_RANDOM = 23;
private static final short NORMAL = 0;
private static final short PREFORMATTED = 1;
private static final short COMMENT = 2;
private static final short ATTRIBVALUE = 4;
private static final short NOWRAP = 8;
private static final short CDATA = 16;
private int[] linebuf = null;
private int lbufsize = 0;
private int linelen = 0;
private int wraphere = 0;
private boolean inAttVal = false;
private boolean InString = false;
private int slide = 0;
private int count = 0;
private Node slidecontent = null;
private Configuration configuration;
public PPrint(Configuration configuration)
{
this.configuration = configuration;
}
/*
1010 A
1011 B
1100 C
1101 D
1110 E
1111 F
*/
/* return one less that the number of bytes used by UTF-8 char */
/* str points to 1st byte, *ch initialized to 1st byte */
public static int getUTF8(byte[] str, int start, MutableInteger ch)
{
int c, n, i, bytes;
c = ((int)str[start]) & 0xFF; // Convert to unsigned.
if ((c & 0xE0) == 0xC0) /* 110X XXXX two bytes */
{
n = c & 31;
bytes = 2;
}
else if ((c & 0xF0) == 0xE0) /* 1110 XXXX three bytes */
{
n = c & 15;
bytes = 3;
}
else if ((c & 0xF8) == 0xF0) /* 1111 0XXX four bytes */
{
n = c & 7;
bytes = 4;
}
else if ((c & 0xFC) == 0xF8) /* 1111 10XX five bytes */
{
n = c & 3;
bytes = 5;
}
else if ((c & 0xFE) == 0xFC) /* 1111 110X six bytes */
{
n = c & 1;
bytes = 6;
}
else /* 0XXX XXXX one byte */
{
ch.value = c;
return 0;
}
/* successor bytes should have the form 10XX XXXX */
for (i = 1; i < bytes; ++i)
{
c = ((int)str[start + i]) & 0xFF; // Convert to unsigned.
n = (n << 6) | (c & 0x3F);
}
ch.value = n;
return bytes - 1;
}
/* store char c as UTF-8 encoded byte stream */
public static int putUTF8(byte[] buf, int start, int c)
{
if (c < 128)
buf[start++] = (byte)c;
else if (c <= 0x7FF)
{
buf[start++] = (byte)(0xC0 | (c >> 6));
buf[start++] = (byte)(0x80 | (c & 0x3F));
}
else if (c <= 0xFFFF)
{
buf[start++] = (byte)(0xE0 | (c >> 12));
buf[start++] = (byte)(0x80 | ((c >> 6) & 0x3F));
buf[start++] = (byte)(0x80 | (c & 0x3F));
}
else if (c <= 0x1FFFFF)
{
buf[start++] = (byte)(0xF0 | (c >> 18));
buf[start++] = (byte)(0x80 | ((c >> 12) & 0x3F));
buf[start++] = (byte)(0x80 | ((c >> 6) & 0x3F));
buf[start++] = (byte)(0x80 | (c & 0x3F));
}
else
{
buf[start++] = (byte)(0xF8 | (c >> 24));
buf[start++] = (byte)(0x80 | ((c >> 18) & 0x3F));
buf[start++] = (byte)(0x80 | ((c >> 12) & 0x3F));
buf[start++] = (byte)(0x80 | ((c >> 6) & 0x3F));
buf[start++] = (byte)(0x80 | (c & 0x3F));
}
return start;
}
private void addC(int c, int index)
{
if (index + 1 >= lbufsize)
{
while (index + 1 >= lbufsize)
{
if (lbufsize == 0)
lbufsize = 256;
else
lbufsize = lbufsize * 2;
}
int[] temp = new int[ lbufsize ];
if (linebuf != null)
System.arraycopy(linebuf, 0, temp, 0, index);
linebuf = temp;
}
linebuf[index] = c;
}
private void wrapLine(Out fout, int indent)
{
int i, p, q;
if (wraphere == 0)
return;
for (i = 0; i < indent; ++i)
fout.outc((int)' ');
for (i = 0; i < wraphere; ++i)
fout.outc(linebuf[i]);
if (InString)
{
fout.outc((int)' ');
fout.outc((int)'\\');
}
fout.newline();
if (linelen > wraphere)
{
p = 0;
if (linebuf[wraphere] == ' ')
++wraphere;
q = wraphere;
addC('\0', linelen);
while (true)
{
linebuf[p] = linebuf[q];
if (linebuf[q] == 0) break;
p++;
q++;
}
linelen -= wraphere;
}
else
linelen = 0;
wraphere = 0;
}
private void wrapAttrVal(Out fout, int indent, boolean inString)
{
int i, p, q;
for (i = 0; i < indent; ++i)
fout.outc((int)' ');
for (i = 0; i < wraphere; ++i)
fout.outc(linebuf[i]);
fout.outc((int)' ');
if (inString)
fout.outc((int)'\\');
fout.newline();
if (linelen > wraphere)
{
p = 0;
if (linebuf[wraphere] == ' ')
++wraphere;
q = wraphere;
addC('\0', linelen);
while (true)
{
linebuf[p] = linebuf[q];
if (linebuf[q] == 0) break;
p++;
q++;
}
linelen -= wraphere;
}
else
linelen = 0;
wraphere = 0;
}
public void flushLine(Out fout, int indent)
{
int i;
if (linelen > 0)
{
if (indent + linelen >= this.configuration.wraplen)
wrapLine(fout, indent);
if (!inAttVal || this.configuration.IndentAttributes)
{
for (i = 0; i < indent; ++i)
fout.outc((int)' ');
}
for (i = 0; i < linelen; ++i)
fout.outc(linebuf[i]);
}
fout.newline();
linelen = 0;
wraphere = 0;
inAttVal = false;
}
public void condFlushLine(Out fout, int indent)
{
int i;
if (linelen > 0)
{
if (indent + linelen >= this.configuration.wraplen)
wrapLine(fout, indent);
if (!inAttVal || this.configuration.IndentAttributes)
{
for (i = 0; i < indent; ++i)
fout.outc((int)' ');
}
for (i = 0; i < linelen; ++i)
fout.outc(linebuf[i]);
fout.newline();
linelen = 0;
wraphere = 0;
inAttVal = false;
}
}
private void printChar(int c, short mode)
{
String entity;
if (c == ' ' && !((mode & (PREFORMATTED | COMMENT | ATTRIBVALUE)) != 0))
{
/* coerce a space character to a non-breaking space */
if ((mode & NOWRAP) != 0)
{
/* by default XML doesn't define */
if (this.configuration.NumEntities || this.configuration.XmlTags)
{
addC('&', linelen++);
addC('#', linelen++);
addC('1', linelen++);
addC('6', linelen++);
addC('0', linelen++);
addC(';', linelen++);
}
else /* otherwise use named entity */
{
addC('&', linelen++);
addC('n', linelen++);
addC('b', linelen++);
addC('s', linelen++);
addC('p', linelen++);
addC(';', linelen++);
}
return;
}
else
wraphere = linelen;
}
/* comment characters are passed raw */
if ((mode & COMMENT) != 0)
{
addC(c, linelen++);
return;
}
/* except in CDATA map < to < etc. */
if (! ((mode & CDATA) != 0) )
{
if (c == '<')
{
addC('&', linelen++);
addC('l', linelen++);
addC('t', linelen++);
addC(';', linelen++);
return;
}
if (c == '>')
{
addC('&', linelen++);
addC('g', linelen++);
addC('t', linelen++);
addC(';', linelen++);
return;
}
/*
naked '&' chars can be left alone or
quoted as & The latter is required
for XML where naked '&' are illegal.
*/
if (c == '&' && this.configuration.QuoteAmpersand)
{
addC('&', linelen++);
addC('a', linelen++);
addC('m', linelen++);
addC('p', linelen++);
addC(';', linelen++);
return;
}
if (c == '"' && this.configuration.QuoteMarks)
{
addC('&', linelen++);
addC('q', linelen++);
addC('u', linelen++);
addC('o', linelen++);
addC('t', linelen++);
addC(';', linelen++);
return;
}
if (c == '\'' && this.configuration.QuoteMarks)
{
addC('&', linelen++);
addC('#', linelen++);
addC('3', linelen++);
addC('9', linelen++);
addC(';', linelen++);
return;
}
if (c == 160 && this.configuration.CharEncoding != Configuration.RAW)
{
if (this.configuration.QuoteNbsp)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -