/* // make sure the user didn't hide the sketch folder ensureExistence(); zipFileContents = new Hashtable(); // nuke the old applet folder because it can cause trouble File appletFolder = new File(folder, "applet"); Base.removeDir(appletFolder); appletFolder.mkdirs(); // build the sketch String foundName = build(appletFolder.getPath(), name); // (already reported) error during export, exit this function if (foundName == null) return false; // if name != exportSketchName, then that's weirdness // BUG unfortunately, that can also be a bug in the preproc :( if (!name.equals(foundName)) { Base.showWarning("Error during export", "Sketch name is " + name + " but the sketch\n" + "name in the code was " + foundName, null); return false; } int wide = PApplet.DEFAULT_WIDTH; int high = PApplet.DEFAULT_HEIGHT; PatternMatcher matcher = new Perl5Matcher(); PatternCompiler compiler = new Perl5Compiler(); // this matches against any uses of the size() function, // whether they contain numbers of variables or whatever. // this way, no warning is shown if size() isn't actually // used in the applet, which is the case especially for // beginners that are cutting/pasting from the reference. // modified for 83 to match size(XXX, ddd so that it'll // properly handle size(200, 200) and size(200, 200, P3D) String sizing = "[\\s\\;]size\\s*\\(\\s*(\\S+)\\s*,\\s*(\\d+)"; Pattern pattern = compiler.compile(sizing); // adds a space at the beginning, in case size() is the very // first thing in the program (very common), since the regexp // needs to check for things in front of it. PatternMatcherInput input = new PatternMatcherInput(" " + code[0].program); if (matcher.contains(input, pattern)) { MatchResult result = matcher.getMatch(); try { wide = Integer.parseInt(result.group(1).toString()); high = Integer.parseInt(result.group(2).toString()); } catch (NumberFormatException e) { // found a reference to size, but it didn't // seem to contain numbers final String message = "The size of this applet could not automatically be\n" + "determined from your code. You'll have to edit the\n" + "HTML file to set the size of the applet."; Base.showWarning("Could not find applet size", message, null); } } // else no size() command found // originally tried to grab this with a regexp matcher, // but it wouldn't span over multiple lines for the match. // this could prolly be forced, but since that's the case // better just to parse by hand. StringBuffer dbuffer = new StringBuffer(); String lines[] = PApplet.split(code[0].program, '\n'); for (int i = 0; i < lines.length; i++) { if (lines[i].trim().startsWith("/**")) { // this is our comment // some smartass put the whole thing on the same line //if (lines[j].indexOf("*/") != -1) break; for (int j = i+1; j < lines.length; j++) { if (lines[j].trim().endsWith("*/")) { // remove the */ from the end, and any extra *s // in case there's also content on this line // nah, don't bother.. make them use the three lines break; } int offset = 0; while ((offset < lines[j].length()) && ((lines[j].charAt(offset) == '*') || (lines[j].charAt(offset) == ' '))) { offset++; } // insert the return into the html to help w/ line breaks dbuffer.append(lines[j].substring(offset) + "\n"); } } } String description = dbuffer.toString(); StringBuffer sources = new StringBuffer(); for (int i = 0; i < codeCount; i++) { sources.append("" + code[i].name + " "); } File htmlOutputFile = new File(appletFolder, "index.html"); FileOutputStream fos = new FileOutputStream(htmlOutputFile); PrintStream ps = new PrintStream(fos); // @@sketch@@, @@width@@, @@height@@, @@archive@@, @@source@@ // and now @@description@@ InputStream is = null; // if there is an applet.html file in the sketch folder, use that File customHtml = new File(folder, "applet.html"); if (customHtml.exists()) { is = new FileInputStream(customHtml); } if (is == null) { is = Base.getStream("applet.html"); } BufferedReader reader = new BufferedReader(new InputStreamReader(is)); String line = null; while ((line = reader.readLine()) != null) { if (line.indexOf("@@") != -1) { StringBuffer sb = new StringBuffer(line); int index = 0; while ((index = sb.indexOf("@@sketch@@")) != -1) { sb.replace(index, index + "@@sketch@@".length(), name); } while ((index = sb.indexOf("@@source@@")) != -1) { sb.replace(index, index + "@@source@@".length(), sources.toString()); } while ((index = sb.indexOf("@@archive@@")) != -1) { sb.replace(index, index + "@@archive@@".length(), name + ".jar"); } while ((index = sb.indexOf("@@width@@")) != -1) { sb.replace(index, index + "@@width@@".length(), String.valueOf(wide)); } while ((index = sb.indexOf("@@height@@")) != -1) { sb.replace(index, index + "@@height@@".length(), String.valueOf(high)); } while ((index = sb.indexOf("@@description@@")) != -1) { sb.replace(index, index + "@@description@@".length(), description); } line = sb.toString(); } ps.println(line); } reader.close(); ps.flush(); ps.close(); // copy the loading gif to the applet String LOADING_IMAGE = "loading.gif"; File loadingImage = new File(folder, LOADING_IMAGE); if (!loadingImage.exists()) { loadingImage = new File("lib", LOADING_IMAGE); } Base.copyFile(loadingImage, new File(appletFolder, LOADING_IMAGE)); // copy the source files to the target, since we like // to encourage people to share their code for (int i = 0; i < codeCount; i++) { try { Base.copyFile(code[i].file, new File(appletFolder, code[i].file.getName())); } catch (IOException e) { e.printStackTrace(); } } // create new .jar file FileOutputStream zipOutputFile = new FileOutputStream(new File(appletFolder, name + ".jar")); ZipOutputStream zos = new ZipOutputStream(zipOutputFile); ZipEntry entry; // add the manifest file addManifest(zos); // add the contents of the code folder to the jar // unpacks all jar files //File codeFolder = new File(folder, "code"); if (codeFolder.exists()) { String includes = Compiler.contentsToClassPath(codeFolder); packClassPathIntoZipFile(includes, zos); } // add contents of 'library' folders to the jar file // if a file called 'export.txt' is in there, it contains // a list of the files that should be exported. // otherwise, all files are exported. Enumeration en = importedLibraries.elements(); while (en.hasMoreElements()) { // in the list is a File object that points the // library sketch's "library" folder File libraryFolder = (File)en.nextElement(); File exportSettings = new File(libraryFolder, "export.txt"); String exportList[] = null; if (exportSettings.exists()) { String info[] = Base.loadStrings(exportSettings); for (int i = 0; i < info.length; i++) { if (info[i].startsWith("applet")) { int idx = info[i].indexOf('='); // get applet= or applet = String commas = info[i].substring(idx+1).trim(); exportList = PApplet.split(commas, ", "); } } } else { exportList = libraryFolder.list(); } for (int i = 0; i < exportList.length; i++) { if (exportList[i].equals(".") || exportList[i].equals("..")) continue; exportList[i] = PApplet.trim(exportList[i]); if (exportList[i].equals("")) continue; File exportFile = new File(libraryFolder, exportList[i]); if (!exportFile.exists()) { System.err.println("File " + exportList[i] + " does not exist"); } else if (exportFile.isDirectory()) { System.err.println("Ignoring sub-folder \"" + exportList[i] + "\""); } else if (exportFile.getName().toLowerCase().endsWith(".zip") || exportFile.getName().toLowerCase().endsWith(".jar")) { packClassPathIntoZipFile(exportFile.getAbsolutePath(), zos); } else { // just copy the file over.. prolly a .dll or something Base.copyFile(exportFile, new File(appletFolder, exportFile.getName())); } } } String bagelJar = "lib/core.jar"; packClassPathIntoZipFile(bagelJar, zos); // files to include from data directory // TODO this needs to be recursive if (dataFolder.exists()) { String dataFiles[] = dataFolder.list(); for (int i = 0; i < dataFiles.length; i++) { // don't export hidden files // skipping dot prefix removes all: . .. .DS_Store if (dataFiles[i].charAt(0) == '.') continue; entry = new ZipEntry(dataFiles[i]); zos.putNextEntry(entry); zos.write(Base.grabFile(new File(dataFolder, dataFiles[i]))); zos.closeEntry(); } } // add the project's .class files to the jar // just grabs everything from the build directory // since there may be some inner classes // (add any .class files from the applet dir, then delete them) // TODO this needs to be recursive (for packages) String classfiles[] = appletFolder.list(); for (int i = 0; i < classfiles.length; i++) { if (classfiles[i].endsWith(".class")) { entry = new ZipEntry(classfiles[i]); zos.putNextEntry(entry); zos.write(Base.grabFile(new File(appletFolder, classfiles[i]))); zos.closeEntry(); } } // remove the .class files from the applet folder. if they're not // removed, the msjvm will complain about an illegal access error, // since the classes are outside the jar file. for (int i = 0; i < classfiles.length; i++) { if (classfiles[i].endsWith(".class")) { File deadguy = new File(appletFolder, classfiles[i]); if (!deadguy.delete()) { Base.showWarning("Could not delete", classfiles[i] + " could not \n" + "be deleted from the applet folder. \n" + "You'll need to remove it by hand.", null); } } } // close up the jar file zos.flush(); zos.close(); Base.openFolder(appletFolder); return true; */