Compare commits
4 Commits
fix/na-cab
...
v2.3.34
| Author | SHA1 | Date | |
|---|---|---|---|
| aa299b285d | |||
| 2be0d1ea92 | |||
| 0554460153 | |||
| 4ae45b1aa7 |
@@ -266,18 +266,7 @@ export default async function ProductPage({ params }: ProductPageProps) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
let technicalItems = [];
|
||||
try {
|
||||
const tabMatch =
|
||||
typeof product.content === 'string' &&
|
||||
product.content.match(/<Block type="productTabs" data={({.*?})}\s*\/>/s);
|
||||
if (tabMatch && tabMatch[1]) {
|
||||
const data = JSON.parse(tabMatch[1]);
|
||||
technicalItems = data.technicalItems || [];
|
||||
}
|
||||
} catch (e) {
|
||||
// Ignore JSON parse errors for AST
|
||||
}
|
||||
let technicalItems: any[] = [];
|
||||
|
||||
const datasheetPath = getDatasheetPath(productSlug, locale);
|
||||
const isFallback = (product.frontmatter as any).isFallback;
|
||||
@@ -296,8 +285,20 @@ export default async function ProductPage({ params }: ProductPageProps) {
|
||||
if (typeof product.content === 'string') {
|
||||
const tabBlockMatch = product.content.match(/<Block type="productTabs".*?\/>/s);
|
||||
if (tabBlockMatch) {
|
||||
descriptionContent = product.content.replace(tabBlockMatch[0], '');
|
||||
technicalContent = tabBlockMatch[0];
|
||||
descriptionContent = product.content.replace(tabBlockMatch[0], '');
|
||||
|
||||
const dataMatch =
|
||||
technicalContent.match(/data="({.*?})"/s) || technicalContent.match(/data={({.*?})}/s);
|
||||
if (dataMatch && dataMatch[1]) {
|
||||
try {
|
||||
const rawJsonStr = dataMatch[1].replace(/"/g, '"');
|
||||
const data = JSON.parse(rawJsonStr);
|
||||
technicalItems = data.technicalItems || [];
|
||||
} catch (e) {
|
||||
console.error('Failed to parse productTabs data for page:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -66,3 +66,81 @@ export function fixMdxDataProps(content: string): string {
|
||||
|
||||
return fixedContent;
|
||||
}
|
||||
|
||||
export function lexicalToMarkdown(node: any, depth = 0): string {
|
||||
if (!node) return '';
|
||||
|
||||
if (typeof node === 'string') return node;
|
||||
|
||||
if (node.type === 'text') {
|
||||
let text = node.text || '';
|
||||
if (node.format === 1) text = `**${text}**`; // Bold
|
||||
if (node.format === 2) text = `*${text}*`; // Italic
|
||||
return text;
|
||||
}
|
||||
|
||||
if (node.type === 'heading') {
|
||||
const level = parseInt((node.tag || 'h1').replace('h', '')) || 1;
|
||||
const prefix = '#'.repeat(level);
|
||||
const text = (node.children || []).map((c: any) => lexicalToMarkdown(c, depth)).join('');
|
||||
return `${prefix} ${text}\n\n`;
|
||||
}
|
||||
|
||||
if (node.type === 'paragraph') {
|
||||
const text = (node.children || []).map((c: any) => lexicalToMarkdown(c, depth)).join('');
|
||||
return text.trim() ? `${text}\n\n` : '\n';
|
||||
}
|
||||
|
||||
if (node.type === 'list') {
|
||||
const isOrdered = node.tag === 'ol';
|
||||
const items = (node.children || [])
|
||||
.map((c: any, index: number) => {
|
||||
const prefix = isOrdered ? `${index + 1}.` : '-';
|
||||
return `${prefix} ${lexicalToMarkdown(c, depth + 1).trim()}`;
|
||||
})
|
||||
.join('\n');
|
||||
return `${items}\n\n`;
|
||||
}
|
||||
|
||||
if (node.type === 'listitem') {
|
||||
return (node.children || []).map((c: any) => lexicalToMarkdown(c, depth)).join('');
|
||||
}
|
||||
|
||||
if (node.type === 'quote') {
|
||||
const text = (node.children || []).map((c: any) => lexicalToMarkdown(c, depth)).join('');
|
||||
return `> ${text}\n\n`;
|
||||
}
|
||||
|
||||
if (node.type === 'link') {
|
||||
const url = node.fields?.url || node.url || '';
|
||||
const text = (node.children || []).map((c: any) => lexicalToMarkdown(c, depth)).join('');
|
||||
return `[${text}](${url})`;
|
||||
}
|
||||
|
||||
if (node.type === 'upload') {
|
||||
const url = node.value?.url || '';
|
||||
const alt = node.value?.alt || node.value?.filename || '';
|
||||
return `\n\n`;
|
||||
}
|
||||
|
||||
if (node.type === 'block') {
|
||||
const blockType = node.fields?.blockType;
|
||||
if (blockType === 'contactSection') {
|
||||
return `<ContactSection showMap={${!!node.fields?.showMap}} showForm={${!!node.fields?.showForm}} showHours={${!!node.fields?.showHours}} />\n\n`;
|
||||
}
|
||||
if (blockType === 'heroSection') {
|
||||
return `<HeroSection badge="${node.fields?.badge || ''}" title="${node.fields?.title || ''}" subtitle="${node.fields?.subtitle || ''}" alignment="${node.fields?.alignment || 'left'}" />\n\n`;
|
||||
}
|
||||
if (blockType === 'features') {
|
||||
return `<FeaturesSection layout="${node.fields?.layout || ''}" />\n\n`;
|
||||
}
|
||||
// Generic MDX block wrapper if unknown
|
||||
return `<Block type="${blockType}" data={${JSON.stringify(node.fields)}} />\n\n`;
|
||||
}
|
||||
|
||||
if (node.children && Array.isArray(node.children)) {
|
||||
return node.children.map((c: any) => lexicalToMarkdown(c, depth)).join('');
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
"prepare": "husky",
|
||||
"preinstall": "npx only-allow pnpm"
|
||||
},
|
||||
"version": "2.3.32",
|
||||
"version": "2.3.34",
|
||||
"pnpm": {
|
||||
"onlyBuiltDependencies": [
|
||||
"@parcel/watcher",
|
||||
|
||||
27
tests/lexical.test.ts
Normal file
27
tests/lexical.test.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { lexicalToMarkdown } from '../lib/mdx-utils';
|
||||
|
||||
describe('lexicalToMarkdown', () => {
|
||||
it('should convert lexical AST to markdown', () => {
|
||||
const ast = {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{ type: 'text', text: 'Hello ' },
|
||||
{ type: 'text', text: 'World', format: 1 }, // bold
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'heading',
|
||||
tag: 'h2',
|
||||
children: [{ type: 'text', text: 'Title' }],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const result = lexicalToMarkdown(ast);
|
||||
expect(result).toBe('Hello **World**\n\n## Title\n\n');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user