001package org.vishia.xml; 002 003import java.io.*; 004 005import org.vishia.mainCmd.*; 006import org.vishia.util.FileSystem; 007 008/** Class for conversion of any plain text files, source codes etc. into a browser visible HTML-format.</br> 009 The problem is: Some browsers shows files with xml content and with the extension txt 010 yet in form of xml files with hardheaded interpretation. If the content of the file 011 will be shown only in text format, all things of xml like scripting should be hided, 012 especially the tag structur. The <-char is converted to < A HTML frame is generated. 013*/ 014 015public class Textfile2Html extends MainCmd 016{ 017 018 /**Version, history and license. 019 * <ul> 020 * <li>2014-05-03 Hartmut bugfix: if a line cannot wrapped on space, a character was missed. 021 * <li>2009-12-31: Hartmut corr: Creation of a directory of output path. 022 * <li>2005-06-00 Hartmut Created. 023 * </ul> 024 * <br><br> 025 * <b>Copyright/Copyleft</b>: 026 * For this source the LGPL Lesser General Public License, 027 * published by the Free Software Foundation is valid. 028 * It means: 029 * <ol> 030 * <li> You can use this source without any restriction for any desired purpose. 031 * <li> You can redistribute copies of this source to everybody. 032 * <li> Every user of this source, also the user of redistribute copies 033 * with or without payment, must accept this license for further using. 034 * <li> But the LPGL is not appropriate for a whole software product, 035 * if this source is only a part of them. It means, the user 036 * must publish this part of source, 037 * but don't need to publish the whole source of the own product. 038 * <li> You can study and modify (improve) this source 039 * for own using or for redistribution, but you have to license the 040 * modified sources likewise under this LGPL Lesser General Public License. 041 * You mustn't delete this Copyright/Copyleft inscription in this source file. 042 * </ol> 043 * If you are intent to use this sources without publishing its usage, you can get 044 * a second license subscribing a special contract with the author. 045 * 046 * @author Hartmut Schorrig = hartmut.schorrig@vishia.de 047 * 048 */ 049 public static final String sVersion = "2014-05-03"; 050 051 052 /**Cmdline-argument, set on -i option. Inputpath.*/ 053 String sPathIn = null; 054 055 /**Cmdline-argument, set on -o option. Outputpath.*/ 056 String sPathOut = null; 057 058 /**Cmdline-argument, set on -f option. Filename.*/ 059 String sFile = ""; 060 061 /**Cmdline-argument, set on -linesize: option.*/ 062 int maxLineSize = 120; 063 064 /** String of spaces to provide some spaces for indent*/ 065 static String sIndent = " "; 066 067 /**Writer of the output used internally.*/ 068 private BufferedWriter writer; 069 070 071 072 /*---------------------------------------------------------------------------------------------*/ 073 /** main started from java 074 * The command line arguments follow this help text: <pre> 075 super.addHelpInfo("param: -iINPUT -oOUTPUT -fFILE -linesize:size"); 076 super.addStandardHelpInfo(); 077 super.addHelpInfo("-iINPUT inputfilepath, a xml like file."); 078 super.addHelpInfo("-oOUTPUT outputfilepath, this file is written."); 079 super.addHelpInfo("-fFILE if this argument is given, read from INPUT/FILE, write to OUTPUT/FILE.html."); 080 super.addHelpInfo("-linesize: length of a line, a wrapping is generated after it."); 081 </pre> 082 * */ 083 public static void main(String [] args) 084 { Textfile2Html main = new Textfile2Html(args); 085 main.execute(); 086 main.exit(); 087 } 088 089 090 /** Executes the cmd-line-application. The functionality application class is created inside this method 091 independent of the command line invoke. 092 */ 093 void execute() 094 { boolean bOk = true; 095 try{ super.parseArguments(); } 096 catch(Exception exception) 097 { setExitErrorLevel(MainCmdLogging_ifc.exitWithArgumentError); 098 bOk = false; 099 } 100 101 if(bOk) 102 { /** The execution class knows the Textfile2Html Main class in form of the MainCmd super class 103 to hold the contact to the command line execution. 104 */ 105 106 try 107 { convert(); 108 } 109 catch(Exception exception) 110 { //catch the last level of error. No error is reported direct on command line! 111 report("Abort the routine:", exception); 112 setExitErrorLevel(MainCmdLogging_ifc.exitWithErrors); 113 } 114 } 115 //note: exit the command line application in static main() 116 } 117 118 119 120 121 122 /*---------------------------------------------------------------------------------------------*/ 123 /** Constructor of the main class. 124 The command line arguments are parsed here. After them the execute class is created as composition of Textfile2Html. 125 */ 126 Textfile2Html(String[] args) 127 { super(args); 128 //super.addHelpInfo(getAboutInfo()); 129 super.addAboutInfo("Translator text files to a html readable represantiation"); 130 super.addAboutInfo("made by JcHartmut, 2006-02-25"); 131 super.addHelpInfo("param: -iINPUT -oOUTPUT -fFILE -linesize:size"); 132 super.addStandardHelpInfo(); 133 super.addHelpInfo("-iINPUT inputfilepath, a xml like file."); 134 super.addHelpInfo("-oOUTPUT outputfilepath, this file is written."); 135 super.addHelpInfo("-fFILE if this argument is given, read from INPUT/FILE, write to OUTPUT/FILE.html."); 136 super.addHelpInfo("-linesize: length of a line, a wrapping is generated after it."); 137 138 } 139 140 141 142 143 144 145 /*---------------------------------------------------------------------------------------------*/ 146 /** Tests one argument. This method is invoked from parseArgument. It is abstract in the superclass MainCmd 147 and must be overwritten from the user. 148 @param argc String of the actual parsed argument from cmd line 149 @param nArg number of the argument in order of the command line, the first argument is number 1. 150 @return true is okay, 151 false if the argument doesn't match. The parseArgument method in MainCmd throws an exception, 152 the application should be aborted. 153 */ 154 @Override 155 public boolean testArgument(String arg, int nArg) 156 { boolean bOk = true; //set to false if the argc is not passed 157 158 if(arg.startsWith("-i")) { sPathIn = getArgument(2);} 159 else if(arg.startsWith("-o")) { sPathOut = getArgument(2);} 160 else if(arg.startsWith("-f")) { sFile = getArgument(2);} 161 else if(arg.startsWith("-linesize:")){ maxLineSize= Integer.parseInt(getArgument(10)); } 162 else bOk=false; 163 164 return bOk; 165 } 166 167 168 169 170 171 /*---------------------------------------------------------------------------------------------*/ 172 /**Checks the cmdline arguments relation together. 173 If there is an inconsistents, a message should be written. It may be also a warning. 174 @return true if successfull, false if failed. 175 */ 176 @Override 177 protected boolean checkArguments() 178 { boolean bOk = true; 179 180 if(sPathIn == null) { bOk = false; writeError("ERROR argument -i is obligat."); } 181 else if(sPathIn.length()==0) { bOk = false; writeError("ERROR argument -i without content.");} 182 183 if(sPathOut == null) { writeWarning("argument -o no outputfile is given, use default"); sPathOut = "out.txt";} 184 else if(sPathOut.length()==0) { bOk = false; writeError("argument -o without content"); } 185 186 if(!bOk) setExitErrorLevel(exitWithArgumentError); 187 188 return bOk; 189 190 } 191 192 193 void convert() 194 throws Exception 195 { 196 BufferedReader reader = null; 197 if(sFile.length()>0 ){ sPathIn = sPathIn + "/" + sFile; } 198 try 199 { reader = new BufferedReader(new FileReader(sPathIn)); 200 } 201 catch(FileNotFoundException exception) 202 { writeError("input file not found", exception); 203 setExitErrorLevel(exitWithFileProblems); 204 throw exception; 205 } 206 207 if(sFile.length()>0 ){ sPathOut = sPathOut + "/" + sFile + ".html"; } 208 try 209 { FileSystem.mkDirPath(sPathOut); //if the dst directory doesn't exists. 210 writer = new BufferedWriter(new FileWriter(sPathOut)); 211 } 212 catch(FileNotFoundException exception) 213 { writeError("output file not found", exception); 214 setExitErrorLevel(exitWithFileProblems); 215 throw exception; 216 } 217 218 report(info, "translate " + sPathIn + " to " + sPathOut); 219 220 writer.write("<html><head><title>" + sPathIn + "</title></head>\n<body><pre>\n"); 221 222 String sLine; 223 while( (sLine = reader.readLine()) != null) 224 { /**ascertain the indentitation of the block of this line*/ 225 int indent = 0; 226 while(sLine.length() > indent && sLine.charAt(indent) == ' '){ indent +=1; } 227 sLine = sLine.substring(indent); //without indentitation. 228 //don't exaggerate it. We haven't enaugh room. 229 //note, that 2 addtional spaces are needed for wrapping a line 230 if(indent > sIndent.length()-2){ indent = sIndent.length()-2; } 231 232 /** Cut the line if it is to long*/ 233 int indentWrapped = indent; //first line with same indent. 234 int maxLength = maxLineSize - indentWrapped; 235 while(sLine.length() > maxLength) 236 { int posLast=sLine.lastIndexOf(' ', maxLength); 237 int posNext = posLast +1; //continue AFTER space, otherwise an infinite loop may occure!!! 238 if(posLast < 0){ posNext = posLast = maxLength; } //cutting it at max Length, continue direct. 239 printLine( sIndent.substring(0, indentWrapped) + sLine.substring(0, posLast)); 240 sLine = sLine.substring(posNext); 241 indentWrapped = indent +2; //next wrapped lines with higher indent. 242 maxLength = maxLineSize - indentWrapped; 243 } 244 printLine( sIndent.substring(0, indentWrapped) + sLine); //print the rest. 245 246 } 247 writer.write("\n</pre>\n</body></html>\n"); 248 writer.close(); 249 writer = null; //no longer used. 250 reportln(info,"....successfull."); 251 } 252 253 void printLine(String sLine) 254 throws IOException 255 { { //the main task: replace all < with the named periphrases. 256 String sLine1 = sLine.replaceAll("&", "&"); 257 sLine1 = sLine1.replaceAll("<", "<"); 258 sLine1 = sLine1.replaceAll(">", ">"); 259 writer.write(sLine); 260 writer.write("\n"); 261 } 262 263 } 264 265 266 267 268 269 270 271} 272 273 274 275