Formatting a Java program for web
Tuesday, October 09, 2012
As a programmer we should always make sure our program is easily readable and understandable by other programming fellows. A program can be easily followed only when it is formatted properly i.e.; with proper indentation, with different coloring for keywords, string literals etc.
I've implemented a Java program to format the code which can be shared on the web. i.e; my program will apply a HTML element with class name (for eg, keywords will be applied a style with <span class="keyword">) for each type of programming element.
All the programs that are posted on my blog uses this program. Please note that indentation hasn't been implemented yet. I shall update again when I implement that. This program output will be generated as an HTML file with all the styles applied.
Every IDE will execute a program something similar to this when you request IDE to reformat your program.
FormatProgramV2.javaimport java.io.FileReader; import java.io.File; import java.io.BufferedReader; import java.io.FileWriter; import java.io.BufferedWriter; import java.util.Stack; /** * This class formats a given Java program. * @author SANTHOSH REDDY MANDADI * @version 1.0 * @since 03-October-2012 */ public class FormatProgramV2 { public static void main(String args[]) throws Exception { String fileName = ""; //Checking for the file name through command line argument if(args!=null && args.length>0) { fileName = args[0]; } else { System.out.println("Please input a Java program file name as below:"); System.out.println("java FormatProgramV2 Example.java"); return; } //Exiting program execution if the file is not of Java if(!fileName.endsWith(".java")) { System.out.println("Sorry, this program can format only Java programs."); return; } if(!(new File(fileName).exists())) { System.out.println("File not found - "+fileName); return; } //Opening file input stream FileReader fileReader = new FileReader(fileName); BufferedReader reader = new BufferedReader(fileReader); //Creating a new file .html to generate output FileWriter fileWriter = new FileWriter(fileName.replaceAll("\\.java", ".html")); BufferedWriter writer = new BufferedWriter(fileWriter); //Reserved words list to apply a keyword class String reservedWords[] = {"class", "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "const", "continue", "default", "do", "double", "else", "enum", "extends", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "package", "private", "protected", "public", "return", "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "try", "void", "volatile", "while" }; //String to hold the entire program String program = ""; //String to hold the generate HTML source StringBuffer html; //Temporary variable to read content from file String str = ""; //Flag to hold whether doubleQuote started boolean doubleQuote = false; //Flag to hold whether singleQuote started boolean singleQuote = false; //Flag to hold whether multiLineComment started boolean multiLineComment = false; //Flag to hold whether keyword started boolean word = false; //Flag to hold whether singleLineComment started boolean singleLineComment = false; //Flag represent any of the above tokens started boolean flag = false; int commentPosition = -1; while(str!=null) { str = reader.readLine(); if(str!=null) { program += str+"\n"; } } program = program.replaceAll("<", "<"); program = program.replaceAll(">", ">"); html = new StringBuffer(program); char prevChar = ' '; char secondPrevChar = ' '; int programPosition=0; int htmlPosition = 0; String keyword = ""; try { for(char ch: program.toCharArray()) { if(Character.isLetterOrDigit(ch)) { keyword += ch; word = true; } else { if(ch=='"' && ((secondPrevChar=='\\' && prevChar=='\\') || prevChar!='\\' ) &&!singleQuote) { //Ending double quote if(doubleQuote) { html.insert(htmlPosition+1, "</span>"); htmlPosition += "</span>".length(); doubleQuote = false; } else { //Inserting double quote html.insert(htmlPosition, "<span class=\"str\">"); htmlPosition += "<span class=\"str\">".length(); doubleQuote = true; } } else if(ch=='\'' && ((secondPrevChar=='\\' && prevChar=='\\') || prevChar!='\\' ) &&!doubleQuote) { if(singleQuote) { //Ending single quote html.insert(htmlPosition+1, "</span>"); htmlPosition += "</span>".length(); singleQuote = false; } else { //Inserting singel quote html.insert(htmlPosition, "<span class=\"char\">"); htmlPosition += "<span class=\"char\">".length(); singleQuote = true; } } else if(ch=='/' && html.charAt(htmlPosition+1)=='*' && !multiLineComment && !doubleQuote) /*/*******/ { //Inserting a comment html.insert(htmlPosition, "<span class=\"comment\">"); htmlPosition += "<span class=\"comment\">".length(); multiLineComment = true; commentPosition = programPosition; } else if(ch=='/' && prevChar == '*' && programPosition>commentPosition+2) { //Ending a comment html.insert(htmlPosition+2, "</span>"); htmlPosition += "</span>".length(); multiLineComment = false; commentPosition = -1; } else if(ch=='/' && html.charAt(htmlPosition+1)=='/' && !singleLineComment && !doubleQuote) { //Inserting a comment html.insert(htmlPosition, "<span class=\"comment\">"); htmlPosition += "<span class=\"comment\">".length(); singleLineComment = true; } else if((ch=='\r' || ch=='\n') && singleLineComment) ////Comments.... { //Ending a comment html.insert(htmlPosition+2, "</span>"); htmlPosition += "</span>".length(); singleLineComment = false; } if(!doubleQuote && !singleQuote && !singleLineComment && !multiLineComment) { word = false; if(!keyword.equals("")) { for(String s:reservedWords) { if(s.equals(keyword)) { //Inserting keyword html.insert(htmlPosition-keyword.length(), "<span class=\"word\">"); htmlPosition += ("<span class=\"word\">".length()); //Ending keyword html.insert(htmlPosition, "</span>"); htmlPosition += ("</span>".length()); } } } keyword = ""; } } secondPrevChar = prevChar; prevChar = ch; programPosition++; htmlPosition++; } } finally { html.insert(0,"<style type=\"text/css\">\n"+ " .program {\n"+ " font: 400 13px Roboto,sans-serif;\n"+ " border-radius: 10px;\n"+ " line-height: 1.5em;\n"+ " overflow: auto;\n"+ " background-color: #f0f0f0;\n"+ " color: black;\n"+ " margin: 3px 0;\n"+ " padding: 10px 0 5px 10px;\n"+ " }\n"+ " .word{\n"+ " color: #008;\n"+ " }\n"+ " .str {\n"+ " color: #080;\n"+ " }\n"+ " .char {\n"+ " color: #080;\n"+ " }\n"+ " .comment{\n"+ " color: #333;\n"+ " }\n"+ "</style><pre class=\"program\">"); writer.write(html.toString()+"</pre>"); writer.close(); fileWriter.close(); reader.close(); fileReader.close(); System.out.println("Generated a formatted source file - "+fileName.replaceAll("\\.java", ".html")); } } }Explanation
Java program file should be passed as a command line argument. I've handled below scenarios to detect the input
- The file should definitely be a Java program
- File should exist on the disk
santhosh> java FormatProgramV2 Please input a Java program file name as below: java FormatProgramV2 Example.java santhosh> java FormatProgramV2 Example.java File not found - Example.java santhosh> java FormatProgramV2 Notepad.java Generated a formatted source file - Notepad.html
If you've sometime, why don't you checkout my other Java programs


Really your publish is actually excellent and that i be thankful. You are writing perfectly that is amazing. I truly astounded by your publish regards.
ReplyDelete