// TODO: dead fields?
int skipUntil = -1;
for ( int c = 0; c < range.numCharacterRuns(); c++ )
{
CharacterRun characterRun = range.getCharacterRun( c );
if ( characterRun == null )
throw new AssertionError();
if ( characterRun.getStartOffset() < skipUntil )
continue;
String text = characterRun.text();
if ( text == null || text.length() == 0
|| text.charAt( 0 ) != FIELD_BEGIN_MARK )
continue;
Field aliveField = ( (HWPFDocument) wordDocument ).getFields()
.getFieldByStartOffset( FieldsDocumentPart.MAIN,
characterRun.getStartOffset() );
if ( aliveField != null )
{
addToStructures( structures, new Structure( aliveField ) );
}
else
{
int[] separatorEnd = tryDeadField_lookupFieldSeparatorEnd(
wordDocument, range, c );
if ( separatorEnd != null )
{
addToStructures(
structures,
new Structure( new DeadFieldBoundaries( c,
separatorEnd[0], separatorEnd[1] ),
characterRun.getStartOffset(), range
.getCharacterRun(
separatorEnd[1] )
.getEndOffset() ) );
c = separatorEnd[1];
}
}
}
}
structures = new ArrayList<Structure>( structures );
Collections.sort( structures );
int previous = range.getStartOffset();
for ( Structure structure : structures )
{
if ( structure.start != previous )
{
Range subrange = new Range( previous, structure.start, range )
{
@Override
public String toString()
{
return "BetweenStructuresSubrange " + super.toString();
}
};
processCharacters( wordDocument, currentTableLevel, subrange,
block );
}
if ( structure.structure instanceof Bookmark )
{
// other bookmarks with same boundaries
List<Bookmark> bookmarks = new LinkedList<Bookmark>();
for ( Bookmark bookmark : ( (HWPFDocument) wordDocument )
.getBookmarks()
.getBookmarksStartedBetween( structure.start,
structure.start + 1 ).values().iterator()
.next() )
{
if ( bookmark.getStart() == structure.start
&& bookmark.getEnd() == structure.end )
{
bookmarks.add( bookmark );
}
}
bookmarkStack.addAll( bookmarks );
try
{
int end = Math.min( range.getEndOffset(), structure.end );
Range subrange = new Range( structure.start, end, range )
{
@Override
public String toString()
{
return "BookmarksSubrange " + super.toString();
}
};
processBookmarks( wordDocument, block, subrange,
currentTableLevel, bookmarks );
}
finally
{
bookmarkStack.removeAll( bookmarks );
}
}
else if ( structure.structure instanceof Field )
{
Field field = (Field) structure.structure;
processField( (HWPFDocument) wordDocument, range,
currentTableLevel, field, block );
}
else if ( structure.structure instanceof DeadFieldBoundaries )
{
DeadFieldBoundaries boundaries = (DeadFieldBoundaries) structure.structure;
processDeadField( wordDocument, block, range,
currentTableLevel, boundaries.beginMark,
boundaries.separatorMark, boundaries.endMark );
}
else
{
throw new UnsupportedOperationException( "NYI: "
+ structure.structure.getClass() );
}
previous = Math.min( range.getEndOffset(), structure.end );
}
if ( previous != range.getStartOffset() )
{
if ( previous > range.getEndOffset() )
{
logger.log( POILogger.WARN, "Latest structure in ", range,
" ended at #" + previous, " after range boundaries [",
range.getStartOffset() + "; " + range.getEndOffset(),
")" );
return true;
}
if ( previous < range.getEndOffset() )
{
Range subrange = new Range( previous, range.getEndOffset(),
range )
{
@Override
public String toString()
{
return "AfterStructureSubrange " + super.toString();
}
};
processCharacters( wordDocument, currentTableLevel, subrange,
block );
}
return true;
}
for ( int c = 0; c < range.numCharacterRuns(); c++ )
{
CharacterRun characterRun = range.getCharacterRun( c );
if ( characterRun == null )
throw new AssertionError();
if ( wordDocument instanceof HWPFDocument
&& ( (HWPFDocument) wordDocument ).getPicturesTable()
.hasPicture( characterRun ) )
{
HWPFDocument newFormat = (HWPFDocument) wordDocument;
Picture picture = newFormat.getPicturesTable().extractPicture(
characterRun, true );
processImage( block, characterRun.text().charAt( 0 ) == 0x01,
picture );
continue;
}
String text = characterRun.text();
if ( text.getBytes().length == 0 )
continue;
if ( characterRun.isSpecialCharacter() )
{
if ( text.charAt( 0 ) == SPECCHAR_AUTONUMBERED_FOOTNOTE_REFERENCE
&& ( wordDocument instanceof HWPFDocument ) )
{
HWPFDocument doc = (HWPFDocument) wordDocument;
processNoteAnchor( doc, characterRun, block );
continue;
}
if ( text.charAt( 0 ) == SPECCHAR_DRAWN_OBJECT
&& ( wordDocument instanceof HWPFDocument ) )
{
HWPFDocument doc = (HWPFDocument) wordDocument;
processDrawnObject( doc, characterRun, block );
continue;
}
if ( characterRun.isOle2()
&& ( wordDocument instanceof HWPFDocument ) )
{
HWPFDocument doc = (HWPFDocument) wordDocument;
processOle2( doc, characterRun, block );
continue;
}
}
if ( text.getBytes()[0] == FIELD_BEGIN_MARK )
{
if ( wordDocument instanceof HWPFDocument )
{
Field aliveField = ( (HWPFDocument) wordDocument )
.getFields().getFieldByStartOffset(
FieldsDocumentPart.MAIN,
characterRun.getStartOffset() );
if ( aliveField != null )
{
processField( ( (HWPFDocument) wordDocument ), range,
currentTableLevel, aliveField, block );
int continueAfter = aliveField.getFieldEndOffset();
while ( c < range.numCharacterRuns()
&& range.getCharacterRun( c ).getEndOffset() <= continueAfter )
c++;
if ( c < range.numCharacterRuns() )
c--;
continue;
}
}
int skipTo = tryDeadField( wordDocument, range,
currentTableLevel, c, block );
if ( skipTo != c )
{
c = skipTo;
continue;
}
continue;
}
if ( text.getBytes()[0] == FIELD_SEPARATOR_MARK )
{
// shall not appear without FIELD_BEGIN_MARK
continue;
}
if ( text.getBytes()[0] == FIELD_END_MARK )
{
// shall not appear without FIELD_BEGIN_MARK
continue;
}
if ( characterRun.isSpecialCharacter() || characterRun.isObj()
|| characterRun.isOle2() )
{
continue;
}
if ( text.endsWith( "\r" )