1 19 20 package org.netbeans.editor.ext.html; 21 22 import javax.swing.text.BadLocationException ; 23 import org.netbeans.api.html.lexer.HTMLTokenId; 24 import org.netbeans.api.lexer.Token; 25 import org.netbeans.api.lexer.TokenHierarchy; 26 import org.netbeans.api.lexer.TokenSequence; 27 import org.netbeans.editor.BaseDocument; 28 import org.netbeans.editor.Syntax; 29 import org.netbeans.editor.ext.html.dtd.DTD; 30 import org.netbeans.editor.ext.html.dtd.DTD.Element; 31 import org.netbeans.modules.editor.structure.formatting.TagBasedLexerFormatter; 32 33 37 38 public class HTMLLexerFormatter extends TagBasedLexerFormatter { 39 private static final String [] UNFORMATTABLE_TAGS = new String []{"pre", "script", "code"}; 41 42 public HTMLLexerFormatter(Class kitClass) { 43 super(kitClass); 44 } 45 46 @Override protected boolean acceptSyntax(Syntax syntax) { 47 return (syntax instanceof HTMLSyntax); 48 } 49 50 @Override protected int getTagEndingAtPosition(TokenHierarchy tokenHierarchy, int position) throws BadLocationException { 51 if (position >= 0) { 52 TokenSequence tokenSequence = tokenHierarchy.tokenSequence(); 53 tokenSequence.move(position); 54 tokenSequence.moveNext(); 55 Token token = tokenSequence.token(); 56 57 if (token.id() == HTMLTokenId.TAG_CLOSE_SYMBOL && 58 !token.text().toString().endsWith("/>")){ 60 while (tokenSequence.movePrevious()){ 61 int tokenOffset = tokenSequence.offset(); 62 63 if (isOpeningTag(tokenHierarchy, tokenOffset) 64 || isClosingTag(tokenHierarchy, tokenOffset)){ 65 return tokenSequence.offset(); 66 } 67 } 68 } 69 } 70 return -1; 71 } 72 73 @Override protected int getTagEndOffset(TokenHierarchy tokenHierarchy, int tagStartOffset){ 74 TokenSequence tokenSequence = tokenHierarchy.tokenSequence(); 75 tokenSequence.move(tagStartOffset); 76 tokenSequence.moveNext(); 77 boolean thereAreMoreTokens = true; 78 79 while (thereAreMoreTokens && tokenSequence.token().id() != HTMLTokenId.TAG_CLOSE_SYMBOL){ 80 thereAreMoreTokens &= tokenSequence.moveNext(); 81 } 82 83 return thereAreMoreTokens ? tokenSequence.offset() : -1; 84 } 85 86 @Override protected boolean isJustBeforeClosingTag(TokenHierarchy tokenHierarchy, int tagTokenOffset) throws BadLocationException { 87 return super.isJustBeforeClosingTag(tokenHierarchy, tagTokenOffset + "</".length()); } 90 91 @Override protected boolean isClosingTag(TokenHierarchy tokenHierarchy, int tagTokenOffset){ 92 Token token = getTokenAtOffset(tokenHierarchy, tagTokenOffset); 93 return token != null && token.id() == HTMLTokenId.TAG_CLOSE; 94 } 95 96 @Override protected boolean isOpeningTag(TokenHierarchy tokenHierarchy, int tagTokenOffset){ 97 Token token = getTokenAtOffset(tokenHierarchy, tagTokenOffset); 98 return token != null && token.id() == HTMLTokenId.TAG_OPEN; 99 } 100 101 @Override protected String extractTagName(TokenHierarchy tokenHierarchy, int tagTokenOffset){ 102 return getTokenAtOffset(tokenHierarchy, tagTokenOffset).text().toString().trim(); 103 } 104 105 @Override protected boolean areTagNamesEqual(String tagName1, String tagName2){ 106 return tagName1.equalsIgnoreCase(tagName2); 107 } 108 109 @Override protected int getOpeningSymbolOffset(TokenHierarchy tokenHierarchy, int tagTokenOffset){ 110 TokenSequence tokenSequence = tokenHierarchy.tokenSequence(); 111 tokenSequence.move(tagTokenOffset); 112 boolean thereAreMoreTokens = true; 113 114 do{ 115 thereAreMoreTokens = tokenSequence.movePrevious(); 116 } 117 while(thereAreMoreTokens && tokenSequence.token().id() != HTMLTokenId.TAG_OPEN_SYMBOL); 118 119 if (thereAreMoreTokens){ 120 return tokenSequence.offset(); 121 } 122 123 return -1; 124 } 125 126 @Override protected boolean isClosingTagRequired(BaseDocument doc, String tagName) { 127 HTMLSyntaxSupport htmlsup = (HTMLSyntaxSupport)(doc.getSyntaxSupport().get(HTMLSyntaxSupport.class)); 128 DTD dtd = htmlsup.getDTD(); 129 130 if (dtd == null){ 131 return false; 133 } 134 135 Element elem = dtd.getElement(tagName.toUpperCase()); 136 137 if (elem == null){ 138 return true; 140 } 141 142 return !elem.isEmpty(); } 144 145 @Override protected boolean isUnformattableToken(TokenHierarchy tokenHierarchy, int tagTokenOffset) { 146 Token token = getTokenAtOffset(tokenHierarchy, tagTokenOffset); 147 148 if (token.id() == HTMLTokenId.BLOCK_COMMENT){ 149 return true; 150 } 151 152 return false; 153 } 154 155 @Override protected boolean isUnformattableTag(String tag) { 156 for(int i = 0; i < UNFORMATTABLE_TAGS.length; i++) { 157 if(tag.equalsIgnoreCase(UNFORMATTABLE_TAGS[i])) { 158 return true; 159 } 160 } 161 162 return false; 163 } 164 } 165 | Popular Tags |