Skip to content

Commit

Permalink
Canvas Card and Md Files Content Scan Implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Ozan Tellioglu committed Feb 7, 2023
1 parent 496389a commit 0dcd3bf
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 8 deletions.
137 changes: 137 additions & 0 deletions src/linkDetector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import { TFile, App } from 'obsidian';

/* -------------------- LINK DETECTOR -------------------- */

type LinkType = 'markdown' | 'wiki' | 'wikiTransclusion' | 'mdTransclusion';

export interface LinkMatch {
type: LinkType;
match: string;
linkText: string;
sourceFilePath: string;
}

/**
*
* @param mdFile : File, of which the text content is scanned
* @param app : Obsidian App
* @param fileText : Optional, If file is not Md format, provide fileText to scan
* @returns Promise<LinkMatch[]>
*/
export const getAllLinkMatchesInFile = async (mdFile: TFile, app: App, fileText?: String): Promise<LinkMatch[]> => {
const linkMatches: LinkMatch[] = [];
if (fileText === undefined) {
fileText = await app.vault.read(mdFile);
}

// --> Get All WikiLinks
let wikiRegex = /\[\[.*?\]\]/g;
let wikiMatches = fileText.match(wikiRegex);
if (wikiMatches) {
let fileRegex = /(?<=\[\[).*?(?=(\]|\|))/;
let altRegex = /(?<=\|).*(?=]])/;

for (let wikiMatch of wikiMatches) {
// --> Check if it is Transclusion
if (matchIsWikiTransclusion(wikiMatch)) {
let fileName = getTransclusionFileName(wikiMatch);
if (fileName !== '') {
let linkMatch: LinkMatch = {
type: 'wikiTransclusion',
match: wikiMatch,
linkText: fileName,
sourceFilePath: mdFile.path,
};
linkMatches.push(linkMatch);
continue;
}
}
// --> Normal Internal Link
let fileMatch = wikiMatch.match(fileRegex);
if (fileMatch) {
// Web links are to be skipped
if (fileMatch[0].startsWith('http')) continue;
let linkMatch: LinkMatch = {
type: 'wiki',
match: wikiMatch,
linkText: fileMatch[0],
sourceFilePath: mdFile.path,
};
linkMatches.push(linkMatch);
}
}
}

// --> Get All Markdown Links
let markdownRegex = /\[(^$|.*?)\]\((.*?)\)/g;
let markdownMatches = fileText.match(markdownRegex);
if (markdownMatches) {
let fileRegex = /(?<=\().*(?=\))/;
let altRegex = /(?<=\[)(^$|.*?)(?=\])/;
for (let markdownMatch of markdownMatches) {
// --> Check if it is Transclusion
if (matchIsMdTransclusion(markdownMatch)) {
let fileName = getTransclusionFileName(markdownMatch);

if (fileName !== '') {
let linkMatch: LinkMatch = {
type: 'mdTransclusion',
match: markdownMatch,
linkText: fileName,

sourceFilePath: mdFile.path,
};
linkMatches.push(linkMatch);
continue;
}
}
// --> Normal Internal Link
let fileMatch = markdownMatch.match(fileRegex);
if (fileMatch) {
// Web links are to be skipped
if (fileMatch[0].startsWith('http')) continue;
let linkMatch: LinkMatch = {
type: 'markdown',
match: markdownMatch,
linkText: fileMatch[0],

sourceFilePath: mdFile.path,
};
linkMatches.push(linkMatch);
}
}
}
return linkMatches;
};

/* ---------- HELPERS ---------- */

