Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add reference to block in pages that were linked. #89

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,16 @@ const settings: SettingSchemaDesc[] = [
"a,b,c,card,now,later,todo,doing,done,wait,waiting,canceled,cancelled,started,in-progress",
title: "Pages to ignore when generating links",
},
{
key: "referenceInPages",
description: "Add the block parsed to the end of the pages that links were generated for.",
type: "boolean",
default: false,
title: "Append block reference to pages linked",
},
];
logseq.useSettingsSchema(settings);

async function getPages() {
const propertyBasedIgnoreList = await fetchPropertyIgnoreList();
let pagesToIgnore = logseq.settings?.pagesToIgnore
Expand Down Expand Up @@ -133,14 +141,30 @@ async function parseBlockForLink(d: string) {
});

let needsUpdate = false;
[content, needsUpdate] = replaceContentWithPageLinks(
let pagesFound = [];
[content, needsUpdate, pagesFound] = replaceContentWithPageLinks(
pageList,
content,
logseq.settings?.parseAsTags,
logseq.settings?.parseSingleWordAsTag
);
if (needsUpdate) {
logseq.Editor.updateBlock(block.uuid, `${content}`);

if (logseq.settings?.referenceInPages) {
for (let page of pagesFound) {
const blocksInPage = await logseq.Editor.getPageBlocksTree(page);

let blockContent = "((" + block.uuid + "))";
if (!blocksInPage?.some(b => b.content == blockContent)) {
logseq.Editor.insertBlock(
page,
blockContent,
{ isPageBlock: true }
);
}
}
}
}
}
}
Expand Down
7 changes: 5 additions & 2 deletions src/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export function replaceContentWithPageLinks(
content: string,
parseAsTags: boolean,
parseSingleWordAsTag: boolean
): [string, boolean] {
): [string, boolean, string[]] {
// Handle content that should not be automatically linked
const codeblockReversalTracker = [];
const inlineCodeReversalTracker = [];
Expand Down Expand Up @@ -100,6 +100,7 @@ export function replaceContentWithPageLinks(
);

let needsUpdate = false;
let pagesFound = [];
allPages.forEach((page) => {
const regex = new RegExp(
`(\\w*(?<!\\[{2}[^[\\]]*)\\w*(?<!\\#)\\w*(?<!\\w+:\\/\\/\\S*))(?<=[\\s,.:;"']|^)(${parseForRegex(
Expand All @@ -118,6 +119,7 @@ export function replaceContentWithPageLinks(
parseAsTags ? `#${page}` : `[[${page}]]`
);
needsUpdate = true;
pagesFound.push(page);
} else if (page.length > 0) {
if (content.toUpperCase().includes(page.toUpperCase())) {
content = content.replaceAll(regex, (match) => {
Expand All @@ -133,6 +135,7 @@ export function replaceContentWithPageLinks(
return `[[${whichCase}]]`;
});
needsUpdate = true;
pagesFound.push(page);
// setTimeout(() => { inProcess = false }, 300)
}
}
Expand Down Expand Up @@ -160,5 +163,5 @@ export function replaceContentWithPageLinks(
content = content.replace(CUSTOM_QUERY_PLACEHOLDER, value);
});

return [content, needsUpdate];
return [content, needsUpdate, pagesFound];
}
35 changes: 23 additions & 12 deletions tests/functions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { replaceContentWithPageLinks } from "../src/functions";

describe("replaceContentWithPageLinks()", () => {
it("should preserve code blocks", () => {
let [content, update] = replaceContentWithPageLinks(
let [content, update, pagesFound] = replaceContentWithPageLinks(
["page"],
"page before ```\npage within code block\n```\npage between\n```\nanother page within code block```\nand finally\n```\nwith `single` backticks and page within\n```\npage after",
false,
Expand All @@ -12,10 +12,11 @@ describe("replaceContentWithPageLinks()", () => {
"[[page]] before ```\npage within code block\n```\n[[page]] between\n```\nanother page within code block```\nand finally\n```\nwith `single` backticks and page within\n```\n[[page]] after"
);
expect(update).toBe(true);
expect(pagesFound).toStrictEqual(["page"]);
});

it("should preserve inline code", () => {
let [content, update] = replaceContentWithPageLinks(
let [content, update, pagesFound] = replaceContentWithPageLinks(
["page"],
"Page before\n`page inside inline code`\npage between\n`another page inline`\n`but not page if inline\nblock is split between newlines`\npage after",
false,
Expand All @@ -25,10 +26,11 @@ describe("replaceContentWithPageLinks()", () => {
"[[Page]] before\n`page inside inline code`\n[[page]] between\n`another page inline`\n`but not page if inline\nblock is split between newlines`\n[[page]] after"
);
expect(update).toBe(true);
expect(pagesFound).toStrictEqual(["page"]);
});

it("should preserve properties", () => {
let [content, update] = replaceContentWithPageLinks(
let [content, update, pagesFound] = replaceContentWithPageLinks(
["page", "price"],
`Some page here with price
price:: 123
Expand All @@ -42,10 +44,11 @@ describe("replaceContentWithPageLinks()", () => {
page:: this is a property`
);
expect(update).toBe(true);
expect(pagesFound).toStrictEqual(["page", "price"]);
});

it("should preserve Markdown links", () => {
let [content, update] = replaceContentWithPageLinks(
let [content, update, pagesFound] = replaceContentWithPageLinks(
["page", "link", "Logseq"],
`This page has a link: [page link will not be touched](http://a.com)
[another page](http://b.com) also with a link
Expand All @@ -59,6 +62,7 @@ describe("replaceContentWithPageLinks()", () => {
[\\[This\\] is a Logseq page](https://logseq.com)`
);
expect(update).toBe(true);
expect(pagesFound).toStrictEqual(["page", "link"]);
});

it("should preserve custom query scripts", () => {
Expand Down Expand Up @@ -109,7 +113,7 @@ describe("replaceContentWithPageLinks()", () => {
#+END_QUERY`,
];

const [content, update] = replaceContentWithPageLinks(
const [content, update, pagesFound] = replaceContentWithPageLinks(
["In Progress", "find", "link"],
`${customQueries[0]}

Expand All @@ -128,6 +132,7 @@ describe("replaceContentWithPageLinks()", () => {
${customQueries[1]}`
);
expect(update).toBe(true);
expect(pagesFound).toStrictEqual(["link"]);
});

it.each([
Expand Down Expand Up @@ -166,7 +171,7 @@ describe("replaceContentWithPageLinks()", () => {
expected: "WAITING A [[Waiting]] [[todo]]",
},
])("should preserve the to do marker for $input", ({ input, expected }) => {
let [content, update] = replaceContentWithPageLinks(
let [content, update, pagesFound] = replaceContentWithPageLinks(
[
"Now",
"Later",
Expand All @@ -190,18 +195,19 @@ describe("replaceContentWithPageLinks()", () => {
});

it("should output tags when parseAsTags is configured", () => {
let [content, update] = replaceContentWithPageLinks(
let [content, update, pagesFound] = replaceContentWithPageLinks(
["page", "multiple words"],
"This page has multiple words",
true,
false
);
expect(content).toBe("This #page has #[[multiple words]]");
expect(update).toBe(true);
expect(pagesFound).toStrictEqual(["page", "multiple words"]);
});

it("should output tags when parseSingleWordAsTag is configured", () => {
let [content, update] = replaceContentWithPageLinks(
let [content, update, pagesFound] = replaceContentWithPageLinks(
["one", "multiple words"],
"This one becomes a tag but multiple words get brackets",
false,
Expand All @@ -211,21 +217,23 @@ describe("replaceContentWithPageLinks()", () => {
"This #one becomes a tag but [[multiple words]] get brackets"
);
expect(update).toBe(true);
expect(pagesFound).toStrictEqual(["one", "multiple words"]);
});

it("should return the same content if nothing was parsed", () => {
let [content, update] = replaceContentWithPageLinks(
let [content, update, pagesFound] = replaceContentWithPageLinks(
["page"],
"This text doesn't have any links to be parsed",
false,
false
);
expect(content).toBe("This text doesn't have any links to be parsed");
expect(update).toBe(false);
expect(pagesFound).toStrictEqual([]);
});

it("should keep the original input case for lowercase pages", () => {
let [content, update] = replaceContentWithPageLinks(
let [content, update, pagesFound] = replaceContentWithPageLinks(
["when", "for pages", "because", "links", "logseq"],
`When creating links, the original case that was typed should be preserved
for PAGES that only have lowercase words.
Expand All @@ -239,10 +247,11 @@ describe("replaceContentWithPageLinks()", () => {
[[Because]] [[logSEQ]] [[LINKS]] are case-insensitive anyway.`
);
expect(update).toBe(true);
expect(pagesFound).toStrictEqual(["when", "for pages", "because", "links", "logseq"]);
});

it("should disregard the input case and use the page case for uppercase, title case and mixed case pages", () => {
let [content, update] = replaceContentWithPageLinks(
let [content, update, pagesFound] = replaceContentWithPageLinks(
["John Doe", "Mary Doe", "ANYWAY", "Logseq", "But"],
`When creating links, the page case should be used when it's not lowercase.
So things like names are properly capitalised even when typed in lowercase: john doe, mary doe.
Expand All @@ -260,10 +269,11 @@ describe("replaceContentWithPageLinks()", () => {
even if you type them in lowercase`
);
expect(update).toBe(true);
expect(pagesFound).toStrictEqual(["John Doe", "Mary Doe", "ANYWAY", "Logseq", "But"]);
});

it("should detect Unicode links", () => {
let [content, update] = replaceContentWithPageLinks(
let [content, update, pagesFound] = replaceContentWithPageLinks(
["가나다"],
`This block implicitly contains unicode words like 가나다.`,
false,
Expand All @@ -272,5 +282,6 @@ describe("replaceContentWithPageLinks()", () => {
expect(content).toBe(
`This block implicitly contains unicode words like [[가나다]].`
);
expect(pagesFound).toStrictEqual(["가나다"]);
});
});