JSON to client (#5553)

This commit is contained in:
Tom Moor
2024-05-24 08:29:00 -04:00
committed by GitHub
parent e1e8257df7
commit d51267b8bc
71 changed files with 651 additions and 378 deletions

View File

@@ -1,18 +0,0 @@
import MarkdownHelper from "./MarkdownHelper";
describe("#MarkdownHelper", () => {
it("should serialize title and text", () => {
expect(MarkdownHelper.toMarkdown({ title: "Title", text: "Test" })).toEqual(
"# Title\n\nTest"
);
});
it("should trim backslashes", () => {
expect(
MarkdownHelper.toMarkdown({
title: "Title",
text: "One\n\\\nTest\n\\",
})
).toEqual("# Title\n\nOne\n\nTest");
});
});

View File

@@ -1,29 +0,0 @@
interface DocumentInterface {
emoji?: string | null;
title: string;
text: string;
}
export default class MarkdownHelper {
/**
* Returns the document as cleaned Markdown for export.
*
* @param document The document or revision to convert
* @returns The document title and content as a Markdown string
*/
static toMarkdown(document: DocumentInterface) {
const text = document.text
.replace(/\n\\(\n|$)/g, "\n\n")
.replace(/“/g, '"')
.replace(/”/g, '"')
.replace(//g, "'")
.replace(//g, "'")
.trim();
const title = `${document.emoji ? document.emoji + " " : ""}${
document.title
}`;
return `# ${title}\n\n${text}`;
}
}

View File

@@ -1,6 +1,7 @@
import { Node, Schema } from "prosemirror-model";
import headingToSlug from "../editor/lib/headingToSlug";
import textBetween from "../editor/lib/textBetween";
import { ProsemirrorData } from "../types";
export type Heading = {
/* The heading in plain text */
@@ -27,7 +28,30 @@ export type Task = {
completed: boolean;
};
export default class ProsemirrorHelper {
export const attachmentRedirectRegex =
/\/api\/attachments\.redirect\?id=(?<id>[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/gi;
export const attachmentPublicRegex =
/public\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\/(?<id>[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/gi;
export class ProsemirrorHelper {
/**
* Get a new empty document.
*
* @returns A new empty document as JSON.
*/
static getEmptyDocument(): ProsemirrorData {
return {
type: "doc",
content: [
{
content: [],
type: "paragraph",
},
],
};
}
/**
* Returns the node as plain text.
*
@@ -160,6 +184,21 @@ export default class ProsemirrorHelper {
return tasks;
}
/**
* Returns a summary of total and completed tasks in the node.
*
* @param doc Prosemirror document node
* @returns Object with completed and total keys
*/
static getTasksSummary(doc: Node): { completed: number; total: number } {
const tasks = ProsemirrorHelper.getTasks(doc);
return {
completed: tasks.filter((t) => t.completed).length,
total: tasks.length,
};
}
/**
* Iterates through the document to find all of the headings and their level.
*

View File

@@ -1,23 +0,0 @@
const CHECKBOX_REGEX = /\[(X|\s|_|-)\]\s(.*)?/gi;
export default function getTasks(text: string) {
const matches = [...text.matchAll(CHECKBOX_REGEX)];
const total = matches.length;
if (!total) {
return {
completed: 0,
total: 0,
};
} else {
const notCompleted = matches.reduce(
(accumulator, match) =>
match[1] === " " ? accumulator + 1 : accumulator,
0
);
return {
completed: total - notCompleted,
total,
};
}
}