@ry-krystal/kicad-converter
Version:
专业的KiCad符号文件与JSON互转工具
202 lines (201 loc) • 7.04 kB
JavaScript
/**
* 增强版转换器实现
* 基于核心转换器,提供额外的优化和错误处理功能
*/
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');
}
}