dart-use-doc-examples

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Using Examples in Dartdoc

在Dartdoc中使用示例

Contents

目录

When writing documentation that requires multi-line code examples, you should generally extract those examples into standalone
.dart
files and inject them using the
{@example}
directive, rather than writing them inline inside
///
comments. This ensures the examples can be analyzed, linted, and executed.
当编写需要多行代码示例的文档时,通常应将这些示例提取到独立的
.dart
文件中,并使用
{@example}
指令注入,而不是直接写在
///
注释内。这样可以确保示例代码能够被分析、检查和执行。

1. The
{@example}
Directive

1.
{@example}
指令

The
{@example}
directive parses an external file and resolves it into a fenced Markdown code block in the generated documentation.
Syntax:
{@example <path>[#<region>] [lang=LANGUAGE] [indent=keep|strip]}
  • <path>
    : The path to the file. A leading
    /
    evaluates from the package root. Otherwise, it is relative to the current file.
  • lang
    : The language for the markdown fence. Auto-detected from the file extension (e.g.,
    dart
    ), but can be explicit (e.g.,
    lang=text
    ).
  • indent
    :
    strip
    (default) aggressively removes shared leading indentation from the code block.
Bad (Inline Markdown):
dart
/// Makes a client service request to the backend.
///
/// ```dart
/// final client = Client();
/// client.send();
/// ```
Good (External File Injection):
dart
/// Makes a client service request to the backend.
///
/// {@example /example/client_request.dart}
{@example}
指令会解析外部文件,并将其转换为生成文档中的Markdown代码块。
语法:
{@example <path>[#<region>] [lang=LANGUAGE] [indent=keep|strip]}
  • <path>
    :文件路径。以
    /
    开头的路径从包根目录开始解析,否则相对于当前文件所在目录。
  • lang
    :Markdown代码块的语言。会根据文件扩展名自动检测(例如
    dart
    ),也可以显式指定(例如
    lang=text
    )。
  • indent
    strip
    (默认值)会主动移除代码块中共享的前导缩进。
  • 不推荐(内联Markdown):
dart
/// 向后端发起客户端服务请求。
///
/// ```dart
/// final client = Client();
/// client.send();
/// ```
  • 推荐(外部文件注入):
dart
/// 向后端发起客户端服务请求。
///
/// {@example /example/client_request.dart}

2. Using Regions

2. 使用代码区域

Often, an external example file contains imports, setup, or
void main()
wrappers that you don't want to show in the documentation. You can extract a specific block of code by appending
#<region>
to the
{@example}
directive path, and wrapping that code with
#region
and
#endregion
comments in the target file.
Dart Code (e.g.,
/example/client.dart
):
dart
import 'package:http/http.dart';

void main() {
  // #region request_snippet
  final client = Client();
  client.send();
  // #endregion request_snippet
}
Dartdoc Usage:
dart
/// Connects the client to the server and sends a request.
///
/// {@example /example/client.dart#request_snippet}
通常,外部示例文件包含导入语句、初始化代码或
void main()
包装器,这些内容你可能不想在文档中展示。你可以通过在
{@example}
指令的路径后追加
#<region>
,并在目标文件中用
#region
#endregion
注释包裹指定代码块,来提取特定的代码片段。
Dart代码(例如
/example/client.dart
):
dart
import 'package:http/http.dart';

void main() {
  // #region request_snippet
  final client = Client();
  client.send();
  // #endregion request_snippet
}
Dartdoc用法:
dart
/// 将客户端连接到服务器并发送请求。
///
/// {@example /example/client.dart#request_snippet}

3. Hiding Setup Code

3. 隐藏初始化代码

If there is a specific line of code within your extracted region that is necessary for the compiler/analyzer to pass but irrelevant (or distracting) for the documentation reader, append
#hide
to that line.
Dart Code:
dart
final mockServer = startServer(); // #hide
final data = await fetch(mockServer.url);
In the generated documentation, only
final data = await fetch(mockServer.url);
will be visible. The line with
#hide
is completely dropped.
如果提取的代码区域中有某一行代码对编译器/分析器来说是必需的,但对文档读者来说无关紧要(或容易分散注意力),可以在该行末尾追加
#hide
Dart代码:
dart
final mockServer = startServer(); // #hide
final data = await fetch(mockServer.url);
在生成的文档中,只有
final data = await fetch(mockServer.url);
会显示出来。带有
#hide
的行将被完全移除。

4. Marker Filtering Rules

4. 标记过滤规则

When working with
#hide
,
#region
, and
#endregion
markers, you must follow these two technical constraints:
  • Region Required: The markers are only processed and stripped when you target a specific region suffix (e.g.,
    {@example file.dart#region_name}
    ). If you inject an entire file without a region suffix, the file is embedded exactly as it appears in the source, including any marker text like
    // #hide
    .
  • Format Agnosticism: The marker system is completely format-agnostic. Dartdoc simply runs a regex to strip lines containing the marker strings, meaning it works identically in non-Dart files (e.g., inside YAML comments
    # #region
    or HTML comments
    <!-- #region -->
    ).
使用
#hide
#region
#endregion
标记时,必须遵循以下两个技术约束:
  • 必须指定区域: 只有当你指定了特定的区域后缀(例如
    {@example file.dart#region_name}
    )时,标记才会被处理和移除。如果不添加区域后缀直接注入整个文件,文件会完全按照源文件的样子嵌入,包括
    // #hide
    等标记文本。
  • 格式无关性: 标记系统完全与格式无关。Dartdoc只是通过正则表达式移除包含标记字符串的行,这意味着它在非Dart文件中的工作方式完全相同(例如YAML注释中的
    # #region
    或HTML注释中的
    <!-- #region -->
    )。

5. Placement and Path Resolution

5. 放置位置与路径解析

The
{@example}
directive is a block-level directive. It must appear on its own line prefixed with
///
. Its internal
<path>
parser follows strict URI reference rules:
  • Package-Root Paths (
    /
    )
    : Paths starting with a leading slash automatically resolve directly to the root of the Dart package. Use this when the destination file is deep.
    • Example:
      {@example /test/data/sample.txt}
      exactly maps to
      <package_root>/test/data/sample.txt
      .
  • Relative Paths: Paths without a leading slash resolve relative to the directory of the file containing the doc comment.
    • Example:
      {@example ../utils/demo.dart}
  • Boundary Enforcement: Using
    ..
    segments to traverse upward is perfectly acceptable, but dartdoc natively stops directory traversal at the package root (it will never escape the package).
  • No Network URLs: Absolute URIs (e.g., starting with
    https://
    ) are strictly not supported. The example file must sit natively somewhere in the local filesystem.
  • Separators & Encoding: Because dartdoc resolves the path as a URI, you must always use forward slashes (
    /
    ) as folder separators (even on Windows). You can natively include URI-encoded characters (like
    %20
    for spaces) as permitted by URI reference rules.
{@example}
指令是块级指令,必须单独出现在一行并以
///
开头。其内部的
<path>
解析器遵循严格的URI引用规则:
  • 包根路径(
    /
    ):
    以斜杠开头的路径会直接解析到Dart包的根目录。当目标文件位置较深时使用此方式。
    • 示例:
      {@example /test/data/sample.txt}
      精确对应
      <package_root>/test/data/sample.txt
  • 相对路径: 不以斜杠开头的路径相对于包含文档注释的文件所在目录解析。
    • 示例:
      {@example ../utils/demo.dart}
  • 边界限制: 使用
    ..
    片段向上遍历目录是允许的,但dartdoc会在包根目录处停止目录遍历(永远不会超出包的范围)。
  • 不支持网络URL: 绝对URI(例如以
    https://
    开头)严格不被支持。示例文件必须位于本地文件系统中。
  • 分隔符与编码: 由于dartdoc将路径作为URI解析,你必须始终使用斜杠(
    /
    )作为文件夹分隔符(即使在Windows系统中)。你可以原生包含URI编码字符(例如用
    %20
    表示空格),这符合URI引用规则。

6. Verification

6. 验证

After injecting examples:
  1. Run
    dart analyze
    on the example files to ensure the hidden setup code compiles.
  2. (Optional) Run
    dart doc
    to verify that dartdoc successfully parsed the directive without throwing a "Failed to read file" or "missing region" warning.
注入示例后:
  1. 对示例文件运行
    dart analyze
    ,确保隐藏的初始化代码可以编译通过。
  2. (可选)运行
    dart doc
    ,验证dartdoc是否成功解析指令,没有抛出“无法读取文件”或“区域缺失”的警告。