Skip to content

feat: add remark-directive support for directive syntax - #11

Merged
3w36zj6 merged 4 commits into
textlint:mainfrom
myakura:support-directives
Mar 17, 2026
Merged

3w36zj6 merged 4 commits into
textlint:mainfrom
myakura:support-directives

Conversation

@myakura

@myakura myakura commented Mar 16, 2026 •

Copy link
Copy Markdown
Contributor

Summary

I use directive syntax in my MDX files and want to lint them with textlint. However, the plugin currently throws a parse error when a directive with attributes is encountered — e.g., ::directive[foo]{bar=baz qux=quux}.

The root cause is that remark-mdx treats the {...} part of a directive as an MDX/JSX expression and tries to parse its content as JavaScript. Attribute syntax like {key1=val1 key2=val2} is not valid JavaScript expression, so parsing fails.

Fix

This PR integrates remark-directive into the plugin's remark pipeline. By adding it before remark-mdx processes the AST, directive nodes (textDirective, leafDirective, containerDirective) are recognized and parsed correctly instead of being handed off to the MDX expression parser.

The three directive node types are mapped to custom textlint AST node types (TextDirective, LeafDirective, ContainerDirective), and directive-specific properties (name, attributes, data) are stripped to keep the AST clean.

Test plan

  • Added fixtures for all three directive types (textDirective, leafDirective, containerDirective)
  • All existing tests continue to pass

@myakura

myakura commented Mar 16, 2026

Copy link
Copy Markdown
Contributor Author

hi @3w36zj6 . thanks for working on that plugin.
what do you think of this approach?

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds remark-directive support to the textlint MDX plugin, enabling proper parsing of CommonMark directive syntax (e.g., :abbr[HTML]{title="..."}, ::youtube[...]{}, :::note[...]) that would otherwise cause parse errors when remark-mdx tries to interpret {...} attribute blocks as JavaScript expressions.

Changes:

  • Integrates remark-directive into the unified pipeline and adds three new AST node types (TextDirective, LeafDirective, ContainerDirective) to the syntax map
  • Handles directive node cleanup during AST traversal by stripping remark-directive–specific properties (name, attributes, data)
  • Adds test fixtures for all three directive types

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/parse.ts Adds remark-directive to the remark pipeline and handles directive node type mapping/cleanup during AST traversal
src/mapping/markdown-syntax-map.ts Adds textDirective, leafDirective, and containerDirective mappings to custom textlint AST types
package.json Adds remark-directive as a devDependency
test/fixtures/textDirective/* Test fixture for inline text directive (:abbr[HTML]{...})
test/fixtures/leafDirective/* Test fixture for leaf directive (::youtube[...]{...})
test/fixtures/containerDirective/* Test fixture for container directive (:::note[...])

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/parse.ts Resolved

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds remark-directive support to the textlint MDX plugin, solving parse errors when directive syntax (e.g., ::directive[foo]{bar=baz}) is used in MDX files. The {...} attribute block was previously misinterpreted as an MDX/JSX expression, causing failures.

Changes:

  • Integrates remark-directive into the remark pipeline (before remark-mdx) so directive nodes are parsed correctly
  • Maps three directive node types (textDirective, leafDirective, containerDirective) to custom textlint AST types and strips directive-specific properties
  • Adds test fixtures for all three directive types

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
package.json Adds remark-directive ^4.0.0 as a devDependency (bundled via esbuild)
src/parse.ts Imports remark-directive, adds it to the unified pipeline, and handles directive node type mapping and property stripping
src/mapping/markdown-syntax-map.ts Adds syntax map entries for the three directive types
test/fixtures/textDirective/* Test fixture for inline text directives
test/fixtures/leafDirective/* Test fixture for leaf (block) directives
test/fixtures/containerDirective/* Test fixture for container directives with content

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds remark-directive support to the textlint MDX plugin, allowing directive syntax (:text, ::leaf, :::container) to be parsed correctly instead of failing when remark-mdx tries to interpret {attributes} as JavaScript expressions.

Changes:

  • Integrates remark-directive into the remark pipeline before remark-mdx, and maps directive node types to custom textlint AST types
  • Strips directive-specific properties (name, attributes, data) from directive nodes and data from general nodes to keep the AST clean
  • Adds test fixtures for all three directive types (textDirective, leafDirective, containerDirective)

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/parse.ts Adds remark-directive to the pipeline and handles directive node type mapping and property stripping
src/mapping/markdown-syntax-map.ts Maps the three directive node types to custom AST type strings
package.json Adds remark-directive as a devDependency
test/fixtures/textDirective/* Test fixture for inline text directive
test/fixtures/leafDirective/* Test fixture for leaf directive
test/fixtures/containerDirective/* Test fixture for container directive

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

myakura and others added 3 commits March 17, 2026 11:50
Integrates `remark-directive` to support the `::name[content]{key=val}`
directive syntax (https://talk.commonmark.org/t/generic-directives-plugins-syntax/444).
Maps `textDirective`, `leafDirective`, and `containerDirective` to custom
AST node types (`TextDirective`, `LeafDirective`, `ContainerDirective`) and
strips directive-specific properties (`name`, `attributes`, `data`) to
conform to the textlint AST.

Adds test fixtures for all three directive types.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ensures `remark-directive` processes directive syntax before `remark-mdx`
sees it, making the ordering match the stated intent and providing a
clearer guarantee that directive nodes are recognized first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
remark-directive sets `data: { directiveLabel: true }` on the label
paragraph child of container directives. This internal metadata was
leaking into the textlint AST since the general node-processing branch
did not strip `data`. Now `data` is stripped consistently across all
node-processing branches.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds remark-directive support to the textlint MDX plugin, fixing parse errors when MDX files contain directive syntax (e.g., ::directive[foo]{bar=baz}). The {...} attribute portion of directives was previously misinterpreted as MDX/JSX expressions, causing parsing failures.

Changes:

  • Integrates remark-directive into the remark pipeline (before remark-mdx) and maps directive node types to custom textlint AST types
  • Strips directive-specific properties (name, attributes, data) from directive nodes and data from general nodes to keep the AST clean
  • Adds test fixtures for all three directive types (text, leaf, container)

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/parse.ts Adds remark-directive to the unified pipeline and handles directive node type mapping/property stripping
src/mapping/markdown-syntax-map.ts Adds mappings for textDirective, leafDirective, and containerDirective to PascalCase AST types
package.json Adds remark-directive ^4.0.0 as a devDependency
bun.lock Lockfile updated with remark-directive and its transitive dependencies
test/fixtures/textDirective/* Test fixture for inline text directive
test/fixtures/leafDirective/* Test fixture for leaf (block-level) directive
test/fixtures/containerDirective/* Test fixture for container directive

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@3w36zj6 3w36zj6 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@3w36zj6
3w36zj6 merged commit 379c24e into textlint:main Mar 17, 2026
7 checks passed
@myakura
myakura deleted the support-directives branch March 17, 2026 03:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants