confluence-cli 2.1.0 → 2.1.1
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/lib/macro-converter.js +26 -16
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/lib/macro-converter.js
CHANGED
|
@@ -2,6 +2,7 @@ const MarkdownIt = require('markdown-it');
|
|
|
2
2
|
const { htmlToMarkdown } = require('./html-to-markdown');
|
|
3
3
|
|
|
4
4
|
const VALID_LINK_STYLES = ['smart', 'plain', 'wiki'];
|
|
5
|
+
const CALLOUT_MARKERS = ['info', 'warning', 'note'];
|
|
5
6
|
|
|
6
7
|
class MacroConverter {
|
|
7
8
|
constructor({ isCloud = false, webUrlPrefix = '', buildUrl = null, linkStyle = null } = {}) {
|
|
@@ -89,27 +90,36 @@ class MacroConverter {
|
|
|
89
90
|
);
|
|
90
91
|
|
|
91
92
|
storage = storage.replace(/<blockquote>(.*?)<\/blockquote>/gs, (_, content) => {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const cleanContent = content.replace(/<p><strong>NOTE<\/strong><\/p>\s*/, '');
|
|
104
|
-
return `<ac:structured-macro ac:name="note">
|
|
105
|
-
<ac:rich-text-body>${cleanContent}</ac:rich-text-body>
|
|
106
|
-
</ac:structured-macro>`;
|
|
107
|
-
} else {
|
|
93
|
+
// Detect the marker only when it sits at the very start of the first
|
|
94
|
+
// paragraph, immediately followed by a `</p>` close (separated form) or
|
|
95
|
+
// a `\n` (same-line body form). This is the same anchor condition the
|
|
96
|
+
// strip step uses below, so detection and stripping stay in sync.
|
|
97
|
+
// Without this anchor, a quotation that merely *mentions* `**INFO**` —
|
|
98
|
+
// e.g. `> Use **INFO** at the start.` — would be silently wrapped in an
|
|
99
|
+
// info macro, surprising the author.
|
|
100
|
+
const marker = CALLOUT_MARKERS.find((m) =>
|
|
101
|
+
new RegExp(`<p><strong>${m.toUpperCase()}<\\/strong>(<\\/p>|\\s*\\n)`).test(content)
|
|
102
|
+
);
|
|
103
|
+
if (!marker) {
|
|
108
104
|
// Plain blockquote — `> …` is a quotation, not an alert. Use the
|
|
109
105
|
// `> **INFO**` / `> **WARNING**` / `> **NOTE**` markers above to
|
|
110
106
|
// produce a Confluence info / warning / note macro instead.
|
|
111
107
|
return `<blockquote>${content}</blockquote>`;
|
|
112
108
|
}
|
|
109
|
+
// Strip the leading `<strong>MARKER</strong>`. markdown-it produces two
|
|
110
|
+
// shapes depending on whether a blank `>` line separates marker and body:
|
|
111
|
+
// case A (separated): `<p><strong>MARKER</strong></p>\n<p>body</p>`
|
|
112
|
+
// case B (same-line): `<p><strong>MARKER</strong>\nbody</p>`
|
|
113
|
+
// The original cleanup only handled case A, so case B leaked the marker
|
|
114
|
+
// into the rendered macro body. README's recommended `> **INFO**\n> body`
|
|
115
|
+
// form parses as case B — exactly the form that broke.
|
|
116
|
+
const cleanContent = content.replace(
|
|
117
|
+
new RegExp(`<p><strong>${marker.toUpperCase()}<\\/strong>(<\\/p>\\s*|\\s*\\n)`),
|
|
118
|
+
(_, tail) => tail.startsWith('</p>') ? '' : '<p>'
|
|
119
|
+
);
|
|
120
|
+
return `<ac:structured-macro ac:name="${marker}">
|
|
121
|
+
<ac:rich-text-body>${cleanContent}</ac:rich-text-body>
|
|
122
|
+
</ac:structured-macro>`;
|
|
113
123
|
});
|
|
114
124
|
|
|
115
125
|
storage = storage.replace(/<table>(.*?)<\/table>/gs, '<table>$1</table>');
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "confluence-cli",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "confluence-cli",
|
|
9
|
-
"version": "2.1.
|
|
9
|
+
"version": "2.1.1",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"axios": "^1.15.0",
|