Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package rumdl for openSUSE:Factory checked 
in at 2026-05-30 22:58:40
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rumdl (Old)
 and      /work/SRC/openSUSE:Factory/.rumdl.new.1937 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rumdl"

Sat May 30 22:58:40 2026 rev:71 rq:1356007 version:0.2.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/rumdl/rumdl.changes      2026-05-29 
18:14:27.824767901 +0200
+++ /work/SRC/openSUSE:Factory/.rumdl.new.1937/rumdl.changes    2026-05-30 
23:01:30.524586075 +0200
@@ -1,0 +2,14 @@
+Sat May 30 06:47:15 UTC 2026 - Johannes Kastl 
<[email protected]>
+
+- Update to version 0.2.4:
+  * Fixed
+    - md060: apply aligned-delimiter when a table auto-compacts
+      past max-width (663f4ba)
+    - md034: don't flag URL arguments of MyST colon directives
+      (d55ed20)
+    - embedded: gate markdown code block formatting behind
+      code-block-tools opt-in (bd23ad1)
+    - md046: treat MyST directive body as directive, not indented
+      code block (060bae2)
+
+-------------------------------------------------------------------

Old:
----
  rumdl-0.2.3.obscpio

New:
----
  rumdl-0.2.4.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ rumdl.spec ++++++
--- /var/tmp/diff_new_pack.EWBysp/_old  2026-05-30 23:01:34.532750845 +0200
+++ /var/tmp/diff_new_pack.EWBysp/_new  2026-05-30 23:01:34.536751009 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           rumdl
-Version:        0.2.3
+Version:        0.2.4
 Release:        0
 Summary:        Markdown Linter written in Rust
 License:        MIT

++++++ _service ++++++
--- /var/tmp/diff_new_pack.EWBysp/_old  2026-05-30 23:01:34.588753147 +0200
+++ /var/tmp/diff_new_pack.EWBysp/_new  2026-05-30 23:01:34.600753640 +0200
@@ -3,7 +3,7 @@
     <param name="url">https://github.com/rvben/rumdl.git</param>
     <param name="scm">git</param>
     <param name="submodules">enable</param>
-    <param name="revision">v0.2.3</param>
+    <param name="revision">v0.2.4</param>
     <param name="match-tag">v*.*.*</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="versionrewrite-pattern">v(.*)</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.EWBysp/_old  2026-05-30 23:01:34.636755120 +0200
+++ /var/tmp/diff_new_pack.EWBysp/_new  2026-05-30 23:01:34.640755285 +0200
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param name="url">https://github.com/rvben/rumdl.git</param>
-              <param 
name="changesrevision">a5a0c2d5d6d631393c5ca773872742726d4fa4db</param></service></servicedata>
+              <param 
name="changesrevision">a0d57ac276a15c3697a27cfe53f46e7742c341b9</param></service></servicedata>
 (No newline at EOF)
 

++++++ rumdl-0.2.3.obscpio -> rumdl-0.2.4.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/CHANGELOG.md new/rumdl-0.2.4/CHANGELOG.md
--- old/rumdl-0.2.3/CHANGELOG.md        2026-05-27 21:28:16.000000000 +0200
+++ new/rumdl-0.2.4/CHANGELOG.md        2026-05-29 21:11:01.000000000 +0200
@@ -43,6 +43,16 @@
 
 
 
