Skip to content

Commit

Permalink
feat(WriteBCToFile): ✨ Option to write as inline fields (fix #140)
Browse files Browse the repository at this point in the history
  • Loading branch information
SkepticMystic committed Nov 19, 2021
1 parent a6cdeab commit dded0df
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 72 deletions.
92 changes: 58 additions & 34 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2626,6 +2626,7 @@ const DEFAULT_SETTINGS = {
trailSeperator: "→",
respectReadableLineLength: true,
limitWriteBCCheckboxStates: {},
writeBCsInline: false,
showWriteAllBCsCmd: false,
visGraph: "Force Directed Graph",
visRelation: "Parent",
Expand Down Expand Up @@ -20309,13 +20310,27 @@ const hierToStr = (hier) => DIRECTIONS.map((dir) => `${ARROW_DIRECTIONS[dir]}: $
function removeDuplicates(arr) {
return [...new Set(arr)];
}
const getOppDir = (dir) => {
switch (dir) {
case "up":
return "down";
case "down":
return "up";
case "same":
return "same";
case "next":
return "prev";
case "prev":
return "next";
}
};
/**
* Adds or updates the given yaml `key` to `value` in the given TFile
* @param {string} key
* @param {string} value
* @param {TFile} file
* @param {FrontMatterCache|undefined} frontmatter
* @param {{[fun:string]:(...args:any} api
* @param {MetaeditApi} api
*/
const createOrUpdateYaml = async (key, value, file, frontmatter, api) => {
const valueStr = value.toString();
Expand All @@ -20329,48 +20344,50 @@ const createOrUpdateYaml = async (key, value, file, frontmatter, api) => {
}
else {
const oldValueFlat = [...[frontmatter[key]]].flat(4);
const newValue = [...oldValueFlat, valueStr].map((val) => `'${val}'`);
const newValue = [...oldValueFlat, `'${valueStr}'`];
console.log(`Updating: ${key}: ${newValue}`);
await api.update(key, `[${newValue.join(", ")}]`, file);
}
};
const getOppDir = (dir) => {
switch (dir) {
case "up":
return "down";
case "down":
return "up";
case "same":
return "same";
case "next":
return "prev";
case "prev":
return "next";
}
};
const writeBCToFile = (app, plugin, currGraphs, file) => {
const writeBCToFile = async (app, plugin, currGraphs, file, inline) => {
var _a, _b;
const { limitWriteBCCheckboxStates, userHierarchies } = plugin.settings;
const frontmatter = (_a = app.metadataCache.getFileCache(file)) === null || _a === void 0 ? void 0 : _a.frontmatter;
const api = (_b = app.plugins.plugins.metaedit) === null || _b === void 0 ? void 0 : _b.api;
if (!api) {
new obsidian.Notice("Metaedit must be enabled for this function to work");
return;
}
iterateAllGs(currGraphs.hierGs, (fieldG, dir, fieldName) => {
const oppDir = getOppDir(dir);
const succs = getInNeighbours(fieldG, file.basename);
succs.forEach(async (succ) => {
const { fieldName } = fieldG.getNodeAttributes(succ);
if (!plugin.settings.limitWriteBCCheckboxStates[fieldName])
return;
const currHier = plugin.settings.userHierarchies.find((hier) => hier[dir].includes(fieldName));
let oppField = currHier[oppDir][0];
if (!oppField)
oppField = `<Reverse>${fieldName}`;
await createOrUpdateYaml(oppField, succ, file, frontmatter, api);
});
});
const { main } = currGraphs;
const succs = getInNeighbours(main, file.basename);
for (const succ of succs) {
const { fieldName } = main.getNodeAttributes(succ);
if (!limitWriteBCCheckboxStates[fieldName])
return;
if (!inline) {
await createOrUpdateYaml(fieldName, succ, file, frontmatter, api);
}
else {
// TODO Check if this note already has this field
let content = await app.vault.read(file);
const splits = splitAtYaml(content);
content = splits[0] + `\n${fieldName}:: [[${succ}]]` + splits[1];
await app.vault.modify(file, content);
}
}
};
function splitAtYaml(content) {
const startsWithYaml = content.startsWith("---");
if (!startsWithYaml)
return ["", content];
else {
const splits = content.split("---");
return [
splits.slice(0, 2).join("---") + "---",
splits.slice(2).join("---"),
];
}
}
function oppFields(field, dir, userHierarchies) {
var _a, _b;
const oppDir = getOppDir(dir);
Expand Down Expand Up @@ -23860,6 +23877,13 @@ class BCSettingTab extends obsidian.PluginSettingTab {
});
}
drawLimitWriteBCCheckboxes(limitWriteBCCheckboxDiv);
new obsidian.Setting(writeBCsToFileDetails)
.setName("Write BCs to file Inline")
.setDesc("When writing BCs to file, should they be written inline (using Dataview syntax), or into the YAML of the note?")
.addToggle((toggle) => toggle.setValue(settings.writeBCsInline).onChange(async (value) => {
settings.writeBCsInline = value;
await plugin.saveSettings();
}));
new obsidian.Setting(writeBCsToFileDetails)
.setName("Show the `Write Breadcrumbs to ALL Files` command")
.setDesc("This command attempts to update ALL files with implied breadcrumbs pointing to them. So, it is not shown by default (even though it has 3 confirmation boxes to ensure you want to run it")
Expand Down Expand Up @@ -35136,9 +35160,9 @@ class BCPlugin extends obsidian.Plugin {
this.addCommand({
id: "Write-Breadcrumbs-to-Current-File",
name: "Write Breadcrumbs to Current File",
callback: () => {
callback: async () => {
const currFile = this.app.workspace.getActiveFile();
writeBCToFile(this.app, this, this.currGraphs, currFile);
await writeBCToFile(this.app, this, this.currGraphs, currFile, this.settings.writeBCsInline);
},
});
this.addCommand({
Expand All @@ -35154,7 +35178,7 @@ class BCPlugin extends obsidian.Plugin {
try {
this.app.vault
.getMarkdownFiles()
.forEach((file) => writeBCToFile(this.app, this, this.currGraphs, file));
.forEach(async (file) => await writeBCToFile(this.app, this, this.currGraphs, file, this.settings.writeBCsInline));
new obsidian.Notice("Operation Complete");
}
catch (error) {
Expand Down
12 changes: 12 additions & 0 deletions src/BreadcrumbsSettingTab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,18 @@ export class BCSettingTab extends PluginSettingTab {

drawLimitWriteBCCheckboxes(limitWriteBCCheckboxDiv);

new Setting(writeBCsToFileDetails)
.setName("Write BCs to file Inline")
.setDesc(
"When writing BCs to file, should they be written inline (using Dataview syntax), or into the YAML of the note?"
)
.addToggle((toggle) =>
toggle.setValue(settings.writeBCsInline).onChange(async (value) => {
settings.writeBCsInline = value;
await plugin.saveSettings();
})
);

new Setting(writeBCsToFileDetails)
.setName("Show the `Write Breadcrumbs to ALL Files` command")
.setDesc(
Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ export const DEFAULT_SETTINGS: BCSettings = {
trailSeperator: "→",
respectReadableLineLength: true,
limitWriteBCCheckboxStates: {},
writeBCsInline: false,
showWriteAllBCsCmd: false,
visGraph: "Force Directed Graph",
visRelation: "Parent",
Expand Down
25 changes: 25 additions & 0 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export interface BCSettings {
trailSeperator: string;
respectReadableLineLength: boolean;
limitWriteBCCheckboxStates: { [field: string]: boolean };
writeBCsInline: boolean;
showWriteAllBCsCmd: boolean;
visGraph: visTypes;
visRelation: Relations;
Expand Down Expand Up @@ -208,3 +209,27 @@ export type ClosedGraphs = {
};

export type PrevNext = { to: string; real: boolean; fieldName: string };

export interface MetaeditApi {
/** Adds the key and value */
createYamlProperty: (
key: string,
value: string,
file: TFile
) => Promise<void>;
/** Changes `key`'s value to `value` (overwrites) */
update: (key: string, value: string, file: TFile) => Promise<void>;
}

declare module "obsidian" {
interface App {
plugins: {
plugins: {
dataview: { api: { page: (page: string) => dvFrontmatterCache } };
metaedit: {
api: MetaeditApi;
};
};
};
}
}
21 changes: 17 additions & 4 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,15 @@ export default class BCPlugin extends Plugin {
this.addCommand({
id: "Write-Breadcrumbs-to-Current-File",
name: "Write Breadcrumbs to Current File",
callback: () => {
callback: async () => {
const currFile = this.app.workspace.getActiveFile();
writeBCToFile(this.app, this, this.currGraphs, currFile);
await writeBCToFile(
this.app,
this,
this.currGraphs,
currFile,
this.settings.writeBCsInline
);
},
});

Expand All @@ -211,8 +217,15 @@ export default class BCPlugin extends Plugin {
try {
this.app.vault
.getMarkdownFiles()
.forEach((file) =>
writeBCToFile(this.app, this, this.currGraphs, file)
.forEach(
async (file) =>
await writeBCToFile(
this.app,
this,
this.currGraphs,
file,
this.settings.writeBCsInline
)
);
new Notice("Operation Complete");
} catch (error) {
Expand Down
84 changes: 50 additions & 34 deletions src/sharedFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import type {
HierarchyFields,
HierarchyGraphs,
JugglLink,
MetaeditApi,
neighbourObj,
PrevNext,
userHierarchy,
Expand Down Expand Up @@ -643,20 +644,35 @@ export function removeDuplicates<T>(arr: T[]) {
return [...new Set(arr)];
}

export const getOppDir = (dir: Directions): Directions => {
switch (dir) {
case "up":
return "down";
case "down":
return "up";
case "same":
return "same";
case "next":
return "prev";
case "prev":
return "next";
}
};

/**
* Adds or updates the given yaml `key` to `value` in the given TFile
* @param {string} key
* @param {string} value
* @param {TFile} file
* @param {FrontMatterCache|undefined} frontmatter
* @param {{[fun:string]:(...args:any} api
* @param {MetaeditApi} api
*/
export const createOrUpdateYaml = async (
key: string,
value: string,
file: TFile,
frontmatter: FrontMatterCache | undefined,
api: { [fun: string]: (...args: any) => any }
api: MetaeditApi
) => {
const valueStr = value.toString();

Expand All @@ -668,33 +684,20 @@ export const createOrUpdateYaml = async (
return;
} else {
const oldValueFlat: string[] = [...[frontmatter[key]]].flat(4);
const newValue = [...oldValueFlat, valueStr].map((val) => `'${val}'`);
const newValue = [...oldValueFlat, `'${valueStr}'`];
console.log(`Updating: ${key}: ${newValue}`);
await api.update(key, `[${newValue.join(", ")}]`, file);
}
};

export const getOppDir = (dir: Directions): Directions => {
switch (dir) {
case "up":
return "down";
case "down":
return "up";
case "same":
return "same";
case "next":
return "prev";
case "prev":
return "next";
}
};

export const writeBCToFile = (
export const writeBCToFile = async (
app: App,
plugin: BCPlugin,
currGraphs: BCIndex,
file: TFile
file: TFile,
inline: boolean
) => {
const { limitWriteBCCheckboxStates, userHierarchies } = plugin.settings;
const frontmatter = app.metadataCache.getFileCache(file)?.frontmatter;
const api = app.plugins.plugins.metaedit?.api;

Expand All @@ -703,25 +706,38 @@ export const writeBCToFile = (
return;
}

iterateAllGs(currGraphs.hierGs, (fieldG, dir, fieldName) => {
const oppDir = getOppDir(dir);
const succs = getInNeighbours(fieldG, file.basename);
const { main } = currGraphs;
const succs = getInNeighbours(main, file.basename);

succs.forEach(async (succ) => {
const { fieldName } = fieldG.getNodeAttributes(succ);
if (!plugin.settings.limitWriteBCCheckboxStates[fieldName]) return;
for (const succ of succs) {
const { fieldName } = main.getNodeAttributes(succ);
if (!limitWriteBCCheckboxStates[fieldName]) return;

const currHier = plugin.settings.userHierarchies.find((hier) =>
hier[dir].includes(fieldName)
);
let oppField: string = currHier[oppDir][0];
if (!oppField) oppField = `<Reverse>${fieldName}`;
if (!inline) {
await createOrUpdateYaml(fieldName, succ, file, frontmatter, api);
} else {
// TODO Check if this note already has this field
let content = await app.vault.read(file);
const splits = splitAtYaml(content);
content = splits[0] + `\n${fieldName}:: [[${succ}]]` + splits[1];

await createOrUpdateYaml(oppField, succ, file, frontmatter, api);
});
});
await app.vault.modify(file, content);
}
}
};

function splitAtYaml(content: string): [string, string] {
const startsWithYaml = content.startsWith("---");
if (!startsWithYaml) return ["", content];
else {
const splits = content.split("---");
return [
splits.slice(0, 2).join("---") + "---",
splits.slice(2).join("---"),
];
}
}

export function oppFields(
field: string,
dir: Directions,
Expand Down

0 comments on commit dded0df

Please sign in to comment.