Revision: 735
Author:
damon...@gmail.com
Date: Fri Aug 3 20:43:29 2012
Log: Pre 1.2.0 release
http://code.google.com/p/caffeine-hx/source/detail?r=735
Added:
/trunk/projects/chxdoc/src/chxdoc/FilterPolicy.hx
/trunk/projects/chxdoc/src/chxdoc/Filters.hx
/trunk/projects/chxdoc/src/chxdoc/Setup.hx
Deleted:
/trunk/projects/chxdoc/src/chxdoc/Settings.hx
Modified:
/trunk/projects/chxdoc/src/CHANGES
/trunk/projects/chxdoc/src/README
/trunk/projects/chxdoc/src/Tools/Run.hx
/trunk/projects/chxdoc/src/chxdoc/ChxDocMain.hx
/trunk/projects/chxdoc/src/chxdoc/ClassHandler.hx
/trunk/projects/chxdoc/src/chxdoc/Defines.hx
/trunk/projects/chxdoc/src/chxdoc/DocProcessor.hx
/trunk/projects/chxdoc/src/chxdoc/EnumHandler.hx
/trunk/projects/chxdoc/src/chxdoc/PackageHandler.hx
/trunk/projects/chxdoc/src/chxdoc/TypeHandler.hx
/trunk/projects/chxdoc/src/chxdoc/TypedefHandler.hx
/trunk/projects/chxdoc/src/chxdoc/Types.hx
/trunk/projects/chxdoc/src/chxdoc/Utils.hx
/trunk/projects/chxdoc/src/haxe/rtti/CType.hx
/trunk/projects/chxdoc/src/haxe/rtti/XmlParser.hx
/trunk/projects/chxdoc/src/haxelib.xml
/trunk/projects/chxdoc/src/haxelib_build.hxml
=======================================
--- /dev/null
+++ /trunk/projects/chxdoc/src/chxdoc/FilterPolicy.hx Fri Aug 3 20:43:29
2012
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2008-2012, The Caffeine-hx project contributors
+ * Original author : Russell Weir
+ * Contributors:
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE CAFFEINE-HX PROJECT CONTRIBUTORS "AS
IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE CAFFEINE-HX PROJECT CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package chxdoc;
+
+enum FilterPolicy {
+ DENY;
+ ALLOW;
+}
=======================================
--- /dev/null
+++ /trunk/projects/chxdoc/src/chxdoc/Filters.hx Fri Aug 3 20:43:29 2012
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2008-2012, The Caffeine-hx project contributors
+ * Original author : Russell Weir
+ * Contributors:
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE CAFFEINE-HX PROJECT CONTRIBUTORS "AS
IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE CAFFEINE-HX PROJECT CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package chxdoc;
+
+//import haxe.rtti.CType;
+
+typedef Filter = {
+ var path : String;
+ var policy : FilterPolicy;
+}
+
+typedef FilterList = List<Filter>;
+
+class Filters {
+ static var defaultPolicy : FilterPolicy = ALLOW;
+ static var rules : FilterList = new FilterList();
+
+ /**
+ * Add a package or class that will be allowed
+ * in the generated documentation. Package paths should
+ * have a trailing . or use pkg.*
+ *
+ * @param path Package or class path
+ **/
+ public static function allow(path:String) {
+ rules.add({path : cleanPath(path), policy : ALLOW});
+ }
+
+ /**
+ * Clear the list of ignored paths
+ **/
+ public static function clear() {
+ rules = new FilterList();
+ }
+
+ /**
+ * Add a package or class that will be filtered out
+ * of the generated documentation. Package paths should
+ * have a trailing . or use pkg.*
+ * @param path Package or class path
+ **/
+ public static function deny(path:String) {
+ rules.add({path : cleanPath(path), policy : DENY });
+ }
+
+ /**
+ * Sets the policy if a package does not match any rules
+ *
+ * @param polval Either "allow" or "deny"
+ **/
+ public static function setDefaultPolicy(p:FilterPolicy) {
+ defaultPolicy = p;
+ }
+
+ static function cleanPath(path:String) : String {
+ if(path.charAt(path.length-1) == "*")
+ path = path.substr(0, path.length-1);
+ if(path == "." || path == "")
+ path = "/";
+ return path;
+ }
+
+ /**
+ * Checks if a package or class is filtered
+ * @param path Package or class path in dotted format
+ * @isPackage set to true if path is a package
+ * @todo Could do some capitalization check here to determine if path is a
package or not
+ * @todo What were the paths ending with "__"?
+ **/
+ public static function isFiltered( path : String, isPackage : Bool ) {
+ if(isPackage) {
+ if(path.charAt(path.length-1) != ".")
+ path += ".";
+ }
+ if( isPackage && path == "Remoting" )
+ return true;
+ if( StringTools.endsWith(path,"__") )
+ return true;
+
+ for(r in rules) {
+ if(matches(path, r)) {
+ return switch(r.policy) {
+ case ALLOW : false;
+ case DENY : true;
+ }
+ }
+ }
+ return switch(defaultPolicy) {
+ case DENY : true;
+ case ALLOW : false;
+ }
+ }
+
+ static function matches(path:String, rule:Filter) {
+ if( path == rule.path )
+ return true;
+ // "root types" is set on pass1 in ChxDocMain and tested
PackageHandler.pass4
+ // and used in the templates
+ if( rule.path == "/" && (path.indexOf(".") < 0 ||
StringTools.startsWith(path,"root types"))) {
+ return true;
+ }
+ if( rule.path.charAt(rule.path.length-1) == "." ) {
+ if(StringTools.startsWith(path,rule.path))
+ return true;
+ }
+ return false;
+ }
+
+}
=======================================
--- /dev/null
+++ /trunk/projects/chxdoc/src/chxdoc/Setup.hx Fri Aug 3 20:43:29 2012
@@ -0,0 +1,629 @@
+package chxdoc;
+
+import haxe.xml.Fast;
+import sys.io.File;
+import sys.FileSystem;
+import chxdoc.FilterPolicy;
+
+using StringTools;
+
+class Setup {
+ /** Xml config **/
+ static var xmlconfig : Fast;
+ /** cache of settings, to prevent constant xml searching **/
+ static var cache : Hash<String>;
+
+ /// testing only ///
+ static function main() {
+ initialize();
+ setup();
+ trace(prettyPrint(xmlconfig,0));
+ trace(ChxDocMain.config);
+
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ ///////////////////////// Public API ////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+
+ public static function setup() {
+ var c = ChxDocMain.config;
+
+ initialize();
+
+ // this whole block does not apply to neko.Web
+ #if neko
+ if(!neko.Web.isModNeko) {
+ #end
+
+ // check if verbose is on command line
+ for( a in Sys.args() ) {
+ if( a == "-v")
+ c.verbose = true;
+ }
+
+ // if the user does not have an existing ~/.chxdoc
+ // attempt to create it.
+ var home = Utils.getHomeDir();
+ try {
+ if(home == null) {
+ ChxDocMain.logWarning("Unable to determine home path");
+ }
+ else if(!FileSystem.exists(home + ".chxdoc")) {
+ Sys.println("Creating default " + home + ".chxdoc");
+ writeConfig(home + ".chxdoc", true);
+ }
+ } catch(e:Dynamic) {
+ ChxDocMain.fatal("Unable to create " + home + ".chxdoc");
+ }
+
+ // erase any list entries created by initialize()
+ setListVal("files",[],true);
+ setListVal("filters",[],true);
+
+ // load user's home/.chxdoc
+ try {
+ if(home != null)
+ loadConfigFile(home + ".chxdoc");
+ } catch(e:Dynamic) {
+ ChxDocMain.fatal("Error reading " + home + ".chxdoc : "+Std.string(e));
+ }
+
+ // end of neko.Web.isModNeko test
+ #if neko
+ }
+ #end
+ }
+
+ /**
+ * Load a chxdoc config xml file
+ * @param filename File name
+ **/
+ public static function loadConfigFile(filename:String) {
+ populate(load(filename));
+ }
+
+ /**
+ * Write current configuration to a file.
+ * @param filename File to write to
+ * @param commentLists Comment out entries in lists like <files> and
<filters>
+ **/
+ public static function writeConfig(filename:String,
commentLists:Bool=false) {
+ try {
+ var fo = File.write(filename, false);
+ fo.writeString( prettyPrint(xmlconfig,0,commentLists) );
+ fo.close();
+ } catch(e:Dynamic) {
+ ChxDocMain.fatal("Error writing " + filename + ": " + Std.string(e));
+ }
+ }
+
+ /**
+ * Delete a config node
+ *
+ * @param name Element name
+ **/
+ public static function deleteVal(name:String) {
+ var n = findNode(name);
+ if(n == null)
+ return;
+ xmlconfig.x.removeChild(n.x);
+ }
+
+ /**
+ * Write a val to the xml config
+ * @param name Xml node name
+ * @param val Value to place in 'value' attribute.
+ **/
+ public static function writeVal(name:String, val:Dynamic) {
+ var n = findNode(name);
+ if(n == null) {
+ var e = Xml.createElement(name);
+ e.set("value", escape(val));
+ xmlconfig.x.addChild(e);
+ return;
+ }
+ n.x.set( "value", val );
+ }
+
+ /**
+ * Adds to the filters.
+ **/
+ public static function addFilter(path:String, policy:FilterPolicy) {
+ var n = findOrCreateNode("filters");
+ n.x.addChild(createFilterEntry(path, policy));
+ switch(policy) {
+ case ALLOW:
+ Filters.allow(path);
+ case DENY:
+ Filters.deny(path);
+ }
+ }
+
+ public static function setFilterPolicy(policy:FilterPolicy) {
+ var n = findOrCreateNode("filters");
+ n.x.set("policy", (policy == ALLOW) ? "allow" : "deny");
+ Filters.setDefaultPolicy(policy);
+ }
+
+ /**
+ * Adds a doc target specified by --file or -f. Checks if an entry for
+ * the filename exists already and will update existing entries
+ *
+ * @param filename Name of the xml file generated by haxe
+ * @param platform Target platform name or null
+ * @param remap Remap target or null
+ **/
+ public static function addTarget(filename:String, platform:String,
remap:String) {
+ var n = findOrCreateNode("files");
+ for(i in n.nodes.file) {
+ if(
i.name == filename) {
+ n.x.removeChild(i.x);
+ }
+ }
+ var found = false;
+ for(e in ChxDocMain.config.files) {
+ if(
e.name == filename) {
+ e.platform = platform;
+ e.remap = remap;
+ found = true;
+ break;
+ }
+ }
+ if(!found)
+ ChxDocMain.config.files.push({name:filename, platform:platform,
remap:remap});
+ n.x.addChild(createFileEntry(filename, platform, remap));
+ }
+
+ // Setup.writeVal("", config.);
+
+
+
+
+ /////////////////////////////////////////////////////////////////////
+ ///////////////////////// Private ///////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ /**
+ * Load xmlconfig from a file
+ * @return Xml data
+ * @throws Strings on errors
+ **/
+ static function load(path:String) : Fast {
+ if(!FileSystem.exists (path))
+ throw "'"+path+"' does not exist";
+ var xml:Fast = null;
+ try {
+ xml = new Fast(Xml.parse(File.getContent(path)).firstElement());
+ } catch (e:Dynamic) {
+ throw(path + " is not valid XML");
+ return null;
+ }
+ return xml;
+ }
+
+ /**
+ * Populate xmlconfig from xml
+ * @param xml Xml data
+ **/
+ static function populate(xml:Fast) {
+ for(n in xml.elements) {
+ var name =
n.name;
+ var value = n.has.value ? n.att.value : null;
+
+ if(name == "files") {
+ for( f in n.nodes.file ) {
+ if(!
f.has.name)
+ throw "<file> node has no 'name' attribute";
+ name =
f.att.name;
+ var platform = f.has.platform ? f.att.platform : null;
+ var remap = f.has.remap ? f.att.remap : null;
+ setListVal("files",[createFileEntry(name,platform,remap)],false);
+ }
+ }
+ else if(name == "filters") {
+ for( f in n.nodes.filter ) {
+ if(!f.has.path)
+ throw "<filter> node has no 'path' attribute";
+ if(!f.has.policy)
+ throw "<filter> node has no 'policy' attribute";
+ var p = ALLOW;
+ switch(f.att.policy) {
+ case "allow": p = ALLOW;
+ case "deny" : p = DENY;
+ default : throw "<filter> policy '"+f.att.policy+"' is invalid";
+ }
+ setListVal("filters",[createFilterEntry(f.att.path, p)],false);
+ }
+ } else {
+ if(value == null)
+ throw "No 'value' attribute for "+name;
+ setVal(name, value);
+ }
+ }
+ }
+
+ /**
+ * Creates xmlconfig using default values
+ **/
+ static function initialize() {
+ cache = new Hash();
+ xmlconfig = new Fast(Xml.parse("<xml></xml>").firstElement());
+ setVal("title", "Haxe Application");
+ setVal("subtitle", "<a href='
http://www.haxe.org/'
target='new'>
http://www.haxe.org/</a>");
+ //setListVal("platforms",
+ setVal("headerText","");
+ setVal("footerText","");
+
+ setVal("headerTextFile","");
+ setVal("footerTextFile", "");
+
+ setListVal("files",[
+ createFileEntry("flash9.xml","flash","flash9"),
+ createFileEntry("neko.xml","neko")
+ ]);
+
+ setVal("dateShort", "%Y-%m-%d");
+ setVal("dateLong", "%a %b %d %H:%M:%S %Z %Y");
+
+ setVal("ignoreRoot", false);
+ setVal("developer", false);
+ setVal("showAuthorTags", false);
+ setVal("showMeta",true);
+ setVal("showPrivateClasses", false);
+ setVal("showPrivateTypedefs", false);
+ setVal("showPrivateEnums", false);
+ setVal("showPrivateMethods", false);
+ setVal("showPrivateVars", false);
+ setVal("showTodoTags", false);
+
+ setVal("output","./docs/");
+ //setVal("packageDirectory","./docs/packages/"); // not user configurable
+ //setVal("typeDirectory","./docs/types/");
+
+ setListVal("filters",[
+ createFilterEntry("haxe.io.Bytes", DENY),
+ createFilterEntry("sys.db.*", ALLOW)
+ ], true, { policy : "allow" });
+
+ setVal("template","default");
+ setVal("templatesDir","");
+ var c = ChxDocMain.config;
+ // Set template to haxelib chxdoc default template
+ // if possible.
+ var tpl : String = null;
+ try {
+ tpl = Utils.getHaxelib() + "chxdoc/" +
c.versionMajor+","+c.versionMinor+","+c.versionRevision;
+ tpl += "/templates/";
+ if(FileSystem.isDirectory(tpl)) {
+ if(FileSystem.isDirectory(tpl + "default")) {
+ setVal("templatesDir", tpl);
+ setVal("template", "default");
+ }
+ }
+ } catch(e:Dynamic) {
+ ChxDocMain.logWarning("Could not find chxdoc in haxelib ("+tpl+")");
+ }
+ setVal("macros","macros.mtt");
+
+ setVal("htmlFileExtension","html");
+ setVal("stylesheet","stylesheet.css");
+
+ setVal("mergeMeta", true);
+
+ //setVal("noPrompt", false);
+ setVal("installImagesDir","true");
+ setVal("installCssFile","true");
+
+ setVal("generateTodo", false);
+ //setListVal("todoLines",[""]);
+ //setVal("todoFile","todo.html"); not user configurable
+
+ setVal("verbose", false);
+ setVal("tmpDir","./__chxdoctmp/");
+
+ //setVal("xmlBasePath",""); // in <files>
+ setVal("webPassword","");
+ }
+
+ /*
+ static function syncFromMain() {
+ var c = ChxDocMain.config;
+ setval("title", c.title, true);
+ setval("subtitle", c.subtitle, true);
+ setval("headerText", c.headerText, true);
+ setval("footerText", c.footerText, true);
+ setval("headerTextFile", c.headerTextFile, true);
+ setval("footerTextFile", c.footerTextFile, true);
+ setval("dateShort", c.dateShort, true);
+ setval("dateLong", c.dateLong, true);
+ setval("ignoreRoot", c.ignoreRoot, true);
+ setval("showAuthorTags", c.showAuthorTags, true);
+ setval("showPrivateClasses", c.showPrivateClasses, true);
+ setval("showPrivateTypedefs", c.showPrivateTypedefs, true);
+ setval("showPrivateEnums", c.showPrivateEnums, true);
+ setval("showPrivateMethods", c.showPrivateMethods, true);
+ setval("showPrivateVars", c.showPrivateVars, true);
+ setval("showTodoTags", c.showTodoTags, true);
+ setval("developer", c.developer, true);
+ setval("output", c.output, true);
+ setval("packageDirectory", c.packageDirectory, true);
+ setval("typeDirectory", c.typeDirectory, true);
+ setval("template", c.template, true);
+ setval("macros", c.macros, true);
+ setval("htmlFileExtension", c.htmlFileExtension, true);
+ setval("stylesheet", c.stylesheet, true);
+ setval("installImagesDir", c.installImagesDir, true);
+ setval("installCssFile", c.installCssFile, true);
+ setval("generateTodo", c.generateTodo, true);
+ setval("verbose", c.verbose, true);
+ setval("tmpDir", c.tmpDir, true);
+ setval("webPassword", c.webPassword, true);
+ }
+ */
+
+ static function escape(val:Dynamic) {
+ var s = Std.string(val);
+ return s.replace('"', "\\\"");
+ }
+
+ /**
+ * Find an element node in the xmlconfig by name
+ **/
+ static function findNode(name:String) : Fast {
+ if(xmlconfig.hasNode.resolve(name))
+ return xmlconfig.node.resolve(name);
+ return null;
+ }
+
+ /**
+ * Will try to find node 'name' but will create it if not found.
+ * @param name Element name
+ **/
+ static function findOrCreateNode(name:String) : Fast {
+ var n = findNode(name);
+ if(n == null) {
+ n = new Fast(Xml.createElement(name));
+ xmlconfig.x.addChild(n.x);
+ }
+ return n;
+ }
+
+ /**
+ * Create an entry to go under <files>
+ *
+ * @param file Xml file name
+ * @param platform Haxe output target platform
+ * @param remap Platform to remap to
+ **/
+ static function createFileEntry(file:String, platform:String=null,
remap:String=null) : Xml {
+ var n = Xml.createElement("file");
+ n.set("name", file);
+ if(platform != null)
+ n.set("platform", platform);
+ if(remap != null)
+ n.set("remap",remap);
+ return n;
+ }
+
+ /**
+ * Create an entry to go under <filters>
+ *
+ * @param pkgOrClass Globbed pkg or specific class path
+ **/
+ static function createFilterEntry(pkgOrClass:String,
policy:FilterPolicy) : Xml {
+ var n = Xml.createElement("filter");
+ n.set("path", pkgOrClass);
+ n.set("policy", ((policy == ALLOW) ? "allow" : "deny"));
+ return n;
+ }
+
+ /**
+ * Search for or create a node, and assign 'val' to the
+ * value attribute, and pass the value through the command
+ * line parameter parsing in ChxDocMain
+ *
+ * @param name Xml node name
+ * @param val Value to place in 'value' attribute.
+ **/
+ static function setVal(name:String, val:Dynamic) {
+ writeVal(name, val);
+ try {
+ ChxDocMain.handleArg("--"+name, function(errMsg) { return
Std.string(val); }, true);
+ } catch(e:String) {
+ throw "Unknown element <" + name + ">";
+ }
+ }
+
+
+
+ /**
+ * Populate an element with an array of xml values as children and
+ * passes the value through the command line parsing in ChxDocMain
+ *
+ * @param name Name of the parent node to find or create
+ * @param values Array of Xml children to add
+ * @param remove Clears existing children from node 'name'
+ * @throws String on format errors in 'values' array
+ **/
+ static function setListVal(name:String,
values:Array<Xml>,remove:Bool=true, atts:Dynamic=null) {
+ var n = findOrCreateNode(name);
+ if(atts != null)
+ for(f in Reflect.fields(atts))
+ n.x.set(f, Std.string(Reflect.field(atts, f)));
+
+ if(remove) {
+ var ea : Array<Xml> = [];
+ // populate a list of existing elements
+ for(e in n.elements)
+ ea.push(e.x);
+ // then remove them.
+ for(e in ea)
+ n.x.removeChild(e);
+ if(name == "files")
+ ChxDocMain.config.files = new Array();
+ else if(name == "filters")
+ Filters.clear();
+ }
+ for(v in values) {
+ if(name == "files") {
+ if(!v.exists("name"))
+ throw "<file> entry requires name attribute";
+ var p = v.get("name");
+ if(v.exists("platform")) {
+ p += "," + v.get("platform");
+ if(v.exists("remap"))
+ p += "," + v.get("remap");
+ }
+ ChxDocMain.handleArg("--file", function(s) { return p; }, true);
+ } else if(name == "filters") {
+ if(!v.exists("path"))
+ throw "<filter> entry requires path attribute";
+ if(!v.exists("policy"))
+ throw "<filter> entry requires policy attribute";
+ var policy = v.get("policy").toLowerCase();
+ if(policy == "allow")
+ ChxDocMain.handleArg("--allow", function(s) return v.get("path"),
true);
+ else if(policy == "deny")
+ ChxDocMain.handleArg("--deny", function(s) return v.get("path"),
true);
+ else
+ throw "<filter> policy '"+v.get("policy")+"' is invalid";
+ } else {
+ throw "Unexpected list " + name;
+ //n.x.addChild(v);
+ }
+ }
+ return n;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ //////////// Value getters for non-list elements ////////////////////
+ /////////////////////////////////////////////////////////////////////
+ static function getStringVal(name:String, defaultVal:String=null) {
+ var n = findNode(name);
+ if(n == null)
+ return defaultVal;
+ try {
+ var val = n.att.resolve(name);
+ return val;
+ } catch(e:Dynamic) {}
+ return defaultVal;
+ }
+
+ static function getBoolVal(name:String, defaultVal:Null<Bool>) {
+ var dvs : String = if(defaultVal ==null) null else
defaultVal ? "true" : "false";
+ var val = getStringVal(name, dvs);
+ if(val == null)
+ return null;
+ val = val.toLowerCase();
+ var c = val.charAt(0);
+ if(c == 'y' || c == 't')
+ return true;
+ return false;
+ }
+
+ static function getIntVal(name:String, defaultVal:Null<Int>) : Null<Int> {
+ var val = null;
+ if(defaultVal == null)
+ val = getStringVal(name, null);
+ else
+ getStringVal(name, Std.string(defaultVal));
+ if(val == null)
+ return null;
+ var n = Std.parseInt(val);
+ if(val == null)
+ return defaultVal;
+ return n;
+ }
+
+ static function prettyPrint(xml:Fast, lvl:Int=0,
commentLists:Bool=false) : String {
+ var s : String = "";
+ if(lvl == 0) {
+ s = "<xml>\n";
+ s += prettyPrint(xml, 1, commentLists);
+ s += "</xml>\n";
+ return s;
+ }
+ var indent = "";
+ for(i in 0...lvl)
+ indent += " ";
+
+ for(e in xml.elements) {
+ var hasChildren = false;
+ var comment = commentFor(
e.name);
+ if(comment != null) {
+ s += "\n" + indent;
+ s += Std.string(comment) + "\n";
+ }
+ s += indent;
+ s += "<";
+ s +=
e.name;
+ var alist = e.x.attributes();
+ var clist = e.x.iterator();
+ if(clist.hasNext() ||
e.name=="files") {
+ hasChildren = true;
+ }
+ for(a in alist) {
+ s += " ";
+ s += (a + "=" + '"');
+ s += e.x.get(a);
+ s += '"';
+ }
+ if(hasChildren) {
+ s += ">\n";
+ if(commentLists /*&& (
e.name == "files" || ...)*/)
+ s += indent + "<!--\n";
+ s += prettyPrint(e, lvl + 1, false);
+ if(commentLists /*&& (
e.name == "files" || ...)*/)
+ s += indent + "-->\n";
+ s += indent + "</" + e.x.nodeName + ">\n";
+ } else {
+ s += " />\n";
+ }
+ }
+ return s;
+ }
+
+ static function commentFor(name:String) : Xml {
+ var mkc = Xml.createComment;
+ return switch(name) {
+ case "verbose": mkc("Turn on verbose mode");
+ case "dateShort":
+ mkc("Format for dates");
+ case "showAuthorTags":
+ mkc("Show @author values in docs");
+ case "showPrivateClasses":
+ mkc("Output items marked private");
+ case "developer":
+ mkc("Turns on all show* values, regardless of their value. Should come
before any show* entries");
+ case "generateTodo":
+ mkc("Turn on todo generation. and file to output todo list to");
+ case "ignoreRoot":
+ mkc("Ignore classes in the root package");
+ case "htmlFileExtension":
+ mkc("File extension for html documentation files");
+ case "title":
+ mkc("Title, subtitle, headers and footers on pages");
+ case "installImagesDir":
+ mkc("Copy the images or css from template to output directory");
+ case "template":
+ mkc("Template name, templates base directory and macros file name of
main macros");
+ case "output":
+ mkc("Output directory");
+ case "stylesheet":
+ mkc("The stylesheet to use");
+ case "webPassword":
+ mkc("Password for mod_neko integration");
+ case "files":
+ mkc("Xml files to parse. List of <file name=\"\" platform=\"\"
[remap=\"\"]>");
+ case "tmpDir":
+ mkc("Temporary directory name for template compilation");
+ case "headerTextFile":
+ mkc("Files to read in as header or footer text");
+ case "filters":
+ mkc("Excluded packages or classes in <exclude value='my.pkg.*'>
elements");
+ case "mergeMeta":
+ mkc("Merge metadata with same names as @doc tags with the @doc tags");
+ default: null;
+ }
+ }
+}
=======================================
--- /trunk/projects/chxdoc/src/chxdoc/Settings.hx Fri Oct 14 14:26:55 2011
+++ /dev/null
@@ -1,8 +0,0 @@
-/**
- This class is automatically generated when installing in haxelib
-**/
-package chxdoc;
-
-class Settings {
- public static var defaultTemplate : String = "./templates/default/";
-}
=======================================
--- /trunk/projects/chxdoc/src/CHANGES Sun Jul 29 14:57:38 2012
+++ /trunk/projects/chxdoc/src/CHANGES Fri Aug 3 20:43:29 2012
@@ -5,6 +5,24 @@
- Add --showSourceFilePath for hard link to source files
- Import docs for methods etc. in classes if they implement an interface
and have no docs
+
+
+1.2.0
+ - --templateDir directive is now split into --templatesDir and --template
to
+ allow for a base path then template name
+ - XML configuration added. Will now pull template from haxelib, if it can
find it
+ - --macroFile changed to --macros
+ - All references to meta. in templates replaced with .webmeta to avoid
+ confusion with class and member meta for haxe metadata support
+ - --file added, no longer will command line blindly accept
flash.xml,flash,remap syntax
+ - -f which was for 'filter' was redundant syntax for --exclude. Both
removed.
+ - -f changed to shortcut for --file
+ - New filtering engine created
+ - Added --allow and --deny for filtering
+ - Changed --generateTodoFile to --generateTodo
+ - Added --mergeMeta which takes any haxe metadata tag that has a simalr
name, and adds it to the
+ the regular tags. Basically this makes @author("Russell Weir") function
blah() {} the same
+ as the "/** @author Russell Weir */" style.
1.1.4
- Haxe 2.10 compatibility
=======================================
--- /trunk/projects/chxdoc/src/README Fri Jan 27 14:34:46 2012
+++ /trunk/projects/chxdoc/src/README Fri Aug 3 20:43:29 2012
@@ -25,16 +25,10 @@
If the optional path parameter is omitted, chxdoc will be installed to the
current directory.
-CHXDOC uses a modified version of temploc, the template compiler system by
Nicolas Cannasse. A compiled
-copy is created when installing from haxelib.
-
-For source code checkouts, there is a neko compiled chxtemploc.n in
the ./utils/
-subdirectory. Simply run 'nekotools boot utils/chxtemploc.n' to generate
the binary,
-which will be in the utils/ directory, named either "chxtemploc.exe"
or "chxtemploc",
-depending on your platform.
-
-Install both the chxtemploc.exe and the chxdoc.exe file to somewhere on
your executable
-path. The templates directory can be placed anywhere.
+CHXDOC uses a modified version of temploc, the template compiler system by
Nicolas Cannasse.
+
+Install the chxdoc.exe file to somewhere on your executable path. The
templates directory
+can be placed anywhere, but chxdoc will read templates out of haxelib if
it is installed there.
= Usage =
@@ -49,8 +43,8 @@
The most common usage of chxdoc would be something like:
{{{
-chxdoc -o docs_dev --developer=true myproject.xml
-chxdoc -o docs --templateDir=templates/release myproject.xml
+chxdoc -o docs_dev --developer=true -f myproject.xml
+chxdoc -o docs --templateDir=templates/release -f myproject.xml
}}}
Two versions of the documentation would be created, one with all the
private data
@@ -68,6 +62,14 @@
= Options =
+--config=[[xmlpath]]
+ Loads a chxdoc configuration file. This option can be specified multiple
times,
+ allowing configuration overlays processed in the order on the command
line. See
+ 'createConfig'.
+
+--createConfig
+ This option writes a default chxdoc config file as chxdocConfig.xml.
+
--developer=[true|false]
This tag is a shortcut to setting the following switches:
--showAuthorTags=bool;
@@ -147,22 +149,55 @@
For generating TODO files and html notes
@type Description
- For adding descriptions for types (<T>)
+ For adding descriptions for anonymous types
= Package and Type filtering =
-Filtering classes and packages is done using the -f switch, which will
prevent
-paths matching the argument from having documentation generated.
-
-A class, enum or typedef named my.pack.MyClass can be specifically
filtered by using
--f my.pack.MyClass
-To filter every class and subpackage in the package 'my.pack' use
--f my.pack
-So, if you apply
--f my
-All of my, including my.pack, and of course then my.pack.MyClass, will not
show up in the
-generated documentation.
-
+Filtering completely changed in chxdoc 1.2 to a more complete way of
describing what
+exactly you need to generate documentation for.
+
+Filtering is done with a series of rules that match either package paths
or class paths. Each
+filter has a policy, which is either to "allow" or "deny" building of
documentation for the path.
+
+In XML, the configuration looks like
+{{{
+<filters policy="allow">
+ <filter policy="deny" path="haxe.rtti.CType"/>
+ <filter policy="allow" path="sys.db.Mysql" />
+ <filter policy="deny" path="sys.db.*" />
+</filters>
+}}}
+
+Filters start with a default policy, which is seen in the top <filters>
element. If the class path
+goes through all the <filter> entries without matching, the default policy
is applied (which is
+'allow' in this example.)
+
+To create documentation for only a specific package... say chxdoc itself,
it might look like this:
+
+{{{
+<filters policy="deny">
+ <filter policy="allow" path="chxdoc.*" />
+ <filter policy="allow" path="/" />
+</filters>
+}}}
+
+A special path "/" matches any package in the root (like Int or Array), so
in addition to allowing
+classes in the chxdoc namespace, documentation for any root types used
will be created.
+
+The filters are applied in the order they appear in the xml configuration,
or on the command line.
+When using the --allow or --deny command line switches, the switch can
take a list of values
+seperated by commas, so the above example could be written on the command
line as
+
+{{{
+chxdoc --allow=chxdoc.*,/
+}}}
+
+Beware though, the command line args are still parsed left to right, so
the first example would
+have to be written as
+
+{{{
+chxdoc --deny=haxe.rtti.CType --allow=sys.db.Mysql --deny=sys.db.*
+}}}
= Planned =
=======================================
--- /trunk/projects/chxdoc/src/Tools/Run.hx Sun Jul 29 14:57:38 2012
+++ /trunk/projects/chxdoc/src/Tools/Run.hx Fri Aug 3 20:43:29 2012
@@ -37,7 +37,6 @@
try {
installdir = makePath(installdir);
compile();
- //makeExe("chxtemploc");
makeExe("chxdoc");
} catch(e:Dynamic) {
neko.Sys.setCwd(curdir);
@@ -68,27 +67,6 @@
static function compile() {
neko.Sys.setCwd(builddir);
- if(!FileSystem.exists("chxdoc/Settings.hx")) {
- print(">> Creating Settings.hx...");
- var sp = builddir + "chxdoc/Settings.hx";
- var fp = neko.io.File.write(sp, false);
- var data : String =
-"/**
- This class is automatically generated when installing with haxelib
-**/
-package chxdoc;
-
-class Settings {
- public static var defaultTemplate : String =
\""+builddir+"templates/default/\";
-}
-";
- fp.writeString(data);
- fp.flush();
- fp.close();
- println(" complete");
- }
-
-
print(">> Compiling in " + neko.Sys.getCwd() + "...");
var p = new neko.io.Process("haxe",["haxelib_build.hxml"]);
var code = p.exitCode();
=======================================
--- /trunk/projects/chxdoc/src/chxdoc/ChxDocMain.hx Sun Jul 29 14:57:38 2012
+++ /trunk/projects/chxdoc/src/chxdoc/ChxDocMain.hx Fri Aug 3 20:43:29 2012
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008-2009, The Caffeine-hx project contributors
+ * Copyright (c) 2008-2012, The Caffeine-hx project contributors
* Original author : Russell Weir
* Contributors: Niel Drummond
* All rights reserved.
@@ -29,8 +29,13 @@
import chxdoc.Defines;
import chxdoc.Types;
+import chxdoc.FilterPolicy;
import haxe.rtti.CType;
import sys.FileSystem;
+import sys.io.File;
+#if neko
+import neko.Web;
+#end
class ChxDocMain {
static var proginfo : String;
@@ -40,9 +45,9 @@
public static var config : Config =
{
versionMajor : 1,
- versionMinor : 1,
- versionRevision : 4,
- buildNumber : 729,
+ versionMinor : 2,
+ versionRevision : 0,
+ buildNumber : 730,
verbose : false,
rootTypesPackage : null,
allPackages : new Array(),
@@ -50,21 +55,24 @@
docBuildDate : Date.now(),
dateShort : DateTools.format(Date.now(), "%Y-%m-%d"),
dateLong : DateTools.format(Date.now(), "%a %b %d %H:%M:%S %Z %Y"),
+ mergeMeta : true,
showAuthorTags : false,
+ showMeta : false,
showPrivateClasses : false,
showPrivateTypedefs : false,
showPrivateEnums : false,
showPrivateMethods : false,
showPrivateVars : false,
showTodoTags : false,
- temploBaseDir : Settings.defaultTemplate,
- temploTmpDir : "./__chxdoctmp/",
- temploMacros : "macros.mtt",
+ template : "default",
+ templatesDir : "",
+ tmpDir : "./__chxdoctmp/",
+ macros : "macros.mtt",
htmlFileExtension : ".html",
stylesheet : "stylesheet.css",
- baseDirectory : "./docs/",
+ output : "./docs/",
packageDirectory : "./docs/packages/",
typeDirectory : "./docs/types/",
@@ -72,7 +80,6 @@
installImagesDir : true,
installCssFile : true,
-
title : "Haxe Application",
subtitle : "
http://www.haxe.org/",
developer : false,
@@ -113,6 +120,7 @@
static var webConfigFile : String = ".chxdoc.hsd";
public static var writeWebConfig : Bool = false;
+ static var createConfig : Bool = false;
//////////////////////////////////////////////
@@ -264,7 +272,7 @@
for(i in a) {
if( config.ignoreRoot ) config.rootTypesPackage = null;
Utils.writeFileContents(
- config.baseDirectory + i + config.htmlFileExtension,
+ config.output + i + config.htmlFileExtension,
execBaseTemplate(i)
);
}
@@ -277,14 +285,14 @@
if(cfg != null)
c = cfg;
var t = new mtwin.templo.Loader(s+".mtt");
- var metaData = {
+ var webMetaData = {
date : config.dateShort,
keywords : new Array<String>(),
stylesheet : config.stylesheet,
};
- metaData.keywords.push("");
+ webMetaData.keywords.push("");
var context : IndexContext = {
- meta : metaData,
+ webmeta : webMetaData,
build : buildData,
config : c,
};
@@ -364,9 +372,11 @@
public static function main() {
chx.Log.redirectTraces(true);
- if( neko.Web.isModNeko )
+ #if neko
+ if( Web.isModNeko )
setNullPrinter();
else
+ #end
setDefaultPrinter();
proginfo = "ChxDoc Generator "+
@@ -382,23 +392,29 @@
print(proginfo + "\n");
initDefaultPaths();
+ Setup.setup();
parseArgs();
initTemplo();
- if( neko.Web.isModNeko ) {
+ #if neko
+ if( Web.isModNeko ) {
checkAllPaths();
- neko.Web.cacheModule(webHandler);
+ Web.cacheModule(webHandler);
webHandler();
}
else {
+ #end
loadXmlFiles();
checkAllPaths();
generate();
installTemplate();
- }
+ #if neko
+ }
+ #end
}
+ #if neko
static function webHandler() : Void {
if(config == null)
fatal("Config is not set");
@@ -407,12 +423,12 @@
if(s == null)
s = "";
if(s.charAt(0) != "/")
- return neko.Web.getCwd() + s;
+ return Web.getCwd() + s;
return s;
}
var updatePaths = function() {
- config.temploBaseDir = modPath(config.temploBaseDir);
- config.temploTmpDir = modPath(config.temploTmpDir);
+ config.template = modPath(config.template);
+ config.tmpDir = modPath(config.tmpDir);
initTemplo();
}
var updateXmlPaths = function() {
@@ -421,7 +437,7 @@
i.name = modPath(
i.name);
}
- var params = neko.Web.getParams();
+ var params = Web.getParams();
if( params.get("showconfig") != null) {
setDefaultPrinter();
if(config.webPassword != params.get("password")) {
@@ -479,6 +495,7 @@
print("File not found : " + base);
}
}
+ #end
static function generate() {
packageHandler = new PackageHandler();
@@ -500,68 +517,73 @@
print(".");
pass3();
print(".");
- if( !neko.Web.isModNeko && !writeWebConfig)
+ if( #if neko !Web.isModNeko && #end !writeWebConfig)
pass4();
+ #if neko
if(writeWebConfig) {
var p = webConfigFile;
- if(neko.Web.isModNeko)
- p = neko.Web.getCwd() + webConfigFile;
- var f = neko.io.File.write(p,false);
+ if(Web.isModNeko)
+ p = Web.getCwd() + webConfigFile;
+ var f = File.write(p,false);
var ser = new chx.Serializer(f);
ser.preSerializeObject = function(o) {
if(Reflect.hasField(o, "originalDoc")) {
untyped o.originalDoc = null;
}
+ if(Reflect.hasField(o, "originalMeta")) {
+ untyped o.originalMeta = null;
+ }
}
ser.serialize(config);
f.close();
}
+ #end
print("\nComplete.\n");
}
static function initDefaultPaths() {
- config.baseDirectory = neko.Sys.getCwd() + "docs/";
- config.packageDirectory = config.baseDirectory + "packages/";
- config.typeDirectory = config.baseDirectory + "types/";
+ config.output = Sys.getCwd() + "docs/";
+ config.packageDirectory = config.output + "packages/";
+ config.typeDirectory = config.output + "types/";
}
static function checkAllPaths() {
initTemplo();
// Add trailing slashes to all directory paths
- config.baseDirectory =
Utils.addSubdirTrailingSlash(config.baseDirectory);
- config.packageDirectory = config.baseDirectory + "packages/";
- config.typeDirectory = config.baseDirectory + "types/";
-
- if( neko.Web.isModNeko || writeWebConfig )
+ config.output = Utils.addSubdirTrailingSlash(config.output);
+ config.packageDirectory = config.output + "packages/";
+ config.typeDirectory = config.output + "types/";
+
+ if( #if neko Web.isModNeko || #end writeWebConfig )
return;
- Utils.createOutputDirectory(config.baseDirectory);
+ Utils.createOutputDirectory(config.output);
Utils.createOutputDirectory(config.packageDirectory);
Utils.createOutputDirectory(config.typeDirectory);
}
static function installTemplate() {
- var targetImgDir = config.baseDirectory + "images";
+ var targetImgDir = config.output + "images";
/*
if(!FileSystem.exists(targetImgDir)) {
var copyImgDir = config.installImagesDir;
- var srcDir = config.temploBaseDir + "images";
+ var srcDir = config.template + "images";
if(FileSystem.exists(srcDir)) {
if(!copyImgDir && !config.noPrompt) {
//copyImgDir = system.Terminal.promptYesNo("Install the images
directory from the template?", true);
}
}
if(copyImgDir) {
- // cp -R srcDir config.baseDirectory
+ // cp -R srcDir config.output
}
}
*/
if(config.installImagesDir) {
Utils.createOutputDirectory(targetImgDir);
- var srcDir = config.temploBaseDir + "images";
+ var srcDir = config.templatesDir + config.template + "/images";
if(FileSystem.exists(srcDir) && FileSystem.isDirectory(srcDir)) {
targetImgDir += "/";
var entries = FileSystem.readDirectory(srcDir);
@@ -571,35 +593,35 @@
continue;
if(config.verbose)
println("Installing " + p + " to " + targetImgDir);
- neko.io.File.copy(p, targetImgDir + i);
+ File.copy(p, targetImgDir + i);
}
} else {
if(config.verbose)
- logWarning("Template " + config.temploBaseDir + " has no 'images'
directory");
+ logWarning("Template " + config.templatesDir + config.template + "
has no 'images' directory");
}
}
if(config.installCssFile) {
- var srcCssFile = config.temploBaseDir + "stylesheet.css";
+ var srcCssFile = config.templatesDir + config.template
+ "/stylesheet.css";
if(FileSystem.exists(srcCssFile)) {
- var targetCssFile = config.baseDirectory + config.stylesheet;
+ var targetCssFile = config.output + config.stylesheet;
if(config.verbose)
println("Installing " + srcCssFile + " to " + targetCssFile);
- neko.io.File.copy(srcCssFile, targetCssFile);
+ File.copy(srcCssFile, targetCssFile);
} else {
if(config.verbose)
- logWarning("Template " + config.temploBaseDir + " has no
stylesheet.css");
+ logWarning("Template " + config.templatesDir + config.template + "
has no stylesheet.css");
}
- var srcJsFile = config.temploBaseDir + "chxdoc.js";
+ var srcJsFile = config.templatesDir + config.template + "/chxdoc.js";
if(FileSystem.exists(srcJsFile)) {
- var targetJsFile = config.baseDirectory + "chxdoc.js";
+ var targetJsFile = config.output + "chxdoc.js";
if(config.verbose)
println("Installing " + srcJsFile + " to " + targetJsFile);
- neko.io.File.copy(srcJsFile, targetJsFile);
+ File.copy(srcJsFile, targetJsFile);
} else {
if(config.verbose)
- logWarning("Template " + config.temploBaseDir + " has no chxdoc.js");
+ logWarning("Template " + config.templatesDir + config.template + "
has no chxdoc.js");
}
}
}
@@ -608,26 +630,25 @@
Initializes Templo, exiting if there is any error.
**/
static function initTemplo() {
- config.temploBaseDir =
Utils.addSubdirTrailingSlash(config.temploBaseDir);
- config.temploTmpDir = Utils.addSubdirTrailingSlash(config.temploTmpDir);
-
- mtwin.templo.Loader.BASE_DIR = config.temploBaseDir;
- mtwin.templo.Loader.TMP_DIR = config.temploTmpDir;
- mtwin.templo.Loader.MACROS = config.temploMacros;
-
- if(! neko.Web.isModNeko && ! writeWebConfig ) {
- var tmf = config.temploBaseDir + config.temploMacros;
+
+ mtwin.templo.Loader.BASE_DIR =
Utils.addSubdirTrailingSlash(config.templatesDir + config.template);
+ mtwin.templo.Loader.TMP_DIR =
Utils.addSubdirTrailingSlash(config.tmpDir);
+ mtwin.templo.Loader.MACROS = config.macros;
+
+ if(! Web.isModNeko && ! writeWebConfig ) {
+ var tmf = Utils.addSubdirTrailingSlash(config.templatesDir +
config.template) + config.macros;
if(!FileSystem.exists(tmf))
fatal("The macro file " + tmf + " does not exist.");
- Utils.createOutputDirectory(config.temploTmpDir);
+ Utils.createOutputDirectory(config.tmpDir);
}
}
static function parseArgs() {
- if( neko.Web.isModNeko ) {
+ #if neko
+ if( Web.isModNeko ) {
var data : String =
try
- neko.io.File.getContent(neko.Web.getCwd()+webConfigFile)
+ File.getContent(Web.getCwd()+webConfigFile)
catch(e:Dynamic) {
fatal("There is no configuration data. Please create one with
--writeWebConfig");
null;
@@ -642,110 +663,37 @@
config = cfg;
return;
}
- var expectOutputDir = false;
- var expectFilter = false;
-
- for( x in neko.Sys.args() ) {
- if( x == "-f" )
- expectFilter = true;
- else if( expectFilter ) {
- Utils.addFilter(x);
- expectFilter = false;
- }
- else if( x == "-o")
- expectOutputDir = true;
- else if( expectOutputDir ) {
- config.baseDirectory = x;
- config.baseDirectory =
StringTools.replace(config.baseDirectory,"\\", "/");
- if(config.baseDirectory.charAt(0) != "/") {
- config.baseDirectory = neko.Sys.getCwd() + config.baseDirectory;
- }
- expectOutputDir = false;
- }
- else if( x == "-v")
- config.verbose = true;
- else if( x == "--writeWebConfig")
- writeWebConfig = true;
- else if( x.indexOf("=") > 0) {
- var parts = x.split("=");
- if(parts.length < 2) {
- fatal("Error with parameter " + x);
- }
+ #end
+
+ var args : Array<String> = Sys.args().copy();
+ var nextArg = function(errMsg:String):String {
+ if(args.length == 0)
+ throw Std.string(errMsg);
+ return args.shift();
+ };
+
+ while( args.length > 0) {
+ var arg = nextArg("fatal");
+ var r = ~/^\-\-([A-Za-z]+)=/;
+ if(r.match(arg)) {
+ var parts = arg.split("=");
if(parts.length > 2) {
var zero = parts.shift();
var rest = parts.join("=");
parts = [zero, rest];
}
- switch(parts[0]) {
- case "--developer":
- var show = getBool(parts[1]);
- config.showAuthorTags = show;
- config.showPrivateClasses = show;
- config.showPrivateTypedefs = show;
- config.showPrivateEnums = show;
- config.showPrivateMethods = show;
- config.showPrivateVars = show;
- config.showTodoTags = show;
- config.generateTodo = show;
- case "--exclude":
- var opts = parts[1].split(",");
- for(p in opts) {
- p = StringTools.trim(p);
- Utils.addFilter(p);
- }
- case "--footerText":
- config.footerText = parts[1];
- case "--footerTextFile":
- try {
- config.footerText = neko.io.File.getContent(parts[1]);
- } catch(e : Dynamic) {
- fatal("Unable to load footer file " + parts[1]);
- }
- case "--headerText":
- config.headerText = parts[1];
- case "--headerTextFile":
- try {
- config.headerText = neko.io.File.getContent(parts[1]);
- } catch(e : Dynamic) {
- fatal("Unable to load header file " + parts[1]);
- }
- case "--generateTodoFile":
- config.generateTodo = getBool(parts[1]);
- case "--ignoreRoot":
- config.ignoreRoot = getBool( parts[1] );
- case "--includeOnly":
- var opts = parts[1].split(",");
- for(p in opts) {
- p = StringTools.trim(p);
- Utils.addAllowOnly(p);
- }
- case "--installTemplate":
- var i = getBool(parts[1]);
- config.installImagesDir = i;
- config.installCssFile = i;
- case "--macroFile": config.temploMacros = parts[1];
- case "--showAuthorTags": config.showAuthorTags = getBool(parts[1]);
- case "--showPrivateClasses": config.showPrivateClasses =
getBool(parts[1]);
- case "--showPrivateTypedefs": config.showPrivateTypedefs =
getBool(parts[1]);
- case "--showPrivateEnums": config.showPrivateEnums = getBool(parts[1]);
- case "--showPrivateMethods": config.showPrivateMethods =
getBool(parts[1]);
- case "--showPrivateVars": config.showPrivateVars = getBool(parts[1]);
- case "--showTodoTags": config.showTodoTags = getBool(parts[1]);
- case "--stylesheet": config.stylesheet = parts[1];
- case "--subtitle": config.subtitle = parts[1];
- case "--templateDir", "--template": config.temploBaseDir = parts[1];
- case "--title": config.title = parts[1];
- case "--tmpDir": config.temploTmpDir = parts[1];
- case "--webPassword": config.webPassword = parts[1];
- case "--writeWebConfig": writeWebConfig = getBool(parts[1]);
- case "--xmlBasePath": config.xmlBasePath = parts[1];
- }
- }
- else if( x == "--help" || x == "-help")
- usage(0);
- else {
- var f = x.split(",");
- config.files.push({name:f[0], platform:f[1], remap:f[2]});
+ if(parts[1].charAt(0) == "\"") {
+ parts[1] = parts[1].substr(1);
+ if(parts[1].charAt(parts[1].length-1) == "\"")
+ parts[1] = parts[1].substr(0, parts[1].length-1);
+ }
+ arg = parts[0];
+ args.unshift(parts[1]);
+ }
+ try {
+ handleArg(arg, nextArg, false);
+ } catch(e:String) {
+ fatal("Error parsing command line: " +e);
}
}
@@ -759,16 +707,214 @@
}
}
+ if(createConfig) {
+ Sys.println("Creating chxdocConfig.xml");
+ Setup.writeConfig("chxdocConfig.xml", true);
+ Sys.exit(0);
+ }
+
+ if(config.htmlFileExtension == "")
+ config.htmlFileExtension = ".html";
+ if(config.htmlFileExtension.charAt(0) != ".")
+ config.htmlFileExtension = "." + config.htmlFileExtension;
config.todoFile = "todo" + config.htmlFileExtension;
+
if( config.showPrivateClasses ||
config.showPrivateTypedefs ||
config.showPrivateEnums ||
config.showPrivateMethods ||
config.showPrivateVars)
config.developer = true;
-
-
+ }
+
+ public static function handleArg(arg:String, nextArg:String->String,
isXml:Bool) {
+ var boolErr = function(s) { return "Expected true or false for --" + s;
};
+ var pathErr = function(s) { return "Expected path for --" + s; };
+ var fileErr = function(s) { return "Expected file name for --" + s; };
+ var textErr = function(s) { return "Expected text for --" + s; };
+ var dir = function(s) { return Utils.addSubdirTrailingSlash(s); };
+ switch(arg) {
+ case "--allow":
+ var opts = nextArg("Expected list for --allow").split(",");
+ for(p in opts) {
+ p = StringTools.trim(p);
+ Setup.addFilter(p, ALLOW);
+ }
+ case "--config":
+ Setup.loadConfigFile(nextArg(fileErr("config")));
+ case "--createConfig":
+ createConfig = true;
+ case "--dateLong":
+ config.dateLong = nextArg("Expected date format for --dateLong");
+ Setup.writeVal("dateLong", config.dateLong);
+ case "--dateShort":
+ config.dateShort = nextArg("Expected date format for --dateShort");
+ Setup.writeVal("dateShort", config.dateShort);
+ case "--deny":
+ var opts = nextArg("Expected list for --deny").split(",");
+ for(p in opts) {
+ p = StringTools.trim(p);
+ Setup.addFilter(p, DENY);
+ }
+ case "--developer":
+ var show = getBool(nextArg(boolErr("developer")));
+ config.showAuthorTags = show;
+ config.showMeta = show;
+ config.showPrivateClasses = show;
+ config.showPrivateTypedefs = show;
+ config.showPrivateEnums = show;
+ config.showPrivateMethods = show;
+ config.showPrivateVars = show;
+ config.showTodoTags = show;
+ config.generateTodo = show;
+ Setup.writeVal("showAuthorTags", config.showAuthorTags);
+ Setup.writeVal("showMeta", config.showMeta);
+ Setup.writeVal("showPrivateClasses", config.showPrivateClasses);
+ Setup.writeVal("showPrivateTypedefs", config.showPrivateTypedefs);
+ Setup.writeVal("showPrivateEnums", config.showPrivateEnums);
+ Setup.writeVal("showPrivateMethods", config.showPrivateMethods);
+ Setup.writeVal("showPrivateVars", config.showPrivateVars);
+ Setup.writeVal("showTodoTags", config.showTodoTags);
+ Setup.writeVal("generateTodo", config.generateTodo);
+ case "-f", "--file":
+ var f = nextArg("Xml file specification expected").split(",");
+ //config.files.push({name:f[0], platform:f[1], remap:f[2]});
+ Setup.addTarget(f[0], f[1], f[2]);
+ case "--footerText":
+ config.footerText = nextArg(textErr("footerText"));
+ Setup.writeVal("footerText", config.footerText);
+ case "--footerTextFile":
+ var file = nextArg(fileErr("footerTextFile"));
+ try {
+ if(file != "") {
+ Setup.deleteVal("footerText");
+ Setup.writeVal("footerTextFile", file);
+ config.footerText = File.getContent(file);
+ }
+ } catch(e : Dynamic) {
+ fatal("Unable to load footer file " + file);
+ }
+ case "--generateTodo":
+ config.generateTodo = getBool(nextArg(boolErr("generateTodo")));
+ Setup.writeVal("generateTodo", config.generateTodo);
+ case "--headerText":
+ config.headerText = nextArg(textErr("headerText"));
+ Setup.writeVal("headerText", config.headerText);
+ case "--headerTextFile":
+ var file = nextArg(fileErr("headerTextFile"));
+ try {
+ if(file != "") {
+ Setup.deleteVal("headerText");
+ Setup.writeVal("headerTextFile", file);
+ config.headerText = File.getContent(file);
+ }
+ } catch(e : Dynamic) {
+ fatal("Unable to load header file " + file);
+ }
+ case "--help","-help":
+ usage(0);
+ case "--htmlFileExtension":
+ config.htmlFileExtension = nextArg("Expected file extension for html
files");
+ Setup.writeVal("htmlFileExtension", config.htmlFileExtension);
+ case "--ignoreRoot":
+ config.ignoreRoot = getBool(nextArg(boolErr("ignoreRoot")));
+ Setup.writeVal("ignoreRoot", config.ignoreRoot);
+ case "--installCssFile":
+ config.installImagesDir = getBool(nextArg(boolErr("installCssFile")));
+ Setup.writeVal("installCssFile", config.installCssFile);
+ case "--installImagesDir":
+ config.installImagesDir =
getBool(nextArg(boolErr("installImagesDir")));
+ Setup.writeVal("installImagesDir", config.installImagesDir);
+ case "--installTemplate":
+ var i = getBool(nextArg(boolErr("installTemplate")));
+ config.installImagesDir = i;
+ config.installCssFile = i;
+ Setup.writeVal("installCssFile", config.installCssFile);
+ Setup.writeVal("installImagesDir", config.installImagesDir);
+ case "--macros":
+ config.macros = nextArg(fileErr("macros"));
+ Setup.writeVal("macros", config.macros);
+ case "--mergeMeta":
+ config.mergeMeta = getBool(nextArg(boolErr("mergeMeta")));
+ Setup.writeVal("mergeMeta", config.mergeMeta);
+ case "-o","--output":
+ config.output = nextArg("Expected output directory");
+ config.output = StringTools.replace(config.output,"\\", "/");
+ if(config.output.charAt(0) != "/") {
+ config.output = Sys.getCwd() + config.output;
+ }
+ config.output = dir(config.output);
+ Setup.writeVal("output", config.output);
+ case "--policy":
+ var policy = nextArg("Expected value for --policy");
+ var p = switch(policy.toLowerCase()) {
+ case "allow": ALLOW;
+ case "deny": DENY;
+ default: throw "Invalid default filter policy " + policy;
+ }
+ Setup.setFilterPolicy(p);
+ case "--showAuthorTags":
+ config.showAuthorTags = getBool(nextArg(boolErr("showAuthorTags")));
+ Setup.writeVal("showAuthorTags", config.showAuthorTags);
+ case "--showMeta":
+ config.showMeta = getBool(nextArg(boolErr("showMeta")));
+ Setup.writeVal("showMeta", config.showMeta);
+ case "--showPrivateClasses":
+ config.showPrivateClasses =
getBool(nextArg(boolErr("showPrivateClasses")));
+ Setup.writeVal("showPrivateClasses", config.showPrivateClasses);
+ case "--showPrivateTypedefs":
+ config.showPrivateTypedefs =
getBool(nextArg(boolErr("showPrivateTypedefs")));
+ Setup.writeVal("showPrivateTypedefs", config.showPrivateTypedefs);
+ case "--showPrivateEnums":
+ config.showPrivateEnums =
getBool(nextArg(boolErr("showPrivateEnums")));
+ Setup.writeVal("showPrivateEnums", config.showPrivateEnums);
+ case "--showPrivateMethods":
+ config.showPrivateMethods =
getBool(nextArg(boolErr("showPrivateMethods")));
+ Setup.writeVal("showPrivateMethods", config.showPrivateMethods);
+ case "--showPrivateVars":
+ config.showPrivateVars = getBool(nextArg(boolErr("showPrivateVars")));
+ Setup.writeVal("showPrivateVars", config.showPrivateVars);
+ case "--showTodoTags":
+ config.showTodoTags = getBool(nextArg(boolErr("showTodoTags")));
+ Setup.writeVal("showTodoTags", config.showTodoTags);
+ case "--stylesheet":
+ config.stylesheet = nextArg(fileErr("stylesheet"));
+ Setup.writeVal("stylesheet", config.stylesheet);
+ case "--subtitle":
+ config.subtitle = nextArg(textErr("subtitle"));
+ Setup.writeVal("subtitle", config.subtitle);
+ case "--templatesDir":
+ config.templatesDir = dir(nextArg(pathErr("templatesDir")));
+ Setup.writeVal("templatesDir", config.templatesDir);
+ case "--template":
+ config.template = nextArg(pathErr("template"));
+ Setup.writeVal("template", config.template);
+ if(config.template.charAt(config.template.length-1) != "/")
+ config.template = config.template + "/";
+ case "--title":
+ config.title = nextArg(textErr("title"));
+ Setup.writeVal("title", config.title);
+ case "--tmpDir":
+ config.tmpDir = dir(nextArg(pathErr("tmpDir")));
+ Setup.writeVal("tmpDir", config.tmpDir);
+ case "-v":
+ config.verbose = true;
+ Setup.writeVal("verbose", config.verbose);
+ case "--verbose":
+ config.verbose = getBool(nextArg(boolErr("verbose")));
+ Setup.writeVal("verbose", config.verbose);
+ case "--webPassword":
+ config.webPassword = nextArg(textErr("webPassword"));
+ Setup.writeVal("webPassword", config.webPassword);
+ case "--writeWebConfig":
+ writeWebConfig = true;
+ case "--xmlBasePath":
+ config.xmlBasePath = dir(nextArg(pathErr("xmlBasePath")));
+ Setup.writeVal("xmlBasePath", config.xmlBasePath);
+ default:
+ throw "Unknown option '" + arg + "'";
+ }
}
static function getBool(s : String) : Bool {
@@ -780,18 +926,31 @@
static function usage(exitVal : Int) {
println(" Usage : chxdoc [options] [xml files]");
println(" Options:");
- println("\t-f filter Add a package or class filter");
- println("\t-o outputdir Sets the output directory (defaults to ./html)");
+ println("\t--allow=[class[,orPkg[,Paths]]] Allow rule for filter chain");
+ println("\t--config=[xmlfile] Load config file (can be multiple)");
+ println("\t--createConfig Will write a default xml config file named
chxdocConfig.xml and exit");
+ println("\t--dateLong=\"[format]\" Format for long dates");
+ println("\t--dateShort=\"[format]\" Format for short dates");
+ println("\t--deny=[class[,orPkg[,Paths]]] Deny rule for filter chain");
println("\t--developer=[true|false] Shortcut to showing all privates, if
true");
+ println("\t-f, --file=name,platform,remap Input xml files. See below");
println("\t--footerText=\"text\" Text that will be added to footer of
Type pages");
println("\t--footerTextFile=/path/to/file Type pages footer text from
file");
+ println("\t--generateTodoFile=[true|false] Generate the todo.html file");
println("\t--headerText=\"text\" Text that will be added to header of
Type pages");
println("\t--headerTextFile=/path/to/file Type pages header text from
file");
- println("\t--generateTodoFile=[true|false] Generate the todo.html file");
+ println("\t--help This usage list");
+ println("\t--htmlFileExtension=html Extension for generated html files");
+ println("\t--ignoreRoot=[true|false] Toggle display of root classes");
+ println("\t--installCssFile=[true|false] Install stylesheet from
template");
+ println("\t--installImagesDir=[true|false] Install images from
template");
println("\t--installTemplate=[true|false] Install stylesheet and images
from template");
- println("\t--includeOnly=[comma delimited packages and classes] Output
only for listed classes and packages");
- println("\t--macroFile=file.mtt Temploc macro file. (default
macros.mtt)");
+ println("\t--macros=file.mtt Temploc macro file. (default macros.mtt)");
+ println("\t--mergeMeta=[true|false] Merge metadata tags to @ tags for
similar names");
+ println("\t-o, --output=outputdir Sets the output directory (defaults
to ./docs)");
+ println("\t--policy=[allow|deny] Sets the default policy for the filter
chain");
println("\t--showAuthorTags=[true|false] Toggles showing @author
contents");
+ println("\t--showMeta=[true|false] Toggle showing metadata");
println("\t--showPrivateClasses=[true|false] Toggle private classes
display");
println("\t--showPrivateTypedefs=[true|false] Toggle private typedef
display");
println("\t--showPrivateEnums=[true|false] Toggle private enum display");
@@ -800,15 +959,15 @@
println("\t--showTodoTags=[true|false] Toggle showing @todo tags in type
documentation");
println("\t--stylesheet=file Sets the stylesheet relative to the
outputdir");
println("\t--subtitle=string Set the package subtitle");
- println("\t--template=path Path to template (.mtt) directory
(default ./templates)");
+ println("\t--template=name Template name relative to --templatesDir
(default is 'default')");
+ println("\t--templatesDir=path Set the base directory for templates");
println("\t--title=string Set the package title");
- println("\t--tmpDir=path Path for tempory file generation
(default ./tmp)");
- println("\t-v Turns on verbose mode");
+ println("\t--tmpDir=path Path for tempory file generation
(default ./__chxdoctmp)");
+ println("\t-v,--verbose=[true|false] Turns on verbose mode");
println("\t--webPassword=[pass] Sets a web password for ?reload
and ?showconfig");
println("\t--writeWebConfig Parses everything, serializes and outputs "+
webConfigFile);
println("\t--xmlBasePath=path Set a default path to xml files");
- println("\t--exclude=[comma,delimited,pkgnames] Exclude packages from
being generated");
- println("\t--ignoreRoot=[true|false] Toggle display of root classes");
+
println("");
println(" XML Files:");
println("\tinput.xml[,platform[,remap]");
@@ -816,15 +975,16 @@
println("\tplatform - generate docs for a given platform" );
println("\tremap - change all references of 'remap' to 'package'");
println("\n Sample usage:");
- println("\tchxdoc flash9.xml,flash,flash9 php.xml,php");
+ println("\tchxdoc -f flash9.xml,flash,flash9 --file=php.xml,php");
println("\t\tWill transform all references to flash.* to flash9.*");
- println("\tchxdoc -o Doc --includeOnly=mypackage.*,Int --developer=true
--generateTodoFile=true --showTodoTags=true neko.xml,neko");
+ println("\tchxdoc -o Doc --includeOnly=mypackage.*,Int --developer=true
--generateTodoFile=true --showTodoTags=true -f neko.xml,neko");
println("\t\tGenerates developer docs for mypackage.* and the Int class
only, generating the TODO file as well as showing @todo\n\t\ttags in user
docs. The output is built in the 'Doc' directory.");
println("");
- if(! neko.Web.isModNeko )
- neko.Sys.exit(exitVal);
- else
+ #if neko
+ if(Web.isModNeko )
throw("");
+ #end
+ Sys.exit(exitVal);
}
static function loadXmlFiles() {
@@ -844,7 +1004,7 @@
static function loadFile(file : String, platform:String, ?remap:String) {
var data : String = null;
try {
- data = neko.io.File.getContent(neko.Sys.getCwd()+file);
+ data = File.getContent(Sys.getCwd()+file);
} catch(e:Dynamic) {
fatal("Unable to load platform xml file " + file);
}
@@ -898,6 +1058,7 @@
**/
public static function logWarning(msg:String, ?pkg:PackageContext, ?ctx :
Ctx, ?pos:haxe.PosInfos) {
if( !config.verbose ) return;
+ setDefaultPrinter();
if(pkg != null) {
msg += " in package " + pkg.full;
}
@@ -923,25 +1084,23 @@
if(exitVal == 0)
exitVal = 1;
println("FATAL: " + msg);
- if(! neko.Web.isModNeko )
- neko.Sys.exit(exitVal);
- else
+ #if neko
+ if(Web.isModNeko )
throw "";
+ #end
+ Sys.exit(exitVal);
}
/**
Sets default print and println functions by platform
**/
static function setDefaultPrinter() {
- #if neko
- if( neko.Web.isModNeko )
- println = function(v) { neko.Lib.print(v); neko.Lib.println("<BR />"); }
- else
- println = neko.Lib.println;
- print = neko.Lib.print;
- #else
- #error
- #end
+ println = Sys.println;
+ print = Sys.print;
+ #if neko
+ if( Web.isModNeko )
+ println = function(v) { Sys.print(v); Sys.println("<BR />"); }
+ #end
}
/**
@@ -961,9 +1120,9 @@
rv.push({ name: "Generated", value: config.dateLong});
for(i in [
"stylesheet",
- "temploBaseDir",
- "temploTmpDir",
- "temploMacros",
+ "template",
+ "tmpDir",
+ "macros",
"xmlBasePath"
])
addCfg(i);
=======================================
--- /trunk/projects/chxdoc/src/chxdoc/ClassHandler.hx Sat Mar 17 17:31:11
2012
+++ /trunk/projects/chxdoc/src/chxdoc/ClassHandler.hx Fri Aug 3 20:43:29
2012
@@ -42,15 +42,15 @@
public function pass2(pkg : PackageContext, ctx : ClassCtx) {
- ctx.docs = DocProcessor.process(pkg, ctx, ctx.originalDoc);
+ ctx.docs = DocProcessor.process(pkg, ctx, ctx.originalDoc,
ctx.originalMeta);
if(ctx.constructor != null)
- ctx.constructor.docs = DocProcessor.process(pkg, ctx.constructor,
ctx.constructor.originalDoc);
+ ctx.constructor.docs = DocProcessor.process(pkg, ctx.constructor,
ctx.constructor.originalDoc, ctx.constructor.originalMeta);
var me = this;
forAllFields(ctx,
function(f:FieldCtx) {
- f.docs = DocProcessor.process(pkg, f, f.originalDoc);
+ f.docs = DocProcessor.process(pkg, f, f.originalDoc, f.originalMeta);
if(f.docs != null) {
if (f.docs.forcePrivate) {
if(f.isMethod && ChxDocMain.config.showPrivateMethods)
@@ -60,7 +60,6 @@
if (f.docs.forcePrivate)
f.isPrivate = true;
}
-
}
}
);
@@ -263,7 +262,8 @@
field.name,
field.isPrivate,
field.platforms,
- field.originalDoc);
+ field.originalDoc,
+ field.originalMeta);
f.params = field.params;
f.docs = field.docs;
@@ -437,7 +437,7 @@
function newClassFieldCtx(c : ClassCtx, f : ClassField, isStatic :
Bool) : FieldCtx
{
var me = this;
- var ctx : FieldCtx = createField(c,
f.name, !f.isPublic, f.platforms,
f.doc);
+ var ctx : FieldCtx = createField(c,
f.name, !f.isPublic, f.platforms,
f.doc, f.meta);
ctx.isStatic = isStatic;
ctx.isOverride = f.isOverride;
=======================================
--- /trunk/projects/chxdoc/src/chxdoc/Defines.hx Mon Jan 16 16:16:38 2012
+++ /trunk/projects/chxdoc/src/chxdoc/Defines.hx Fri Aug 3 20:43:29 2012
@@ -35,6 +35,12 @@
/** a dotted class path **/
typedef DotPath = String; // a.b.c
+/** A value indicating the string value should contain a trailing slash **/
+typedef FILEPATH = String;
+
+/** A file name, without the path **/
+typedef FILENAME = String;
+
/**
Links include the html escaped text and href, as well as the css type.
**/
@@ -56,22 +62,27 @@
var docBuildDate : Date;
var dateShort : String; // YYYY-MM-DD
var dateLong : String; // Web Feb 12 HH:MM:SS GMT 2008
+ var mergeMeta : Bool; // merge similar metadata tags to regular tags
var showAuthorTags : Bool;
+ var showMeta : Bool;
var showPrivateClasses : Bool;
var showPrivateTypedefs : Bool;
var showPrivateEnums : Bool;
var showPrivateMethods : Bool;
var showPrivateVars : Bool;
var showTodoTags : Bool;
- var temploBaseDir : String; // path
- var temploTmpDir : String; // path
- var temploMacros : String; // macros.mtt
+ /** base path to the directory with templates **/
+ var templatesDir : FILEPATH;
+ /** relative path to template **/
+ var template : String; // path
+ var tmpDir : FILEPATH;
+ var macros : FILENAME; // macros.mtt
var htmlFileExtension : String; // .html
/** the stylesheet name, relative to baseDirectory **/
- var stylesheet : String; // stylesheet.css
- var baseDirectory : String; // /my/path/html/ (index.html,
all_classes.html etc)
- var packageDirectory : String; // /my/path/packages/
(pkg/path/package.html)
- var typeDirectory : String; // /my/path/types/ (pkg/path/Class.html)
+ var stylesheet : FILENAME; // stylesheet.css
+ var output : FILEPATH; // /my/path/html/ (index.html, all_classes.html
etc)
+ var packageDirectory : FILEPATH; // /my/path/packages/
(pkg/path/package.html)
+ var typeDirectory : FILEPATH; // /my/path/types/ (pkg/path/Class.html)
var noPrompt : Bool; // turn off prommpting (not implemented)
var installImagesDir : Bool;
@@ -95,7 +106,7 @@
////////////////////////////////////////
//// used primarily for web config /////
/** Base path to the xml files in files **/
- var xmlBasePath : String;
+ var xmlBasePath : FILEPATH;
/** files to load **/
var files : Array<{name:String, platform:String, remap:String}>;
// var rendered : Hash<String>; // rendered html by path
@@ -110,7 +121,7 @@
var comment : Html; // raw comment
};
-typedef MetaData = {
+typedef WebMetaData = {
/**
Short date for <META NAME="date" CONTENT="2009-01-23">
**/
@@ -134,6 +145,7 @@
/** Set to "" or a message if deprecated is true **/
var deprecatedMsg : Html; // deprecation text
var params : Array<{ arg : Html, desc : Html }>;
+ var meta : Array<{ name : String, value : String }>;
var requires : Array<Html>;
var returns : Array<Html>;
var see : Array<Html>;
@@ -160,7 +172,7 @@
/** filesystem path to package files **/
var resolvedPackageDir : String;
- var meta : MetaData;
+ var webmeta : WebMetaData;
/**
These 2 exist only at the point the structure is passed to the
template generator
@@ -174,7 +186,7 @@
index, overview, all_packages and all_classes generation.
**/
typedef IndexContext = {
- var meta : MetaData;
+ var webmeta : WebMetaData;
var config : Config;
var build : BuildData;
}
=======================================
--- /trunk/projects/chxdoc/src/chxdoc/DocProcessor.hx Mon Jan 16 16:16:38
2012
+++ /trunk/projects/chxdoc/src/chxdoc/DocProcessor.hx Fri Aug 3 20:43:29
2012
@@ -29,6 +29,7 @@
import chxdoc.Defines;
import chxdoc.Types;
+import haxe.xml.Fast;
/**
<ul>
@@ -42,8 +43,10 @@
var docCtx : DocsContext;
/** The original doc, unixified in constructor **/
var doc : String;
-
- private function new(pkg : PackageContext, ctx: Ctx, doc : String) {
+ /** The original meta string **/
+ var meta : Xml;
+
+ private function new(pkg : PackageContext, ctx: Ctx, doc : String, meta :
Xml) {
this.pkg = pkg;
this.ctx = ctx;
this.docCtx = {
@@ -52,6 +55,7 @@
deprecated : false,
deprecatedMsg : null,
params : new Array(),
+ meta : new Array(),
requires : new Array(),
returns : new Array(),
see : new Array(),
@@ -62,20 +66,57 @@
version : new Array(),
forcePrivate : false,
};
- this.doc = doc.split("\r\n").join("\n").split("\r").join("\n");
+ if(doc != null)
+ this.doc = doc.split("\r\n").join("\n").split("\r").join("\n");
+ /*
+ <meta>
+ <m n="values">
+ <e>-1</e>
+ <e>100</e>
+ </m>
+ </meta>
+ */
+ if(meta != null && ChxDocMain.config.showMeta) {
+ var fast = new Fast(Xml.parse(Std.string(meta)).firstElement());
+ for(m in fast.nodes.m) {
+ var res = { name : "", value : "" };
+ if(!m.has.n)
+ continue;
+
res.name = m.att.n;
+ var first = true;
+ for(e in m.nodes.e) {
+ if(first)
+ first = false;
+ else
+ res.value += ",";
+ res.value += e.innerData;
+ }
+ if(ChxDocMain.config.mergeMeta) {
+
+ switch(
res.name) {
+ case "author":
+ this.docCtx.authors.push(res.value);
+ continue;
+ }
+ }
+ docCtx.meta.push(res);
+ }
+ }
}
- public static function process(pkg : PackageContext, ctx: Ctx, doc :
String) : DocsContext
- {
- if( doc == null || doc.length == 0)
+ public static function process(pkg : PackageContext, ctx: Ctx, doc :
String, meta : Xml) : DocsContext
+ {
+ if( (doc == null || doc.length == 0) && (meta == null |
| !ChxDocMain.config.showMeta) )
return null;
- var p = new DocProcessor(pkg, ctx, doc);
+ var p = new DocProcessor(pkg, ctx, doc, meta);
return p.convert();
}
/**
**/
function convert() : DocsContext {
+ if(doc == null)
+ return docCtx;
// trim stars
doc = ~/^([ \t]*)\*+/gm.replace(doc, "$1");
doc = ~/\**[ \t]*$/gm.replace(doc, "");
@@ -109,9 +150,6 @@
docCtx.typeParams.reverse();
return docCtx;
}
-
-
-
function doEmbeddedTags(s : String) : String {
//{@revision Date msg}
=======================================
--- /trunk/projects/chxdoc/src/chxdoc/EnumHandler.hx Fri Jan 16 01:29:56
2009
+++ /trunk/projects/chxdoc/src/chxdoc/EnumHandler.hx Fri Aug 3 20:43:29
2012
@@ -57,14 +57,14 @@
**/
public function pass2(pkg : PackageContext, ctx : EnumCtx) {
if(ctx.originalDoc != null)
- ctx.docs = DocProcessor.process(pkg, ctx, ctx.originalDoc);
+ ctx.docs = DocProcessor.process(pkg, ctx, ctx.originalDoc,
ctx.originalMeta);
else
ctx.docs = null;
for(f in ctx.constructorInfo) {
if(f.originalDoc == null)
f.docs = null;
else
- f.docs = DocProcessor.process(pkg, f, f.originalDoc);
+ f.docs = DocProcessor.process(pkg, f, f.originalDoc, f.originalMeta);
}
}
@@ -83,7 +83,7 @@
}
function newEnumFieldCtx(ctx : EnumCtx, f : EnumField) : FieldCtx {
- var ctx = createField(ctx,
f.name, false, f.platforms, f.doc);
+ var ctx = createField(ctx,
f.name, false, f.platforms, f.doc, null);
if(f.args != null) {
var me = this;
ctx.args = doStringBlock( function() {
=======================================
--- /trunk/projects/chxdoc/src/chxdoc/PackageHandler.hx Mon Jan 16 16:16:38
2012
+++ /trunk/projects/chxdoc/src/chxdoc/PackageHandler.hx Fri Aug 3 20:43:29
2012
@@ -56,7 +56,7 @@
rootRelative : new String(ChxDocMain.baseRelPath),
packageUri : null,
types : new Array(),
- meta : TypeHandler.newMetaData(),
+ webmeta : TypeHandler.newWebMetaData(),
};
pkg.packageUri = "packages/" + Utils.makeRelativePackageLink(pkg)
+ "package" + config.htmlFileExtension;
@@ -126,7 +126,7 @@
var newTypes = new Array<Ctx>();
for(ctx in pkg.types) {
- if(Utils.isFiltered(ctx.path, false))
+ if(Filters.isFiltered(ctx.path, false))
continue;
print(ctx.nameDots);
switch(ctx.type) {
@@ -167,7 +167,7 @@
}
for(ctx in pkg.types) {
- //if(Utils.isFiltered(ctx.path, false))
+ //if(Filters.isFiltered(ctx.path, false))
// continue;
switch(ctx.type) {
case "class", "interface":
@@ -197,7 +197,7 @@
var writeCtxHtml = function(ctx : Ctx, content: String) {
var path = makeCtxPath(ctx);
Utils.writeFileContents(path, content);
- neko.Lib.print(".");
+ Sys.print(".");
}
var newTypes = new Array<Ctx>();
@@ -235,7 +235,7 @@
/** Returns true if the type is filtered **/
function isFilteredCtx(ctx : Ctx) : Bool {
- if(Utils.isFiltered(ctx.path, false))
+ if(Filters.isFiltered(ctx.path, false))
return true;
var showFlag = switch(ctx.type) {
case "class", "interface": ChxDocMain.config.showPrivateClasses;
@@ -255,7 +255,7 @@
}
function isFilteredPackage(full : String) {
- return Utils.isFiltered(full, true);
+ return Filters.isFiltered(full, true);
}
/**
=======================================
--- /trunk/projects/chxdoc/src/chxdoc/TypeHandler.hx Mon Jan 16 13:53:29
2012
+++ /trunk/projects/chxdoc/src/chxdoc/TypeHandler.hx Fri Aug 3 20:43:29
2012
@@ -53,7 +53,7 @@
}
public dynamic function output(str) {
- neko.Lib.print(str);
+ Sys.print(str);
}
public function write(str, ?params : Dynamic ) {
@@ -75,14 +75,14 @@
/**
Creates a new metaData entry, with one empty entry in keywords
**/
- public static function newMetaData() {
- var metaData = {
+ public static function newWebMetaData() {
+ var webMetaData = {
date : ChxDocMain.config.dateShort,
keywords : new Array<String>(),
stylesheet : ChxDocMain.baseRelPath + "../" +
ChxDocMain.config.stylesheet,
};
- metaData.keywords.push("");
- return metaData;
+ webMetaData.keywords.push("");
+ return webMetaData;
}
function processType( t : CType ) {
@@ -167,7 +167,7 @@
}
function makePathUrl( path : Path, css ) {
- if(Utils.isFiltered(path, false))
+ if(Filters.isFiltered(path, false))
return path;
var p = path.split(".");
var name = p.pop();
@@ -247,8 +247,9 @@
access : (t.isPrivate ? "private" : "public"),
docs : null,
- meta : newMetaData(),
+ webmeta : newWebMetaData(),
originalDoc : t.doc,
+ originalMeta : t.meta,
}
if( t.params != null && t.params.length > 0 )
@@ -265,7 +266,7 @@
return c;
}
- function createField(parentCtx : Ctx, name : String, isPrivate : Bool,
platforms : List<String>, originalDoc : String) : FieldCtx {
+ function createField(parentCtx : Ctx, name : String, isPrivate : Bool,
platforms : List<String>, originalDoc : String, originalMeta : Xml) :
FieldCtx {
var c : FieldCtx = {
type : "field",
@@ -287,9 +288,10 @@
access : (isPrivate ? "private" : "public"),
docs : null,
- meta : null,
+ webmeta : null,
originalDoc : originalDoc,
+ originalMeta : originalMeta,
args : "",
returns : "",
@@ -316,7 +318,7 @@
Sets the default meta keywords for a context
**/
function resetMetaKeywords(ctx : Ctx) : Void {
- ctx.meta.keywords[0] = ctx.nameDots + " " + ctx.type;
+ ctx.webmeta.keywords[0] = ctx.nameDots + " " + ctx.type;
}
/**
@@ -381,7 +383,7 @@
default:
throw ChxDocMain.fatal("Could not determing template type for " +
ctx.type);
}
-// Reflect.setField(ctx, "meta", TypeHandler.newMetaData());
+// Reflect.setField(ctx, "webmeta", TypeHandler.newMetaData());
Reflect.setField(ctx, "build", ChxDocMain.buildData );
Reflect.setField(ctx, "config", ChxDocMain.config );
var t = new mtwin.templo.Loader(type + ".mtt");
=======================================
--- /trunk/projects/chxdoc/src/chxdoc/TypedefHandler.hx Mon Jan 19 18:42:19
2009
+++ /trunk/projects/chxdoc/src/chxdoc/TypedefHandler.hx Fri Aug 3 20:43:29
2012
@@ -105,7 +105,7 @@
switch(t) {
case CAnonymous(fields): // fields == list<{t:CType, name:String}>
for( f in fields ) {
- var field = createField(context,
f.name, false, platforms, "");
+ var field = createField(context,
f.name, false, platforms, "", null);
field.returns = doStringBlock(
function() {
me.processType(f.t);
@@ -147,7 +147,7 @@
**/
public function pass2(pkg : PackageContext, ctx : TypedefCtx) {
if(ctx.originalDoc != null)
- ctx.docs = DocProcessor.process(pkg, ctx, ctx.originalDoc);
+ ctx.docs = DocProcessor.process(pkg, ctx, ctx.originalDoc,
ctx.originalMeta);
else
ctx.docs = null;
}
=======================================
--- /trunk/projects/chxdoc/src/chxdoc/Types.hx Mon Jan 16 16:16:38 2012
+++ /trunk/projects/chxdoc/src/chxdoc/Types.hx Fri Aug 3 20:43:29 2012
@@ -66,7 +66,7 @@
var access : String; // 'public' or 'private'
var docs : DocsContext;
- var meta : MetaData;
+ var webmeta : WebMetaData;
/**
These 2 exist only at the point the structure is passed to the
template generator
@@ -75,6 +75,7 @@
**/
var originalDoc : String;
+ var originalMeta : Xml;
}
/**
@@ -118,7 +119,7 @@
typedef EnumCtx = {
- >Ctx,
+ > Ctx,
/** Only uses the [platforms], [name], [args] and [docs] fields of the
FieldCtx **/
var constructorInfo : Array<FieldCtx>; // only
};
@@ -127,7 +128,7 @@
A parent TypedefCtx does not contain valid [alias] or [fields] values.
Each member of the [contexts] array will either have [alias] or [fields] set
**/
typedef TypedefCtx = {
- >Ctx,
+ > Ctx,
/** true if an alias, false if typedef **/
var isAlias : Bool;
/** Html content for aliases, or null if child is a typedef **/
=======================================
--- /trunk/projects/chxdoc/src/chxdoc/Utils.hx Sun Jun 3 09:44:14 2012
+++ /trunk/projects/chxdoc/src/chxdoc/Utils.hx Fri Aug 3 20:43:29 2012
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008-2009, The Caffeine-hx project contributors
+ * Copyright (c) 2008-2012, The Caffeine-hx project contributors
* Original author : Russell Weir
* Contributors:
* All rights reserved.
@@ -31,10 +31,9 @@
import chxdoc.Defines;
import chxdoc.Types;
import sys.FileSystem;
+import sys.io.File;
class Utils {
- static var filters : List<String> = new List<String>();
- static var allowedOnly : List<String> = new List<String>();
/**
Takes all items in arr and prefixes them with the
@@ -56,7 +55,7 @@
// and any private types, which are
// created in subdirectories with a leading underscore,, have
// the underscore directory removed.
- public static function normalizeTypeInfosPath(path : String) : String {
+ public static function normalizeTypeInfosPath(path : Path) : String {
if( path.substr(0,7) == "flash9." )
return "flash."+path.substr(7);
return path;
@@ -144,66 +143,10 @@
return "<a href=\"" + ChxDocMain.baseRelPath + url +
ChxDocMain.config.htmlFileExtension + "\"
class=\""+cssClass+"\">"+text+"</a>";
}
- public static function makeTypeBaseRelPath(path : String) {
+ public static function makeTypeBaseRelPath(path : Path) {
var parts = path.split(".");
}
-
- /////////////////////////////////////
- // FILTERS //
- /////////////////////////////////////
- public static function addFilter(s : String) {
- filters.add(s);
- }
-
- /**
- * Sets a package or class name that may be allowed,
- * filtering everything else
- *
- * @param s Class path (ie. mypackage.* or mypackage.MyClass)
- */
- public static function addAllowOnly(s:String) : Void {
- if(s==null || s.length == 0) return;
- if(s.charAt(s.length-1) == "*")
- s = s.substr(0, s.length-1);
- if(s.indexOf(".") < 0) // a root type
- {
- allowedOnly.remove("root types.");
- allowedOnly.add("root types.");
- }
- allowedOnly.add(s);
- }
-
- /**
- * Checks if a package or class is filtered
- **/
- public static function isFiltered( path : Path, isPackage : Bool ) {
- if( isPackage && path == "Remoting" )
- return true;
- if( StringTools.endsWith(path,"__") )
- return true;
- for( x in filters )
- if( StringTools.startsWith(path,x) )
- return true;
- var ao = false;
- if(isPackage)
- path += ".";
- for( x in allowedOnly ) {
- ao = true;
- if( x.charAt(x.length-1) == "." ) {
- if( StringTools.startsWith(path,x) )
- return false;
- }
- if( path == x ) {
- return false;
- }
- }
- // if there were any allowedOnly entries, anything
- // else is filtered.
- if(ao) return true;
-
- return false;
- }
public static function writeFileContents(filePath:String, contents:
String) {
var fp = neko.io.File.write(filePath, true);
@@ -258,6 +201,66 @@
throw "Output path " + dir + " is not a directory.";
}
+ /**
+ * Determines the user's home path
+ * @return Path with trailing slash, or null if directory does not exist
+ **/
+ public static function getHomeDir() {
+ var home = "";
+ var env = Sys.environment();
+ if (env.exists ("HOME"))
+ home = env.get("HOME");
+ else if (env.exists("USERPROFILE"))
+ home = env.get("USERPROFILE");
+ else if (env.exists("HOMEDRIVE"))
+ home = Sys.getEnv("HOMEDRIVE") + Sys.getEnv("HOMEPATH");
+ else
+ return null;
+ if(FileSystem.exists(home) && FileSystem.isDirectory(home))
+ return addSubdirTrailingSlash(home);
+ return null;
+ }
+
+ /**
+ * Get the base path of haxelib
+ * @return Path with trailing slash
+ * @throws Strings when directory can not be determined
+ **/
+ public static function getHaxelib() {
+ var win = Sys.systemName() == "Windows";
+ var haxepath = Sys.getEnv("HAXEPATH");
+ if( haxepath != null ) {
+ var last = haxepath.charAt(haxepath.length - 1);
+ if( last != "/" && last != "\\" )
+ haxepath += "/";
+ }
+ var config_file;
+ if( win )
+ config_file = Sys.getEnv("HOMEDRIVE") + Sys.getEnv("HOMEPATH");
+ else
+ config_file = Sys.getEnv("HOME");
+ config_file += "/.haxelib";
+ var rep = try
+ File.getContent(config_file)
+ catch( e : Dynamic ) try
+ File.getContent("/etc/.haxelib")
+ catch( e : Dynamic ) {
+ if( win ) {
+ // Windows has a default directory (no need for setup)
+ if( haxepath == null )
+ throw "HAXEPATH environment variable not defined";
+ var rep = haxepath+"lib";
+ if(!FileSystem.isDirectory(rep))
+ throw "The directory '"+rep+"' defined by HAXEPATH does not exist";
+ return rep+"\\";
+ }
+ throw "Haxelib setup must be run first";
+ }
+ rep = StringTools.trim(rep);
+ if( !FileSystem.exists(rep) )
+ throw "haxelib repository "+rep+" does not exist.";
+ return rep+"/";
+ }
/**
* Translates html special characters for links etc.
* <ul>
=======================================
--- /trunk/projects/chxdoc/src/haxe/rtti/CType.hx Sat Dec 25 11:38:56 2010
+++ /trunk/projects/chxdoc/src/haxe/rtti/CType.hx Fri Aug 3 20:43:29 2012
@@ -64,16 +64,19 @@
var set : Rights;
var params : TypeParams;
var platforms : Platforms;
+ var meta : Xml;
+ var line : Null<Int>;
}
typedef TypeInfos = {
var path : Path;
var module : Path;
+ var file : Null<String>;
var params : TypeParams;
var doc : String;
var isPrivate : Bool;
var platforms : Platforms;
- var file : String;
+ var meta : Xml;
}
typedef Classdef = {> TypeInfos,
=======================================
--- /trunk/projects/chxdoc/src/haxe/rtti/XmlParser.hx Sat Jul 28 12:09:53
2012
+++ /trunk/projects/chxdoc/src/haxe/rtti/XmlParser.hx Fri Aug 3 20:43:29
2012
@@ -317,13 +317,14 @@
var interfaces = new List();
var fields = new List();
var statics = new List();
+ var m = null;
for( c in x.elements )
switch(
c.name ) {
case "haxe_doc": doc = c.innerData;
case "extends": csuper = xpath(c);
case "implements": interfaces.add(xpath(c));
case "haxe_dynamic": tdynamic = xtype(new Fast(c.x.firstElement()));
- case "meta":
+ case "meta": m = c.x;
default:
if( c.x.exists("static") )
statics.add(xclassfield(c));
@@ -345,6 +346,7 @@
statics : statics,
tdynamic : tdynamic,
platforms : defplat(),
+ meta : m,
};
}
@@ -352,10 +354,11 @@
var e = x.elements;
var t = xtype(e.next());
var doc = null;
+ var m = null;
for( c in e )
switch(
c.name ) {
case "haxe_doc": doc = c.innerData;
- case "meta":
+ case "meta": m = c.x;
default: xerror(c);
}
return {
@@ -363,21 +366,25 @@
type : t,
isPublic : x.x.exists("public"),
isOverride : x.x.exists("override"),
+ line : if( x.has.line ) Std.parseInt(x.att.line) else null,
doc : doc,
get : if( x.has.get ) mkRights(x.att.get) else RNormal,
set : if( x.has.set ) mkRights(x.att.set) else RNormal,
params : if( x.has.params ) mkTypeParams(x.att.params) else null,
platforms : defplat(),
+ meta : m,
};
}
function xenum( x : Fast ) : Enumdef {
var cl = new List();
var doc = null;
+ var m = null;
for( c in x.elements )
if(
c.name == "haxe_doc" )
doc = c.innerData;
- else if (
c.name == "meta" ) { }
+ else if (
c.name == "meta" )
+ m = c.x;
else
cl.add(xenumfield(c));
return {
@@ -390,6 +397,7 @@
params : mkTypeParams(x.att.params),
constructors : cl,
platforms : defplat(),
+ meta : m,
};
}
@@ -424,10 +432,12 @@
function xtypedef( x : Fast ) : Typedef {
var doc = null;
var t = null;
+ var m = null;
for( c in x.elements )
if(
c.name == "haxe_doc" )
doc = c.innerData;
- else if (
c.name == "meta" ) { }
+ else if (
c.name == "meta" )
+ m = c.x;
else
t = xtype(c);
var types = new Hash();
@@ -443,6 +453,7 @@
type : t,
types : types,
platforms : defplat(),
+ meta : m,
};
}
=======================================
--- /trunk/projects/chxdoc/src/haxelib.xml Sun Jul 29 14:57:38 2012
+++ /trunk/projects/chxdoc/src/haxelib.xml Fri Aug 3 20:43:29 2012
@@ -1,5 +1,5 @@
<project name="chxdoc" url="
http://code.google.com/p/caffeine-hx/"
license="BSD">
<user name="Madrok"/>
<description>Haxe documentation generator</description>
- <version name="1.1.4">@private tags supported and fix to inherited
vars</version>
+ <version name="1.2.0">New xml config, filtering engine and metadata
support</version>
</project>
=======================================
--- /trunk/projects/chxdoc/src/haxelib_build.hxml Fri Oct 14 14:26:55 2011
+++ /trunk/projects/chxdoc/src/haxelib_build.hxml Fri Aug 3 20:43:29 2012
@@ -1,6 +1,3 @@
-neko chxdoc.n
-main chxdoc/ChxDocMain.hx
---next
--neko chxtemploc.n
--main mtwin.templo.Main