NAME

 src2doc.pl - Extract comments in a source file, with optional fake code generation


SYNOPSIS

 src2doc.pl file.js > file.cpp

or in a pipeline:

 cat file.js | src2doc.pl > file.cpp


DESCRIPTION

This will extract comments from a source file. All comments are extracted, though typically the ones of interest are the javadoc-style ones.

No attempt is made to parse non-comment content in the input file (though any extension module may choose to). This means that this utility could be used with a variety of source programming languages (and the source programming language could use a variety of idioms).

Any input lines which are completely white space are passed through to the output (regardless of whether inside or outside a comment).

This program may be used directly as a Doxygen filter.

Generated Output

In addition to normal comment extraction, it also looks for special comments that start with "//:". These are interpreted as directives for code generation.

The idea is that this can be used to put code in the output that may not even be the same programming language as the input (but may be processed by a javadoc-like program in the output pipeline).

At the moment, the only output programming language supported is C++. (This is in part because C++ is the default language expected by doxygen, and currently doxygen only changes that language expectation according to file suffix, which is awkward in a pipeline/filtering setup. Also, C++ supports more paradigms than Java.)

We do document here what the output would be if we were generating Java.

The supported generation directives fall into these categories:

   namespace
   class
   interface
   global
   enum

Note that in some output languages, not all of these entities are available, but we attempt to make meaningful approximations. For example, C++ has no "interface", and Java has no "enum".

Namespace Directives

 example javascript input:
   /** this namespace does trigonometry */
   //:NSBEGIN Trigonemtry
   var Trigonometry = {};
   /** ratio of circumference to diameter */
   //:NSCONSTANT Number PI = 3.14159
   Trigonometry.PI = 3.14159;
   /** array of figures created */
   //:NSVAR Array figures
   Trigonometry.figures = [];
   /** calculate the area of a circle */
   //:NSFUNCTION Number calculateArea(Number radius)
   Trigonometry.calculateArea = function(radius) {return 2 * Trigonometry.PI * radius};
   //:NSEND
 another (equivalent) example javascript input, with identical comments:
    /** this namespace does trigonometry */
    //:NSBEGIN Trigonemtry
    var Trigonometry = {
      /** ratio of circumference to diameter */
      //:NSCONSTANT Number PI = 3.14159
      PI: 3.14159,
      /** array of figures created */
      //:NSVAR Array figures
      figures: [],
      /** calculate the area of a circle */
      //:NSFUNCTION Number calculateArea(Number radius)
      calculateArea: function(radius) {return 2 * Trigonometry.PI * radius}
    //:NSEND
    };
 example C++ output:
   /** this namespace does trigonometry */
   namespace Trigonometry {
      /** ratio of circumference to diameter */
     const Number PI = 3.14159;
      /** array of figures created */
     Array figures;
      /** calculate the area of a circle */
     Number calculateArea(Number radius) {}
   }
namespace begin - NSBEGIN
   synopsis: //:NSBEGIN $token
   C++: namespace $token {
   java: public class $token {
namespace constant - NSCONSTANT
   synopsis:  //:NSCONSTANT $line
   C++: const $line;
   java: public static final $line;
namespace variable - NSVAR
   synopsis: //:NSVAR $line
   C++: $line;
   java: public static $line;
namespace function - NSFUNCTION
   synopsis: //:NSFUNCTION $line
   C++: $line {}
   java: $line {}
namespace end - NSEND
   synopsis: //:NSEND [$token]
   C++: }
   java: }

Class Directives

 example javascript input (with no javadoc comments):
   //:CLBEGIN Foo extends Bar
   function Foo() {
      Bar.call(this);
   }
   Foo.prototype = new Bar();
   Foo.prototype.constructor = Foo;
   //:CLCONSTANT int CLASSICAL_PI = 3
   Foo.CLASSICAL_PI = 3;
   //:CLEND Foo
 example C++ output:
   class Foo : public Bar {public:
     static const int CLASSICAL_PI = 3;
   };
