|
1 | 1 | import { |
| 2 | + Block, |
2 | 3 | PartialBlock, |
3 | 4 | BlockSchema, |
4 | 5 | PropSchema, |
5 | 6 | Props, |
6 | 7 | } from "../../extensions/Blocks/api/blockTypes"; |
7 | | -import { PartialInlineContent } from "../../extensions/Blocks/api/inlineContentTypes"; |
| 8 | +import { |
| 9 | + InlineContent, |
| 10 | + PartialInlineContent, |
| 11 | +} from "../../extensions/Blocks/api/inlineContentTypes"; |
8 | 12 | import { DefaultBlockSchema } from "../.."; |
9 | 13 | import Tokenizr from "tokenizr"; |
10 | 14 |
|
@@ -275,15 +279,15 @@ function createInlineContent(text: string): PartialInlineContent[] { |
275 | 279 | inlineContent.push({ |
276 | 280 | type: "link", |
277 | 281 | href: token.value, |
278 | | - content: token.value, |
| 282 | + content: "file", |
279 | 283 | }); |
280 | 284 | downloadFile(token.value, false); |
281 | 285 | break; |
282 | 286 | case "image-link": |
283 | 287 | inlineContent.push({ |
284 | 288 | type: "link", |
285 | 289 | href: token.value, |
286 | | - content: token.value, |
| 290 | + content: "image", |
287 | 291 | }); |
288 | 292 | downloadFile(token.value, true); |
289 | 293 | break; |
@@ -745,3 +749,136 @@ export function parseNoteToBlocks(note: string): PartialBlock<BlockSchema>[] { |
745 | 749 | postProcessBlocks(blocks); |
746 | 750 | return blocks; |
747 | 751 | } |
| 752 | + |
| 753 | +function serializeTaskStates(prop: Props<PropSchema>): string { |
| 754 | + if (prop.checked === "true") { |
| 755 | + return "[x]"; |
| 756 | + } else if (prop.canceled === "true") { |
| 757 | + return "[-]"; |
| 758 | + } else if (prop.scheduled === "true") { |
| 759 | + return "[>]"; |
| 760 | + } else { |
| 761 | + return "[ ]"; |
| 762 | + } |
| 763 | +} |
| 764 | + |
| 765 | +function serializeBlockContent(content: InlineContent[]): string { |
| 766 | + let text = ""; |
| 767 | + let contentLength = content.length; |
| 768 | + for (let i = 0; i < contentLength; ++i) { |
| 769 | + let contentItem = content[i]; |
| 770 | + switch (contentItem.type) { |
| 771 | + case "text": |
| 772 | + // serialize styles |
| 773 | + if (contentItem.styles.bold) { |
| 774 | + text += "**" + contentItem.text + "**"; |
| 775 | + } else if (contentItem.styles.italic) { |
| 776 | + text += "*" + contentItem.text + "*"; |
| 777 | + } else if (contentItem.styles.strike) { |
| 778 | + text += "~~" + contentItem.text + "~~"; |
| 779 | + } else if (contentItem.styles.backgroundColor === "highlight-color") { |
| 780 | + text += "::" + contentItem.text + "::"; |
| 781 | + } else if (contentItem.styles.code) { |
| 782 | + text += "`" + contentItem.text + "`"; |
| 783 | + } else { |
| 784 | + text += contentItem.text; |
| 785 | + } |
| 786 | + break; |
| 787 | + case "link": |
| 788 | + const linkContent = serializeBlockContent(contentItem.content); |
| 789 | + switch (linkContent) { |
| 790 | + case "file": |
| 791 | + case "image": |
| 792 | + text += ""; |
| 793 | + break; |
| 794 | + default: |
| 795 | + text += "[" + linkContent + "](" + contentItem.href + ")"; |
| 796 | + break; |
| 797 | + } |
| 798 | + break; |
| 799 | + } |
| 800 | + } |
| 801 | + return text; |
| 802 | +} |
| 803 | + |
| 804 | +export function serializeBlock( |
| 805 | + block: Block<BlockSchema>, |
| 806 | + depth: number |
| 807 | +): string { |
| 808 | + let text = " ".repeat(depth); |
| 809 | + // serialize block types |
| 810 | + switch (block.type) { |
| 811 | + case "heading": |
| 812 | + text += "#".repeat(parseInt(block.props?.level || "1")) + " "; |
| 813 | + break; |
| 814 | + case "quoteListItem": |
| 815 | + text += "> "; |
| 816 | + break; |
| 817 | + case "bulletListItem": |
| 818 | + text += "- "; |
| 819 | + break; |
| 820 | + case "numberedListItem": |
| 821 | + text += "1. "; |
| 822 | + break; |
| 823 | + case "taskListItem": |
| 824 | + text += "* " + serializeTaskStates(block.props || {}) + " "; |
| 825 | + break; |
| 826 | + case "checkListItem": |
| 827 | + text += "+ " + serializeTaskStates(block.props || {}) + " "; |
| 828 | + break; |
| 829 | + case "paragraph": |
| 830 | + break; |
| 831 | + } |
| 832 | + |
| 833 | + // serialize content array with InlineContent |
| 834 | + text += serializeBlockContent(block.content); |
| 835 | + |
| 836 | + // end block with newline |
| 837 | + text += "\n"; |
| 838 | + let children = block.children || []; |
| 839 | + let childrenLength = children.length; |
| 840 | + |
| 841 | + for (let i = 0; i < childrenLength; ++i) { |
| 842 | + text += serializeBlock(children[i], depth + 1); |
| 843 | + } |
| 844 | + |
| 845 | + return text; |
| 846 | +} |
| 847 | + |
| 848 | +function postProcessNote(note: string): string { |
| 849 | + // adjust numbering of numbered list items according to their level |
| 850 | + let lines = note.split(/\r?\n/); |
| 851 | + let linesLength = lines.length; |
| 852 | + let currentNumber = 0; |
| 853 | + let previousLevel = 0; |
| 854 | + for (let i = 0; i < linesLength; ++i) { |
| 855 | + let line = lines[i]; |
| 856 | + let matches = /^(\s*?)(\d+)\.\s+(.*)/.exec(line); |
| 857 | + console.log(matches); |
| 858 | + if (matches != null) { |
| 859 | + let leadingWhitespace = matches[1].length; |
| 860 | + let level = 0; |
| 861 | + if (leadingWhitespace > 1) { |
| 862 | + level = Math.floor(leadingWhitespace / 2); |
| 863 | + } |
| 864 | + if (level === previousLevel) { |
| 865 | + currentNumber++; |
| 866 | + } else { |
| 867 | + currentNumber = 1; |
| 868 | + } |
| 869 | + lines[i] = matches[1] + currentNumber.toString() + ". " + matches[3]; |
| 870 | + previousLevel = level; |
| 871 | + } |
| 872 | + } |
| 873 | + return lines.join("\n"); |
| 874 | +} |
| 875 | + |
| 876 | +export function serializeBlocksToNote(blocks: Block<BlockSchema>[]): string { |
| 877 | + let text = ""; |
| 878 | + let blocksLength = blocks.length; |
| 879 | + for (let i = 0; i < blocksLength; ++i) { |
| 880 | + text += serializeBlock(blocks[i], 0); |
| 881 | + } |
| 882 | + // post process text |
| 883 | + return postProcessNote(text); |
| 884 | +} |
0 commit comments