Skip to content

Commit 9f3d51e

Browse files
committed
fix: super-robust dual-mode branching tree detection
1 parent d81d27c commit 9f3d51e

1 file changed

Lines changed: 28 additions & 17 deletions

File tree

js/detail.js

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -255,16 +255,29 @@
255255
'</div>';
256256
};
257257

258-
// DETECTION: Check for square brackets [Path 1] [Path 2] first, then fall back to pipes
258+
// SUPER ROBUST DETECTION & NORMALIZATION
259+
// 1. Convert all variations to standard chars
260+
var cleanRec = rec.replace(/[]/g, '|')
261+
.replace(/[]/g, '[')
262+
.replace(/[]/g, ']')
263+
.replace(/&lbrack;/g, '[')
264+
.replace(/&rbrack;/g, ']')
265+
.replace(/&#91;/g, '[')
266+
.replace(/&#93;/g, ']');
267+
259268
var rawPaths = [];
260-
var bracketMatches = rec.match(/\[([^\]]+)\]/g);
269+
// 2. Bracket Split: look for the gap between brackets: ] [ or ][
270+
if (cleanRec.indexOf('[') !== -1 && cleanRec.indexOf(']') !== -1) {
271+
rawPaths = cleanRec.split(/\]\s*\[/).map(function(p) {
272+
return p.replace(/[\[\]]/g, '').trim();
273+
}).filter(Boolean);
274+
}
261275

262-
if (bracketMatches && bracketMatches.length > 1) {
263-
rawPaths = bracketMatches.map(function(m) {
264-
return m.replace(/[\[\]]/g, '').trim();
276+
// 3. Fallback to Pipe Split:
277+
if (rawPaths.length <= 1) {
278+
rawPaths = cleanRec.split(/[|]/).map(function (s) {
279+
return s.replace(/[\[\]]/g, '').trim();
265280
}).filter(Boolean);
266-
} else {
267-
rawPaths = rec.split(/[|]/).map(function (s) { return s.trim(); }).filter(Boolean);
268281
}
269282

270283
var pathHTML = '<div class="enhancement-tree">';
@@ -273,21 +286,20 @@
273286
// BRANCHING LOGIC
274287
// 1. Parse all paths into arrays of steps
275288
var processedPaths = rawPaths.map(function(p) {
276-
return p.split(/[>;;]/).map(function(s) { return s.trim(); }).filter(Boolean);
289+
return p.split(/[>;;]/).map(function(s) {
290+
return s.replace(/[\[\]]/g, '').trim();
291+
}).filter(Boolean);
277292
});
278293

279294
// 2. Identify common root (assume first item of first path as root candidate)
280-
var rootName = processedPaths[0][0];
281-
var allShareRoot = processedPaths.every(function(p) {
295+
var rootName = (processedPaths[0] && processedPaths[0][0]) || '';
296+
var allShareRoot = rootName && processedPaths.every(function(p) {
282297
return p.length > 0 && p[0].toLowerCase() === rootName.toLowerCase();
283298
});
284299

285300
if (allShareRoot) {
286-
// Render Shared Root Node
287301
pathHTML += renderNode(rootName, 'base', name);
288302
pathHTML += '<div class="enhancement-arrow">↓</div>';
289-
290-
// Remove root from each path for branching display
291303
processedPaths.forEach(function(p) { p.shift(); });
292304
}
293305

@@ -298,9 +310,7 @@
298310
pathHTML += '<div class="enhancement-branch">';
299311
steps.forEach(function(sName, idx) {
300312
var rank = (idx === steps.length - 1) ? 'max' : 'up';
301-
// If we didn't have a shared root, the first item of each branch might be 'base'
302313
if (!allShareRoot && idx === 0) rank = 'base';
303-
304314
pathHTML += renderNode(sName, rank, name);
305315
if (idx < steps.length - 1) pathHTML += '<div class="enhancement-arrow">↓</div>';
306316
});
@@ -310,12 +320,13 @@
310320
pathHTML += '</div>';
311321
} else {
312322
// LINEAR LOGIC
313-
var steps = rec.split(/[>;|]/).map(function (s) { return s.trim(); }).filter(Boolean);
323+
var steps = cleanRec.split(/[>;|]/).map(function (s) {
324+
return s.replace(/[\[\]]/g, '').trim();
325+
}).filter(Boolean);
314326
steps.forEach(function (stepName, idx) {
315327
var rank = "up";
316328
if (idx === 0) rank = "base";
317329
else if (idx === steps.length - 1 && steps.length > 1) rank = "max";
318-
319330
pathHTML += renderNode(stepName, rank, name);
320331
if (idx < steps.length - 1) pathHTML += '<div class="enhancement-arrow">↓</div>';
321332
});

0 commit comments

Comments
 (0)