Skip to content

Commit

Permalink
feat(Hierarchy Note): ✨ Much better reliability + indicate field befo…
Browse files Browse the repository at this point in the history
…re link (fix #102)

- upFieldName [[Link]]
  • Loading branch information
SkepticMystic committed Nov 19, 2021
1 parent 74992ad commit 1cedf22
Show file tree
Hide file tree
Showing 4 changed files with 273 additions and 274 deletions.
244 changes: 118 additions & 126 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -20801,6 +20801,26 @@ function iterateAllGs(currGraphs, cb) {
}
}
}
/**
* Get all the fields in `dir`.
* Returns all fields if `dir === 'all'`
* @param {userHierarchy[]} userHierarchies
* @param {Directions|"all"} dir
*/
function getFields(userHierarchies, dir = "all") {
const fields = [];
userHierarchies.forEach((hier) => {
if (dir === "all") {
DIRECTIONS.forEach((eachDir) => {
fields.push(...hier[eachDir]);
});
}
else {
fields.push(...hier[dir]);
}
});
return fields;
}
function getAllFieldGs(fields, currGraphs) {
const fieldGs = [];
iterateAllGs(currGraphs, (g, dir, fieldName) => {
Expand All @@ -20810,9 +20830,6 @@ function getAllFieldGs(fields, currGraphs) {
return fieldGs;
}
const hierToStr = (hier) => DIRECTIONS.map((dir) => `${ARROW_DIRECTIONS[dir]}: ${hier[dir].join(", ")}`).join("\n");
function removeDuplicates(arr) {
return [...new Set(arr)];
}
const getOppDir = (dir) => {
switch (dir) {
case "up":
Expand Down Expand Up @@ -35249,78 +35266,6 @@ class BCPlugin extends obsidian.Plugin {
this.registerInterval(this.refreshIntervalID);
}
};
this.hierarchyNoteAdjList = (str) => {
let noteContent = str;
const { settings } = this;
const yamlRegex = new RegExp(/^---.*/);
const hasYaml = yamlRegex.test(noteContent);
if (hasYaml) {
noteContent = noteContent.split("---").slice(2).join("---");
}
const layers = noteContent.split("\n").filter((line) => line);
const getDepth = (line) => line.split(/[-*+]/)[0].length;
const depths = layers.map(getDepth);
const differences = [];
depths.forEach((dep, i) => {
if (i >= 1) {
differences.push(dep - depths[i - 1]);
}
});
debug(settings, { differences });
const posDifferences = differences
.filter((diff) => diff !== 0)
.map(Math.abs);
const lcm = Math.min(...posDifferences);
if (!posDifferences.every((diff) => diff % lcm === 0)) {
new obsidian.Notice("Please make sure the indentation is consistent in your hierarchy note.");
return [];
}
const difference = lcm;
const adjItems = [];
// TODO Allow user to pick the field name they want
const lineRegex = new RegExp(/\s*[-*+] \[\[(.*)\]\]/);
const pushNoteUp = (hier, currNote, currDepth) => {
const copy = [...hier];
const noteUp = copy
.reverse()
.findIndex((adjItem) => adjItem.depth === currDepth - difference);
if (noteUp > -1)
hier[noteUp].children.push(currNote);
};
let lineNo = 0;
while (lineNo < layers.length) {
const currLine = layers[lineNo];
const currNote = currLine.match(lineRegex)[1];
const currDepth = getDepth(currLine);
adjItems[lineNo] = { note: currNote, depth: currDepth, children: [] };
if (lineNo !== layers.length - 1) {
const nextLine = layers[lineNo + 1];
const nextNote = nextLine.match(lineRegex)[1];
const nextDepth = getDepth(nextLine);
if (nextDepth > currDepth) {
adjItems[lineNo].children.push(nextNote);
pushNoteUp(adjItems, currNote, currDepth);
}
else if (currDepth === 0)
return;
else {
pushNoteUp(adjItems, currNote, currDepth);
}
}
else {
const prevLine = layers[lineNo - 1];
const prevDepth = getDepth(prevLine);
if (prevDepth >= currDepth) {
pushNoteUp(adjItems, currNote, currDepth);
}
}
lineNo++;
}
adjItems.forEach((item) => {
item.children = removeDuplicates(item.children);
});
return adjItems;
};
}
async refreshIndex() {
if (!this.activeLeafChange)
Expand Down Expand Up @@ -35395,7 +35340,7 @@ class BCPlugin extends obsidian.Plugin {
this.addCommand({
id: "open-vis-modal",
name: "Open Visualisation Modal",
callback: async () => {
callback: () => {
new VisModal(this.app, this).open();
},
});
Expand Down Expand Up @@ -35453,6 +35398,54 @@ class BCPlugin extends obsidian.Plugin {
}
return null;
}
async getHierarchyNoteItems(file) {
const { listItems } = this.app.metadataCache.getFileCache(file);
if (!listItems)
return [];
const content = await this.app.vault.cachedRead(file);
const lines = content.split("\n");
const hierarchyNoteItems = [];
const afterBulletReg = new RegExp(/\s*[+*-]\s(.*$)/);
const dropWikiLinksReg = new RegExp(/\[\[(.*?)\]\]/);
const fieldNameReg = new RegExp(/(.*?)\[\[.*?\]\]/);
const problemFields = [];
const upFields = getFields(this.settings.userHierarchies, "up");
for (const item of listItems) {
const currItem = lines[item.position.start.line];
const afterBulletCurr = afterBulletReg.exec(currItem)[1];
const dropWikiCurr = dropWikiLinksReg.exec(afterBulletCurr)[1];
let fieldNameCurr = fieldNameReg.exec(afterBulletCurr)[1].trim() || null;
// Ensure fieldName is one of the existing up fields. `null` if not
if (fieldNameCurr !== null && !upFields.includes(fieldNameCurr)) {
problemFields.push(fieldNameCurr);
fieldNameCurr = null;
}
const { parent } = item;
if (parent >= 0) {
const parentNote = lines[parent];
const afterBulletParent = afterBulletReg.exec(parentNote)[1];
const dropWikiParent = dropWikiLinksReg.exec(afterBulletParent)[1];
hierarchyNoteItems.push({
currNote: dropWikiCurr,
parentNote: dropWikiParent,
fieldName: fieldNameCurr,
});
}
else {
hierarchyNoteItems.push({
currNote: dropWikiCurr,
parentNote: null,
fieldName: fieldNameCurr,
});
}
}
if (problemFields.length > 0) {
const msg = `'${problemFields.join(", ")}' is/are not in any of your hierarchies, but are being used in: '${file.basename}'`;
new obsidian.Notice(msg);
console.log(msg, { problemFields });
}
return hierarchyNoteItems;
}
// SECTION OneSource
populateGraph(g, currFileName, fieldValues, dir, fieldName) {
//@ts-ignore
Expand All @@ -35466,6 +35459,25 @@ class BCPlugin extends obsidian.Plugin {
addEdgeIfNot(g, currFileName, value, { dir, fieldName });
});
}
populateMain(main, currFileName, dir, fieldName, targets, neighbours, neighbourObjArr) {
addNodeIfNot(main, currFileName, {
dir,
fieldName,
order: neighbours.order,
});
targets.forEach((target) => {
var _a, _b;
addNodeIfNot(main, target, {
dir,
fieldName,
order: (_b = (_a = neighbourObjArr.find((neighbour) => (neighbour.current.basename || neighbour.current.name) === target)) === null || _a === void 0 ? void 0 : _a.order) !== null && _b !== void 0 ? _b : 9999,
});
addEdgeIfNot(main, currFileName, target, {
dir,
fieldName,
});
});
}
async getCSVRows() {
const { CSVPaths } = this.settings;
const CSVRows = [];
Expand Down Expand Up @@ -35514,21 +35526,17 @@ class BCPlugin extends obsidian.Plugin {
}
const neighbourObjArr = await getNeighbourObjArr(this, fileFrontmatterArr);
debugGroupStart(settings, "debugMode", "Hierarchy Note Adjacency List");
let hierarchyNotesArr = [];
const hierarchyNotesArr = [];
if (settings.hierarchyNotes[0] !== "") {
const contentArr = [];
settings.hierarchyNotes.forEach(async (note) => {
for (const note of settings.hierarchyNotes) {
const file = this.app.metadataCache.getFirstLinkpathDest(note, "");
if (file) {
const content = await this.app.vault.cachedRead(file);
contentArr.push(content);
hierarchyNotesArr.push(...(await this.getHierarchyNoteItems(file)));
}
else {
new obsidian.Notice(`${note} is no longer in your vault. The Hierarchy note should still work, but it is best to remove ${note} from your list of hierarchy notes in Breadcrumbs settings.`);
new obsidian.Notice(`${note} is no longer in your vault. It is best to remove it in Breadcrumbs settings.`);
}
});
await Promise.all(contentArr);
hierarchyNotesArr = contentArr.map(this.hierarchyNoteAdjList).flat();
}
debug(settings, { hierarchyNotesArr });
}
debugGroupEnd(settings, "debugMode");
Expand Down Expand Up @@ -35562,24 +35570,7 @@ class BCPlugin extends obsidian.Plugin {
const g = graphs.hierGs[i][dir][fieldName];
const targets = hier[dir][fieldName];
this.populateGraph(g, currFileName, targets, dir, fieldName);
addNodeIfNot(graphs.main, currFileName, {
dir,
fieldName,
order: neighbours.order,
});
targets.forEach((target) => {
var _a, _b;
addNodeIfNot(graphs.main, target, {
dir,
fieldName,
order: (_b = (_a = neighbourObjArr.find((neighbour) => (neighbour.current.basename || neighbour.current.name) ===
target)) === null || _a === void 0 ? void 0 : _a.order) !== null && _b !== void 0 ? _b : 9999,
});
addEdgeIfNot(graphs.main, currFileName, target, {
dir,
fieldName,
});
});
this.populateMain(graphs.main, currFileName, dir, fieldName, targets, neighbours, neighbourObjArr);
if (useCSV) {
this.addCSVCrumbs(g, CSVRows, dir, fieldName);
this.addCSVCrumbs(graphs.main, CSVRows, dir, fieldName);
Expand All @@ -35589,33 +35580,34 @@ class BCPlugin extends obsidian.Plugin {
});
});
if (hierarchyNotesArr.length) {
const { hierarchyNoteUpFieldName, hierarchyNoteDownFieldName } = settings;
if (hierarchyNoteUpFieldName !== "") {
const gUp = graphs.hierGs.find((hierG) => hierG.up[hierarchyNoteUpFieldName]).up[hierarchyNoteUpFieldName];
hierarchyNotesArr.forEach((adjListItem) => {
adjListItem.children.forEach((child) => {
//@ts-ignore
addNodeIfNot(gUp, adjListItem.note, { dir: "up" });
gUp.addEdge(child, adjListItem.note, {
dir: "up",
fieldName: hierarchyNoteUpFieldName,
});
const { hierarchyNoteUpFieldName } = settings;
const { main } = graphs;
const upFields = getFields(userHierarchies, "up");
hierarchyNotesArr.forEach((hnItem) => {
var _a, _b;
if (hnItem.parentNote === null)
return;
const upField = (_a = hnItem.fieldName) !== null && _a !== void 0 ? _a : (hierarchyNoteUpFieldName || upFields[0]);
const downField = (_b = getOppFields(userHierarchies, upField)[0]) !== null && _b !== void 0 ? _b : `${upField}<up>`;
const gUp = graphs.hierGs.find((hierG) => hierG.up[upField]).up[upField];
const gDown = graphs.hierGs.find((hierG) => hierG.down[downField]).down[downField];
[gUp, main].forEach((g) => {
addNodeIfNot(g, hnItem.currNote);
addNodeIfNot(g, hnItem.parentNote);
addEdgeIfNot(g, hnItem.currNote, hnItem.parentNote, {
dir: "up",
fieldName: upField,
});
});
}
if (hierarchyNoteDownFieldName !== "") {
const gDown = graphs.hierGs.find((hierG) => hierG.down[hierarchyNoteDownFieldName]).down[hierarchyNoteDownFieldName];
hierarchyNotesArr.forEach((adjListItem) => {
adjListItem.children.forEach((child) => {
//@ts-ignore
addNodeIfNot(gDown, adjListItem.note, { dir: "down" });
gDown.addEdge(adjListItem.note, child, {
dir: "down",
fieldName: hierarchyNoteDownFieldName,
});
[gDown, main].forEach((g) => {
addNodeIfNot(g, hnItem.parentNote);
addNodeIfNot(g, hnItem.currNote);
addEdgeIfNot(g, hnItem.parentNote, hnItem.currNote, {
dir: "down",
fieldName: downField,
});
});
}
});
}
DIRECTIONS.forEach((dir) => {
const allXGs = getAllGsInDir(graphs.hierGs, dir);
Expand Down
5 changes: 5 additions & 0 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ export interface ParentObj {
current: TFile;
parents: string[];
}
export interface HierarchyNoteItem {
parentNote: string;
fieldName: string;
currNote: string;
}

export interface fileFrontmatter {
file: TFile;
Expand Down
Loading

0 comments on commit 1cedf22

Please sign in to comment.