Frans Slothouber and Petteri Kettunen
Copyright 1994-2004 Frans Slothouber, Petteri Kettunen, Jacco van Weert
翻译:李若
这里有一个好消息:这样的愿望是现在可以实现的了!现在,已经有了一些专门帮助我 们进行这样的工作开发工具了,比如 KDE 开发组开发的 kdoc、还有一个叫做 doxygen 的工具,都是这个方面的好帮手。据我所知,kdoc 和 doxygen 支持很多不同的程序设 计语言,但是都不支持 Fortran。进一步的好消息是:RoboDoc 也是一个这样的工具, 并且能够支持Fortran,在做科学与工程计算界中,很多开发者喜爱使用 Fortran 进行 开发,现在在 Fortran 中我们也能够使用这样方便的开发方式了。
我们下面一步一步的来说明上面使用步骤。
/****f* financial.library/StealMoney * NAME * StealMoney -- Steal money from the Federal Reserve Bank. (V77) * SYNOPSIS * error = StealMoney( userName, amount, destAccount, falseTrail ) * FUNCTION * Transfer money from the Federal Reserve Bank into the * specified interest-earning checking account. No records of * the transaction will be retained. * INPUTS * userName - name to make the transaction under. Popular * favorites include "Ronald Reagan" and * "Mohamar Quadaffi". * amount - Number of dollars to transfer (in thousands). * destAccount - A filled-in AccountSpec structure detailing the * destination account (see financial/accounts.h). * If NULL, a second Great Depression will be * triggered. * falseTrail - If the DA_FALSETRAIL bit is set in the * destAccount, a falseTrail structure must be * provided. * RESULT * error - zero for success, else an error code is returned * (see financial/errors.h). * EXAMPLE * Federal regulations prohibit a demonstration of this function. * NOTES * Do not run on Tuesdays! * BUGS * Before V88, this function would occasionally print the * address and home phone number of the caller on local police * 976 terminals. We are confident that this problem has been * resolved. * SEE ALSO * CreateAccountSpec(),security.device/SCMD_DESTROY_EVIDENCE, * financial/misc.h ****** * You can use this space for remarks that should not be included * in the documentation. */一个头部包含有三个不同的部分:一个起始标志、一些条目和一个结束标志。 上面这个例子中,起始标志为:
****f* financial.library/StealMoneyRoboDoc 读到这个标志,就知道一个文档的头部开始了,并且它指定了随后的 这段文档的名字为 StealMoney ,这段文档是作为文档段 financial.library 的一部分的。这段文档的类型标识为 f ,表示这是一个函数的文档。RoboDoc 要求您必须提供用一个斜杠 / 分开的文档段名称对,用来将文档按树型结构 组织起来。在 段 部分,我们还会仔细讨论。
结束标志为
******用来表示一个头部的结束。
每个条目由一个条目名开头,后面的部分是该条目的内容,例如
* FUNCTION * Transfer money from the Federal Reserve Bank into the * specified interest-earning checking account. No records of * the transaction will be retained.这里条目名称为 FUNCTION,条目的每一行都是由一个注释标志开始, 这个例子里是一个 * 号。
上面的这个例子是一个 C 程序的例子,RoboDoc 支持很多种的程序语言。 下面列举的是所有的 RoboDoc 支持的注释标志:
/**** C, C++ * ***///**** C++ // //***(**** Pascal, Modula-2 * *** *){**** Pascal * *** *};**** M68K assembler ; ;******* M68K assembler, COBOL * ***C **** Fortran C C ***REM **** BASIC REM * REM ***%**** LaTeX, TeX, Postscript % %***#**** Tcl/Tk # #***--**** Occam -- --***<!--**** HTML Code * ***<!---**** HTML Code * ***|**** GNU Assembler | |***$!**** DCL $! $!***'**** Visual Basic, Lotus script '* '***.**** DB/C .* .***!!**** FORTRAN 90 !! !!***!**** FORTRAN 90 ! !***这些注释标志还可以混合使用,并不仅仅限于上面所列举的这些程序 设计语言。所以如果您使用的程序设计语言使用的是 # 作为注释标志 的话,您可以使用 Tcl/Tk 的注释标志,写下面形式的头部:#****f* Foo/Bar # FUNCTION # Bar snarfs the Foo input and mangles it. Given the right settings # it might also do a bit of snu snu. #***
RoboDoc 定义了一系列的头部类型标识,您不一定要使用它们,但是使用正确 的头部类型标识可以使得文档被更好的分类组织起来。头部类型标识告诉了 RoboDoc 您是在为什么对象写文档,这样 RoboDoc 就能够产生更加有用的文档 索引。
头部类型表示是使用一到两个字符标识的。RoboDoc 会将头部其实标志后的第 四个 * 号后面读取它,所以
#****f是一个正确的头部类型 标识,而
#**f**就不对。
使用单个字符标识的头部类型如下表
标识符 | 标识符指定的类型 |
---|---|
c | Header for a class. |
d | Header for a constant (from define). |
f | Header for a function. |
h | Header for a module in a project. |
m | Header for a method. |
s | Header for a structure. |
t | Header for a types. |
u | Header for a unittest. |
v | Header for a variable. |
* | Generic header for every thing else. |
如果使用两个字符来指定,那么第一个字符必须是 i
,第二个字符
是上表中的任一字符。这将会产生一个内部的头部类型。内部的头部
类型是比较特殊的,能够用来隐藏一些头部,只有当您指定将这些头部
进行展开的时候,它们才会被展开。这样您就可以写一些给内部的开发
者使用,而不想给用户看到的文档。比如
被指定为内部头的文档缺省的将不会被产生出来。您可以通过使用选项
--internal将它们产生出来,而且通过使用选项
--internalonly您可以单独将内部文档产生出来。
通过修改全局配置文件 robodoc.rc,您还可以自己定义头部类型,这样 您就可以自由的对任何东西进行操作了。
在缺省情况下,RoboDoc 会识别下面的这些条目:
条目名 | 条目的内容 |
---|---|
NAME | Item name plus a short description. |
COPYRIGHT | Who own the copyright : "(c) |
SYNOPSIS, USAGE | How to use it. |
FUNCTION, DESCRIPTION, PURPOSE | What does it do. |
AUTHOR | Who wrote it. |
CREATION DATE | When did the work start. |
MODIFICATION HISTORY, HISTORY | Who has done which changes and when. |
INPUTS, ARGUMENTS, OPTIONS, PARAMETERS, SWITCHES | What can we feed into it. |
OUTPUT, SIDE EFFECTS | What output is made. |
RESULT, RETURN VALUE | What do we get returned. |
EXAMPLE | A clear example of the items use. |
NOTES | Any annotations |
DIAGNOSTICS | Diagnostic output |
WARNINGS, ERRORS | Warning and error-messages. |
BUGS | Known bugs. |
TODO, IDEAS | What to implement next and ideas. |
PORTABILITY | Where does it come from, where will it work. |
SEE ALSO | References to other functions, man pages, other documentation. |
METHODS, NEW METHODS | OOP methods. |
ATTRIBUTES, NEW ATTRIBUTES | OOP attributes |
TAGS | Tag-item description. |
COMMANDS | Command description. |
DERIVED FROM | OOP super class. |
DERIVED BY | OOP sub class. |
USES, CHILDREN | What modules are used by this one. |
USED BY, PARENTS | Which modules do use this one. |
SOURCE | Source code inclusion. |
一个开发项目的源码常常是树型结构的,项目包含着几个应用,每个应用又有几个模块, 每个模块都有一些函数或者几个子模块。RoboDoc 能帮您将文档按照这样的树型结构进行 组织,实现的方式就是在头部中就进行这样的结构指定。
比如,您准备开发一个项目,目的是要实现一种新的语言,假设这种语言的名字为 D , 在这个项目中,有三个应用程序,一个预处理器、一个编译器和一个连接器,在编译器 中又包含两个模块,分别是语法分析器和目标产生器,在语法分析器中又有好些个函数。
下面的三个头部就能够显示这样的树型结构:
#****h* D-Language/Compiler # FUNCTION # The compiler takes a preprocessed source file and # turns it into an object file. #*** #****h* D-Language/Linker # FUNCTION # The linker module contains functions that scan a # object file and build the executable. #*** #****h* Compiler/Parser # FUNCTION # The parser module contains functions that scan a # preprocessed source file and build the syntax tree. #*** #****f* Parser/ReadToken # FUNCTION # ReadToken reads the next token from the input # file. #***当您在产生文档的时候使用了选项
--section的时候, RoboDoc 就会根据这些信息产生出树型结构的文档。比如在 HTML 形式的 文档中, 段 会使用根据级别的 < H1 >, < H2 >, < H3 > 进行标识,产生的文档 样子会如下所示:
1. D-Language/Compiler 1.1 Compiler/Parser 1.1.1 Parser/ReadToken 2. D-Language/Linker
现在,假设我们已经使用了上面描述的格式准备了源代码,就要用 RoboDoc 来产生文档了。首先我们要做一些抉择,;-)
robodoc {--src source directory} {--doc document directory} {--multidoc} [other options]还有一个很有用的参数是
--index
,这会针对每种头部类型产生一系列的索引文件。
robodoc {--src source directory} {--doc document file without extension} {--singledoc} [other options]
robodoc {--src source file} {--doc document file} {--singlefile} [other options]
输出格式 | 得到该格式文档使用的选项 |
---|---|
HTML | --html |
RTF | --rtf |
LaTEX | --latex |
XML DocBook | --dbxml |
选项 | 功能 |
---|---|
-c | Show the copyright message. |
--cmode | Use ANSI C grammar in SOURCE items and use this for some syntax highlighting (HTML only). |
--css | Use to content of the specified file to create the robodoc.css. The content of the file is copied into robodoc.css. |
--dbxml | Generate documentation in XML DocBook format. |
--doc | Define the path to the documentation directory or documentation file. A path can start with ./ or /. Do not use .. in the path. The documentation directory can be a subdirectory of the source directory, or be parallel to the source directory, however they can not be equal. So --src ./sources together with --doc ./documents is fine, but --src ./Everything together with --doc ./Everything is not. |
--folds | Use fold marks to split a big document into smaller ones. |
--html | Generate documentation in HTML format. |
--internal | Also include headers marked internal. |
--internalonly | Only include headers marked internal. |
--index | Also create a master index file. |
--lock | Per source file robodoc locks on the first headermarker it finds and will recognize only that particular headermarker for the remaining part of the file. In addition it locks on the first remark marker in each header and will recognize only that particular remark marker for the remaining part of the header. |
--multidoc | Generate one document per source file, and copy the directory hierarchy. |
--nosource | Do not include the SOURCE items. |
--nodesc | Do not scan any subdirectories, scan only the top level directory of the source tree. |
--rc | Use the specified file instead of robodoc.rc. |
--rtf | Generate documentation in RTF format. |
--sections | Create sections based on the module hierarchy. |
--singledoc | Define the documentation directory or documentation file. |
--singlefile | Generate a single document from a single file |
--src | Define the path for the source directory or source file. The path can start with ./ or /. Do not use .. in the path. |
--tabsize | Lets you specify the tabsize. |
--toc | Add a table of contents. This works in multidoc mode as well as singledoc mode. |
--latex | Generate documentation in LaTEX format. |
--tell | ROBODoc tells you what steps it is taking. |
# Example robodoc.rc # items: NAME SYNOPSIS INPUTS OUTPUTS SIDE EFFECTS HISTORY BUGS ignore items: HISTORY BUGS options: --src ./source --doc ./doc --html --multidoc --index --tabsize 8 headertypes: e "Makefile Entries" robo_mk_entries x "System Tests" robo_syst_tests q Queries robo_queries ignore files: README CVS *.bak *~ test_*整个配置文件分成几个部分,每个部分由一个名称开头,后面紧跟一个冒号。 在这个例子中有五个部分: items, ignore items, options, header types 和 ignore files 。 每个部分有一系列的值,每个值的前面至少有一个空格。
如果您没有给 items 部分,那么 RoboDoc 会使用缺省的条名称。如果您指定 了 items 部分,那么只有列出来的这些条名称会被识别,不过 SOURCE 是一个 例外,它总是能被识别。
--rc
。这样,您可以
如下例一样方便的产生不同格式的文档:
robodoc --rc htmlsingle.rc robodoc --rc rtfsingle.rc robodoc --rc htmlmulti.rc
robodoc --src ./Source --doc ./HDocs --multidoc --index --html
robodoc --src ./Source --doc api --singledoc --rtf --sections缺省情况下产生的 RTF 文档非常朴素,您可以通过在一个 Word 一样 的编辑器中处理一下。
robodoc --src ./Source --doc api --singledoc --latex --sections latex api.tex latex api.tex makeindex api.idx latex api.tex xdvi api.dvi您可以从这个 DVI 文件中的到您想要的 PS 或者 PDF 格式的文档。
robodoc --src ./Source --doc api --singledoc --dbxml --sections xmlto html api.xml
/****m* pipe/pipetest * NAME * pipetest * NAME * Simple header to show "piping" features in items. * EXAMPLE * Only "pipes" which match selected output style are picked up. * |html <CENTER>This will be included in <B>HTML</B> output.</CENTER> * |latex \centerline{This will be included in \LaTeX output} * Space is mandatory following the pipe marker. The following is not a * valid pipe marker: * |html<B>Moi!</B> * You should see an equation on the following line: * |html y = x^2 (sorry, plain HTML is not very powerful) * |latex \centerline{$y = x^2$} * How does this look like? * Here comes a multi-line equation array: * |latex \begin{eqnarray} * |latex \frac{\partial u}{\partial \tau} & = & D_u {\nabla}^2 u + * |latex \frac{1}{\epsilon} * |latex \left ( \hat{u}-{\hat{u}}^2-f\, {v} \, \frac{\hat{u}-q}{\hat{u}+q} * |latex \right ) \; , \label{diffspot:1} \\ * |latex \frac{\partial v}{\partial \tau} & = & \hat{u}-v \; , * |latex \label{diffspot:2} \\ * |latex \frac{\partial r}{\partial \tau} & = & D_r {\nabla}^2 r \; . * |latex \label{diffspAot:3} * |latex \end{eqnarray} * |html <I>TODO: write this in html</I> * End of the example. ****** */
使用语法 转换成的 HTML 的形式 href:body <a href="body">body</A> file:/body <a href="file:/body">file:/body</A> mailto:body <a href="mailto:body">body</A> http://body <a href="http://body">http://body</A> image:body <image src<nop>="body">
RoboDoc 会为每个头部产生一个可以用于这样的目的的 Anchor,其名称是该 头部的名称和模块名通过一些变换得到的,比如头部 Analyser/RB_ToBeAdded 会被转换为 Analyser2fRB5fToBeAdded 。其中斜杠和下划线都转换成为了 它们的 16 进制的 ASCII 码。