diff --git a/websocket/getHelpfeels.ts b/websocket/getHelpfeels.ts new file mode 100644 index 0000000..57542c9 --- /dev/null +++ b/websocket/getHelpfeels.ts @@ -0,0 +1,30 @@ +import type { BaseLine } from "@cosense/types/userscript"; + +/** Extract Helpfeel entries from text + * + * Helpfeel is a Scrapbox notation for questions and help requests. + * Lines starting with "?" are considered Helpfeel entries and are + * used to collect questions and support requests within a project. + * + * ```ts + * import { assertEquals } from "@std/assert/equals"; + * + * const text = `test page + * [normal]link + * but \`this [link]\` is not a link + * + * code:code + * Links [link] and images [https://scrapbox.io/files/65f29c0c9045b5002522c8bb.svg] in code blocks should be ignored + * + * ? Need help with setup!! + * `; + * + * assertEquals(getHelpfeels(text.split("\n").map((text) => ({ text }))), [ + * "Need help with setup!!", + * ]); + * ``` + */ +export const getHelpfeels = (lines: Pick[]): string[] => + lines.flatMap(({ text }) => + /^\s*\? .*$/.test(text) ? [text.trimStart().slice(2)] : [] + ); diff --git a/websocket/getPageMetadataFromLines.test.ts b/websocket/getPageMetadataFromLines.test.ts deleted file mode 100644 index 1284058..0000000 --- a/websocket/getPageMetadataFromLines.test.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { - getHelpfeels, - getPageMetadataFromLines, -} from "./getPageMetadataFromLines.ts"; -import { assertEquals } from "@std/assert/equals"; - -// Test data for metadata extraction from a Scrapbox page -// This sample includes various Scrapbox syntax elements: -// - Regular links: [link-text] -// - Code blocks (links inside should be ignored) -// - Helpfeel notation: lines starting with "?" -// - Infobox tables -// - Hashtags -// - Project internal links: [/project/page] -// - Image links -const text = `test page -[normal]link - but \`this [link]\` is not a link - -code:code - Links [link] and images [https://scrapbox.io/files/65f29c0c9045b5002522c8bb.svg] in code blocks should be ignored - - - ? Need help with setup!! - - table:infobox - Name [scrapbox.icon] - Address Add [link2] here - Phone Adding # won't create a link - Strengths List about 3 items - -#hashtag is recommended -[/forum-en] links should be excluded - [/help-en/] too - [/icons/example.icon][takker.icon] -[/help-en/external-link] - -Prepare thumbnail -[https://scrapbox.io/files/65f29c24974fd8002333b160.svg] - -[https://scrapbox.io/files/65e7f4413bc95600258481fb.svg https://scrapbox.io/files/65e7f82e03949c0024a367d0.svg]`; - -Deno.test("getPageMetadataFromLines()", () => { - assertEquals(getPageMetadataFromLines(text), [ - "test page", - [ - "normal", - "link2", - "hashtag", - ], - [ - "/help-en/external-link", - ], - [ - "scrapbox", - "takker", - ], - "https://scrapbox.io/files/65f29c24974fd8002333b160.svg", - [ - "[normal]link", - "but `this [link]` is not a link", - "`Links [link] and images [https://scrapbox.io/files/65f29c0c9045b5002522c8bb.svg] in code blocks should be ignored`", - "`? Need help with setup!!`", - "#hashtag is recommended", - ], - [ - "65f29c24974fd8002333b160", - "65e7f82e03949c0024a367d0", - "65e7f4413bc95600258481fb", - ], - [ - "Need help with setup!!", - ], - [ - "Name\t[scrapbox.icon]", - "Address\tAdd [link2] here", - "Phone\tAdding # won't create a link", - "Strengths\tList about 3 items", - ], - 26, - 659, - ]); -}); - -// Test Helpfeel extraction (lines starting with "?") -// These are used for collecting questions and help requests in Scrapbox -Deno.test("getHelpfeels()", () => { - assertEquals(getHelpfeels(text.split("\n").map((text) => ({ text }))), [ - "Need help with setup!!", - ]); -}); diff --git a/websocket/getPageMetadataFromLines.ts b/websocket/getPageMetadataFromLines.ts index 898ba04..985f90d 100644 --- a/websocket/getPageMetadataFromLines.ts +++ b/websocket/getPageMetadataFromLines.ts @@ -1,22 +1,88 @@ import { type Node, parse } from "@progfay/scrapbox-parser"; -import type { BaseLine } from "@cosense/types/userscript"; import { toTitleLc } from "../title.ts"; import { parseYoutube } from "../parser/youtube.ts"; /** Extract metadata from Scrapbox page text * - * This function parses a Scrapbox page and extracts various types of metadata: + * ```ts + * import { assertEquals } from "@std/assert/equals"; + * + * const text = `test page + * [normal]link + * but \`this [link]\` is not a link + * + * code:code + * Links [link] and images [https://scrapbox.io/files/65f29c0c9045b5002522c8bb.svg] in code blocks should be ignored + * + * ? Need help with setup!! + * + * table:infobox + * Name [scrapbox.icon] + * Address Add [link2] here + * Phone Adding # won't create a link + * Strengths List about 3 items + * + * \#hashtag is recommended + * [/forum-en] links should be excluded + * [/help-en/] too + * [/icons/example.icon][takker.icon] + * [/help-en/external-link] + * + * Prepare thumbnail + * [https://scrapbox.io/files/65f29c24974fd8002333b160.svg] + * + * [https://scrapbox.io/files/65e7f4413bc95600258481fb.svg https://scrapbox.io/files/65e7f82e03949c0024a367d0.svg]`; + * + * assertEquals(getPageMetadataFromLines(text), [ + * "test page", + * [ + * "normal", + * "link2", + * "hashtag", + * ], + * [ + * "/help-en/external-link", + * ], + * [ + * "scrapbox", + * "takker", + * ], + * "https://scrapbox.io/files/65f29c24974fd8002333b160.svg", + * [ + * "[normal]link", + * "but `this [link]` is not a link", + * "`Links [link] and images [https://scrapbox.io/files/65f29c0c9045b5002522c8bb.svg] in code blocks should be ignored`", + * "`? Need help with setup!!`", + * "#hashtag is recommended", + * ], + * [ + * "65f29c24974fd8002333b160", + * "65e7f82e03949c0024a367d0", + * "65e7f4413bc95600258481fb", + * ], + * [ + * "Need help with setup!!", + * ], + * [ + * "Name\t[scrapbox.icon]", + * "Address\tAdd [link2] here", + * "Phone\tAdding # won't create a link", + * "Strengths\tList about 3 items", + * ], + * 25, + * 659, + * ]); + * ``` + * + * @param text - Raw text content of a Scrapbox page + * @returns A tuple containing `[links, projectLinks, icons, image, files, helpfeels, infoboxDefinition]` * - links: Regular page links and hashtags * - projectLinks: Links to pages in other projects * - icons: User icons and decorative icons - * - image: First image or YouTube thumbnail for page preview + * - image: First image or YouTube thumbnail for page preview, which can be null if no suitable preview image is found * - files: Attached file IDs * - helpfeels: Questions or help requests (lines starting with "?") * - infoboxDefinition: Structured data from infobox tables - * - * @param text - Raw text content of a Scrapbox page - * @returns A tuple containing [links, projectLinks, icons, image, files, helpfeels, infoboxDefinition] - * where image can be null if no suitable preview image is found */ export const getPageMetadataFromLines = ( text: string, @@ -212,14 +278,3 @@ const makeInlineCodeForDescription = (text: string): `\`${string}\`` => `\`${text.trim().replaceAll("`", "\\`").slice(0, 198)}\``; const cutId = (link: string): string => link.replace(/#[a-f\d]{24,32}$/, ""); - -/** Extract Helpfeel entries from text - * - * Helpfeel is a Scrapbox notation for questions and help requests. - * Lines starting with "?" are considered Helpfeel entries and are - * used to collect questions and support requests within a project. - */ -export const getHelpfeels = (lines: Pick[]): string[] => - lines.flatMap(({ text }) => - /^\s*\? .*$/.test(text) ? [text.trimStart().slice(2)] : [] - ); diff --git a/websocket/makeChanges.ts b/websocket/makeChanges.ts index de42787..97859ac 100644 --- a/websocket/makeChanges.ts +++ b/websocket/makeChanges.ts @@ -1,12 +1,10 @@ import { diffToChanges } from "./diffToChanges.ts"; import type { Page } from "@cosense/types/rest"; import type { ChangeToPush } from "@cosense/types/websocket"; -import { - getHelpfeels, - getPageMetadataFromLines, -} from "./getPageMetadataFromLines.ts"; +import { getPageMetadataFromLines } from "./getPageMetadataFromLines.ts"; import { isSameArray } from "./isSameArray.ts"; import { isString } from "@core/unknownutil/is/string"; +import { getHelpfeels } from "./getHelpfeels.ts"; export function* makeChanges( before: Page,