src.org.python.indexer.demos.StyleApplier Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jython Show documentation
Show all versions of jython Show documentation
Jython is an implementation of the high-level, dynamic, object-oriented
language Python written in 100% Pure Java, and seamlessly integrated with
the Java platform. It thus allows you to run Python on any Java platform.
/**
* Copyright 2009, Google Inc. All rights reserved.
* Licensed to PSF under a Contributor Agreement.
*/
package org.python.indexer.demos;
import org.python.indexer.StyleRun;
import java.util.ArrayList;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
/**
* Turns a list of {@link StyleRun}s into HTML spans.
*/
class StyleApplier {
// Empirically, adding the span tags multiplies length by 6 or more.
private static final int SOURCE_BUF_MULTIPLIER = 6;
private SortedSet tags = new TreeSet();
private StringBuilder buffer; // html output buffer
private String source; // input source code
private String path; // input source path, for logging
// Current offset into the source being copied into the html buffer.
private int sourceOffset = 0;
abstract class Tag implements Comparable{
int offset;
StyleRun style;
public int compareTo(Tag other) {
if (this == other) {
return 0;
}
if (this.offset < other.offset) {
return -1;
}
if (other.offset < this.offset) {
return 1;
}
return this.hashCode() - other.hashCode();
}
void insert() {
// Copy source code up through this tag.
if (offset > sourceOffset) {
copySource(sourceOffset, offset);
}
}
}
class StartTag extends Tag {
public StartTag(StyleRun style) {
offset = style.start();
this.style = style;
}
@Override
void insert() {
super.insert();
switch (style.type) {
case ANCHOR:
buffer.append("");
}
}
class EndTag extends Tag {
public EndTag(StyleRun style) {
offset = style.end();
this.style = style;
}
@Override
void insert() {
super.insert();
switch (style.type) {
case ANCHOR:
case LINK:
buffer.append("");
break;
default:
buffer.append("");
break;
}
}
}
public StyleApplier(String path, String src, List runs) {
this.path = path;
source = src;
for (StyleRun run : runs) {
tags.add(new StartTag(run));
tags.add(new EndTag(run));
}
}
/**
* @return the html
*/
public String apply() {
buffer = new StringBuilder(source.length() * SOURCE_BUF_MULTIPLIER);
int lastStart = -1;
for (Tag tag : tags) {
tag.insert();
}
// Copy in remaining source beyond last tag.
if (sourceOffset < source.length()) {
copySource(sourceOffset, source.length());
}
return buffer.toString();
}
/**
* Copies code from the input source to the output html.
* @param beg the starting source offset
* @param end the end offset, or -1 to go to end of file
*/
private void copySource(int beg, int end) {
// Be robust if the analyzer gives us bad offsets.
try {
String src = escape((end == -1)
? source.substring(beg)
: source.substring(beg, end));
buffer.append(src);
} catch (RuntimeException x) {
System.err.println("Warning: " + x);
}
sourceOffset = end;
}
private String escape(String s) {
return s.replace("&", "&")
.replace("'", "'")
.replace("\"", """)
.replace("<", "<")
.replace(">", ">");
}
private String toCSS(StyleRun style) {
return style.type.toString().toLowerCase().replace("_", "-");
}
}