EndTag getNextEndTag() { Tag tag=this; while (true) { tag=tag.getNextTag(); if (tag==null) return null; if (tag instanceof EndTag) return (EndTag)tag; } }
static final Tag getNextTag(final Source source, final int pos, final TagType tagType) { // returns null if pos is out of range. if (tagType==null) return getNextTag(source,pos); if (source.useSpecialTypesCache) return source.cache.getNextTag(pos,tagType); return getNextTagUncached(source,pos,tagType,ParseText.NO_BREAK); }
/** * Returns the {@link Tag} beginning at or immediately following the specified position in the source document. * <p> * See the {@link Tag} class documentation for more details about the behaviour of this method. * <p> * Use {@link Tag#getNextTag()} to get the tag immediately following another tag. * * @param pos the position in the source document from which to start the search, may be out of bounds. * @return the {@link Tag} beginning at or immediately following the specified position in the source document, or <code>null</code> if none exists or the specified position is out of bounds. */ public Tag getNextTag(final int pos) { return Tag.getNextTag(this,pos); }
private void updateNextTag() { // ensures that nextTag is up to date while (nextTag!=null) { if (nextTag.begin>=index) return; nextTag=nextTag.getNextTag(); } }
/** * Returns the {@link Tag} of the specified {@linkplain TagType type} beginning at or immediately following the specified position in the source document. * <p> * See the {@link Tag} class documentation for more details about the behaviour of this method. * * @param pos the position in the source document from which to start the search, may be out of bounds. * @param tagType the <code>TagType</code> to search for. * @return the {@link Tag} of the specified {@linkplain TagType type} beginning at or immediately following the specified position in the source document, or <code>null</code> if none exists or the specified position is out of bounds. */ public Tag getNextTag(final int pos, final TagType tagType) { return Tag.getNextTag(this,pos,tagType); }
StartTag getNextStartTag() { Tag tag=this; while (true) { tag=tag.getNextTag(); if (tag==null) return null; if (tag instanceof StartTag) return (StartTag)tag; } }
Tag getNextTag(final TagType tagType) { if (tagType==null) return getNextTag(); if (tagType==StartTagType.UNREGISTERED || tagType==EndTagType.UNREGISTERED) return getNextTag(source,begin+1,tagType); Tag tag=this; while (true) { if (tag.nextTag==NOT_CACHED) return getNextTag(source,tag.begin+1,tagType); tag=tag.nextTag; if (tag==null) return null; if (tag.getTagType()==tagType) return tag; } }
static StartTag getNext(final Source source, int pos) { final Tag tag=Tag.getNextTag(source,pos); if (tag==null) return null; if (tag instanceof StartTag) return (StartTag)tag; return tag.getNextStartTag(); }
static EndTag getNext(final Source source, int pos) { final Tag tag=Tag.getNextTag(source,pos); if (tag==null) return null; if (tag instanceof EndTag) return (EndTag)tag; return tag.getNextEndTag(); } }
/** * Returns a list of all {@link Tag} objects of the specified {@linkplain TagType type} that are {@linkplain #encloses(Segment) enclosed} by this segment. * <p> * See the {@link Tag} class documentation for more details about the behaviour of this method. * <p> * Specifying a <code>null</code> argument to the <code>tagType</code> parameter is equivalent to {@link #getAllTags()}. * * @param tagType the {@linkplain TagType type} of tags to get. * @return a list of all {@link Tag} objects of the specified {@linkplain TagType type} that are {@linkplain #encloses(Segment) enclosed} by this segment. * @see #getAllStartTags(StartTagType) */ public List<Tag> getAllTags(final TagType tagType) { Tag tag=checkTagEnclosure(Tag.getNextTag(source,begin,tagType)); if (tag==null) return Collections.emptyList(); final ArrayList<Tag> list=new ArrayList<Tag>(); do { list.add(tag); tag=checkTagEnclosure(tag.getNextTag(tagType)); } while (tag!=null); return list; }
/** * Returns the next tag in the source document. * <p> * This method also returns {@linkplain TagType#isServerTag() server tags}. * <p> * The result of a call to this method is cached. * Performing a {@linkplain Source#fullSequentialParse() full sequential parse} prepopulates this cache. * <p> * If the result is not cached, a call to this method is equivalent to <code>source.</code>{@link Source#getNextTag(int) getNextTag}<code>(</code>{@link #getBegin() getBegin()}<code>+1)</code>. * <p> * See the {@link Tag} class documentation for more details about the behaviour of this method. * * @return the next tag in the source document, or <code>null</code> if this is the last tag. */ public Tag getNextTag() { if (nextTag==NOT_CACHED) { final Tag localNextTag=getNextTag(source,begin+1); if (source.wasFullSequentialParseCalled()) return localNextTag; // Don't set nextTag if this is an orphaned tag. See isOrphaned() for details. nextTag=localNextTag; } return nextTag; }
public Segment next() { final int oldPos=pos; if (nextTag!=null) { if (oldPos<nextTag.begin) return nextNonTagSegment(oldPos,nextTag.begin); final Tag tag=nextTag; nextTag=nextTag.getNextTag(); if (nextTag!=null && nextTag.begin>=segment.end) nextTag=null; if (pos<tag.end) pos=tag.end; return tag; } else { if (!hasNext()) throw new NoSuchElementException(); return nextNonTagSegment(oldPos,segment.end); } }
Tag appendTidy(final Appendable appendable, Tag nextTag) throws IOException { appendable.append(' ').append(nameSegment); if (valueSegment!=null) { appendable.append("=\""); while (nextTag!=null && nextTag.begin<valueSegment.begin) nextTag=nextTag.getNextTag(); if (nextTag==null || nextTag.begin>=valueSegment.end) { appendTidyValue(appendable,valueSegment); } else { int i=valueSegment.begin; while (nextTag!=null && nextTag.begin<valueSegment.end) { appendTidyValue(appendable,new Segment(source,i,nextTag.begin)); if (nextTag.end>valueSegment.end) { appendable.append(new Segment(source,nextTag.begin,i=valueSegment.end)); break; } appendable.append(nextTag); i=nextTag.end; nextTag=nextTag.getNextTag(); } if (i<valueSegment.end) appendTidyValue(appendable,new Segment(source,i,valueSegment.end)); } appendable.append('"'); } return nextTag; }
private EndTag getOptionalEndTag(final HTMLElementTerminatingTagNameSets terminatingTagNameSets) { int pos=end; while (pos<source.end) { final Tag tag=Tag.getNextTag(source,pos); if (tag==null) break; Set<String> terminatingTagNameSet; if (tag instanceof EndTag) { if (tag.name==name) return (EndTag)tag; terminatingTagNameSet=terminatingTagNameSets.TerminatingEndTagNameSet; } else { terminatingTagNameSet=terminatingTagNameSets.NonterminatingElementNameSet; if (terminatingTagNameSet!=null && terminatingTagNameSet.contains(tag.name)) { Element nonterminatingElement=((StartTag)tag).getElement(); pos=nonterminatingElement.end; continue; } terminatingTagNameSet=terminatingTagNameSets.TerminatingStartTagNameSet; } if (terminatingTagNameSet!=null && terminatingTagNameSet.contains(tag.name)) return new EndTag(source,tag.begin,tag.begin,EndTagType.NORMAL,name); pos=tag.begin+1; } // Ran out of tags. The only legitimate case of this happening is if the HTML end tag is missing, in which case the end of the element is the end of the source document return new EndTag(source,source.end,source.end,EndTagType.NORMAL,name); }
/** * Returns a list of all {@link StartTag} objects of the specified {@linkplain StartTagType type} that are {@linkplain #encloses(Segment) enclosed} by this segment. * <p> * See the {@link Tag} class documentation for more details about the behaviour of this method. * <p> * Specifying a <code>null</code> argument to the <code>startTagType</code> parameter is equivalent to {@link #getAllStartTags()}. * * @param startTagType the {@linkplain StartTagType type} of tags to get. * @return a list of all {@link StartTag} objects of the specified {@linkplain StartTagType type} that are {@linkplain #encloses(Segment) enclosed} by this segment. */ public List<StartTag> getAllStartTags(final StartTagType startTagType) { if (startTagType==null) return getAllStartTags(); StartTag startTag=(StartTag)checkTagEnclosure(Tag.getNextTag(source,begin,startTagType)); if (startTag==null) return Collections.emptyList(); final ArrayList<StartTag> list=new ArrayList<StartTag>(); do { list.add(startTag); startTag=(StartTag)checkTagEnclosure(startTag.getNextTag(startTagType)); } while (startTag!=null); return list; }
if (name==null) return (EndTag)Tag.getNextTag(source,pos,endTagType); if (name.length()==0) throw new IllegalArgumentException("name argument must not be zero length"); if (source.wasFullSequentialParseCalled()) { EndTag endTag=(EndTag)Tag.getNextTag(source,pos,endTagType); while (true) { if (endTag==null) return null;
StartTag startTag=(StartTag)Tag.getNextTag(source,pos,searchStartTagType); while (true) { if (startTag==null) return null;
nextTag=tag.getNextTag(); final int tagEnd=(tag.end<end) ? tag.end : end; assert index<tagEnd;