class begin - CLBEGIN
    synopsis: //:CLBEGIN $classname [extends $superclass] [implements $interface1, $interface2]
    C++:  class $classname [: public $superclass, public $interface1, public $interface2] { public:
    java: public $classname [extends $superclass] [implements $interface1, $interface2] {
class begin - CLABEGIN
Begin an abstract base class. For C++ output, this is the same as CLBEGIN (since C++ automatically determines that an ABC is one with a pure virtual method). For Java output, an extra 'abstract' is added to the class declaration.

class constant - CLCONSTANT
    synopsis: //:CLCONSTANT $line
    C++: static const $line;
    java: public static final $line;
class instance variable - CLIVAR
    synopsis: //:CLIVAR  $line
    C++:  $line;
class static variable - CLCVAR
    synopsis: //:CLCVAR $line
    C++:  static $line;
class instance method - CLIMETHOD
    synopsis: //:CLIMETHOD $line
    C++: $line {}
class constructor method - CLCONSTRUCT
    synopsis: //:CLCONSTRUCT $line
    C++: $line {}
class static method - CLCMETHOD
    synopsis: //:CLCMETHOD $line
    C++: static $line {}
class abstract method - CLAMETHOD
For C++ output, this the same as IFMETHOD. For Java output, it is different because interface methods and class abstract methods are declared differently.
    synopsis: //:CLAMETHOD $line
    C++: virtual $line = 0;
    java: abstract $line;

Interface Directives

interface begin - IFBEGIN
    synopsis: //:IFBEGIN $token
    C++:  class $token { public:
    java: interface $token {
interface constant - IFCONSTANT
    synopsis: //:IFCONSTANT $line
    C++: static const $line;
    java: static final $line;
interface method - IFMETHOD
    synopsis: //:IFMETHOD $line
    C++: virtual $line = 0;
    java: $line;
interface end - IFEND
    synopsis: //:IFEND
    C++:  };
    java: }

Global Directives

global constant - GLCONSTANT
    synopsis: //:GLCONSTANT $line
    C++: const $line;
    java: public static final $line;
global variable - GLVAR
    synopsis: //:GLVAR $line
    C++: $line;
    java: $line;
global function - GLFUNCTION
    synopsis: //:GLFUNCTION $line
    C++: $line {}

Enum Directives

enum begin - ENUMBEGIN
     synopsis: //:ENUMBEGIN $typename
     C++:  enum $typename {
enum value - ENUMVAL
     synopsis:  //:ENUMVAL $valname $value $comment
     C++: $valname [= $value], /**< $comment */
enum end - ENUMEND
     synopsis: //:ENUMEND
     C++: };

Extension Modules

The utility will attempt to load a module named 'src2doc_extend.pm' (from the perl include path, augmented by the directory this program is in). If available, it must define a global variable $CMD_HOOK which is a sub taking parameters ($lang, $cmd, $args). When called, it can read any number of input lines. It should return false if it does not handle the command.


TODO

Currently only C++ output is implemented.


SEE ALSO

src2code.pl

The opposite side of this utility is src2code.pl, which extracts just the code, not the comments.

Literate Programming

Purists will realize that these utilities do not actually constitute literate programming. Knuth's "weave" (get documentation) and "tangle" (get code) support re-ordering of code, and in general presumes a more intimate relationship between documentation and executable artifacts.

js2doxy.pl

As part of his JsUnit project, Jorg Schaible implemented a perl program that converts javascript source code to C++ suitable for doxygen processing: js2doxy.pl, http://jsunit.berlios.de/internal.html .

It generates C++ not from parsed comments (as we do), but instead by attempting to parse the javascript source code itself. If you write your code following his conventions, that can be more convenient. However, it makes the tool javascript-specific, and limits the javascript idioms that can be used. The tool also limits the set of javadoc tags that can be used. It is also not set up to be used directly as a doxygen filter (src2doc.pl is). Instead it supplies a largely superfluous 'jsdoc' wrapper.

JSDoc

An apparently abandoned sourceforge project at http://jsdoc.sourceforge.net/ it consists of 1-page perl program that attempts to emulate javadoc.

JSdoc

Located at http://www.stud.tu-ilmenau.de/~thla-in/scripts/JSdoc/ and is unrelated to the sourceforge JSDoc project. It seems not to be released, just described.

jsdoc.js

There is a basic javascript program that like the perl jsdoc attempts to implement javadoc: http://lxr.mozilla.org/mozilla/source/js/rhino/examples/jsdoc.js


AUTHOR

Copyright 2003, Mark D. Anderson, mda@discerning.com.

This is free software; you can redistribute it and/or modify it under the same terms as Perl itself.