Skip to content

Standardize and robustify dartdoc directive parsing logic #4205

Open

Description

@szakarias

Currently, dartdoc directives are processed using a series of independent regular expressions on the raw documentation string. This "regex soup" approach lacks context awareness and leads to several robustness issues.

This issue tracks the work to unify the parsing logic and implement a standard set of rules for all directives. We should consider the following:

  • Context Awareness (Code Fences):
    Directives could be ignored if they appear inside Markdown code blocks (fenced ``` or inline `).

  • Escaping Support:
    Implement a standard escaping mechanism (e.g., \{@directive ...}) to allow users to document directives literally without executing them.

  • Line-Level Enforcement (for Block Directives):
    Block-level directives could be required to appear on their own line .

  • Strict Argument Parsing:
    The current shared _parseArgs utility (backed by package:args) accidentally allows flag-style arguments (e.g., --lang=dart) in addition to the documented key=value syntax. Decide on the canonical syntax (likely key=value) and update the parser to strictly enforce it.

  • Move Parsing to Analyzer:
    Ideally, the parsing, resolution, and validation logic for these directives should live in the analyzer package. This would enable IDE features like hover previews, auto-completion, and real-time error reporting for directives.

Activity

  1. jonasfj commented on Feb 13, 2026

    @jonasfj
    Member

    I'd add the following considerations aswell:

    • (A) Should dartdoc directives always be on the form {@<directive> <args...> [<option>=...]}.
      Today, most are on this form, except @nodoc. We could allow {@nodoc} and deprecate the old @nodoc.

    • (B) What casing should dartdoc directives have.

      • camelCase, like {@subCategory} and {@canonicalFor}.
      • kebab-stick, like {@inject-html}, {@end-inject-html}, {@end-tool}.
      • monocase, like @nodoc and {@endtemplate}.
    • (C) How should block-style dartdoc directives be terminated.

      • Today, we have {@end-inject-html} and {@endtemplate}
      • We could do {/inject-html} and {/template}?
    • (D) How should arguments and options be passed to dartdoc directives?

      • {@category Assets and Icons}
      • {@subCategory Information displays}
      • {@template template_name}
      • {@macro template_name}
      • {@youtube 320 240 https://www.youtube.com/watch?v=oHg5SJYRHA0}
      • {@animation 320 240 URL [id=ID]}
      • {@canonicalFor some_library.SomeClass}
      • {@example path/to/file.dart [lang=dart] [indent=strip]}
      • {@tool drill --flag --option="value" $INPUT}

    We might have to choose our battles here. Some of these are easy to do.
    But it would be nice if dartdoc directive parsing wasn't specific to the kind of directive being parsed.

  2. srawlins commented on Feb 13, 2026

    @srawlins
    Member

    Move Parsing to Analyzer:
    Ideally, the parsing, resolution, and validation logic for these directives should live in the analyzer package. This would enable IDE features like hover previews, auto-completion, and real-time error reporting for directives.

    There is currently parsing, resolution, and validation in the analyzer for most (all?) of the existing directives. Dartdoc just doesn't use it yet. The parsed results live in the Comment class which has .docDirectives, a list of DocDirectives. This data can live in the ModelNode class, as it is not stored in the analyzer element model, and so needs to be snatched from the AST.

    This can be stored in ModelNodes. See how CommentData there already has CommentDocImportData.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-enhancementA request for a change that isn't a bug

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions