From a62913330e1050acb4f8b0ae2888ac81c7356635 Mon Sep 17 00:00:00 2001 From: pajowu Date: Fri, 17 Nov 2023 11:38:51 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20plaintext=20export?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #385 --- frontend/src/editor/export/index.tsx | 5 ++++ frontend/src/editor/export/plaintext.tsx | 38 ++++++++++++++++++++++++ frontend/src/utils/export/plaintext.ts | 18 +++++++++++ 3 files changed, 61 insertions(+) create mode 100644 frontend/src/editor/export/plaintext.tsx create mode 100644 frontend/src/utils/export/plaintext.ts diff --git a/frontend/src/editor/export/index.tsx b/frontend/src/editor/export/index.tsx index 802d7bed..b8241b84 100644 --- a/frontend/src/editor/export/index.tsx +++ b/frontend/src/editor/export/index.tsx @@ -6,6 +6,7 @@ import { Modal } from '../../components/modal'; import { WebVttExportBody } from './webvtt'; import { TranscribeeExportBody } from './transcribee'; import { ApiDocument } from '../../api/document'; +import { PlaintextExportBody } from './plaintext'; export type ExportProps = { outputNameBase: string; @@ -29,6 +30,10 @@ const exportTypes: ExportType[] = [ name: 'Subtitles', component: WebVttExportBody, }, + { + name: 'Plaintext', + component: PlaintextExportBody, + }, { name: 'Transcribee Archive', component: TranscribeeExportBody, diff --git a/frontend/src/editor/export/plaintext.tsx b/frontend/src/editor/export/plaintext.tsx new file mode 100644 index 00000000..200e921f --- /dev/null +++ b/frontend/src/editor/export/plaintext.tsx @@ -0,0 +1,38 @@ +import { useState } from 'react'; +import * as Automerge from '@automerge/automerge'; + +import { Checkbox } from '../../components/form'; +import { downloadTextAsFile } from '../../utils/download_text_as_file'; +import { ExportProps } from '.'; +import { PrimaryButton, SecondaryButton } from '../../components/button'; +import { generatePlaintext } from '../../utils/export/plaintext'; + +export function PlaintextExportBody({ onClose, outputNameBase, editor }: ExportProps) { + const [includeSpeakerNames, setIncludeSpeakerNames] = useState(true); + + return ( +
+ setIncludeSpeakerNames(x)} + /> +
+ + Cancel + + { + e.preventDefault(); + const plaintext = generatePlaintext(Automerge.toJS(editor.doc), includeSpeakerNames); + downloadTextAsFile(`${outputNameBase}.txt`, `text/plain`, plaintext); + onClose(); + }} + > + Export + +
+ + ); +} diff --git a/frontend/src/utils/export/plaintext.ts b/frontend/src/utils/export/plaintext.ts new file mode 100644 index 00000000..8f9f0a5b --- /dev/null +++ b/frontend/src/utils/export/plaintext.ts @@ -0,0 +1,18 @@ +import { Document } from '../../editor/types'; +import { getSpeakerName } from '../document'; + +export function generatePlaintext(doc: Document, includeSpeakerNames: boolean): string { + let last_speaker: string | null = null; + return doc.children + .map((paragraph) => { + let paragraphText = ''; + if (includeSpeakerNames && last_speaker !== paragraph.speaker) { + paragraphText += `${getSpeakerName(paragraph.speaker, doc.speaker_names)}:\n`; + last_speaker = paragraph.speaker; + } + paragraphText += paragraph.children.map((x) => x.text).join(''); + return paragraphText.trim(); + }) + .filter((x) => x !== '') + .join('\n\n'); +}