diff --git a/src/app/components/editor/output.ts b/src/app/components/editor/output.ts new file mode 100644 index 00000000..771dda31 --- /dev/null +++ b/src/app/components/editor/output.ts @@ -0,0 +1,78 @@ +import { Text } from 'slate'; +import { sanitizeText } from '../../utils/sanitize'; +import { BlockType } from './Elements'; +import { CustomElement, FormattedText } from './slate'; + +const textToCustomHtml = (node: FormattedText): string => { + let string = sanitizeText(node.text); + if (node.bold) string = `${string}`; + if (node.italic) string = `${string}`; + if (node.underline) string = `${string}`; + if (node.strikeThrough) string = `${string}`; + if (node.code) string = `${string}`; + return string; +}; + +const elementToCustomHtml = (node: CustomElement, children: string): string => { + switch (node.type) { + case BlockType.Paragraph: + return `

${children}

`; + case BlockType.Heading: + return `${children}`; + case BlockType.CodeLine: + return `${children}\n`; + case BlockType.CodeBlock: + return `
${children}
`; + case BlockType.QuoteLine: + return `

${children}

`; + case BlockType.BlockQuote: + return `
${children}
`; + case BlockType.ListItem: + return `
  • ${children}

  • `; + case BlockType.OrderedList: + return `
      ${children}
    `; + case BlockType.UnorderedList: + return ``; + default: + return children; + } +}; + +export const toMatrixCustomHTML = (node: CustomElement | Text): string => { + if (Text.isText(node)) return textToCustomHtml(node); + + const children = node.children.map((n) => toMatrixCustomHTML(n)).join(''); + return elementToCustomHtml(node, children); +}; + +const elementToPlainText = (node: CustomElement, children: string): string => { + switch (node.type) { + case BlockType.Paragraph: + return `${children}\n\n`; + case BlockType.Heading: + return `${children}\n\n`; + case BlockType.CodeLine: + return `${children}\n`; + case BlockType.CodeBlock: + return `${children}\n`; + case BlockType.QuoteLine: + return `| ${children}\n`; + case BlockType.BlockQuote: + return `${children}\n`; + case BlockType.ListItem: + return `- ${children}\n`; + case BlockType.OrderedList: + return `${children}\n`; + case BlockType.UnorderedList: + return `${children}\n`; + default: + return children; + } +}; + +export const toPlainText = (node: CustomElement | Text): string => { + if (Text.isText(node)) return sanitizeText(node.text); + + const children = node.children.map((n) => toPlainText(n)).join(''); + return elementToPlainText(node, children); +}; diff --git a/src/app/utils/sanitize.ts b/src/app/utils/sanitize.ts new file mode 100644 index 00000000..555089de --- /dev/null +++ b/src/app/utils/sanitize.ts @@ -0,0 +1,10 @@ +export const sanitizeText = (body: string) => { + const tagsToReplace: Record = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + }; + return body.replace(/[&<>'"]/g, (tag) => tagsToReplace[tag] || tag); +};