`
sofire
  • 浏览: 146169 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Ddoc文档注释学习笔记

阅读更多
Ddoc学习笔记

ddoc的英文文档在:
http://www.digitalmars.com/d/ddoc.html

D语言可以在代码中嵌入文档注释(以下称文档)。
它不仅仅是注释,而且还是一段可供阅读的文档。
这样做的好处是,在开发、维护代码的时候,就能同时维护文档。
对于程序员,写文档比写代码还痛苦;写注释倒是一个大家还可以接受的事情。
在写代码的时候,顺便把文档写了,也许能改善一下文档不全的问题。
个人挺喜欢这样方式的。至于太团队项目开发中有没有效果。
因为还没有实践过,不敢乱做评判。


文档有以下几个步骤处理:
  1. 词法 文档注释被 附加的记号 标识..
  2. 解析 文档注释 被关联到 特殊的定义和组合
  3. 段落 每个文档注释 被 分解到一个段落的序列
  4. 处理特定的节.
  5. 非特殊的段落完成后高亮显示.
  6. 合并模块中的所有段落.
  7. 在最终结果执行宏文本替换.


下面按照这个顺序来展开;

推荐先熟悉文档的写法,一般编译方法,常用节;和学习使用Candydoc;
其他内容可以后期在看;


文档的语法

从一个最简单的程序开始吧:

/**
 * 这个一个Ddoc文档例子
 * 
 * Authors: Dehong Liu
 * Date:    2007年8月13日
 */

void main()
{
}

注意注释符号 /**,和单词Authors/Date。

编译这个文件(a1.d),并且生成文档doc1/a1.html
dmd -Dddoc1 a1.d			# -DdXXX 指定文档生成路径为XXX

用浏览器打开这个html文件,看起来像下面这样【见附件 doc1/a1.html】:
a1

void main();
    这个一个Ddoc文档例子

    Authors:
    Dehong Liu

    Date:
    2007年8月13日 

-------------------------------------------------------------	
Page generated by Ddoc. 

看着很奇怪?这只是个开始。至少明白了哪些写法会变成文档,表现形式和怎么生成。

现在一个个开始解释。
文档有下面三种写法:
 
 /** ...   */       	/ 后面两个*	
 /++ ...   +/       	/ 后面两个+
 ///					三个 /	


下面有一个完整的文档写法例子(a2.d):
/// 这是一个行文档注释

/** 这也是 */

/++ 同样 +/

/**
   这是一个摘要文档
 */

/**
 * 开头的* 不是文档的一部分
 */

/*********************************
   在 /** 后面的连续的*,
   不是文档的一部分
 */

/++
   这也是一个摘要文档
 +/

/++
 + 开头的+ 不是文档的一部分
 +/

/+++++++++++++++++++++++++++++++++
   在 /++ 后面的连续的+,
   不是文档的一部分
   上面的斜杠是中文符号,避免语法错误

   换行:注意上面的空行
 +/

/*********** 前面连续的*号不是,这部分*****是文档,后面的又不是  *****************/

module a2;



输出的html结果【见附件 doc1/a2.html】:
a2
这是一个行文档注释

这也是

同样



这是一个摘要文档



开头的* 不是文档的一部分



在 /** 后面的连续的*, 不是文档的一部分



这也是一个摘要文档



开头的+ 不是文档的一部分



在 /++ 后面的连续的+, 不是文档的一部分 上面的斜杠是中文符号,避免语法错误

换行:注意上面的空行

前面连续的*号不是,这部分*****是文档,后面的又不是 



文档和申明关联

每一个文档都和一个申明(declaration)相关联:
引用

1. 如果某单行文档的最左边是空格,它就和下面的申明关联
2. 多个关联到同一个申明的文档会被连接在一起
3. 没有关联到申明的文档会被忽略
4. 在module申明前的所有文档会被应用到整个模块
5. 如果文档出现在申明的右边,则关联到它
6. 如果文档只是ditto,则应用上一个申明的文档
7. 如果一个申明没有文档,则不会出现在html输出中,要出现,可以写一个空的文档,如 ///


看一个例子吧:
/**
 * 整个模块的文档
 */

module a3;

int a;  /// a;的文档,b没有文档
int b;

/** c和d的文档 */
/** 再添加些c和d的文档的文档 */
int c;
/** ditto */
int d;

/** e和f的文档 */ int e;
int f;	/// ditto

/** g的文档 */
int g; /// 在添加点g的文档

/// C和D的文档
class C
{
    int x;    /// C.x的文档

    /** C.y 和 C.z的文档 */
    int y;
    int z;    /// ditto
}

/// ditto
class D
{
}

int h; // 只有注释,没有文档,不会出现在html中

// 下面是空文档
int j; /// 

/// 被忽略的文档


看起来像这样【见附件 doc1/a3.html】
a3
整个模块的文档

int a;
    a;的文档,b没有文档

int c;
int d;
    c和d的文档

    再添加些c和d的文档的文档

int e;
int f;
    e和f的文档

int g;
    g的文档

    在添加点g的文档

class C;
class D;
    C和D的文档

    int x;
        C.x的文档

    int y;
    int z;
        C.y 和 C.z的文档

int j;



文档的节

a1.d例子中的Authors / Date 就是节(Sections)。
节由 "非空格字符" + ":" 组成,其中标识符部分叫节名,它不区分大小写

概要(Summary):
第一个节就是概要,它没有节名;
它是第一个段落,遇到空行或者节名结束;
可以把概要写成多行,但写成一行比较好
概要节是可选的

描述(Description):
第二个没有名字的节 是描述
遇到一个节名或者到文档的结束

给个例子(a4.d):
/***********************************
 * 这是一个概要(Brief summary)
 * 描述myfunch函数的使用;这两行形成一个概要节
 *
 * 描述节的第一个段落
 *
 * 还是描述节:
 * 可以写更多内容
 */

void myfunc() { }

html输出【见附件 doc1/a4.html】:
void myfunc();
    这是一个概要(Brief summary) 描述myfunch函数的使用;这两行形成一个概要节

    描述节的第一个段落

    还是描述节: 可以写更多内容 



标准节

有一些预定义好了的节,看看它们的意思:
  • Authors: 列出作者名字
  • Bugs: 列出已知BUG
  • Date: 列出当前修订的时间,应当是 std.date 能解析的形式
  • Deprecated: 做 "抗议"标记(?弃用标记)--最好给出理由和纠正的方法
  • Examples: 例子
  • History: 修订历史
  • License: 版权申明
  • Returns: 解释函数的返回值;如果返回void,就不要写在文档中了
  • See_Also: 列出相关符号,或者URL链接
  • Standards: 如果申明涉及到某个标准,在此描述
  • Throws: 列出在哪些环境下会抛出异常
  • Version: 指定当前申明的版本号
  • See_Also: 列出相关符号,或者链接
  • See_Also: 列出相关符号,或者链接


特殊节:一些有特殊含义和语法的节
  • Copyright: 版权申明。如果是在module申明中,该节会被COPYRIGHT宏替换;
  • Params: 函数的参数描述文档;
  • "标识符 =' 开始一个新的参数描述;它可以跨越多行
  • Macros: 和Params节有类似的语法;它是一系列 NAME=value 组成
  • NAME 是宏名,VALUE是要替换成的文字


全部列出来看看:
/** Copyright: Public Domain */

module a5;

/**
 * Authors: Melvin D. Nerd, melvin@mailinator.com
 *
 * Bugs: Doesn't work for negative values.
 *
 * Date: March 14, 2003
 */

void foo1() {}

/**
 * Deprecated: superseded by function bar().
 */

deprecated void foo2() {  }

/**
 * Examples:
 * --------------------
 * writefln("3"); // writes '3' to stdout
 * --------------------
 *
 * History:
 *  V1 is initial version
 *
 *  V2 added feature X
 *
 * License: use freely for any purpose
 */

void bar() { }

/**
 * Read the file.
 * Returns: The contents of the file.
 */

void[] readFile(char[] filename) { return "filename"; }

/**
 * See_Also:
 *    foo, bar, http://www.digitalmars.com/d/phobos/index.html
 *
 * Standards: Conforms to DSPEC-1234
 *
 * Throws: WriteException on failure.
 *
 * Version: 1.6a
 */

void writeFile(char[] filename) {  }

// 特殊节

/***********************************
 * foo does this.
 * Params:
 *  x = is for this
 *      and not for that
 *  y = is for that
 */

void foo(int x, int y)
{
}

/**
 * Macros:
 *  FOO =   now is the time for
 *      all good men
 *  BAR =   bar
 *  MAGENTA =   <font color=magenta></font>
 *  COPYRIGHT = 版权归热爱地球的火星人所有
 */

/**
 * Foo: $(FOO)
 * Bar: $(BAR)
 * MAGENTA: $(MAGENTA)
 * Copyright: Public Domain 
 */
void foo3() {   }


输出效果是【见附件doc1/a5.html】:
a5

void foo1();
    Authors:
    Melvin D. Nerd, melvin@mailinator.com

    BUGS:
    Doesn't work for negative values.

    Date:
    March 14, 2003

deprecated void foo2();
    Deprecated:
    superseded by function bar().

void bar();
    Examples:

     writefln("3"); // writes '3' to stdout



    History:
    V1 is initial version

    V2 added feature X

    License:
    use freely for any purpose

void[] readFile(char[] filename);
    Read the file.

    Returns:
    The contents of the file.

void writeFile(char[] filename);
    See Also:
    foo, bar, http://www.digitalmars.com/d/phobos/index.html

    Standards:
    Conforms to DSPEC-1234

    Throws:
    WriteException on failure.

    Version:
    1.6a

void foo(int x, int y);
    foo does this.

    Params:
    int x 	is for this and not for that
    int y 	is for that

void foo3();
    Foo:
    now is the time for all good men

    Bar:
    bar

    MAGENTA:
    <font color=magenta></font>

    Copyright:
    Public Domain

Page generated by Ddoc. 版权归热爱地球的火星人所有 


上面的例子都还好理解,把不容易理解的说说:
/** Copyright: Public Domain */ 在module申明前和后的效果不一样;
前者的效果在哪里?看页面的最后一行

代码的文档是这么写的:
* Examples:  
* --------------------  
* writefln("3"); // writes '3' to stdout  
* --------------------  

代码的上下有一条分割线:至少三个连字符(-)

文档的高亮处理

内嵌注释 Embedded Comments
不懂

内嵌代码 Embedded Code
上面已经演示了

内嵌的HTML Embedded HTML
内嵌的HTML代码不会被转译,直接输出给html文件
虽然如此,基于某些原因(我没看懂),还是最好不要用html
/** Example of embedded HTML:
 *   
 *      <li> <a href="http://www.digitalmars.com">Digital Mars</a> </li>
 *      <li> <a href="http://www.classicempire.com">Empire</a> </li>
 */


强调 Emphasis
函数参数等标识符会被以斜体,粗体,超链接等形式强调处理;具体形式文档没有说

特殊符号Character Entities
< > & 有特殊含义,如果要使用这3个符号,换成相应的:&lt; &gt; &amp;
以下情况除外:在代码节中;不是立即跟一个 # 或 字母

文档的宏

宏来自于下面这些地方,并按照特定步骤处理:
  1. 预定义宏
  2. sc.ini配置文件中的DDOCFILE项指定的文件
  3. 命令行指定的*.ddoc文件
  4. Ddoc运行时产生的定义,如BODY,TITLE
  5. 文件中的宏节


宏主要用在对文档格式的自定义上。
通过修改宏,能自定义HTML输出格式。

CandyDoc的使用

dmd默认的格式很简单,可以使用CandyDoc来美化文档格式和增强功能。
使用方法很简单:(.ddoc是宏文件的后缀)
下载CandyDoc程序
主页:http://www.dsource.org/projects/helix/wiki/CandyDoc
下载:http://svn.dsource.org/projects/helix/downloads/candydoc-0.80.zip

假设要编译: a5.d  doc2/candydoc
dmd -c -Dddoc2 a5.d doc2/candydoc/*.ddoc

生成的a5.html文件在 doc2/目录下,和candydoc一个目录,如果不是同一目录,会显示不正常;

candydoc有2个.ddoc文件:candy.ddoc  modules.ddoc
如果要定义样式,在candy.ddoc中定义,一般不改;
modules.ddoc 要修改成自己的模块,默认是:
MODULES = 
    $(MODULE helix.basic)
    $(MODULE helix.color)
    $(MODULE helix.config)
    $(MODULE helix.linalgebra)


以上面的5个程序为例:
MODULES =
    $(MODULE a.a1)
    $(MODULE a.a2)
    $(MODULE a.a3)
    $(MODULE a.a4)
    $(MODULE a.a5)

编译之:
dmd -c -Dddoc2 a1 a2 a3 a4 a5.d doc2/candydoc/*.ddoc


如果要用Candydoc替换默认的文档格式,这么做:
修改dmd.conf文件,添加一行:
DDOCFILE=candy.ddoc
看起来像这样
[Environment]
DFLAGS=-I%@P%/../src/phobos -L-L%@P%/../lib -L-L/usr/lib -L-L/usr/local/lib -version=Phobos
DDOCFILE=candy.ddoc


上面的配置只写了candy.ddoc文件,没有写module.ddoc。所以编译的时候要添加module.ddoc,这样做很不爽;
我的办法是自己写一个.ddoc文件--proj.ddoc
把candydoc.ddoc和 module.ddoc两个文件合并在一起

[模块部分的导航要求所有的html都在一个目录下,这点还没有仔细研究,回头再写]

注意,如果没有效果,检查:
1. Linux是修改dmd.conf文件;Windows是修改sc.ini文件;不要弄错了
2. dmd.conf 可能在多个地方:/etc 或 dmd命令所在目录等
3. candy.doc是相对于当前目录而已,不是dmd.conf文件;请按照实际情况设定路径


文档用起来还算简单,开始会不习惯,慢慢就习惯了。


  • d_ddoc.zip (498.1 KB)
  • 描述: 包括:文章中的源代码,html输出结果,candidoc-0.80压缩包和ddoc英文文档
  • 下载次数: 31
分享到:
评论
6 楼 tomqyp 2007-08-15  
5 楼 sofire 2007-08-14  
转换成其他语言?是说用汉字吗?
4 楼 Colorful 2007-08-14  

Good work.
不知道上面的定义的节名能不能自动转换成其他语言,我估计很玄,呵呵。
3 楼 oldrev 2007-08-14  
2 楼 qiezi 2007-08-14  
漂亮啊
1 楼 sofire 2007-08-14  
请教:UBB标签编辑器能不能用表格?

相关推荐

    DDoc.js:用 JS 生成 word 文档

    使用 DDoc.js,你可以生成一份 word 文档,在此文档中可以添加多种元素并设置多种属性。 可添加的元素 段落 超链接 标题 表格 列表 图片 可设置的属性 font:字体,比如:"Microsoft YaHei UI" fontSize:字体大小,...

    BOOTLOADER.Ddoc.rar

    总的来说,BOOTLOADER.Ddoc很可能是一份关于引导加载器技术的详细文档,对于理解计算机启动机制、学习Bootloader的开发和管理,以及解决相关问题都有很高的参考价值。如果你对这方面感兴趣,解压并阅读这份文档将能...

    ddoc:用C编写的Web流量计费程序

    介绍曾经获得过具有多个域的服务器。 客户询问哪个域受到的... 总而言之,ddoc可帮助您在最短的时间内确定哪个域名受到的攻击最多,哪个URL受到的请求最多,哪个IP对该域名的攻击最多。 到目前为止,ddoc可在RedHat /

    DDoS攻击原理及防御方法

    DDoS攻击原理及防御方法

    dlang.org:dlang.org网站的页面,D编程语言的所在地

    DDoc能够从源代码中的特殊注释中提取文档,生成易于阅读的HTML格式文档。dlang.org网站的大部分文档就是通过DDoc生成的,这使得维护和更新文档变得非常方便。通过参与dlang.org的源码,你可以学习如何使用DDoc为自己...

    tree-sitter-d

    保姆-d 该存储库为托管了一个语法。... 虽然使用 DDoc 文档的规范方法是指定一个带有自定义宏定义的文件并使用它运行 DMD 的 DDoc 宏处理器,但这里使用的方法是实现一个(这也有助于验证我们对 DDoc 语法的假设)

    ab.signal:用 D 编程语言编写的观察者设计模式的实现

    异常信号使用信号和槽实现观察者设计模式的简单明了。 它是用 D 编程语言和 D 编程语言(D 记住 D2)编写的。...文件化您可以在“ddoc”子文件夹中找到自动生成的 ddoc 文档。联系人斯坦尼斯拉夫·

    Laravel开发-laravel-tdd-docs

    `laravel-tdd-docs-master` 包含的文档可能涵盖了以上所有内容,为 Laravel 开发者提供了关于如何有效实施 TDD 的详细指南。通过深入学习和实践,开发者将能够利用 TDD 提升代码质量和项目可靠性,从而在 Laravel ...

    数据字典自动生成文档

    数据字典自动生成文档是一种高效的方法,用于整理和呈现数据库中的结构化信息。在这个场景中,我们关注的是一个使用PHP开发的工具,它能够自动读取数据库内容,并将其以可视化的形式展示在网页上,同时支持导出为...

    高手对付DDoS攻击的绝招

    从拒绝服务攻击诞生到现在已经有了很多的发展,从最初的简单Dos到现在的DdoS。那么什么是Dos和DdoS呢?DoS是一种利用单台计算机的攻击 方式。而DdoS是一种基于DoS的特殊形式的拒绝服务攻击,是一种分布、协作的大规模...

    couchdb-jsonselect:使用jsonselect来处理ouchdb中的文档

    它使访问复杂的JSON文档中的数据变得容易。 感觉就像CSS。 有关查询的更多详细信息,请参见 docs。 安装 npm i couchdb-jsonselect -g 将jsonselect添加到CouchDB数据库 couchdb-jsonselect ...

    domino xpages 开发 获取富域的html

    首先,从视图 `view` 中获取第一个文档 `doc`,然后调用 `wrapDocument` 包装成 `DominoDocument` 对象 `ddoc`。接下来,通过 `ddoc.getRichTextItem("Body")` 获取名为 "Body" 的 RichText 项,并使用 `getHTML()` ...

    gl3n:OpenGL Math for D(不适用于D的glm)

    Gl3n gl3n提供了使用...文献资料gl3n使用ddoc进行文档编制。 您可以使用Makefile轻松构建它: make ddoc但是,当然也有可用。安装在Linux上,您可以使用以下命令自行构建gl3n: makemake install# archlinux structu

    c语言word版(谭浩强)

    《C语言Word版》是针对初学者和有一定基础的学习者提供的C语言教程,采用Word文档格式,便于阅读和打印。这个资源可能包含了谭浩强教授的C语言经典教材的电子版,他是中国计算机教育领域的一位重要人物,以其深入浅...

    和利时/Hollysys_MACS硬件手册_FM131-D.doc

    和利时/Hollysys_MACS硬件手册_FM131-Ddoc,和利时/Hollysys_MACS硬件手册_FM131-D

    使用OpenCascade实现三维视图

    - `OCCVIewer3DView.cpp`和`OCCVIewer3DDoc.cpp`:这两个文件可能是实现视图类和文档类的源代码,视图类负责绘制和用户交互,而文档类通常用于存储数据模型。 - `AISDialogs.cpp`:AIS是OpenCascade中的Application ...

Global site tag (gtag.js) - Google Analytics