// Copyright 2004 Triveni Digital Inc. All rights reserved. package com.bradfordholcombe.JSPWiki.filters; import com.ecyrd.jspwiki.TextUtil; import com.ecyrd.jspwiki.WikiContext; import com.ecyrd.jspwiki.filters.BasicPageFilter; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * Translates a new table syntax into JSPWiki standard. The new table format: * * ||| * cell 1, 1 * cell 1, 2 * || * cell 2, 1 * || * cell 3, 1 * cell 3, 2 * cell 3, 3 * ||| * * This would be translated into : * * |cell 1, 1|cell 2, 1|cell 3, 1 * |cell 1, 2||cell 3, 2 * |||cell 3, 3 * * This translation happens before the TranslatorReader gets it. * * Note that the last ||| must have a newline after it! * * This filter has the side effect of converting all newline sequences to the native newline sequence of the server platform. * * @author bradfordholcombe */ public class ExplodedTableFilter extends BasicPageFilter { /** * @see com.ecyrd.jspwiki.filters.PageFilter#preTranslate(com.ecyrd.jspwiki.WikiContext, java.lang.String) */ public final String preTranslate( WikiContext wikiContext, String content ) { if( wikiContext != null ) { //return content; } String lineSeparator = System.getProperty("line.separator"); String wikiContent = TextUtil.replaceString( content, "\r\n", lineSeparator ); wikiContent = TextUtil.replaceString( wikiContent, "\r", lineSeparator ); wikiContent = TextUtil.replaceString( wikiContent, "\n", lineSeparator ); String tableDelimiter = "|||" + lineSeparator; int cursor = 0; StringBuffer translatedContent = new StringBuffer(); int tableStart = wikiContent.indexOf( tableDelimiter ); while( tableStart > -1 ) { int tableEnd = wikiContent.indexOf( tableDelimiter, tableStart + tableDelimiter.length() ); translatedContent.append( wikiContent.substring( cursor, tableStart ) ); writeTable( translatedContent, wikiContent.substring( tableStart + tableDelimiter.length(), tableEnd ) ); tableStart = wikiContent.indexOf( tableDelimiter, tableEnd + tableDelimiter.length() ); cursor = tableEnd + tableDelimiter.length(); } translatedContent.append( wikiContent.substring( cursor ) ); return translatedContent.toString(); } /** * @param translatedContent * @param tableMarkup */ private void writeTable( StringBuffer translatedContent, String tableMarkup ) { String lineSeparator = System.getProperty("line.separator"); List rows = new ArrayList(); List currentRow = new ArrayList(); rows.add( currentRow ); // collect columns int lineEnd = tableMarkup.indexOf( lineSeparator ); int cursor = 0; int row = 0; int column = 0; while( lineEnd > -1 ) { String line = tableMarkup.substring( cursor, lineEnd ); if( "||".equals( line ) ) { currentRow = (List)rows.get( 0 ); row = 0; column++; } else { // get the next row if( row >= rows.size() ) { currentRow = new ArrayList(); rows.add( currentRow ); } else { currentRow = (List)rows.get( row ); } // pad out any missing cells for( int i = currentRow.size(); i < column; i++ ) { currentRow.add( null ); } currentRow.add( line ); row++; } cursor = lineEnd + 1; lineEnd = tableMarkup.indexOf( lineSeparator, cursor ); } // generate table for( Iterator columnListList = rows.iterator(); columnListList.hasNext(); ) { currentRow = (List)columnListList.next(); for( Iterator columnList = currentRow.iterator(); columnList.hasNext(); ) { String cell = (String)columnList.next(); translatedContent.append( "|" ); if( cell != null && !lineSeparator.equals( cell ) ) { translatedContent.append( cell ); } else { translatedContent.append( " " ); } } translatedContent.append( lineSeparator ); } } /** * Test * * @param args */ public static void main( final String[] args ) { String input = "|||\ncell 1, 1\ncell 1, 2\n||\ncell 2, 1\n||\ncell 3, 1\ncell 3, 2\ncell 3, 3\n|||\n"; String result = new ExplodedTableFilter().preTranslate( null, input ); System.out.println( "table:\n" + result ); System.out.println(); input = "|||\ncell 1, 1\n|||\n"; result = new ExplodedTableFilter().preTranslate( null, input ); System.out.println( "table:\n" + result ); input = "|||\n|||\n"; result = new ExplodedTableFilter().preTranslate( null, input ); System.out.println( "table:\n" + result ); String input4 = "|||\n||\n||\n\n\ncell 3, 3\n|||\n"; String result4 = new ExplodedTableFilter().preTranslate( null, input4 ); System.out.println( "table:\n" + result4 ); String input5 = "This is a test.\nthis is a test.\n" + "|||\n|Sections\n[Web links|web] - Links to interesting web resources\n[Books, etc.|Books] - Non-web resources\n" + "[Biographies] - Background on important people\n[Essays] - Contributed (or found) writings\n" + "[Organizations] - Groups focused on the [godless] life.\n[Encyclopedia] - Terms and concepts\n[Topics] - General discussion\n" + "[Products] - Godless merchandise\n[Secular Wiki FAQ|FAQ] - Frequently asked questions\n[Please Help] - How to help out\n" + "||\n|Tools\n[Info on SecWiki|About]\n[News] - Items on big changes\n[Recent Changes] - Recent page updates\n" + "[To do] - Chore list\n[Find pages by keyword|FindPage]\n[Page Index] - Alphabetical by page title\n" + "[SandBox] - for trying out editing\n[Text Formatting Rules]\n[Edit Page Help]\n[Tour|SecWikiTour] - What does this thing do? *snap*\n" + "[Ideas] - Want something that isn't here yet?\n[Bug Reports] - Is something broken?\n[Refactor Me] - Pages that need help.\n" + "||\n|Background\n[What is a wiki?|OneMinuteWiki]\n[On the evolution of wikis|http://www.evowiki.org/wiki.phtml?title=Wiki_evolution]\n" + "[Wiki Etiquette]\n[How to organize a wiki|JSPWiki:HowToOrganizeWiki]\n|||\n" + "\n\nThis is more of a test.\n" + "|||\ncell 1, 1\ncell 1, 2\n||\ncell 2, 1\n||\ncell 3, 1\ncell 3, 2\ncell 3, 3\n|||\n" + "This is the last test.\n\n\n\nABC"; String result5 = new ExplodedTableFilter().preTranslate( null, input5 ); System.out.println( "table:\n" + result5 ); } }