Synopsis is designed to be flexible in how you comment your code. All three stages of Synopsis deal with comments: the parser extracts them, the linker processes them, and the formatter formats them.
The parser is where the comments are extracted, and is the least flexible because the parsers use existing parser components (Python, IDL) or are hard coded in C++. Each parser looks for comments before declarations, and attaches them to the following declaration. The general rule is that comments must be immediately before the declaration, and there must be no blank lines between the comments and the start of the declaration. See below for an exception to this rule for C++.
The following is okay:
// A comment /* Another comment * more text */ // Another comment void the_declaration();
The following are not okay; the comments will be ignored:
// A comment void the_declaration(); void the_declaration() // A comment { some_code(); }
The exception for C++ is when the option 'extract_tails' (-Wp,-t on the command line) is used. In this case, all comments from the originating source file are included, but the ones which would not usually be included are flagged as 'suspect'. Comments that occurred after all declarations in a block (file, class, or namespace) are attached to a 'dummy' declaration, which must be removed in the Linker stage using one of the 'dummy' or 'prev' comment processors. The former removes the dummy declarations and suspect comments, the latter does the same but checks for special syntax first, as shown:
int i; //< A trailing comment enum Foo { Foo_A, //< A trailing comment for A Foo_B //< A trailing comment for B attached to a dummy declaration };//< A trailing comment for Foo void func() { } //< A trailing comment for func attached to a dummy declaration (if func was at the end of the file after preprocessing)
The '<' character at the start of the comment (after removing the prefix, // in this case) tells the 'prev' comment processor to move the comment to the previous declaration. As you can see, this also applies to enumerators. The comment can be anywhere after the declaration - on the same line, the next line, or even further down.
The Linker deals with comments in the Comments linker operation. The Comments operation uses the config option 'comment_processors' to find a list of Comment Processors to use, one after the other, on the whole AST. Each processor typically traverses the whole AST looking for comments, and performing operations on them.
The first comment processor in the list should always be one which strips away the comment characters, such as "//", "//.", "/* .. */", "//!", etc. After that, there are a number of processors you can use, for things like extracting JavaDoc style tags (@return, @param, etc), dealing with suspect comments and dummy declarations for C++ code, and deciding on a summary for the comment. The processor 'group' is a processor that uses comments to organise declarations into 'groups', within a class or namespace.
The comment processors are all written in Python, and you can specify your own in a config file to perform custom processing, or to deal with unusual comment styles.
See the chapter on the Linker for more information on this.
Formatting comments is mostly concerned with dealing with the styling (which uses CSS in HTML, so you can change it from the stylesheet withing writing any code), and processing the tags found in the comments. The tags are already extracted by the linker (if you use the 'javatags' comment processor), so it's just a matter of formatting them in HTML or whatever. The only complexity is the @see tag, which has to try and find the referenced declaration to make a URL link.
See the chapter on the formatter you want to use for more information on comments (if there is any special support).