+
+## [0.2.4](https://github.com/rvben/rumdl/compare/v0.2.3...v0.2.4) - 2026-05-29
+
+### Fixed
+
+- **md060**: apply aligned-delimiter when a table auto-compacts past max-width 
([663f4ba](https://github.com/rvben/rumdl/commit/663f4babbb24102bd80924c2d31c9bd7005c61e7))
+- **md034**: don't flag URL arguments of MyST colon directives 
([d55ed20](https://github.com/rvben/rumdl/commit/d55ed20eab6a5b7d17f53976af53c019e4d3b0c1))
+- **embedded**: gate markdown code block formatting behind code-block-tools 
opt-in 
([bd23ad1](https://github.com/rvben/rumdl/commit/bd23ad15e02499100f9d76ed24e9aae16b8750b6))
+- **md046**: treat MyST directive body as directive, not indented code block 
([060bae2](https://github.com/rvben/rumdl/commit/060bae2292c7e25805abc1d86de709252c607641))
+
 ## [0.2.3](https://github.com/rvben/rumdl/compare/v0.2.2...v0.2.3) - 2026-05-27
 
 ### Fixed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/Cargo.lock new/rumdl-0.2.4/Cargo.lock
--- old/rumdl-0.2.3/Cargo.lock  2026-05-27 21:28:16.000000000 +0200
+++ new/rumdl-0.2.4/Cargo.lock  2026-05-29 21:11:01.000000000 +0200
@@ -2274,7 +2274,7 @@
 
 [[package]]
 name = "rumdl"
-version = "0.2.3"
+version = "0.2.4"
 dependencies = [
  "anyhow",
  "assert_cmd",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/Cargo.toml new/rumdl-0.2.4/Cargo.toml
--- old/rumdl-0.2.3/Cargo.toml  2026-05-27 21:28:16.000000000 +0200
+++ new/rumdl-0.2.4/Cargo.toml  2026-05-29 21:11:01.000000000 +0200
@@ -1,6 +1,6 @@
 [package]
 name = "rumdl"
-version = "0.2.3"
+version = "0.2.4"
 edition = "2024"
 rust-version = "1.94.0"
 description = "A fast Markdown linter written in Rust (Ru(st) MarkDown Linter)"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/README.md new/rumdl-0.2.4/README.md
--- old/rumdl-0.2.3/README.md   2026-05-27 21:28:16.000000000 +0200
+++ new/rumdl-0.2.4/README.md   2026-05-29 21:11:01.000000000 +0200
@@ -206,7 +206,7 @@
 mise install rumdl
 
 # Use a specific version for the project
-mise use [email protected]
+mise use [email protected]
 ```
 
 ### Using Nix (macOS/Linux)
@@ -405,7 +405,7 @@
 ```yaml
 repos:
   - repo: https://github.com/rvben/rumdl-pre-commit
-    rev: v0.2.3
+    rev: v0.2.4
     hooks:
       - id: rumdl      # Lint only (fails on issues)
       - id: rumdl-fmt  # Auto-format and fail if issues remain
@@ -427,7 +427,7 @@
 ```yaml
 repos:
   - repo: https://github.com/rvben/rumdl-pre-commit
-    rev: v0.2.3
+    rev: v0.2.4
     hooks:
       - id: rumdl
         args: [--no-exclude]  # Disable all exclude patterns
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/docs/global-settings.md 
new/rumdl-0.2.4/docs/global-settings.md
--- old/rumdl-0.2.3/docs/global-settings.md     2026-05-27 21:28:16.000000000 
+0200
+++ new/rumdl-0.2.4/docs/global-settings.md     2026-05-29 21:11:01.000000000 
+0200
@@ -1342,7 +1342,7 @@
 
 ```yaml
 - repo: https://github.com/rvben/rumdl-pre-commit
-  rev: v0.2.3
+  rev: v0.2.4
   hooks:
     - id: rumdl
       args: [--config=.rumdl.toml]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/npm/cli-darwin-arm64/package.json 
new/rumdl-0.2.4/npm/cli-darwin-arm64/package.json
--- old/rumdl-0.2.3/npm/cli-darwin-arm64/package.json   2026-05-27 
21:28:16.000000000 +0200
+++ new/rumdl-0.2.4/npm/cli-darwin-arm64/package.json   2026-05-29 
21:11:01.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@rumdl/cli-darwin-arm64",
-  "version": "0.2.3",
+  "version": "0.2.4",
   "description": "rumdl binary for macOS ARM64 (Apple Silicon)",
   "license": "MIT",
   "repository": {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/npm/cli-darwin-x64/package.json 
new/rumdl-0.2.4/npm/cli-darwin-x64/package.json
--- old/rumdl-0.2.3/npm/cli-darwin-x64/package.json     2026-05-27 
21:28:16.000000000 +0200
+++ new/rumdl-0.2.4/npm/cli-darwin-x64/package.json     2026-05-29 
21:11:01.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@rumdl/cli-darwin-x64",
-  "version": "0.2.3",
+  "version": "0.2.4",
   "description": "rumdl binary for macOS x64 (Intel)",
   "license": "MIT",
   "repository": {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/npm/cli-linux-arm64/package.json 
new/rumdl-0.2.4/npm/cli-linux-arm64/package.json
--- old/rumdl-0.2.3/npm/cli-linux-arm64/package.json    2026-05-27 
21:28:16.000000000 +0200
+++ new/rumdl-0.2.4/npm/cli-linux-arm64/package.json    2026-05-29 
21:11:01.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@rumdl/cli-linux-arm64",
-  "version": "0.2.3",
+  "version": "0.2.4",
   "description": "rumdl binary for Linux ARM64 (glibc)",
   "license": "MIT",
   "repository": {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/npm/cli-linux-arm64-musl/package.json 
new/rumdl-0.2.4/npm/cli-linux-arm64-musl/package.json
--- old/rumdl-0.2.3/npm/cli-linux-arm64-musl/package.json       2026-05-27 
21:28:16.000000000 +0200
+++ new/rumdl-0.2.4/npm/cli-linux-arm64-musl/package.json       2026-05-29 
21:11:01.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@rumdl/cli-linux-arm64-musl",
-  "version": "0.2.3",
+  "version": "0.2.4",
   "description": "rumdl binary for Linux ARM64 (musl/Alpine)",
   "license": "MIT",
   "repository": {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/npm/cli-linux-x64/package.json 
new/rumdl-0.2.4/npm/cli-linux-x64/package.json
--- old/rumdl-0.2.3/npm/cli-linux-x64/package.json      2026-05-27 
21:28:16.000000000 +0200
+++ new/rumdl-0.2.4/npm/cli-linux-x64/package.json      2026-05-29 
21:11:01.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@rumdl/cli-linux-x64",
-  "version": "0.2.3",
+  "version": "0.2.4",
   "description": "rumdl binary for Linux x64 (glibc)",
   "license": "MIT",
   "repository": {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/npm/cli-linux-x64-musl/package.json 
new/rumdl-0.2.4/npm/cli-linux-x64-musl/package.json
--- old/rumdl-0.2.3/npm/cli-linux-x64-musl/package.json 2026-05-27 
21:28:16.000000000 +0200
+++ new/rumdl-0.2.4/npm/cli-linux-x64-musl/package.json 2026-05-29 
21:11:01.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@rumdl/cli-linux-x64-musl",
-  "version": "0.2.3",
+  "version": "0.2.4",
   "description": "rumdl binary for Linux x64 (musl/Alpine)",
   "license": "MIT",
   "repository": {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/npm/cli-win32-x64/package.json 
new/rumdl-0.2.4/npm/cli-win32-x64/package.json
--- old/rumdl-0.2.3/npm/cli-win32-x64/package.json      2026-05-27 
21:28:16.000000000 +0200
+++ new/rumdl-0.2.4/npm/cli-win32-x64/package.json      2026-05-29 
21:11:01.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@rumdl/cli-win32-x64",
-  "version": "0.2.3",
+  "version": "0.2.4",
   "description": "rumdl binary for Windows x64",
   "license": "MIT",
   "repository": {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/npm/rumdl/package.json 
new/rumdl-0.2.4/npm/rumdl/package.json
--- old/rumdl-0.2.3/npm/rumdl/package.json      2026-05-27 21:28:16.000000000 
+0200
+++ new/rumdl-0.2.4/npm/rumdl/package.json      2026-05-29 21:11:01.000000000 
+0200
@@ -1,6 +1,6 @@
 {
   "name": "rumdl",
-  "version": "0.2.3",
+  "version": "0.2.4",
   "description": "A fast Markdown linter written in Rust",
   "license": "MIT",
   "repository": {
@@ -33,12 +33,12 @@
     "node": ">=18.0.0"
   },
   "optionalDependencies": {
-    "@rumdl/cli-darwin-x64": "0.2.3",
-    "@rumdl/cli-darwin-arm64": "0.2.3",
-    "@rumdl/cli-linux-x64": "0.2.3",
-    "@rumdl/cli-linux-arm64": "0.2.3",
-    "@rumdl/cli-linux-x64-musl": "0.2.3",
-    "@rumdl/cli-linux-arm64-musl": "0.2.3",
-    "@rumdl/cli-win32-x64": "0.2.3"
+    "@rumdl/cli-darwin-x64": "0.2.4",
+    "@rumdl/cli-darwin-arm64": "0.2.4",
+    "@rumdl/cli-linux-x64": "0.2.4",
+    "@rumdl/cli-linux-arm64": "0.2.4",
+    "@rumdl/cli-linux-x64-musl": "0.2.4",
+    "@rumdl/cli-linux-arm64-musl": "0.2.4",
+    "@rumdl/cli-win32-x64": "0.2.4"
   }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/src/file_processor/processing.rs 
new/rumdl-0.2.4/src/file_processor/processing.rs
--- old/rumdl-0.2.3/src/file_processor/processing.rs    2026-05-27 
21:28:16.000000000 +0200
+++ new/rumdl-0.2.4/src/file_processor/processing.rs    2026-05-29 
21:11:01.000000000 +0200
@@ -229,10 +229,15 @@
             Some(Path::new(file_path)),
         );
 
-        // Format embedded markdown blocks (recursive formatting)
-        // Use filtered_rules to respect per-file-ignores for embedded content
-        let embedded_formatted = format_embedded_markdown_blocks(&mut content, 
&filtered_rules, config);
-        warnings_fixed += embedded_formatted;
+        // Format embedded markdown blocks (recursive formatting). This is 
opt-in
+        // via code-block-tools (`[code-block-tools.languages.markdown] lint = 
["rumdl"]`)
+        // and gated identically to the check path, so `--fix` never rewrites 
the
+        // contents of a markdown code block that `check` did not report on.
+        // filtered_rules respects per-file-ignores for the embedded content.
+        if should_lint_embedded_markdown(&config.code_block_tools) {
+            let embedded_formatted = format_embedded_markdown_blocks(&mut 
content, &filtered_rules, config);
+            warnings_fixed += embedded_formatted;
+        }
 
         // Format doc comments in Rust files
         if Path::new(file_path).extension().is_some_and(|ext| ext == "rs") {
@@ -304,10 +309,15 @@
             Some(Path::new(file_path)),
         );
 
-        // Format embedded markdown blocks (recursive formatting)
-        // Use filtered_rules to respect per-file-ignores for embedded content
-        let embedded_formatted = format_embedded_markdown_blocks(&mut content, 
&filtered_rules, config);
-        warnings_fixed += embedded_formatted;
+        // Format embedded markdown blocks (recursive formatting). This is 
opt-in
+        // via code-block-tools (`[code-block-tools.languages.markdown] lint = 
["rumdl"]`)
+        // and gated identically to the check path, so `--fix` never rewrites 
the
+        // contents of a markdown code block that `check` did not report on.
+        // filtered_rules respects per-file-ignores for the embedded content.
+        if should_lint_embedded_markdown(&config.code_block_tools) {
+            let embedded_formatted = format_embedded_markdown_blocks(&mut 
content, &filtered_rules, config);
+            warnings_fixed += embedded_formatted;
+        }
 
         // Format doc comments in Rust files
         if Path::new(file_path).extension().is_some_and(|ext| ext == "rs") {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/src/lint_context/flavor_detection.rs 
new/rumdl-0.2.4/src/lint_context/flavor_detection.rs
--- old/rumdl-0.2.3/src/lint_context/flavor_detection.rs        2026-05-27 
21:28:16.000000000 +0200
+++ new/rumdl-0.2.4/src/lint_context/flavor_detection.rs        2026-05-29 
21:11:01.000000000 +0200
@@ -1017,7 +1017,7 @@
 /// Check if a line is a MyST colon directive opener.
 /// Pattern: 0-3 leading spaces, 3+ colons, immediately followed by `{name}`.
 /// Returns the colon count if it's an opener, None otherwise.
-fn myst_colon_directive_opener(line: &str) -> Option<usize> {
+pub(super) fn myst_colon_directive_opener(line: &str) -> Option<usize> {
     let spaces = count_leading_spaces(line);
     if spaces > 3 {
         return None;
@@ -1278,11 +1278,15 @@
                 }
             }
         } else {
-            // Code-bearing directive: mark opener/closer as directive but 
keep in_code_block
-            if end_line_idx > 0
-                && let Some(closer_line) = lines.get_mut(end_line_idx - 1)
-            {
-                closer_line.in_myst_directive = true;
+            // Code-bearing directive (e.g. `{eval-rst}`, `{code-block}`): the 
body is
+            // opaque code, so keep `in_code_block` set on the body lines. 
Mark every
+            // line of the directive (opener, body, closer) as 
`in_myst_directive` so
+            // rules that skip directive structure (MD046, MD048) treat the 
whole block
+            // as one directive. Marking only the fences left the indented 
body lines
+            // looking like a standalone indented code block to those rules.
+            let body_end = end_line_idx.min(lines.len());
+            for line in &mut lines[start_line_idx..body_end] {
+                line.in_myst_directive = true;
             }
         }
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/src/lint_context/mod.rs 
new/rumdl-0.2.4/src/lint_context/mod.rs
--- old/rumdl-0.2.3/src/lint_context/mod.rs     2026-05-27 21:28:16.000000000 
+0200
+++ new/rumdl-0.2.4/src/lint_context/mod.rs     2026-05-29 21:11:01.000000000 
+0200
@@ -984,6 +984,22 @@
         Self::binary_search_ranges(&self.myst_comment_ranges, byte_pos)
     }
 
+    /// Check if a line (1-indexed) is a MyST colon-fence directive opener 
(`:::{name} ...`).
+    ///
+    /// The text after `{name}` on an opener is the directive's argument (an 
opaque
+    /// path, URL, or label), not markdown prose. Rules that reformat prose 
should
+    /// skip these lines. Returns false for non-MyST flavors and for directive 
body
+    /// or closer lines.
+    pub fn is_myst_colon_directive_opener_line(&self, line_num: usize) -> bool 
{
+        if !self.flavor.supports_myst_directives() {
+            return false;
+        }
+        self.lines.get(line_num.wrapping_sub(1)).is_some_and(|info| {
+            info.in_myst_directive
+                && 
flavor_detection::myst_colon_directive_opener(info.content(self.content)).is_some()
+        })
+    }
+
     /// Get HTML tags - computed lazily on first access
     pub fn html_tags(&self) -> Arc<Vec<HtmlTag>> {
         Arc::clone(self.html_tags_cache.get_or_init(|| {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/src/rules/md034_no_bare_urls.rs 
new/rumdl-0.2.4/src/rules/md034_no_bare_urls.rs
--- old/rumdl-0.2.3/src/rules/md034_no_bare_urls.rs     2026-05-27 
21:28:16.000000000 +0200
+++ new/rumdl-0.2.4/src/rules/md034_no_bare_urls.rs     2026-05-29 
21:11:01.000000000 +0200
@@ -497,6 +497,15 @@
             .skip_mdx_comments()
             .skip_obsidian_comments()
         {
+            // Skip MyST colon-fence directive openers (`:::{name} <arg>`). 
The text
+            // after the directive name is an opaque argument (a URL, path, or 
label),
+            // not markdown prose, so a bare URL there must not be wrapped in 
angle
+            // brackets. Directive body lines are not openers, so they fall 
through to
+            // `check_line` and are linted as usual.
+            if ctx.is_myst_colon_directive_opener_line(line.line_num) {
+                continue;
+            }
+
             let mut line_warnings =
                 self.check_line(line.content, ctx, line.line_num, &code_spans, 
&mut buffers, line_index);
 
@@ -732,4 +741,105 @@
             "URL in backticks after a fenced code block inside MDX must not be 
flagged: {result:?}"
         );
     }
+
+    /// Issue #642: a URL given as the argument of a MyST colon-fence directive
+    /// (`:::{name} <url>`) is the directive's opaque argument, not markdown 
prose,
+    /// and must not be wrapped in angle brackets.
+    #[test]
+    fn test_myst_colon_directive_argument_url_not_flagged() {
+        use crate::config::MarkdownFlavor;
+        use crate::lint_context::LintContext;
+        let rule = MD034NoBareUrls;
+        let content = "\
+:::{anywidget} 
https://cdn.jsdelivr.net/npm/[email protected]/dist/repo-review-anywidget.mjs
+{
+  \"deps\": [\"repo-review~=1.1.0\"]
+}
+:::
+";
+        let ctx = LintContext::new(content, MarkdownFlavor::MyST, None);
+        let result = rule.check(&ctx).unwrap();
+        assert!(
+            result.is_empty(),
+            "URL argument on a MyST colon directive opener must not be 
flagged: {result:?}"
+        );
+    }
+
+    /// A nested MyST colon directive opener also carries an opaque argument.
+    #[test]
+    fn test_myst_nested_colon_directive_argument_url_not_flagged() {
+        use crate::config::MarkdownFlavor;
+        use crate::lint_context::LintContext;
+        let rule = MD034NoBareUrls;
+        let content = "\
+::::{grid}
+:::{card} https://example.com/card-target
+Some caption.
+:::
+::::
+";
+        let ctx = LintContext::new(content, MarkdownFlavor::MyST, None);
+        let result = rule.check(&ctx).unwrap();
+        assert!(
+            result.is_empty(),
+            "URL argument on a nested MyST colon directive opener must not be 
flagged: {result:?}"
+        );
+    }
+
+    /// A bare URL in the *body* of a content directive (e.g. `{note}`) is 
genuine
+    /// prose and must still be flagged. The opener exemption must not leak to 
the body.
+    #[test]
+    fn test_myst_directive_body_url_still_flagged() {
+        use crate::config::MarkdownFlavor;
+        use crate::lint_context::LintContext;
+        let rule = MD034NoBareUrls;
+        let content = "\
+:::{note}
+See https://example.com/docs for more details.
+:::
+";
+        let ctx = LintContext::new(content, MarkdownFlavor::MyST, None);
+        let result = rule.check(&ctx).unwrap();
+        assert_eq!(
+            result.len(),
+            1,
+            "Bare URL in a MyST directive body must still be flagged: 
{result:?}"
+        );
+    }
+
+    /// An unclosed colon directive (no terminating `:::`) still has its opener
+    /// argument treated as opaque: the URL must not be flagged.
+    #[test]
+    fn test_myst_unclosed_colon_directive_argument_url_not_flagged() {
+        use crate::config::MarkdownFlavor;
+        use crate::lint_context::LintContext;
+        let rule = MD034NoBareUrls;
+        let content = "\
+:::{anywidget} https://example.com/widget.mjs
+Some trailing content with no closing fence.
+";
+        let ctx = LintContext::new(content, MarkdownFlavor::MyST, None);
+        let result = rule.check(&ctx).unwrap();
+        assert!(
+            result.is_empty(),
+            "URL argument on an unclosed MyST colon directive opener must not 
be flagged: {result:?}"
+        );
+    }
+
+    /// The colon-directive exemption is MyST-specific: under the Standard 
flavor a
+    /// `:::{...}` line is ordinary text and a bare URL on it must still be 
flagged.
+    #[test]
+    fn test_colon_directive_url_flagged_in_standard_flavor() {
+        use crate::config::MarkdownFlavor;
+        use crate::lint_context::LintContext;
+        let rule = MD034NoBareUrls;
+        let content = ":::{anywidget} https://example.com/widget.mjs\n";;
+        let ctx = LintContext::new(content, MarkdownFlavor::Standard, None);
+        let result = rule.check(&ctx).unwrap();
+        assert_eq!(
+            result.len(),
+            1,
+            "Under Standard flavor a bare URL on a `:::` line must still be 
flagged: {result:?}"
+        );
+    }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/rumdl-0.2.3/src/rules/md060_table_format/md060_config.rs 
new/rumdl-0.2.4/src/rules/md060_table_format/md060_config.rs
--- old/rumdl-0.2.3/src/rules/md060_table_format/md060_config.rs        
2026-05-27 21:28:16.000000000 +0200
+++ new/rumdl-0.2.4/src/rules/md060_table_format/md060_config.rs        
2026-05-29 21:11:01.000000000 +0200
@@ -166,7 +166,9 @@
     ///   body rows remain compact/tight and are not padded.
     ///
     /// No effect under `aligned` / `aligned-no-space` (those styles already
-    /// align the delimiter row by construction).
+    /// align the delimiter row by construction), except when a table exceeds
+    /// `max-width` and auto-compacts: the effective output style is then
+    /// `compact`, so the delimiter row is aligned to the header column widths.
     ///
     /// Mirrors markdownlint MD060's `aligned_delimiter` option; the snake_case
     /// alias is accepted for cross-tool compatibility.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/src/rules/md060_table_format.rs 
new/rumdl-0.2.4/src/rules/md060_table_format.rs
--- old/rumdl-0.2.3/src/rules/md060_table_format.rs     2026-05-27 
21:28:16.000000000 +0200
+++ new/rumdl-0.2.4/src/rules/md060_table_format.rs     2026-05-29 
21:11:01.000000000 +0200
@@ -899,11 +899,27 @@
                 let calc_aligned_width = 1 + (num_columns * 3) + 
column_widths.iter().sum::<usize>();
                 aligned_width = Some(calc_aligned_width);
 
-                // Auto-compact: if aligned table exceeds max width, use 
compact formatting instead
+                // Auto-compact: if aligned table exceeds max width, use 
compact formatting instead.
+                // The effective output style is now `compact`, so honor 
`aligned-delimiter`
+                // exactly as the explicit `compact` style does: align the 
delimiter row's pipes
+                // to the header column widths while body rows stay compact.
                 if calc_aligned_width > self.effective_max_width() {
                     auto_compacted = true;
-                    for line in &stripped_lines {
+                    let header_widths = if self.config.aligned_delimiter && 
stripped_lines.len() >= 2 {
+                        let header_cells = 
Self::parse_table_row_with_flavor(stripped_lines[0], flavor);
+                        Some(Self::header_cell_widths(&header_cells))
+                    } else {
+                        None
+                    };
+                    for (row_idx, line) in stripped_lines.iter().enumerate() {
                         let cells = Self::parse_table_row_with_flavor(line, 
flavor);
+                        if row_idx == 1
+                            && let Some(widths) = &header_widths
+                        {
+                            // Auto-compact always produces the single-space 
compact form.
+                            
result.push(Self::format_delimiter_aligned_to_header(&cells, widths, true));
+                            continue;
+                        }
                         result.push(Self::format_table_compact(&cells));
                     }
                 } else {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/rumdl-0.2.3/tests/regressions/embedded_markdown_fix_gate_issue_643_test.rs 
new/rumdl-0.2.4/tests/regressions/embedded_markdown_fix_gate_issue_643_test.rs
--- 
old/rumdl-0.2.3/tests/regressions/embedded_markdown_fix_gate_issue_643_test.rs  
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/rumdl-0.2.4/tests/regressions/embedded_markdown_fix_gate_issue_643_test.rs  
    2026-05-29 21:11:01.000000000 +0200
@@ -0,0 +1,153 @@
+//! Regression tests: `--fix` must not rewrite the contents of a ` ```markdown 
`
+//! code block unless embedded markdown linting is explicitly opted into via
+//! code-block-tools.
+//!
+//! Embedded markdown linting is documented as opt-in (the special `rumdl` 
tool in
+//! `[code-block-tools.languages.markdown] lint = ["rumdl"]`). The check path
+//! honored that gate, but the fix path ran the recursive embedded formatter
+//! unconditionally, so `rumdl check --fix` silently rewrote code-block content
+//! that `rumdl check` never reported. For MyST directive blocks this mangled 
the
+//! directive (MD046 converting the fence to an indented block, MD040 
injecting a
+//! `text` language), corrupting content the user wrote verbatim inside a 
fence.
+//!
+//! These tests run the real binary end-to-end so they exercise the exact fix
+//! coordinator + embedded gating used in production.
+
+use std::fs;
+use std::process::Command;
+use tempfile::tempdir;
+
+/// Run `rumdl check --fix` on a file containing `markdown`, using `config` as 
the
+/// sole configuration source, and return the file contents after the fix. The
+/// config is passed via `--config` and the working directory is the temp dir 
so
+/// the project's own config never leaks in. `--no-cache` keeps the result
+/// deterministic across repeated runs.
+fn fix_with_config(markdown: &str, config: &str) -> String {
+    let dir = tempdir().unwrap();
+    let file_path = dir.path().join("doc.md");
+    let config_path = dir.path().join(".rumdl.toml");
+    fs::write(&file_path, markdown).unwrap();
+    fs::write(&config_path, config).unwrap();
+
+    let output = Command::new(env!("CARGO_BIN_EXE_rumdl"))
+        .current_dir(dir.path())
+        .arg("check")
+        .arg("--fix")
+        .arg("--no-cache")
+        .arg("--config")
+        .arg(&config_path)
+        .arg(&file_path)
+        .output()
+        .expect("Failed to execute rumdl");
+
+    let exit_code = output.status.code().unwrap_or(-1);
+    assert_ne!(
+        exit_code,
+        2,
+        "rumdl errored (exit 2)\nstdout: {}\nstderr: {}",
+        String::from_utf8_lossy(&output.stdout),
+        String::from_utf8_lossy(&output.stderr),
+    );
+
+    fs::read_to_string(&file_path).unwrap()
+}
+
+/// The exact reproduction from the issue: a ` ````markdown ` block containing 
a
+/// MyST ` ```{eval-rst} ` directive, under MyST flavor with reflow enabled.
+/// Without opting into embedded markdown linting, the block must be untouched.
+#[test]
+fn eval_rst_directive_in_markdown_block_unchanged_without_optin() {
+    let markdown = "````markdown\n```{eval-rst}\n.. autofunction:: 
example.refraction.snell\n    :noindex:\n    :toctree: generated\n```\n````\n";
+
+    let config = r#"
+[global]
+flavor = "myst"
+disable = ["MD031", "MD057", "MD059"]
+
+[MD013]
+reflow = true
+code-blocks = false
+tables = false
+"#;
+
+    let fixed = fix_with_config(markdown, config);
+    assert_eq!(
+        fixed, markdown,
+        "embedded MyST directive must be left byte-for-byte unchanged when 
embedded markdown linting is not enabled"
+    );
+}
+
+/// A plain ` ```markdown ` block with an obvious fixable issue inside
+/// (MD018: no space after `#`). Without opt-in the inner content must not be
+/// touched, so users can show intentionally "broken" markdown examples in 
docs.
+#[test]
+fn markdown_block_content_unchanged_without_optin() {
+    let markdown = "# Doc\n\n```markdown\n#Heading without space\n```\n";
+
+    let config = "[global]\nflavor = \"standard\"\n";
+
+    let fixed = fix_with_config(markdown, config);
+    assert_eq!(
+        fixed, markdown,
+        "markdown code block content must not be rewritten when embedded 
markdown linting is not enabled"
+    );
+}
+
+/// When embedded markdown linting IS opted into, the recursive formatter runs 
and
+/// fixes the inner content. This proves the gate (not a blanket disable) is 
the
+/// deciding factor, keeping the documented feature working.
+#[test]
+fn markdown_block_content_fixed_with_optin() {
+    let markdown = "# Doc\n\n```markdown\n#Heading without space\n```\n";
+
+    let config = r#"
+[global]
+flavor = "standard"
+
+[code-block-tools]
+enabled = true
+
+[code-block-tools.languages.markdown]
+lint = ["rumdl"]
+"#;
+
+    let fixed = fix_with_config(markdown, config);
+    assert!(
+        fixed.contains("# Heading without space"),
+        "embedded markdown should be formatted when opted in via 
code-block-tools, got:\n{fixed}"
+    );
+    assert_ne!(fixed, markdown, "opt-in run should have changed the embedded 
content");
+}
+
+/// Opt-in must not corrupt a MyST directive. Uses the reporter's full config
+/// (MyST flavor + reflow + the same disabled rules) so the embedded sub-lint 
runs
+/// every rule that previously mangled the directive: MD046 converting the 
fence
+/// to an indented block, and MD040 injecting a `text` language. The directive,
+/// including its multi-line option body, must survive byte-for-byte.
+#[test]
+fn eval_rst_directive_preserved_under_myst_with_optin() {
+    let markdown = "````markdown\n```{eval-rst}\n.. autofunction:: 
example.refraction.snell\n    :noindex:\n    :toctree: generated\n```\n````\n";
+
+    let config = r#"
+[global]
+flavor = "myst"
+disable = ["MD031", "MD057", "MD059"]
+
+[MD013]
+reflow = true
+code-blocks = false
+tables = false
+
+[code-block-tools]
+enabled = true
+
+[code-block-tools.languages.markdown]
+lint = ["rumdl"]
+"#;
+
+    let fixed = fix_with_config(markdown, config);
+    assert_eq!(
+        fixed, markdown,
+        "MyST directive (fence + indented option body) must be preserved even 
with embedded linting enabled, got:\n{fixed}"
+    );
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/tests/regressions/mod.rs 
new/rumdl-0.2.4/tests/regressions/mod.rs
--- old/rumdl-0.2.3/tests/regressions/mod.rs    2026-05-27 21:28:16.000000000 
+0200
+++ new/rumdl-0.2.4/tests/regressions/mod.rs    2026-05-29 21:11:01.000000000 
+0200
@@ -1,5 +1,6 @@
 mod code_block_blockquote_edge_cases;
 mod consistency_regression_tests;
+mod embedded_markdown_fix_gate_issue_643_test;
 mod escaped_brackets_test;
 mod final_confidence_assessment;
 mod html_comments_test;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/tests/rules/md046_test.rs 
new/rumdl-0.2.4/tests/rules/md046_test.rs
--- old/rumdl-0.2.3/tests/rules/md046_test.rs   2026-05-27 21:28:16.000000000 
+0200
+++ new/rumdl-0.2.4/tests/rules/md046_test.rs   2026-05-29 21:11:01.000000000 
+0200
@@ -920,3 +920,43 @@
         "The inner ``` should be preserved as indented content, got:\n{fixed}"
     );
 }
+
+#[test]
+fn test_myst_eval_rst_directive_body_not_indented_block() {
+    // A fenced MyST directive (`{eval-rst}`) is parsed as a code block whose 
body
+    // is opaque reStructuredText. Its indented option lines (`:noindex:`,
+    // `:toctree:`) must NOT be counted as a standalone indented code block, so
+    // under the default consistent style MD046 reports nothing and leaves the
+    // directive untouched.
+    let rule = MD046CodeBlockStyle::new(CodeBlockStyle::Consistent);
+    let content =
+        "```{eval-rst}\n.. autofunction:: example.refraction.snell\n    
:noindex:\n    :toctree: generated\n```\n";
+    let ctx = LintContext::new(content, 
rumdl_lib::config::MarkdownFlavor::MyST, None);
+
+    let warnings = rule.check(&ctx).unwrap();
+    assert!(
+        warnings.is_empty(),
+        "MD046 must not flag a MyST directive's indented body as an indented 
code block, got: {warnings:?}"
+    );
+
+    let fixed = rule.fix(&ctx).unwrap();
+    assert_eq!(
+        fixed, content,
+        "MD046 must not rewrite a MyST directive body, got:\n{fixed}"
+    );
+}
+
+#[test]
+fn test_myst_directive_body_not_indented_block_with_preceding_heading() {
+    // Same as above but with content before the directive, guarding both the
+    // first-block and later-block code paths.
+    let rule = MD046CodeBlockStyle::new(CodeBlockStyle::Consistent);
+    let content = "# Title\n\n```{eval-rst}\n.. autofunction:: 
example.refraction.snell\n    :noindex:\n    :toctree: generated\n```\n";
+    let ctx = LintContext::new(content, 
rumdl_lib::config::MarkdownFlavor::MyST, None);
+
+    let warnings = rule.check(&ctx).unwrap();
+    assert!(
+        warnings.is_empty(),
+        "MD046 must not flag a MyST directive body regardless of position, 
got: {warnings:?}"
+    );
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rumdl-0.2.3/tests/rules/md060_test.rs 
new/rumdl-0.2.4/tests/rules/md060_test.rs
--- old/rumdl-0.2.3/tests/rules/md060_test.rs   2026-05-27 21:28:16.000000000 
+0200
+++ new/rumdl-0.2.4/tests/rules/md060_test.rs   2026-05-29 21:11:01.000000000 
+0200
@@ -3523,6 +3523,80 @@
     );
 }
 
+fn md060_aligned_config_with_max_width(aligned_delimiter: bool, max_width: 
usize) -> MD060Config {
+    MD060Config {
+        enabled: true,
+        style: "aligned".to_string(),
+        max_width: LineLength::from_const(max_width),
+        column_align: ColumnAlign::Auto,
+        column_align_header: None,
+        column_align_body: None,
+        loose_last_column: false,
+        aligned_delimiter,
+    }
+}
+
+#[test]
+fn test_md060_aligned_autocompact_honors_aligned_delimiter() {
+    // #646: when an `aligned` table exceeds max-width it auto-compacts. The 
effective output
+    // style is then `compact`, so `aligned-delimiter = true` must align the 
delimiter row's
+    // pipes to the header column widths, exactly as `style = "compact"` would.
+    let config = md060_aligned_config_with_max_width(true, 40);
+    let rule = MD060TableFormat::from_config_struct(config, 
default_md013_config(), false);
+
+    let content = "| ID | Description |\n| --- | --- |\n| 1 | A very long 
description that causes the table to exceed the configured maximum width |\n| 2 
| Another long description that keeps the table in compact mode |";
+    let ctx = LintContext::new(content, MarkdownFlavor::Standard, None);
+
+    let fixed = rule.fix(&ctx).unwrap();
+    // "ID" = 2 cols → 2 dashes; "Description" = 11 cols → 11 dashes. Body 
rows stay compact.
+    let expected = "| ID | Description |\n| -- | ----------- |\n| 1 | A very 
long description that causes the table to exceed the configured maximum width 
|\n| 2 | Another long description that keeps the table in compact mode |";
+    assert_eq!(
+        fixed, expected,
+        "auto-compacted aligned table must align the delimiter row to header 
widths when aligned-delimiter is set"
+    );
+}
+
+#[test]
+fn 
test_md060_aligned_autocompact_without_aligned_delimiter_keeps_minimal_dashes() 
{
+    // Default (aligned-delimiter = false): auto-compact keeps the minimal 
compact delimiter.
+    let config = md060_aligned_config_with_max_width(false, 40);
+    let rule = MD060TableFormat::from_config_struct(config, 
default_md013_config(), false);
+
+    let content = "| ID | Description |\n| --- | --- |\n| 1 | A very long 
description that causes the table to exceed the configured maximum width |\n| 2 
| Another long description that keeps the table in compact mode |";
+    let ctx = LintContext::new(content, MarkdownFlavor::Standard, None);
+
+    let fixed = rule.fix(&ctx).unwrap();
+    let expected = "| ID | Description |\n| --- | --- |\n| 1 | A very long 
description that causes the table to exceed the configured maximum width |\n| 2 
| Another long description that keeps the table in compact mode |";
+    assert_eq!(
+        fixed, expected,
+        "without aligned-delimiter the auto-compacted delimiter row keeps 
minimal dashes (no regression)"
+    );
+}
+
+#[test]
+fn test_md060_aligned_autocompact_aligned_delimiter_idempotent() {
+    // Running the fix twice on an auto-compacted + aligned-delimiter table 
must be stable.
+    let config = md060_aligned_config_with_max_width(true, 40);
+    let rule = MD060TableFormat::from_config_struct(config, 
default_md013_config(), false);
+
+    let content = "| ID | Description |\n| --- | --- |\n| 1 | A very long 
description that causes the table to exceed the configured maximum width |\n| 2 
| Another long description that keeps the table in compact mode |";
+    let ctx = LintContext::new(content, MarkdownFlavor::Standard, None);
+    let fixed_once = rule.fix(&ctx).unwrap();
+
+    let ctx2 = LintContext::new(&fixed_once, MarkdownFlavor::Standard, None);
+    let fixed_twice = rule.fix(&ctx2).unwrap();
+
+    assert_eq!(
+        fixed_once, fixed_twice,
+        "auto-compact + aligned-delimiter fix must be idempotent"
+    );
+    let warnings = rule.check(&ctx2).unwrap();
+    assert!(
+        warnings.is_empty(),
+        "Already-correct auto-compacted aligned-delimiter table should produce 
no warnings, got: {warnings:?}"
+    );
+}
+
 #[test]
 fn test_md060_compact_accepts_mdformat_empty_cell() {
     // mdformat writes empty compact cells as `| |` (single space between 
pipes).

++++++ rumdl.obsinfo ++++++
--- /var/tmp/diff_new_pack.EWBysp/_old  2026-05-30 23:01:35.928808235 +0200
+++ /var/tmp/diff_new_pack.EWBysp/_new  2026-05-30 23:01:35.932808399 +0200
@@ -1,5 +1,5 @@
 name: rumdl
-version: 0.2.3
-mtime: 1779910096
-commit: a5a0c2d5d6d631393c5ca773872742726d4fa4db
+version: 0.2.4
+mtime: 1780081861
+commit: a0d57ac276a15c3697a27cfe53f46e7742c341b9
 

++++++ vendor.tar.zst ++++++
/work/SRC/openSUSE:Factory/rumdl/vendor.tar.zst 
/work/SRC/openSUSE:Factory/.rumdl.new.1937/vendor.tar.zst differ: char 7722, 
line 46

Reply via email to