You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/uix/soma/components/words/engine/commands.ts

168 lines
4.9 KiB

import type { WordsBlockType, WordsHeadingLevel, WordsListKind, WordsMark, WordsTextAlign } from './document';
import {
clearFormatting,
decreaseIndent,
deleteBackward,
deleteForward,
deleteLineBackward,
deleteLineForward,
deleteRange,
deleteWordBackward,
deleteWordForward,
increaseIndent,
insertLink,
insertLineBreak,
insertParagraph,
insertText,
replaceDocument,
setBlock,
setTextAlign,
toggleList,
toggleMark,
unlink,
type WordsEditorState,
type WordsOperationResult
} from './operations';
import { renderWordsPlainText } from './render';
import { parseWordsHtml, serializeWordsHtml } from './serialize-html';
import { parseWordsJson, serializeWordsJson } from './serialize-json';
import { parseWordsMarkdown, serializeWordsMarkdown } from './serialize-markdown';
import { parseWordsPlainText } from './serialize-text';
import { replaceAllTextInDocument } from './find-replace';
export type WordsImportFormat = 'json' | 'text' | 'html' | 'markdown';
export type WordsExportFormat = 'json' | 'text' | 'html' | 'markdown';
export type WordsCommand =
| { type: 'insertText'; text: string }
| { type: 'insertParagraph' }
| { type: 'insertLineBreak' }
| { type: 'deleteBackward' }
| { type: 'deleteForward' }
| { type: 'deleteWordBackward' }
| { type: 'deleteWordForward' }
| { type: 'deleteLineBackward' }
| { type: 'deleteLineForward' }
| { type: 'deleteRange' }
| { type: 'toggleMark'; mark: WordsMark }
| { type: 'clearFormatting' }
| { type: 'setBlock'; block: Exclude<WordsBlockType, 'list'>; level?: WordsHeadingLevel }
| { type: 'setTextAlign'; align: WordsTextAlign }
| { type: 'increaseIndent' }
| { type: 'decreaseIndent' }
| { type: 'toggleList'; kind: WordsListKind }
| { type: 'insertLink'; href: string; title?: string }
| { type: 'unlink' }
| { type: 'replaceDocument'; document: unknown }
| { type: 'replaceAllText'; query: string; replacement: string }
| { type: 'importContent'; content: string; format: WordsImportFormat }
| { type: 'exportContent'; format: WordsExportFormat };
export function applyWordsCommand(
state: WordsEditorState,
command: WordsCommand
): WordsOperationResult {
switch (command.type) {
case 'insertText':
return insertText(state, command.text);
case 'insertParagraph':
return insertParagraph(state);
case 'insertLineBreak':
return insertLineBreak(state);
case 'deleteBackward':
return deleteBackward(state);
case 'deleteForward':
return deleteForward(state);
case 'deleteWordBackward':
return deleteWordBackward(state);
case 'deleteWordForward':
return deleteWordForward(state);
case 'deleteLineBackward':
return deleteLineBackward(state);
case 'deleteLineForward':
return deleteLineForward(state);
case 'deleteRange':
return deleteRange(state);
case 'toggleMark':
return toggleMark(state, command.mark);
case 'clearFormatting':
return clearFormatting(state);
case 'setBlock':
return setBlock(state, command.block, { level: command.level });
case 'setTextAlign':
return setTextAlign(state, command.align);
case 'increaseIndent':
return increaseIndent(state);
case 'decreaseIndent':
return decreaseIndent(state);
case 'toggleList':
return toggleList(state, command.kind);
case 'insertLink':
return insertLink(state, command.href, command.title);
case 'unlink':
return unlink(state);
case 'replaceDocument':
return replaceDocument(state, command.document);
case 'replaceAllText':
return replaceAllText(state, command.query, command.replacement);
case 'importContent':
return importWordsContent(state, command.content, command.format);
case 'exportContent':
return exportWordsContent(state, command.format);
}
}
function importWordsContent(
state: WordsEditorState,
content: string,
format: WordsImportFormat
): WordsOperationResult {
try {
return replaceDocument(
state,
format === 'json'
? parseWordsJson(content)
: format === 'html'
? parseWordsHtml(content)
: format === 'markdown'
? parseWordsMarkdown(content)
: parseWordsPlainText(content)
);
} catch {
return { state, changed: false };
}
}
function exportWordsContent(
state: WordsEditorState,
format: WordsExportFormat
): WordsOperationResult {
const exportedContent =
format === 'json'
? serializeWordsJson(state.document)
: format === 'html'
? serializeWordsHtml(state.document)
: format === 'markdown'
? serializeWordsMarkdown(state.document)
: renderWordsPlainText(state.document);
return { state, changed: false, exportedContent };
}
function replaceAllText(
state: WordsEditorState,
query: string,
replacement: string
): WordsOperationResult {
if (!query) return { state, changed: false };
const nextDocument = replaceAllTextInDocument(state.document, query, replacement);
if (nextDocument === state.document) return { state, changed: false };
return {
state: {
document: nextDocument,
selection: state.selection,
activeMarks: state.activeMarks
},
changed: true
};
}

Powered by TurnKey Linux.