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-standalone Show documentation
Show all versions of jython-standalone 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("_", "-");
}
}