Main /
JSDocJSDoc Public OutputJSDoc output, updated every 5 minutes
See Also
JSDoc
JSDoc Summary
Problems and solutions for JSDoc writersThe message "Unable to parse a tag's type expression for source file" appearsSee https://www.terraswarm.org/accessors/wiki/Main/JSDoc#JSDocArrays JSDoc Implementation DetailsHow JSDoc creates the PtDoc.xml filesSummary: running (cd $PTII/org/terraswarm/accessor/accessors/web; ant) or reloading an accessor runs a custom version of JSDoc that reads Details: Keep in mind that we can run jsdoc in two locations, the terraswarm accessors repo and the ptII repo. Here, we discuss how files like $PTII/org/terraswarm/accessor/accessors/web/audio/AudioCapturePtDoc.xml are created, see https://www.terraswarm.org/accessors/audio/AudioCapturePtDoc.xml for example: <property name="documentation" class="ptolemy.vergil.basic.DocAttribute"><property name="author" class="ptolemy.kernel.util.StringAttribute" value="Ilge Akkya"> </property><property name="description" class="ptolemy.kernel.util.StringAttribute" value="<p>Capture audio from the microphone. </p> <p> This accessor requires the optional 'audio' module, which may or may not be provided by an accessor host.</p>"> </property><property name="trigger (port)" class="ptolemy.kernel.util.StringAttribute" value="undefined Input that triggers recording."> </property><property name="signal (port)" class="ptolemy.kernel.util.StringAttribute" value="({names:["number"]}) A sequence of numbers representing the captured audio signal."> </property><property name="version" class="ptolemy.kernel.util.StringAttribute" value="$$Id: AudioCapture.js 342 2015-10-31 15:48:43Z cxh $$"> </property></property> The The way The <target name="ptdoc" depends="vendors-jsdoc" description="Invoke jsdoc to read *.js files and generate *PtDoc.xml files suitable for Ptolemy" > <echo>Invoke jsdoc to read *.js files and generate *PtDoc.xml files suitable for Ptolemy. See https://chess.eecs.berkeley.edu/ptexternal/wiki/Main/JSDocSystems See jsdoc/jsdoc.json See jsdoc/plugins/accessorJSDocTags.js See jsdoc/templates/ptdoc/publish.js </echo> <exec executable="${jsdoc.home}/jsdoc"> <arg value="--configure" /> <arg value="jsdoc/jsdoc.json" /> <arg value="--recurse" /> <arg value="--template" /> <arg value="jsdoc/templates/ptdoc" /> <arg value="--verbose" /> <arg value="." /> </exec> </target> The To invoke the command by hand: bash-3.2$ cd $PTII/org/terraswarm/accessor/accessors/web bash-3.2$ ant ptdoc Buildfile: /Users/cxh/ptII/org/terraswarm/accessor/accessors/web/build.xml -check-vendors-jsdoc: vendors-jsdoc: ptdoc: [echo] Invoke jsdoc to read *.js files and generate *PtDoc.xml files suitable for Ptolemy. [echo] See https://chess.eecs.berkeley.edu/ptexternal/wiki/Main/JSDocSystems [echo] See jsdoc/jsdoc.json [echo] See jsdoc/plugins/accessorJSDocTags.js [echo] See jsdoc/templates/ptdoc/publish.js [echo] [exec] Parsing /Users/cxh/ptII/org/terraswarm/accessor/accessors/web/audio/AudioCapture.js ... [exec] Parsing /Users/cxh/ptII/org/terraswarm/accessor/accessors/web/audio/AudioPlayer.js ... ... To see what command is invoked: bash-3.2$ cd $PTII/org/terraswarm/accessor/accessors/web bash-3.2$ ant -v ptdoc Apache Ant(TM) version 1.9.4 compiled on April 29 2014 Trying the default build file: build.xml Buildfile: /Users/cxh/ptII/org/terraswarm/accessor/accessors/web/build.xml ... ptdoc: [echo] Invoke jsdoc to read *.js files and generate *PtDoc.xml files suitable for Ptolemy. [echo] See https://chess.eecs.berkeley.edu/ptexternal/wiki/Main/JSDocSystems [echo] See jsdoc/jsdoc.json [echo] See jsdoc/plugins/accessorJSDocTags.js [echo] See jsdoc/templates/ptdoc/publish.js [echo] [exec] Current OS is Mac OS X [exec] Executing 'vendors/jsdoc/jsdoc' with arguments: [exec] '--configure' [exec] 'jsdoc/jsdoc.json' [exec] '--recurse' [exec] '--template' [exec] 'jsdoc/templates/ptdoc' [exec] '--verbose' [exec] '.' To run jsdoc by hand to build ptdoc files: bash-3.2$ cd $PTII/org/terraswarm/accessor/accessors/web bash-3.2$ ./vendors/jsdoc/jsdoc --configure jsdoc/jsdoc.json --recurse --template jsdoc/templates/ptdoc --verbose . ./vendors/jsdoc/jsdoc --configure jsdoc/jsdoc.json --recurse --template jsdoc/templates/ptdoc --verbose . Parsing /Users/cxh/ptII/org/terraswarm/accessor/accessors/web/audio/AudioCapture.js ... Parsing /Users/cxh/ptII/org/terraswarm/accessor/accessors/web/audio/AudioPlayer.js ... ... The template directory is jsdoc/templates/ptdoc, which maps to In that directory is a JSDoc Simple ExampleThis example downloads the non-accessor-specifc JSDoc code and runs it on the Ptolemy II .js files. This example is an illustration of getting started with JSDoc, instead of following this example, we now have a custom branch of JSDoc, ant rules and Java code that invokes the ant rules
JSDoc Ant Ptolemy ExampleWe now have an ant rule that generates JSDoc output in $PTII/doc/codeDoc/js/index.html
Note that the file For formatting instructions see Getting Started and Block Tags Continuous IntegrationWe use continuous integration to update the websites with the documentation. Recall from above that the docs appear on both the CHESS website and the TerraSwarm website.
How the Ptolemy JavaScript website is updatedWe have a continuous integration (CI) build that updates https://chess.eecs.berkeley.edu/ptexternal/src/ptII/doc/codeDoc/js/index.html by checking the ptII svn repo for changes every 5 minutes. See http://terra.eecs.berkeley.edu:8080/job/ptIIci/ During the build, The chess website is updated at the end of the build process by a To see this step requires a Jenkins account with access to the ptIIci configuration. The settings are below:
How the TerraSwarm website is updatedWe have a continuous integration (CI) build that updates https://www.terraswarm.org/accessors/doc/jsdoc/ by checking the accessors svn repo for changes every 5 minutes. See http://terra.eecs.berkeley.edu:8080/job/accessors/ During the build, The TerraSwarm website is updated by a "Send build artifacts over SSH" post-build step. The settings are below: JSDoc Custom TagsUnfortunately, the docs for adding custom tags to JSDoc are a bit sparse. https://github.com/jsdoc3/jsdoc says: "Templates and Build Tools" "The JSDoc community has created numerous templates and other tools to help you generate and customize your documentation. Here are just a few: Templates"
JSDoc Custom Tag PluginBelow is a description of what was necessary to set up the custom JSDoc Custom Tag Plugin for both the There are two components: The plugin (covered here) and the JSDoc Custom Tag Fork (below). Below are the steps that were done to set up the plugin in the
What the above code does is define tags that, when invoked, update an array that contains the instances of that tag. Now the problem is how to use those tags. JSDoc Custom Tag ForkAfter an analysis of JSDoc Custom Tags documentation above, it seems that the best way to add our tags is to fork the git hub repo. So, we have https://github.com/terraswarm/jsdoc. When
The following changes were made to the JSDoc repository.
JSDoc Custom Tag NotesNotes about how the above procedure was determined. Unable to parse a tag's type expression.In the accessors repo, if dictionary.defineTag("input", { capnHaveType: true, canHaveName: true, onTagged: function(doclet, tag) { console.log("accessors/web/jsdoc/plugins/accessorJSDocTags.js: input tag:" + tag); doclet.input = tag.name; } }); Then running [exec] Parsing /Users/cxh/src/accessors/web/FFT.js ... [exec] accessors/web/jsdoc/plugins/accessorJSDocTags.js: input tag:[object Object] [exec] accessors/web/jsdoc/plugins/accessorJSDocTags.js: input tag:[object Object] [exec] Parsing /Users/cxh/src/accessors/web/RangeSensor.js ...ERROR: Unable to parse a tag's type expression for source file /Users\ /cxh/src/accessors/web/FFT.js with tag title "input" and text "{[number]} signalIn Input signal array": Invalid type expression "[number\ ]": Expected "!", "$", "'", "(", "*", ".", "...", "0", "?", "Function", "\"", "\\", "_", "break", "case", "catch", "class", "const", "co\ ntinue", "debugger", "default", "delete", "do", "else", "enum", "export", "extends", "false", "finally", "for", "function", "if", "imple\ ments", "import", "in", "instanceof", "interface", "let", "new", "null", "package", "private", "protected", "public", "return", "static"\ , "super", "switch", "this", "throw", "true", "try", "typeof", "undefined", "var", "void", "while", "with", "yield", "{", Unicode letter\ number, Unicode lowercase letter, Unicode modifier letter, Unicode other letter, Unicode titlecase letter, Unicode uppercase letter or \ [1-9] but "[" found. [exec] [exec] ERROR: Unable to parse a tag's type expression for source file /Users/cxh/src/accessors/web/FFT.js with tag title "input" an\ d text "{[number]} signalIn Input signal array": Invalid type expression "[number]": Expected "!", "$", "'", "(", "*", ".", "...", "0", \ "?", "Function", "\"", "\\", "_", "break", "case", "catch", "class", "const", "continue", "debugger", "default", "delete", "do", "else",\ "enum", "export", "extends", "false", "finally", "for", "function", "if", "implements", "import", "in", "instanceof", "interface", "let\ ", "new", "null", "package", "private", "protected", "public", "return", "static", "super", "switch", "this", "throw", "true", "try", "t\ ypeof", "undefined", "var", "void", "while", "with", "yield", "{", Unicode letter number, Unicode lowercase letter, Unicode modifier let\ ter, Unicode other letter, Unicode titlecase letter, Unicode uppercase letter or [1-9] but "[" found. What's happening here is that we are getting an Object. https://github.com/jsdoc3/jsdoc/issues/498 has a link to some code: https://github.com/AnalyticalGraphicsInc/cesium/blob/92babfac/Tools/jsdoc3/plugins/customTags.js /** @overview Define custom tags for Cesium @module plugins/customTags @author Kristian Calhoun <kristian.calhoun@gmail.com> */ exports.defineTags = function(dictionary) { dictionary.defineTag('enumeration', { onTagged: function(doclet, tag) { doclet.addTag('kind', 'enumeration'); doclet.filename = doclet.name; } }); dictionary.defineTag('performance', { mustHaveValue: true, onTagged: function(doclet, tag) { if (!doclet.performance) { doclet.performance = []; } doclet.performance.push(tag.value); } }); dictionary.defineTag('glsl', { onTagged: function(doclet, tag) { doclet.addTag('kind', 'glsl'); doclet.filename = doclet.name; } }).synonym('glslStruct').synonym('glslUniform').synonym('glslConstant').synonym('glslFunction'); dictionary.defineTag('demo', { mustHaveValue: true, onTagged: function(doclet, tag) { if (!doclet.demo) { doclet.demo = []; } doclet.demo.push(tag.value); } }); }; <?js if(typeof meta.filename === 'string' && (kind === 'class' || kind === 'module' || kind === 'enumeration' || kind === 'glsl')){?> <h5>Source:</h5> <ul class="see-list"> <li><a href='<?js= args[5]+args[6]+args[4]+meta.filename.substring(5) ?>' target="_blank"><?js= meta.filename.substring(5) ?></a></li> </ul> <?js }?> So, one possibility would be to override the templates, see http://usejsdoc.org/about-configuring-default-template.html https://code.google.com/p/jsdoc/source/browse/trunk/modules/jsdoc/tag/dictionary/definitions.js?r=19 has the following definition for param dictionary.defineTag('param', { mustHaveValue: true, canHaveType: true, canHaveName: true, onTagged: function(doclet, tag) { if (!doclet.params) { doclet.params = []; } doclet.params.push(tag.value); } }) Using that code results in something that at least does not cause errors. exports.defineTags = function(dictionary) { dictionary.defineTag("accessor", { mustHaveValue: true, onTagged: function(doclet, tag) { doclet.accessor = tag.name; } }); dictionary.defineTag("input", { mustHaveValue: true, canHaveType: true, canHaveName: true, onTagged: function(doclet, tag) { if (!doclet.inputs) { doclet.inputs = []; } doclet.inputs.push(tag.value); } }); dictionary.defineTag("output", { mustHaveValue: true, canHaveType: true, canHaveName: true, onTagged: function(doclet, tag) { if (!doclet.outputs) { doclet.outputs = []; } doclet.outputs.push(tag.value); } }); dictionary.defineTag("parameter", { mustHaveValue: true, canHaveType: true, canHaveName: true, onTagged: function(doclet, tag) { if (!doclet.parameters) { doclet.parameters = []; } doclet.parameters.push(tag.value); } }); }; The next step is to modify the template files Modifying JSDoc's Template FilesConfiguring JSDoc's default template states: "Overriding the default template's layout file" "The default template uses a file named layout.tmpl to specify the header and footer for each page in the generated documentation. In particular, this file defines which CSS and JavaScript files are loaded for each page. In JSDoc 3.3.0 and later, you can specify your own layout.tmpl file to use, which allows you to load your own custom CSS and JavaScript files in addition to, or instead of, the standard files." "To use this feature, set the option templates.default.layoutFile to the path to your customized layout file. Relative paths are resolved against the path to the config.json file; the current working directory; and the JSDoc directory, in that order." To do this, { ... "templates": { "default": { "layoutFile": [ "./jsdoc/templates/accessorLayout.tmpl" ] } } } The above works, but where to insert my changes? Ideally, I would like to define an option that would invoke some JavaScript that would process my custom arguments...
Ideally, we would like to only copy a portion the default 1.1Mb of jsdoc/templates/default/ One idea is to define a method that would search our directory first. AntInvoke jsdoc directly
jsdoc3-ant-taskSummary: Do not use Instead, execute jsdoc directly as above Use https://github.com/jannon/jsdoc3-ant-task, it is for JSDoc 3
However, I'm still not getting output? It looks like this uses a custom version of jsdoc3 from Also, pmWiki to JSDocWe have pmWiki pages at https://www.terraswarm.org/accessors/wiki/Version0/OptionalJavaScriptModules that we would like to show up at https://chess.eecs.berkeley.edu/ptexternal/src/ptII/doc/codeDoc/js/index.html The way we do this is
https://www.terraswarm.org/accessors/wiki/Version0/OptionalJavaScriptModules?action=markdown using wget.
Adding Hierarchy to JSDocProblem:This page still doesn't show accessors in subdirectories: https://chess.eecs.berkeley.edu/ptexternal/src/ptII/doc/codeDoc/js/index.html Eventually, they will all be in subdirectories. All the more mature ones are in subdirectories REST, Camera, ImageFilters, etc) Resources
Ideas
Invoke JSDoc on itself#!/bin/sh ./vendors/jsdoc/jsdoc \ --verbose \ --recurse \ -c \ doc/jsdoc/jsdoc.json \ -R \ doc/jsdoc/topREADME.md \ -d \ doc/codeDoc/js \ vendors/jsdoc { "plugins": ["plugins/markdown", "doc/jsdoc/plugins/accessorJSDocTags"], "markdown": { "tags": ["accessor", "input", "output", "parameter"] }, "source": { "excludePattern": "(fixtures|templates|test|rhino|plugins|node_modules)" } } Running Modules jsdoc/app jsdoc/augment jsdoc/borrow jsdoc/config jsdoc/doclet jsdoc/env jsdoc/fs jsdoc/name jsdoc/opts/argparser jsdoc/opts/args jsdoc/package jsdoc/path jsdoc/readme jsdoc/src/astnode jsdoc/src/filter jsdoc/src/handlers Use the directory name in the accessor tagOne possibility is to have accessors/web/camera/Camera.js use * @accessor camera/Camera instead of * @accessor Camera If this is done, then any accessors will be listed appropriately. The nice thing about this is that it is similar to the @module tag in https://github.com/jsdoc3/jsdoc/blob/master/lib/jsdoc/src/filter.js @module jsdoc/src/filter Determine the root directory automatically.If we did not want to go with using the directory in the @accessor tag, then in theory we could try to determine it. However, as we are running jsdoc in $PTII and it is possible that the accessors repo is checked out, how would we determine that
Type Info as a separate AttributeEdward wrote: "Actually, it would be better if the type information appeared in the PtDoc XML file as a separate attribute. I.e, in RESTPtDoc.xml, instead of generating:"
<property name="timeout (parameter)" class="ptolemy.kernel.util.StringAttribute" value="({names:["int"]}) The amount of time (in milliseconds) to wait for a response before triggering a null response and an error. This defaults to 5000."> "we should be generating:"
<property name="timeout (parameter)" class="ptolemy.kernel.util.StringAttribute" type="int" value="The amount of time (in milliseconds) to wait for a response before triggering a null response and an error. This defaults to 5000.">
Here's a diff of that file bash-3.2$ svn diff Index: jsdoc/templates/ptdoc/publish.js =================================================================== --- jsdoc/templates/ptdoc/publish.js (revision 432) +++ jsdoc/templates/ptdoc/publish.js (working copy) @@ -70,8 +70,8 @@ // <property name="price (output, number)" class="ptolemy.kernel.util.StringAttribute" value="The most recent trade price\ for the stock."> moml += ' <property name="' + xmlEscape(name) + " (" + propertyName + ")" - + '" class="ptolemy.kernel.util.StringAttribute" value="' - + xmlEscape(type) + " " + + '" class="ptolemy.kernel.util.StringAttribute" type="' + + xmlEscape(type) + '" value="' + xmlEscape(description) + '">\n' + ' </property>\n'; }); bash-3.2$ However, the output is not necessarily in the format we want. The type= elements look like: bash-3.2$ find . -name "*PtDoc.xml" | xargs grep type= | awk -F \" '{for(i=1;i<=NF;i++) { if ($i ~ /type=/) {print $(i+1)}}}' | sort | uniq -c 13 ({names:["JSON"]}) 4 ({names:["Object"]}) 3 ({names:["array"]}) 1 ({names:["array.<number>"]}) 1 ({names:["array.<{'horizontal': 'number', 'vertical': 'number'}>"]}) 1 ({names:["array.<{'real': 'number', 'imag': 'number'}>"]}) 25 ({names:["boolean"]}) 1 ({names:["general"]}) 33 ({names:["int"]}) 9 ({names:["number"]}) 1 ({names:["port"]}) 2 ({names:["record"]}) 66 ({names:["string"]}) 70 undefined bash-3.2$ For example, the type in ./image/MotionDetectorPtDoc.xml is an array: <property name="cog (port)" class="ptolemy.kernel.util.StringAttribute" type="({names:["array.<{'horizontal': 'number', 'vertical': 'number'}>"]}) value="The horizontal and vertical position of the center of gravity of motion, in pixels."> We could eliminate the /** Parse the input, output, or parameter accessor xml and generate MoML. * @param {String} propertyName Either 'port' or 'parameter' * @param elements Array of elements consisting of name, type and description fields. * The type field is expected to be an object. * @return MoML representation of the accessor xml. */ function accessorPropertiesToMoML(propertyName, elements) { var moml = '', _debugging = false; elements .forEach(function (element) { var name = element.name, type = element.type, description = element.description; if (type !== undefined) { type = type.toSource(); } if (_debugging) { console.error(propertyName + " name: " + name); console.error(propertyName + " type: " + type); console.error(propertyName + " description: " + description); } // What we want: // <property name="price (output, number)" class="ptolemy.kernel.util.StringAttribute" type="int" value="The most recent trade price for the stock."> simplerType = xmlEscape(type); if (type !== undefined) { simplerType = simplerType.replace(/^\({names:\["/g, '').replace(/"\]}\)$/g, ''); //console.error("simplerType: type: " + type + ", new simpleType: " + simplerType); } moml += ' <property name="' + xmlEscape(name) + " (" + propertyName + ")" + '" class="ptolemy.kernel.util.StringAttribute" type="' + simplerType + '" value="' + xmlEscape(description) + '">\n' + ' </property>\n'; }); return moml; Now, these are the types: bash-3.2$ find . -name "*PtDoc.xml" | xargs grep type= | awk -F \" '{for(i=1;i<=NF;i++) { if ($i ~ /type=/) {print $(i+1)}}}' | sort |\ uniq -c | sort -nr 70 undefined 66 string 33 int 25 boolean 13 JSON 9 number 4 Object 3 array 2 record 1 port 1 general 1 array.<{'real': 'number', 'imag': 'number'}> 1 array.<{'horizontal': 'number', 'vertical': 'number'}> 1 array.<number> bash-3.2$
|