generated from obsidianmd/obsidian-sample-plugin
-
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6 from davisriedel/master
Add API for use in other plugins or scripts
- Loading branch information
Showing
4 changed files
with
180 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { bake as bakeUtil } from "./bake"; | ||
import { | ||
TFile, | ||
} from 'obsidian'; | ||
import EasyBake, { BakeSettings } from './main'; | ||
|
||
export class EasyBakeApi { | ||
private plugin: EasyBake; | ||
|
||
constructor(plugin: EasyBake) { | ||
this.plugin = plugin; | ||
} | ||
|
||
public async bakeToString( | ||
inputPath: string, | ||
settings: BakeSettings | ||
) { | ||
const app = this.plugin.app; | ||
const file = app.vault.getAbstractFileByPath(inputPath); | ||
|
||
if (!(file instanceof TFile)) { | ||
console.error("Input file does not exist"); | ||
return; | ||
} | ||
|
||
return await bakeUtil(app, file, null, new Set(), settings); | ||
} | ||
|
||
public async bakeToFile( | ||
inputPath: string, | ||
outputPath: string, | ||
settings: BakeSettings | ||
) { | ||
const baked = await this.bakeToString(inputPath, settings); | ||
if (!baked) return; | ||
|
||
const app = this.plugin.app; | ||
let existing = app.vault.getAbstractFileByPath(outputPath); | ||
if (existing instanceof TFile) { | ||
await app.vault.modify(existing, baked); | ||
} else { | ||
existing = await app.vault.create(outputPath, baked); | ||
} | ||
} | ||
|
||
public async bakeAndOpen( | ||
inputPath: string, | ||
outputPath: string, | ||
settings: BakeSettings | ||
) { | ||
await this.bakeToFile(inputPath, outputPath, settings); | ||
|
||
const app = this.plugin.app; | ||
let existing = app.vault.getAbstractFileByPath(outputPath); | ||
if (existing instanceof TFile) { | ||
await app.workspace.getLeaf('tab').openFile(existing); | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import { | ||
App, | ||
FileSystemAdapter, | ||
Platform, | ||
TFile, | ||
parseLinktext, | ||
resolveSubpath, | ||
} from 'obsidian'; | ||
|
||
import { BakeSettings } from './main'; | ||
import { | ||
applyIndent, | ||
extractSubpath, | ||
sanitizeBakedContent, | ||
stripFirstBullet, | ||
} from './util'; | ||
|
||
const lineStartRE = /(?:^|\n) *$/; | ||
const listLineStartRE = /(?:^|\n)([ \t]*)(?:[-*+]|[0-9]+[.)]) +$/; | ||
const lineEndRE = /^ *(?:\r?\n|$)/; | ||
|
||
export async function bake( | ||
app: App, | ||
file: TFile, | ||
subpath: string | null, | ||
ancestors: Set<TFile>, | ||
settings: BakeSettings | ||
) { | ||
const { vault, metadataCache } = app; | ||
|
||
let text = await vault.cachedRead(file); | ||
const cache = metadataCache.getFileCache(file); | ||
|
||
// No cache? Return the file as is... | ||
if (!cache) return text; | ||
|
||
// Get the target block or section if we have a subpath | ||
const resolvedSubpath = subpath ? resolveSubpath(cache, subpath) : null; | ||
if (resolvedSubpath) { | ||
text = extractSubpath(text, resolvedSubpath, cache); | ||
} | ||
|
||
const links = settings.bakeLinks ? cache.links || [] : []; | ||
const embeds = settings.bakeEmbeds ? cache.embeds || [] : []; | ||
const targets = [...links, ...embeds]; | ||
|
||
// No links in the current file; we can stop here... | ||
if (targets.length === 0) return text; | ||
|
||
targets.sort((a, b) => a.position.start.offset - b.position.start.offset); | ||
|
||
const newAncestors = new Set(ancestors); | ||
newAncestors.add(file); | ||
|
||
// This helps us keep track of edits we make to the text and sync them with | ||
// position data held in the metadata cache | ||
let posOffset = 0; | ||
for (const target of targets) { | ||
const { path, subpath } = parseLinktext(target.link); | ||
const linkedFile = metadataCache.getFirstLinkpathDest(path, file.path); | ||
|
||
if (!linkedFile) continue; | ||
|
||
const start = target.position.start.offset + posOffset; | ||
const end = target.position.end.offset + posOffset; | ||
const prevLen = end - start; | ||
|
||
const before = text.substring(0, start); | ||
const after = text.substring(end); | ||
|
||
const listMatch = settings.bakeInList | ||
? before.match(listLineStartRE) | ||
: null; | ||
const isInline = | ||
!(listMatch || lineStartRE.test(before)) || !lineEndRE.test(after); | ||
const isMarkdownFile = linkedFile.extension === 'md'; | ||
|
||
const replaceTarget = (replacement: string) => { | ||
text = before + replacement + after; | ||
posOffset += replacement.length - prevLen; | ||
}; | ||
|
||
if (!isMarkdownFile) { | ||
// Skip link processing if we're not converting file links... | ||
if (!settings.convertFileLinks) continue; | ||
|
||
const adapter = app.vault.adapter as FileSystemAdapter; | ||
|
||
// FYI: The mobile adapter also has getFullPath so this should work on mobile and desktop | ||
// The mobile adapter isn't exported in the public API, however | ||
if (!adapter.getFullPath) continue; | ||
const fullPath = adapter.getFullPath(linkedFile.path); | ||
const protocol = Platform.isWin ? 'file:///' : 'file://'; | ||
replaceTarget(`![](${protocol}${encodeURI(fullPath)})`); | ||
continue; | ||
} | ||
|
||
// Replace the link with its text if the it's inline or would create an infinite loop | ||
if (newAncestors.has(linkedFile) || isInline) { | ||
replaceTarget(target.displayText || path); | ||
continue; | ||
} | ||
|
||
// Recurse and bake the linked file... | ||
const baked = sanitizeBakedContent( | ||
await bake(app, linkedFile, subpath, newAncestors, settings) | ||
); | ||
replaceTarget( | ||
listMatch ? applyIndent(stripFirstBullet(baked), listMatch[1]) : baked | ||
); | ||
} | ||
|
||
return text; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters