UNPKG

@ry-krystal/kicad-converter

Version:

专业的KiCad符号文件与JSON互转工具

202 lines (201 loc) 7.04 kB
/** * 增强版转换器实现 * 基于核心转换器,提供额外的优化和错误处理功能 */ import { KiCadConverter } from '../core/index.js'; /** * 增强版转换器类 */ export class EnhancedConverter extends KiCadConverter { options; constructor(options = {}) { super(); this.options = { enableOptimization: true, enableErrorRecovery: true, maxRetries: 3, ...options }; } /** * 增强版KiCad转JSON */ async kicadToJson(kicadContent, options = {}) { const mergedOptions = { ...this.options, ...options }; // 使用重试机制 for (let attempt = 1; attempt <= (mergedOptions.maxRetries || 1); attempt++) { try { const result = await super.kicadToJson(kicadContent, mergedOptions); if (result.success) { // 应用增强优化 if (mergedOptions.enableOptimization && result.data) { result.data = this.optimizeJsonOutput(result.data); } return result; } // 如果不是最后一次尝试,继续重试 if (attempt < (mergedOptions.maxRetries || 1)) { continue; } return result; } catch (error) { if (attempt === (mergedOptions.maxRetries || 1)) { return { success: false, errors: [`增强版转换失败: ${error instanceof Error ? error.message : String(error)}`], warnings: [] }; } } } return { success: false, errors: ['增强版转换失败:超过最大重试次数'], warnings: [] }; } /** * 增强版JSON转KiCad */ async jsonToKicad(jsonContent, options = {}) { const mergedOptions = { ...this.options, ...options }; // 使用重试机制 for (let attempt = 1; attempt <= (mergedOptions.maxRetries || 1); attempt++) { try { const result = await super.jsonToKicad(jsonContent, mergedOptions); if (result.success) { // 应用增强优化 if (mergedOptions.enableOptimization && result.data) { result.data = this.optimizeKicadOutput(result.data); } return result; } // 如果不是最后一次尝试,继续重试 if (attempt < (mergedOptions.maxRetries || 1)) { continue; } return result; } catch (error) { if (attempt === (mergedOptions.maxRetries || 1)) { return { success: false, errors: [`增强版转换失败: ${error instanceof Error ? error.message : String(error)}`], warnings: [] }; } } } return { success: false, errors: ['增强版转换失败:超过最大重试次数'], warnings: [] }; } /** * 批量转换(增强版) */ async batchConvert(files, outputDir) { const results = []; let successCount = 0; let failCount = 0; for (const file of files) { try { const result = await this.kicadToJson(file.content); if (result.success) { successCount++; results.push({ filename: file.path, success: true, outputPath: `${outputDir}/${file.path.replace(/\.[^/.]+$/, '.json')}` }); } else { failCount++; results.push({ filename: file.path, success: false, error: result.errors.join('; ') }); } } catch (error) { failCount++; results.push({ filename: file.path, success: false, error: error instanceof Error ? error.message : String(error) }); } } return { totalFiles: files.length, successfulConversions: successCount, failedConversions: failCount, results }; } /** * 自检功能 */ async selfTest() { try { // 简单的自检:测试一个最小的KiCad符号 const testKiCad = '(kicad_symbol_lib (version 20230620) (generator test) (symbol "Test" (property "Reference" "U" (at 0 0 0)) (property "Value" "Test" (at 0 0 0))))'; const jsonResult = await this.kicadToJson(testKiCad); if (!jsonResult.success) return false; const kicadResult = await this.jsonToKicad(jsonResult.data); if (!kicadResult.success) return false; return true; } catch { return false; } } /** * 优化JSON输出 */ optimizeJsonOutput(jsonString) { try { const data = JSON.parse(jsonString); // 排序符号 if (data.symbols && Array.isArray(data.symbols)) { data.symbols.sort((a, b) => a.name.localeCompare(b.name)); // 排序每个符号的属性和引脚 data.symbols.forEach((symbol) => { if (symbol.properties) { symbol.properties.sort((a, b) => a.name.localeCompare(b.name)); } if (symbol.pins) { symbol.pins.sort((a, b) => { const aNum = parseInt(a.number?.text) || 0; const bNum = parseInt(b.number?.text) || 0; return aNum - bNum; }); } }); } return JSON.stringify(data, null, 2); } catch { return jsonString; // 如果优化失败,返回原始数据 } } /** * 优化KiCad输出 */ optimizeKicadOutput(kicadString) { // 基本格式化优化 return kicadString .replace(/\s+/g, ' ') // 标准化空格 .replace(/\(\s+/g, '(') // 移除括号后的多余空格 .replace(/\s+\)/g, ')') // 移除括号前的多余空格 .split('\n') .map(line => line.trim()) .filter(line => line.length > 0) .join('\n'); } }