@rspress-theme-anatole/plugin-container-syntax 0.1.30 → 0.1.32

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.
Files changed (3) hide show
  1. package/container.css +101 -22
  2. package/dist/index.js +164 -17
  3. package/package.json +1 -1
package/container.css CHANGED
@@ -129,28 +129,6 @@
129
129
  color: var(--rp-container-tip-text);
130
130
  }
131
131
 
132
-
133
-
134
-
135
- .rspress-doc .rspress-directive.tabs {
136
- border-color: var(--rp-container-tip-border);
137
- background-color: var(--rp-container-tip-bg);
138
- }
139
-
140
- .rspress-doc .rspress-directive.tabs .rspress-directive-title {
141
- color: var(--rp-container-tip-text);
142
- }
143
-
144
- .rspress-doc .rspress-directive.tabs code {
145
- color: var(--rp-container-tip-text);
146
- background-color: var(--rp-container-tip-code-bg);
147
- }
148
-
149
- .rspress-doc .rspress-directive.tabs a {
150
- color: var(--rp-container-tip-text);
151
- }
152
-
153
-
154
132
  .rspress-doc .rspress-directive.info {
155
133
  border-color: var(--rp-container-info-border);
156
134
  background-color: var(--rp-container-info-bg);
@@ -225,4 +203,105 @@
225
203
 
226
204
  .rspress-doc .rspress-directive.details a {
227
205
  color: var(--rp-container-details-link);
206
+ }
207
+
208
+
209
+
210
+
211
+
212
+
213
+ .rspress-doc .rspress-directive.tabs {
214
+ border-color: var(--rp-container-tip-border);
215
+ background-color: var(--rp-container-tip-bg);
216
+ padding: 0;
217
+ overflow: hidden;
218
+ }
219
+
220
+ .rspress-doc .rspress-directive.tabs .rspress-directive-title {
221
+ color: var(--rp-container-tip-text);
222
+ display: none;
223
+ /* Hide the default title for tabs */
224
+ }
225
+
226
+ .rspress-doc .rspress-directive.tabs .rspress-directive-content {
227
+ padding: 0;
228
+ }
229
+
230
+ /* Tabs navigation styling */
231
+ .rspress-doc .tabs-nav {
232
+ display: flex;
233
+ border-bottom: 1px solid var(--rp-container-tip-border);
234
+ background-color: rgba(7, 156, 112, 0.03);
235
+ padding: 0;
236
+ margin: 0;
237
+ }
238
+
239
+ .rspress-doc .tabs-nav-item {
240
+ padding: 8px 16px;
241
+ cursor: pointer;
242
+ margin: 0;
243
+ font-size: 14px;
244
+ font-weight: 500;
245
+ color: var(--rp-container-tip-text);
246
+ border-bottom: 2px solid transparent;
247
+ transition: all 0.2s ease;
248
+ }
249
+
250
+ .rspress-doc .tabs-nav-item.active {
251
+ border-bottom: 2px solid var(--rp-container-tip-text);
252
+ background-color: rgba(7, 156, 112, 0.08);
253
+ }
254
+
255
+ /* Tab content styling */
256
+ .rspress-doc .tabs-content {
257
+ padding: 16px 24px;
258
+ }
259
+
260
+ .rspress-doc .tabs-panel {
261
+ display: none;
262
+ }
263
+
264
+ .rspress-doc .tabs-panel.active {
265
+ display: block;
266
+ }
267
+
268
+ .rspress-doc .tabs-nav-item:hover {
269
+ background-color: rgba(7, 156, 112, 0.06);
270
+ cursor: pointer;
271
+ }
272
+
273
+
274
+
275
+ /* ...existing styles... */
276
+
277
+ .rspress-directive.tabs {
278
+ margin: 1rem 0;
279
+ }
280
+
281
+ .tabs-nav {
282
+ display: flex;
283
+ border-bottom: 1px solid #ddd;
284
+ margin-bottom: 1rem;
285
+ }
286
+
287
+ .tabs-nav-item {
288
+ padding: 0.5rem 1rem;
289
+ cursor: pointer;
290
+ border: 1px solid transparent;
291
+ border-bottom: none;
292
+ margin-bottom: -1px;
293
+ }
294
+
295
+ .tabs-nav-item.active {
296
+ background-color: #fff;
297
+ border-color: #ddd;
298
+ border-bottom-color: #fff;
299
+ }
300
+
301
+ .tabs-panel {
302
+ display: none;
303
+ }
304
+
305
+ .tabs-panel.active {
306
+ display: block;
228
307
  }
package/dist/index.js CHANGED
@@ -21,10 +21,138 @@ const parseTitle = (rawTitle = '', isMDX = false) => {
21
21
  const matched = rawTitle?.match(isMDX ? TITLE_REGEX_IN_MDX : TITLE_REGEX_IN_MD);
22
22
  return trimTailingQuote(matched?.[1] || rawTitle);
23
23
  };
24
+
24
25
  const createContainer = (type, title, children) => {
26
+ // console.log('createContainer', JSON.stringify(children, null, 2));
27
+
25
28
  const isDetails = 'details' === type;
29
+ const isTabs = 'tabs' === type;
26
30
  const rootHName = isDetails ? 'details' : 'div';
27
31
  const titleHName = isDetails ? 'summary' : 'div';
32
+
33
+ // Handle tabs differently
34
+ if (isTabs) {
35
+ // Identify tab sections by finding paragraphs starting with ==
36
+ const tabSections = [];
37
+ let currentTabTitle = '';
38
+ let currentTabContent = null;
39
+
40
+ // Process children to find tab sections
41
+ for (let i = 0; i < children.length; i++) {
42
+ const child = children[i];
43
+
44
+ if (child.type === 'paragraph' &&
45
+ child.children &&
46
+ child.children[0] &&
47
+ child.children[0].type === 'text' &&
48
+ child.children[0].value.trim().startsWith('==')) {
49
+ // If we already have a tab section, push it
50
+ if (currentTabContent) {
51
+ tabSections.push({
52
+ title: currentTabTitle,
53
+ content: currentTabContent
54
+ });
55
+ }
56
+
57
+ let text = child.children[0].value.trim();
58
+
59
+ if (text.includes('\r\n')) {
60
+ let match = text.split('\r\n', 2);
61
+ currentTabTitle = match[0].substring(2).trim();
62
+ currentTabContent = [{
63
+ type: 'text',
64
+ value: text.substring(match[0].length).trim()
65
+ }];
66
+ }
67
+ else {
68
+ currentTabTitle = text.substring(2).trim();
69
+ currentTabContent = [];
70
+ }
71
+
72
+ continue;
73
+ }
74
+
75
+ // Add content to the current tab section
76
+ if (currentTabContent !== null) {
77
+ currentTabContent.push(child);
78
+ }
79
+ }
80
+
81
+ // Add the last tab section if it exists
82
+ if (currentTabContent && currentTabContent.length) {
83
+ tabSections.push({
84
+ title: currentTabTitle,
85
+ content: currentTabContent
86
+ });
87
+ }
88
+
89
+ // Create tab navigation
90
+ const tabNavItems = tabSections.map((section, index) => ({
91
+ type: 'paragraph',
92
+ data: {
93
+ hName: 'div',
94
+ hProperties: {
95
+ class: `tabs-nav-item${index === 0 ? ' active' : ''}`,
96
+ 'data-tab-index': index
97
+ }
98
+ },
99
+ children: [
100
+ {
101
+ type: 'text',
102
+ value: section.title
103
+ }
104
+ ]
105
+ }));
106
+
107
+ // Create tab content panels
108
+ const tabContentPanels = tabSections.map((section, index) => ({
109
+ type: 'paragraph',
110
+ data: {
111
+ hName: 'div',
112
+ hProperties: {
113
+ class: `tabs-panel${index === 0 ? ' active' : ''}`,
114
+ id: `tab-${index}`
115
+ }
116
+ },
117
+ children: section.content
118
+ }));
119
+
120
+ // Create the tabs container
121
+ return {
122
+ type: 'containerDirective',
123
+ data: {
124
+ hName: rootHName,
125
+ hProperties: {
126
+ class: `rspress-directive ${type}`
127
+ }
128
+ },
129
+ children: [
130
+ // Navigation tabs
131
+ {
132
+ type: 'paragraph',
133
+ data: {
134
+ hName: 'div',
135
+ hProperties: {
136
+ class: 'tabs-nav'
137
+ }
138
+ },
139
+ children: tabNavItems
140
+ },
141
+ // Tab content container
142
+ {
143
+ type: 'paragraph',
144
+ data: {
145
+ hName: 'div',
146
+ hProperties: {
147
+ class: 'tabs-content'
148
+ }
149
+ },
150
+ children: tabContentPanels
151
+ },
152
+ ]
153
+ };
154
+ }
155
+
28
156
  return {
29
157
  type: 'containerDirective',
30
158
  data: {
@@ -62,12 +190,15 @@ const createContainer = (type, title, children) => {
62
190
  ]
63
191
  };
64
192
  };
193
+
65
194
  function transformer(tree) {
66
195
  let i = 0;
67
196
  try {
68
197
  while (i < tree.children.length) {
69
198
  const node = tree.children[i];
70
- if ('children' in node) transformer(node);
199
+ if ('children' in node) {
200
+ transformer(node);
201
+ }
71
202
  if ('containerDirective' === node.type) {
72
203
  const type = node.name;
73
204
  if (DIRECTIVE_TYPES.includes(type)) tree.children.splice(i, 1, createContainer(type, node.attributes?.title ?? type.toUpperCase(), node.children));
@@ -89,6 +220,7 @@ function transformer(tree) {
89
220
  i++;
90
221
  continue;
91
222
  }
223
+
92
224
  const firstTextNode = node.children[0];
93
225
  const text = firstTextNode.value;
94
226
  const metaText = text.split('\n')[0];
@@ -110,7 +242,7 @@ function transformer(tree) {
110
242
  continue;
111
243
  }
112
244
  const wrappedChildren = [];
113
- if (content?.endsWith(':::')) {
245
+ if (node.type === 'text' && node.value.endsWith(':::')) {
114
246
  wrappedChildren.push({
115
247
  type: 'paragraph',
116
248
  children: [
@@ -133,30 +265,40 @@ function transformer(tree) {
133
265
  value: content
134
266
  });
135
267
  paragraphChild.children.push(...node.children.slice(1, -1));
268
+
136
269
  if (0 === paragraphChild.children.length) wrappedChildren.pop();
270
+
137
271
  const lastChildInNode = node.children[node.children.length - 1];
272
+
138
273
  if ('text' === lastChildInNode.type && REGEX_END.test(lastChildInNode.value)) {
139
274
  const lastChildInNodeText = lastChildInNode.value;
140
275
  const matchedEndContent = lastChildInNodeText.slice(0, -3).trim();
141
- if (wrappedChildren.length) wrappedChildren[0].children.push({
142
- type: 'text',
143
- value: matchedEndContent
144
- });
145
- else if (matchedEndContent) wrappedChildren.push({
146
- type: 'paragraph',
147
- children: [
148
- {
149
- type: 'text',
150
- value: matchedEndContent
151
- }
152
- ]
153
- });
276
+ if (wrappedChildren.length) {
277
+ wrappedChildren[0].children.push({
278
+ type: 'text',
279
+ value: matchedEndContent
280
+ });
281
+ }
282
+ else if (matchedEndContent) {
283
+ wrappedChildren.push({
284
+ type: 'paragraph',
285
+ children: [
286
+ {
287
+ type: 'text',
288
+ value: matchedEndContent
289
+ }
290
+ ]
291
+ });
292
+ }
293
+
154
294
  const newChild = createContainer(type, title, wrappedChildren);
155
295
  tree.children.splice(i, 1, newChild);
156
296
  i++;
157
297
  continue;
158
298
  }
159
- if (lastChildInNode !== firstTextNode && wrappedChildren.length) wrappedChildren[0].children.push(lastChildInNode);
299
+ if (lastChildInNode !== firstTextNode && wrappedChildren.length) {
300
+ wrappedChildren[0].children.push(lastChildInNode);
301
+ }
160
302
  let j = i + 1;
161
303
  while (j < tree.children.length) {
162
304
  const currentParagraph = tree.children[j];
@@ -166,6 +308,7 @@ function transformer(tree) {
166
308
  continue;
167
309
  }
168
310
  const lastChild = currentParagraph.children[currentParagraph.children.length - 1];
311
+
169
312
  if (lastChild === firstTextNode || 'text' === lastChild.type && REGEX_END.test(lastChild.value)) {
170
313
  const lastChildText = lastChild.value;
171
314
  const matchedEndContent = lastChildText.slice(0, -3).trim();
@@ -179,6 +322,7 @@ function transformer(tree) {
179
322
  }
180
323
  ]
181
324
  });
325
+
182
326
  const newChild = createContainer(type, title, wrappedChildren);
183
327
  tree.children.splice(i, j - i + 1, newChild);
184
328
  break;
@@ -197,6 +341,7 @@ function transformer(tree) {
197
341
  throw e;
198
342
  }
199
343
  }
344
+
200
345
  const remarkPluginContainer = () => transformer;
201
346
  const src_dirname = (0, __WEBPACK_EXTERNAL_MODULE__rspress_shared_baa012d0__.normalizePosixPath)(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].dirname((0, __WEBPACK_EXTERNAL_MODULE_node_url_e96de089__.fileURLToPath)(import.meta.url)));
202
347
  function pluginContainerSyntax() {
@@ -207,7 +352,9 @@ function pluginContainerSyntax() {
207
352
  remarkPluginContainer
208
353
  ]
209
354
  },
210
- globalStyles: __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].posix.join(src_dirname, '../container.css')
355
+ globalStyles: __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].posix.join(src_dirname, '../container.css'),
356
+
211
357
  };
212
358
  }
359
+
213
360
  export { pluginContainerSyntax };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rspress-theme-anatole/plugin-container-syntax",
3
- "version": "0.1.30",
3
+ "version": "0.1.32",
4
4
  "license": "MIT",
5
5
  "sideEffects": [
6
6
  "*.css",