import java.io.IOException;
import org.jruby.Ruby;
import org.jruby.RubyArray;
import org.jruby.RubyClass;
import org.jruby.RubyHash;
import org.jruby.RubyModule;
import org.jruby.RubyNumeric;
import org.jruby.RubyObject;
import org.jruby.RubyObjectAdapter;
import org.jruby.RubyRegexp;
import org.jruby.RubyString;
import org.jruby.anno.JRubyMethod;
import org.jruby.exceptions.RaiseException;
import org.jruby.javasupport.JavaEmbedUtils;
import org.jruby.runtime.Arity;
import org.jruby.runtime.Block;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.callback.Callback;
import org.jruby.exceptions.RaiseException;
import org.jruby.runtime.load.BasicLibraryService;
import org.jruby.util.ByteList;
public class HpricotCss {
public void FILTER(String id) {
IRubyObject[] args = new IRubyObject[fargs];
System.arraycopy(fvals, 0, args, 0, fargs);
mod.callMethod(ctx, id, args);
tmpt.rb_clear();
fargs = 1;
}
public void FILTERAUTO() {
try {
FILTER(new String(data, ts, te - ts, "ISO-8859-1"));
} catch(java.io.UnsupportedEncodingException e) {}
}
public void PUSH(int aps, int ape) {
RubyString str = RubyString.newString(runtime, data, aps, ape-aps);
fvals[fargs++] = str;
tmpt.append(str);
}
private IRubyObject self, mod, str, node;
private int cs, act, eof, p, pe, ts, te, aps, ape, aps2, ape2;
private byte[] data;
private int fargs = 1;
private IRubyObject[] fvals = new IRubyObject[6];
private RubyArray focus;
private RubyArray tmpt;
private Ruby runtime;
private ThreadContext ctx;
public HpricotCss(IRubyObject self, IRubyObject mod, IRubyObject str, IRubyObject node) {
this.self = self;
this.mod = mod;
this.str = str;
this.node = node;
this.runtime = self.getRuntime();
this.ctx = runtime.getCurrentContext();
this.focus = RubyArray.newArray(runtime, node);
this.tmpt = runtime.newArray();
fvals[0] = focus;
if(!(str instanceof RubyString)) {
throw runtime.newArgumentError("bad CSS selector, String only please.");
}
ByteList bl = ((RubyString)str).getByteList();
data = bl.bytes;
p = bl.begin;
pe = p + bl.realSize;
eof = pe;
}
%%{
machine hpricot_css;
action a {
aps = p;
}
action b {
ape = p;
PUSH(aps, ape);
}
action c {
ape = p;
aps2 = p;
}
action d {
ape2 = p;
PUSH(aps, ape);
PUSH(aps2, ape2);
}
commas = space* "," space*;
traverse = [>+~];
sdot = "\\.";
utfw = alnum | "_" | "-" |
(0xc4 0xa8..0xbf) | (0xc5..0xdf 0x80..0xbf) |
(0xe0..0xef 0x80..0xbf 0x80..0xbf) |
(0xf0..0xf4 0x80..0xbf 0x80..0xbf 0x80..0xbf);
utfword = utfw+;
utfname = (utfw | sdot)+;
quote1 = "'" [^']* "'";
quote2 = '"' [^"]* '"';
cssid = "#" %a utfname %b;
cssclass = "." %a utfname %b;
cssname = "[name=" %a utfname %b "]";
cssattr = "[" %a utfname %c space* [^ \n\t]? "=" %d space* (quote1 | quote2 | [^\]]+) "]";
csstag = utfname >a %b;
cssmod = ("even" | "odd" | (digit | "n" | "+" | "-")* );
csschild = ":" %a ("only" | "nth" | "last" | "first") "-child" %b ("(" %a cssmod %b ")")?;
csspos = ":" %a ("nth" | "eq" | "gt" | "lt" | "first" | "last" | "even" | "odd") %b ("(" %a digit+ %b ")")?;
pseudop = "(" [^)]+ ")";
pseudoq = "'" (pseudop+ | [^'()]*) "'" |
'"' (pseudop+ | [^"()]*) '"' |
(pseudop+ | [^"()]*);
pseudo = ":" %a utfname %b ("(" %a pseudoq %b ")")?;
main := |*
cssid => { FILTER("ID"); };
cssclass => { FILTER("CLASS"); };
cssname => { FILTER("NAME"); };
cssattr => { FILTER("ATTR"); };
csstag => { FILTER("TAG"); };
cssmod => { FILTER("MOD"); };
csschild => { FILTER("CHILD"); };
csspos => { FILTER("POS"); };
pseudo => { FILTER("PSUEDO"); };
commas => { focus = RubyArray.newArray(runtime, node); };
traverse => { FILTERAUTO(); };
space;
*|;
write data nofinal;
}%%
public IRubyObject scan() {
%% write init;
%% write exec;
return focus;
}
}