/******************************************************************************* * ALMA - Atacama Large Millimeter Array * Copyright (c) ESO - European Southern Observatory, 2011 * (in the framework of the ALMA collaboration). * All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *******************************************************************************/ /* * Created on Oct 5, 2006 by mschilli */ package alma.acs.jhelpgen; import java.io.File; import java.io.IOException; import java.util.LinkedList; import java.util.List; import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Gen { public static void main (String[] args) { try { if (args.length < 1) throw new IllegalArgumentException("too few arguments"); File helpDir = new File(args[0]); if (!helpDir.isDirectory()) throw new IllegalArgumentException("not a directory: "+helpDir); List<File> fArgs = new LinkedList<File>(); if (args.length == 1) fArgs.add (helpDir); else for (int i=1; i<args.length; i++) { File f = new File(args[i]); if (! f.getPath().startsWith(helpDir.getName())) throw new IllegalArgumentException("toc-dir|toc-file must live under help-dir "+helpDir.getAbsolutePath()+": "+f.getAbsolutePath()); fArgs.add (f); } new Gen().go(helpDir, fArgs); } catch (IllegalArgumentException e) { System.err.println("Error: "+e.getMessage()); System.err.println("Usage: (this) help-dir {toc-dir|toc-file}+"); } catch (Exception e) { System.err.println("Error: "+e); } } protected void go (File helpDir, List<File> fArgs) throws IOException { StringBuilder worklog = new StringBuilder(); StringBuilder sbToc = new StringBuilder(); StringBuilder sbMap = new StringBuilder(); List<File> files = new Vector<File>(); for (File f : fArgs) if (f.isDirectory()) Util.findFiles (files, f, ".html", ".htm", ".HTML", ".HTM", ".input"); else files.add(f); String firstFileId = null; for (File f : files) { String fileContents = Util.readFile(f); String fileId = f.getPath().substring(helpDir.getName().length()+1).replace("\\", "/"); if (firstFileId == null) firstFileId = fileId; AnchorNode root = htmlToDom(fileContents); // tweak anchors a little for (AnchorNode n : root.depthFirst(new Vector<AnchorNode>())) n.anchorName = fileId +"#"+ n.anchorName; domToToc (root.children, sbToc); domToMap (root.children, sbMap); } File fToc = new File(helpDir, Const.TOC_FILENAME); File fMap = new File(helpDir, Const.MAP_FILENAME); File fSet = new File(helpDir, Const.SET_FILENAME); String toc = finishToc(sbToc); String map = finishMap(sbMap, firstFileId); String set = finishHelpset(fToc.getName(), fMap.getName()); Util.writeFile(toc, fToc); Util.writeFile(map, fMap); Util.writeFile(set, fSet); worklog.append("Created "+fToc.getPath()+"\n"); worklog.append("Created "+fMap.getPath()+"\n"); worklog.append("Created "+fSet.getPath()+"\n"); // copy images from our jar to helpdir String[] imageNames = new String[]{"chapTopic.gif", "topic.gif", "toplevel.gif"}; File imageDir = new File(helpDir, "images"); imageDir.mkdir(); for (String imageName : imageNames) { String imageContent = Util.readResource("/alma/acs/jhelpgen/content/" + imageName); File fImage = new File(imageDir, imageName); Util.writeFile(imageContent, fImage); worklog.append("Created " + fImage.getPath()+"\n"); } System.out.println("\n" + worklog); } protected AnchorNode htmlToDom (String contents) { AnchorNode root = new AnchorNode(0, "root", ""); AnchorNode latest = root; Pattern headingPattern = Pattern.compile("<[Hh]([1-6]).*?</[Hh]([1-6])>"); Pattern anchorPattern = Pattern.compile("<[Aa].* name=['\"]?(\\w*)['\"]?.*>(.*)</[Aa]>"); Matcher hm = headingPattern.matcher(contents); while (hm.find()) { String heading = hm.group().trim(); int level = Integer.parseInt(hm.group(1)); Matcher am = anchorPattern.matcher(heading); if (am.find()) { String anchor = am.group(1).trim(); String pretty = am.group(2).trim(); AnchorNode n = new AnchorNode(level, anchor, pretty); // sort into tree AnchorNode cand = latest; while (cand.level >= n.level) cand = cand.parent; cand.add(n); latest = n; } } return root; } protected void domToMap (List<AnchorNode> nn, StringBuilder sb) { for (AnchorNode m : nn) domToMap(m, sb); } protected void domToMap (AnchorNode n, StringBuilder sb) { sb.append("\n\t"); sb.append("<mapID target=\"").append(n.anchorName).append("\""); sb.append(" url=\"").append(n.anchorName).append("\"/>"); domToMap (n.children, sb); } protected void domToToc (List<AnchorNode> nn, StringBuilder sb) { for (AnchorNode m : nn) domToToc(m, sb); } protected void domToToc (AnchorNode n, StringBuilder sb) { sb.append("\n").append("\t\t\t\t\t\t".substring(0, n.level)); sb.append("<tocitem text=\"").append(n.prettyName).append("\""); sb.append(" target=\"").append(n.anchorName).append("\""); if (n.children.size() == 0) sb.append("/>"); else { sb.append(">"); domToToc (n.children, sb); sb.append("\n").append("\t\t\t\t\t\t".substring(0, n.level)); sb.append("</tocitem>"); } } protected String finishToc (StringBuilder sb) { String begin = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" + "\n<!DOCTYPE toc PUBLIC \"-//Sun Microsystems Inc.//DTD JavaHelp TOC Version 1.0//EN\"" + "\n \"http://java.sun.com/products/javahelp/toc_1_0.dtd\">" + "\n<toc version=\"1.0\" categoryclosedimage=\"_chapter\" topicimage=\"_topic\">"; String end = "\n</toc>"; return begin + sb + end; } protected String finishMap (StringBuilder sb, String introFileId) { String begin = "<?xml version='1.0' encoding='ISO-8859-1' ?>" + "\n<!DOCTYPE map PUBLIC \"-//Sun Microsystems Inc.//DTD JavaHelp Map Version 1.0//EN\" " + "\n \"http://java.sun.com/products/javahelp/map_1_0.dtd\"> " + "\n<map version=\"1.0\"> " + "\n\t<mapID target=\"_toplevelfolder\" url=\"images/toplevel.gif\" /> " + "\n\t<mapID target=\"_chapter\" url=\"images/chapTopic.gif\" /> " + "\n\t<mapID target=\"_topic\" url=\"images/topic.gif\" />" + "\n" + "\n\t<mapID target=\"_intro\" url=\""+introFileId+"\" />"; String end = "\n</map>"; return begin + sb + end; } protected String finishHelpset (String fTocName, String fMapName) { String b = "<?xml version='1.0' encoding='ISO-8859-1' ?> <!DOCTYPE helpset PUBLIC \"-//Sun Microsystems Inc.//DTD JavaHelp HelpSet Version 2.0//EN\" " + "\"../dtd/helpset_2_0.dtd\"> <?MyFavoriteApplication this is data for my favorite application ?>" + "<helpset version=\"1.0\"> <title>Online Help</title>" + "\n<maps>" + "\n\t<homeID>_intro</homeID>" + "\n\t<mapref location=\""+fMapName+"\"/>" + "\n</maps>" + "\n<view>" + "\n\t<name>TOC</name>" + "\n\t<label>Online Help</label>" + " \n\t<type>javax.help.TOCView</type>" + "\n\t<data>"+fTocName+"</data>" + "\n</view>" + "\n</helpset>"; return b; } protected class AnchorNode { public int level; public String anchorName; public String prettyName; public AnchorNode parent; public List<AnchorNode> children = new Vector<AnchorNode>(); AnchorNode(int level, String anchorName, String prettyName) { this.level = level; this.anchorName = anchorName; this.prettyName = prettyName; } void add (AnchorNode n) { n.parent = this; children.add(n); } List<AnchorNode> depthFirst (List<AnchorNode> ret) { ret.add(this); for (AnchorNode m : children) m.depthFirst(ret); return ret; } @Override public String toString() { return "AnchorNode[level="+level+", anchor="+anchorName+", caption="+prettyName+"]"; } } }