📄 links.g
字号:
{import java.util.Vector;}/** Parse an entire html file, firing events to a single listener * for each image and href link encountered. All tokens are * defined to skip so the lexer will continue scarfing until EOF. */class LinkExtractor extends Lexer;options { caseSensitive=false; k=2; filter=SCARF; charVocabulary='\3'..'\177';}{ protected LinkListener listener; public void addLinkListener(LinkListener listener) { this.listener = listener; } public void removeLinkListener(LinkListener listener) { this.listener = null; } public void fireImageLinkEvent(String target, int line) { listener.imageReference(target, line); } public void fireHREFLinkEvent(String target, int line) { listener.hrefReference(target, line); } /** strip quotes from "..." or '...' strings */ public static String stripQuotes(String src) { int h = src.indexOf('"'); if ( h==-1 ) h = src.indexOf('\''); int t = src.lastIndexOf('"'); if ( t==-1 ) t = src.lastIndexOf('\''); if ( h==-1 || t==-1 ) return src; return src.substring(h+1,t); }}AHREF : "<a" WS (ATTR)+ '>' {$setType(Token.SKIP);} ;IMG : "<img" WS (ATTR)+ '>' {$setType(Token.SKIP);} ;protectedATTRoptions { ignore=WS;} : w:WORD '=' ( s:STRING | v:WORD ) { String target = s!=null ? stripQuotes(s.getText()) : v.getText(); if ( w.getText().equalsIgnoreCase("href") ) { fireHREFLinkEvent(target, getLine()); } else if ( w.getText().equalsIgnoreCase("src") ) { fireImageLinkEvent(target, getLine()); } } ;/** Match until next whitespace; can be file, int, etc... */protectedWORD: ( options { generateAmbigWarnings=false; } : 'a'..'z' | '0'..'9' | '/' | '.' | '#' | '_' )+ ;protectedSTRING : '"' (~'"')* '"' | '\'' (~'\'')* '\'' ;protectedWS : ( ' ' | '\t' | '\f' | ( "\r\n" // DOS | '\r' // Macintosh | '\n' // Unix (the right way) ) { newline(); } ) { $setType(Token.SKIP); } ;protectedSCARF : WS // track line numbers while you scarf | . ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -