const fs = require('fs');
|
const path = require('path');
|
|
const JSON_FILES = [
|
'doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.BusinessLogic.json',
|
'doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.ImageProcessor.json',
|
'doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.ScannerController.json',
|
'doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.TransportManager.json',
|
'doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.UIView.json'
|
];
|
|
// 1.優先
|
// team_task_classification 團隊分工覆寫
|
const PRIM_TAGS_TO_FIE = {
|
// // ScannerController
|
// 'ScannerController.acquisitionHandler': 'scan/acquisition.pas',
|
// 'ScannerController.twainWrapper': 'scan/twain.pas',
|
//
|
// // ImageProcessor
|
// 'ImageProcessor.transformer': 'img/transformer.pas',
|
// 'ImageProcessor.converter': 'img/converter.pas',
|
// 'ImageProcessor.anchorAnalyzer': 'img/anchor.pas',
|
// 'ImageProcessor.payloadArchiver': 'img/imgArchiver.pas',
|
|
'初始化與生命週期': 'CB_IMGPSScanImp.lfcycle.pas',
|
'API 呼叫相關': 'CB_IMGPSScanImp.api.pas',
|
'轉換區(名稱/格式轉換)': 'CB_IMGPSScanImp.convert.pas',
|
'案件管理(TreeView / 案件操作)': 'CB_IMGPSScanImp.caseMgr.pas',
|
'清單管理': 'CB_IMGPSScanImp.listMgr.pas',
|
'檔案操作': 'CB_IMGPSScanImp.fileOp.pas',
|
'上傳前置資料產生': 'CB_IMGPSScanImp.prUpload.pas',
|
'文件份數/頁數/查詢': 'CB_IMGPSScanImp.docq.pas',
|
'自訂文件': 'CB_IMGPSScanImp.custdoc.pas',
|
'舊案/異動件處理': 'CB_IMGPSScanImp.docmod.pas',
|
'入庫文件/可見性': 'CB_IMGPSScanImp.inbound.pas',
|
// '影像瀏覽/顯示': 'CB_IMGPSScanImp.image.pas',
|
'OMR 檢核': 'CB_IMGPSScanImp.omr.pas',
|
'縮圖預覽(PreViewISB)': 'CB_IMGPSScanImp.preview.pas',
|
'其他內部': 'CB_IMGPSScanImp.misc.pas',
|
}
|
|
// 2.若 1未定義到, 則從這裡分類
|
const TAGS_TO_FILE = {
|
// ScannerController
|
'ScannerController.acquisitionHandler': 'scan/acquisition.pas',
|
'ScannerController.twainWrapper': 'scan/twain.pas',
|
|
// ImageProcessor
|
'ImageProcessor.transformer': 'img/transformer.pas',
|
'ImageProcessor.converter': 'img/converter.pas',
|
'ImageProcessor.anchorAnalyzer': 'img/anchor.pas',
|
'ImageProcessor.payloadArchiver': 'img/imgArchiver.pas',
|
|
// TransportManager
|
'TransportManager.apiClient': 'transp/apiClient.pas',
|
'TransportManager.fileTransfer': 'transp/fileClient.pas',
|
'TransportManager.certificateManager': 'transp/certManager.pas',
|
'TransportManager.payloadArchiver': 'transp/payloadArchiver.pas',
|
|
// BusinessLogic
|
'BusinessLogic.systemInternal': 'bloc/sys.pas',
|
'BusinessLogic.configRepository': 'bloc/cfg.pas',
|
'BusinessLogic.ormRuleEngine': 'bloc/ormRuleEngine.pas',
|
'BusinessLogic.entityMapping': 'bloc/entityMapping.pas',
|
'BusinessLogic.fileManager': 'bloc/fileManager.pas',
|
'BusinessLogic.caseManager': 'bloc/caseManager.pas',
|
'BusinessLogic.entityModel': 'bloc/entityModel.pas',
|
'BusinessLogic.activeXWrapper': 'bloc/ocx.pas',
|
|
// UIView
|
'UIView.statusMessenger': 'view/msger.pas',
|
'UIView.events': 'view/events.pas',
|
'UIView.i18n': 'view/i18n.pas',
|
'UIView.inputHandler': 'view/input.pas',
|
'UIView.configRepository': 'view/cfg.pas',
|
'UIView.treeView': 'view/treeView.pas',
|
'UIView.toolBar': 'view/toolBar.pas',
|
'UIView.imageScrollBox': 'view/isb.pas',
|
'UIView.popupMenu': 'view/popupMenu.pas',
|
'UIView.listView': 'view/listView.pas',
|
'UIView.scrollView': 'view/scrollView.pas',
|
'UIView.misc': 'view/misc.pas'
|
};
|
|
const SRC_FILE = 'CB_IMGPSScanImp.pas.bk';
|
const DEST_FILE = 'CB_IMGPSScanImp.pas';
|
const OUTPUT_DEST = 'reassemble';
|
const REMAININGS_FILE = 'scripts/dist/scanimpl_annalysis.remainings.txt';
|
|
function getVisualWidth(str) {
|
let width = 0;
|
for (let i = 0; i < str.length; i++) {
|
const code = str.charCodeAt(i);
|
if (code >= 0x4e00 && code <= 0x9fff) {
|
width += 2;
|
} else {
|
width += 1;
|
}
|
}
|
return width;
|
}
|
|
function wrapText(text, limit, wrapIndent) {
|
if (!text) return "";
|
|
// 處理 1. 2. 3. 這種標示點,先進行初步換行
|
// 尋找符合 "數字." 的模式,並在其前面加上換行符(如果不是在開頭的話)
|
let formattedText = text.replace(/(\d+\.)/g, (match, p1, offset) => {
|
return offset === 0 ? match : "\n" + match;
|
});
|
|
const segments = formattedText.split('\n');
|
let resultLines = [];
|
|
segments.forEach(segment => {
|
let currentLine = "";
|
let currentLineWidth = 0;
|
|
// 將 segment 依字元處理
|
for (let i = 0; i < segment.length; i++) {
|
const char = segment[i];
|
const charWidth = getVisualWidth(char);
|
|
if (currentLineWidth + charWidth > limit) {
|
resultLines.push(currentLine);
|
currentLine = char;
|
currentLineWidth = charWidth;
|
} else {
|
currentLine += char;
|
currentLineWidth += charWidth;
|
}
|
}
|
if (currentLine) resultLines.push(currentLine);
|
});
|
|
return resultLines.join("\n" + wrapIndent);
|
}
|
|
function getDocString(m) {
|
const methodName = m.matcher.match(/^(procedure|function)\s+TCB_IMGPSScanX\.([\w\.]+)/i)?.[2] || m.matcher;
|
const deps = (m.deps || []).join(', ');
|
const wrappedDeps = wrapText(deps, 68, " ");
|
const desc = m.description || '';
|
const wrappedDesc = wrapText(desc, 68, " ");
|
|
return `{ ==============================================================================
|
方法名稱:${methodName}
|
引用相依:${wrappedDeps}
|
方法描述:${wrappedDesc}
|
============================================================================== }\n`;
|
}
|
|
function main() {
|
console.log('Copying ' + SRC_FILE + ' to ' + DEST_FILE);
|
fs.copyFileSync(SRC_FILE, DEST_FILE);
|
|
const originalContent = fs.readFileSync(DEST_FILE, 'utf8');
|
const lines = originalContent.split(/\r?\n/);
|
|
const allMethods = [];
|
JSON_FILES.forEach(jsonFile => {
|
if (!fs.existsSync(jsonFile)) return;
|
const data = JSON.parse(fs.readFileSync(jsonFile, 'utf8'));
|
data.forEach(m => {
|
const lIndex = parseInt(m.lIndex);
|
const rIndex = parseInt(m.rIndex);
|
if (lIndex > 0 && rIndex > 0) {
|
allMethods.push({
|
...m,
|
lIndex,
|
rIndex
|
});
|
}
|
});
|
});
|
|
const lineToTargetFile = new Array(lines.length + 1).fill(null);
|
const fileToMethods = {};
|
|
allMethods.forEach(m => {
|
let targetFile = null;
|
// team_task_classification 團隊分工覆寫
|
if (!targetFile) {
|
for (const tag of m.tags) {
|
if (PRIM_TAGS_TO_FIE[tag]) {
|
targetFile = PRIM_TAGS_TO_FIE[tag];
|
break;
|
}
|
}
|
}
|
if (!targetFile) {
|
for (const tag of m.tags) {
|
if (TAGS_TO_FILE[tag]) {
|
targetFile = TAGS_TO_FILE[tag];
|
break;
|
}
|
}
|
}
|
|
if (!targetFile) targetFile = 'view/misc.pas';
|
|
if (!fileToMethods[targetFile]) {
|
fileToMethods[targetFile] = [];
|
}
|
fileToMethods[targetFile].push(m);
|
|
for (let i = m.lIndex; i <= m.rIndex; i++) {
|
if (i <= lines.length) {
|
lineToTargetFile[i] = targetFile;
|
}
|
}
|
});
|
|
// Create sub-files
|
for (const targetFile in fileToMethods) {
|
const methods = fileToMethods[targetFile];
|
methods.sort((a, b) => a.lIndex - b.lIndex);
|
|
let subFileContent = '';
|
methods.forEach(m => {
|
const methodLines = lines.slice(m.lIndex - 1, m.rIndex);
|
subFileContent += getDocString(m) + methodLines.join('\n') + '\n\n';
|
});
|
|
const fullPath = path.join(OUTPUT_DEST, targetFile);
|
fs.mkdirSync(path.dirname(fullPath), { recursive: true });
|
fs.writeFileSync(fullPath, subFileContent);
|
console.log(`Saved ${methods.length} methods to ${fullPath}`);
|
}
|
|
// Rewrite main file and generate remainings
|
const newMainLines = [];
|
const remainingsLines = [];
|
const includedFiles = new Set();
|
|
for (let i = 1; i <= lines.length; i++) {
|
const targetFile = lineToTargetFile[i];
|
if (targetFile) {
|
if (!includedFiles.has(targetFile)) {
|
newMainLines.push(`{$I ${OUTPUT_DEST}/${targetFile}}`);
|
includedFiles.add(targetFile);
|
}
|
} else {
|
newMainLines.push(lines[i - 1]);
|
remainingsLines.push(lines[i - 1]);
|
}
|
}
|
|
const finalContent = newMainLines.join('\n');
|
fs.writeFileSync(DEST_FILE, finalContent);
|
|
if (!fs.existsSync(path.dirname(REMAININGS_FILE))) {
|
fs.mkdirSync(path.dirname(REMAININGS_FILE), { recursive: true });
|
}
|
fs.writeFileSync(REMAININGS_FILE, remainingsLines.join('\n'));
|
|
console.log('\n--- Content of ' + DEST_FILE + ' after disaggregation ---\n');
|
console.log(finalContent.substring(0, 1000) + '\n...');
|
console.log('\n--- End of Preview ---\n');
|
console.log('Remainings saved to: ' + REMAININGS_FILE);
|
console.log('Done.');
|
}
|
|
main();
|