const wikiTransclusionRegex = /\[\[(.*?)#.*?\]\]/;
const wikiTransclusionFileNameRegex = /(?<=\[\[)(.*)(?=#)/;
const wikiTransclusionBlockRef = /(?<=#).*?(?=]])/;

const mdTransclusionRegex = /\[.*?]\((.*?)#.*?\)/;
const mdTransclusionFileNameRegex = /(?<=\]\()(.*)(?=#)/;
const mdTransclusionBlockRef = /(?<=#).*?(?=\))/;

const matchIsWikiTransclusion = (match: string): boolean => {
return wikiTransclusionRegex.test(match);
};

const matchIsMdTransclusion = (match: string): boolean => {
return mdTransclusionRegex.test(match);
};

/**
* @param match
* @returns file name if there is a match or empty string if no match
*/
const getTransclusionFileName = (match: string): string => {
let isWiki = wikiTransclusionRegex.test(match);
let isMd = mdTransclusionRegex.test(match);
if (isWiki || isMd) {
let fileNameMatch = match.match(isWiki ? wikiTransclusionFileNameRegex : mdTransclusionFileNameRegex);
if (fileNameMatch) return fileNameMatch[0];
}
return '';
};
32 changes: 24 additions & 8 deletions src/util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { App, TFile } from 'obsidian';
import OzanClearImages from './main';
import { getAllLinkMatchesInFile, LinkMatch } from './linkDetector';

/* ------------------ Image Handlers ------------------ */

Expand Down Expand Up @@ -50,10 +51,7 @@ const getAttachmentPathSetForVault = async (app: App, type: 'image' | 'all'): Pr
if (resolvedLinks) {
for (const [mdFile, links] of Object.entries(resolvedLinks)) {
for (const [filePath, nr] of Object.entries(resolvedLinks[mdFile])) {
var imageMatch = filePath.match(imageRegex);
if (imageMatch) attachmentsSet.add(imageMatch[0]);
// If all, include the rest of the attachments
if (type === 'all' && !(filePath as String).endsWith('.md')) {
if (!(filePath as String).endsWith('.md')) {
attachmentsSet.add(filePath);
}
}
Expand All @@ -63,8 +61,9 @@ const getAttachmentPathSetForVault = async (app: App, type: 'image' | 'all'): Pr
let allFiles = app.vault.getFiles();
for (let i = 0; i < allFiles.length; i++) {
let obsFile = allFiles[i];
// Check Frontmatter for md files
// Check Frontmatter for md files and additional links that might be missed in resolved links
if (obsFile.extension === 'md') {
// Frontmatter
let fileCache = app.metadataCache.getFileCache(obsFile);
if (fileCache.frontmatter) {
let frontmatter = fileCache.frontmatter;
Expand All @@ -74,14 +73,19 @@ const getAttachmentPathSetForVault = async (app: App, type: 'image' | 'all'): Pr
let fileName = frontmatter[k].match(bannerRegex)[1];
let file = app.metadataCache.getFirstLinkpathDest(fileName, obsFile.path);
if (file) {
attachmentsSet.add(file.path);
addToSet(attachmentsSet, file.path);
}
} else if (pathIsAnImage(frontmatter[k])) {
attachmentsSet.add(frontmatter[k]);
addToSet(attachmentsSet, frontmatter[k]);
}
}
}
}
// Any Additional Link
let linkMatches: LinkMatch[] = await getAllLinkMatchesInFile(obsFile, app);
for (let linkMatch of linkMatches) {
addToSet(attachmentsSet, linkMatch.linkText);
}
}
// Check Canvas for links
else if (obsFile.extension === 'canvas') {
Expand All @@ -91,12 +95,18 @@ const getAttachmentPathSetForVault = async (app: App, type: 'image' | 'all'): Pr
for (const node of canvasData.nodes) {
// node.type: 'text' | 'file'
if (node.type === 'file') {
attachmentsSet.add(node.file);
addToSet(attachmentsSet, node.file);
} else if (node.type == 'text') {
let linkMatches: LinkMatch[] = await getAllLinkMatchesInFile(obsFile, app, node.text);
for (let linkMatch of linkMatches) {
addToSet(attachmentsSet, linkMatch.linkText);
}
}
}
}
}
}
console.log(attachmentsSet);
return attachmentsSet;
};

Expand Down Expand Up @@ -181,3 +191,9 @@ export const getFormattedDate = () => {
second: '2-digit',
});
};

const addToSet = (setObj: Set<string>, value: string) => {
if (!setObj.has(value)) {
setObj.add(value);
}
};

0 comments on commit 0dcd3bf

Please sign in to comment.