confluence-cli 2.0.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -809,6 +809,24 @@ A paragraph containing only `**ANCHOR: my-section**` becomes a Confluence anchor
809
809
  **ANCHOR: my-section**
810
810
  ```
811
811
 
812
+ ### `**EXPAND: title** … **EXPAND_END**` — collapsible expand macro
813
+
814
+ Wrap a block of content between `**EXPAND: title**` and `**EXPAND_END**` markers (each on its own paragraph) to render it as a Confluence expand macro with a collapsible body:
815
+
816
+ ````markdown
817
+ **EXPAND: Show generated code**
818
+
819
+ ```js
820
+ const x = 1;
821
+ ```
822
+
823
+ **EXPAND_END**
824
+ ````
825
+
826
+ The body may contain any content that is converted earlier in the pipeline (code blocks, tables, callout blockquotes). The reverse direction emits the same `**EXPAND: title**` / `**EXPAND_END**` markers so the conversion round-trips.
827
+
828
+ Inline markdown inside the title (`*em*`, backtick code, links, `~~strike~~`) is stripped at capture time — Confluence's storage normalizer treats macro titles as plain text and will silently truncate or reject HTML in a `<ac:parameter>`. Title-less expand macros created in the Confluence UI still convert to `<details>/<summary>` blocks.
829
+
812
830
  ### `[text](#id)` — same-page anchor link
813
831
 
814
832
  A standard markdown link whose href starts with `#` becomes an `ac:link` with `ac:anchor`, rendering as an in-page jump in Confluence:
@@ -125,6 +125,20 @@ class MacroConverter {
125
125
  '<ac:structured-macro ac:name="anchor"><ac:parameter ac:name="">$1</ac:parameter></ac:structured-macro>'
126
126
  );
127
127
 
128
+ // **EXPAND: title** … **EXPAND_END** → Confluence expand macro. Runs
129
+ // after code/blockquote/table conversion so the body can contain those
130
+ // macros. Strips inline HTML from the title because Confluence's storage
131
+ // normalizer treats <ac:parameter> as text-only — it silently truncates
132
+ // at the first '<' and rejects <s> outright with HTTP 500. Entities
133
+ // (&amp;, &lt;) survive because the regex requires a literal '<'.
134
+ storage = storage.replace(
135
+ /<p><strong>EXPAND: (.*?)<\/strong><\/p>\s*([\s\S]*?)\s*<p><strong>EXPAND_END<\/strong><\/p>/g,
136
+ (_, title, body) => {
137
+ const cleanTitle = title.replace(/<[^>]+>/g, '').trim();
138
+ return `<ac:structured-macro ac:name="expand"><ac:parameter ac:name="title">${cleanTitle}</ac:parameter><ac:rich-text-body>${body.trim()}</ac:rich-text-body></ac:structured-macro>`;
139
+ }
140
+ );
141
+
128
142
  // Same-page anchor links (href="#id") → ac:link with ac:anchor. Must run
129
143
  // before the general link conversion below so the #id pattern is not
130
144
  // consumed by the generic <a href> replacement (and so it works under
@@ -235,6 +249,16 @@ class MacroConverter {
235
249
  return `\n\`\`\`mermaid\n${code.trim()}\n\`\`\`\n`;
236
250
  });
237
251
 
252
+ // Titled expand macros → **EXPAND: title** / **EXPAND_END** markers
253
+ // (round-trip with markdownToStorage). Must run before the generic
254
+ // <details> fallback below, which would otherwise drop the title.
255
+ markdown = markdown.replace(
256
+ /<ac:structured-macro ac:name="expand"[^>]*>[\s\S]*?<ac:parameter ac:name="title">([\s\S]*?)<\/ac:parameter>[\s\S]*?<ac:rich-text-body>([\s\S]*?)<\/ac:rich-text-body>[\s\S]*?<\/ac:structured-macro>/g,
257
+ '\n**EXPAND: $1**\n\n$2\n\n**EXPAND_END**\n'
258
+ );
259
+
260
+ // Title-less expand macros (e.g. created in the Confluence UI without a
261
+ // title) fall back to <details>/<summary> with a localized default label.
238
262
  markdown = markdown.replace(/<ac:structured-macro ac:name="expand"[^>]*>[\s\S]*?<ac:rich-text-body>([\s\S]*?)<\/ac:rich-text-body>[\s\S]*?<\/ac:structured-macro>/g, (_, content) => {
239
263
  return `\n<details>\n<summary>${labels.expandDetails}</summary>\n\n${content}\n\n</details>\n`;
240
264
  });
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "confluence-cli",
3
- "version": "2.0.2",
3
+ "version": "2.1.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "confluence-cli",
9
- "version": "2.0.2",
9
+ "version": "2.1.0",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "axios": "^1.15.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "confluence-cli",
3
- "version": "2.0.2",
3
+ "version": "2.1.0",
4
4
  "description": "A command-line interface for Atlassian Confluence with page creation and editing capabilities",
5
5
  "main": "index.js",
6
6
  "bin": {