Given the following:
> This is level 1 > This is level 2 >> This is level 2.1 >> This is level 2.2 >>> This is level 2.2.1 >>> This is level 2.2.2 > This is level 3
How would you convert that text to XHTML, without a parser library such as ANTLR? That is:
<ul>
<li>This is level 1</li>
<li>This is level 2
<ul>
<li>This is level 2.1</li>
<li>This is level 2.2
<ul>
<li>This is level 2.2.1</li>
<li>This is level 2.2.2</li>
</ul>
</li>
</ul>
</li>
<li>This is level 3</li>
</ul>
I have tried both recursive and iterative algorithms. The troubling part is closing the ul
tags from depth 3 (2.2.2) to depth 1 (3).
Solution
The following code solves the problem. The solution marked as correct was correct when each level represented a single number, rather than a line of text. New lines in the output are for human readability, but since (X)HTML is computer-read, they have been removed from the code below.
public String transform( String source ) {
// Level 0 means no >, level 1 for one >, etc.
//
int currentLevel = 0;
int nextLevel = 0;
StringBuilder sb = new StringBuilder( 512 );
// Split source on newlines.
//
String[] lines = source.split( "\\r?\\n" );
for( String line: lines ) {
int indents = line.lastIndexOf( ">" );
if( indents < 0 ) {
continue;
}
String content = line.substring( indents + 1 ).trim();
nextLevel = indents + 1;
if( nextLevel == currentLevel ) {
sb.append( "</li><li>" );
}
else if( nextLevel > currentLevel ) {
sb.append( "<ul><li>" );
}
else if( nextLevel < currentLevel ) {
for( int i = 0; i < currentLevel - nextLevel; i++ ) {
sb.append( "</li></ul>" );
}
sb.append( "</li><li>" );
}
sb.append( content );
currentLevel = nextLevel;
}
// Close the remaining levels.
//
for( int i = 0; i < currentLevel; i++ ) {
sb.append( "</li></ul>" );
}
return sb.toString();
}