diff options
-rw-r--r-- | src/client/apis/google_docs/GoogleApiClientUtils.ts | 32 | ||||
-rw-r--r-- | src/new_fields/RichTextUtils.ts | 44 |
2 files changed, 31 insertions, 45 deletions
diff --git a/src/client/apis/google_docs/GoogleApiClientUtils.ts b/src/client/apis/google_docs/GoogleApiClientUtils.ts index fdd708e31..3026f6e17 100644 --- a/src/client/apis/google_docs/GoogleApiClientUtils.ts +++ b/src/client/apis/google_docs/GoogleApiClientUtils.ts @@ -94,29 +94,39 @@ export namespace GoogleApiClientUtils { export namespace Utils { - export type ExtractResult = { text: string, runs: docs_v1.Schema$TextRun[] }; + export type ExtractResult = { text: string, paragraphs: DeconstructedParagraph[] }; export const extractText = (document: docs_v1.Schema$Document, removeNewlines = false): ExtractResult => { - let runs = extractTextRuns(document); - let text = runs.map(run => run.content).join(""); + let paragraphs = extractParagraphs(document); + let text = paragraphs.map(paragraph => paragraph.runs.map(run => run.content).join("")).join(""); text = text.substring(0, text.length - 1); removeNewlines && text.ReplaceAll("\n", ""); - return { text, runs }; + return { text, paragraphs }; }; - const extractTextRuns = (document: docs_v1.Schema$Document, filterEmpty = true) => { - const fragments: docs_v1.Schema$TextRun[] = []; + export type DeconstructedParagraph = { runs: docs_v1.Schema$TextRun[], bullet: Opt<number> }; + const extractParagraphs = (document: docs_v1.Schema$Document, filterEmpty = true): DeconstructedParagraph[] => { + const fragments: DeconstructedParagraph[] = []; if (document.body && document.body.content) { for (const element of document.body.content) { - if (element.paragraph && element.paragraph.elements) { - for (const inner of element.paragraph.elements) { - if (inner && inner.textRun) { - fragments.push(inner.textRun); + let runs: docs_v1.Schema$TextRun[] = []; + let bullet: Opt<number>; + if (element.paragraph) { + if (element.paragraph.elements) { + for (const inner of element.paragraph.elements) { + if (inner && inner.textRun) { + let run = inner.textRun; + (run.content || !filterEmpty) && runs.push(inner.textRun); + } } } + if (element.paragraph.bullet) { + bullet = element.paragraph.bullet.nestingLevel || 0; + } } + runs.length && fragments.push({ runs, bullet }); } } - return filterEmpty ? fragments.filter(run => run.content) : fragments; + return fragments; }; export const endOf = (schema: docs_v1.Schema$Document): number | undefined => { diff --git a/src/new_fields/RichTextUtils.ts b/src/new_fields/RichTextUtils.ts index bc338e45b..4d40040ac 100644 --- a/src/new_fields/RichTextUtils.ts +++ b/src/new_fields/RichTextUtils.ts @@ -97,50 +97,26 @@ export namespace RichTextUtils { }; export const Import = async (documentId: GoogleApiClientUtils.Docs.DocumentId): Promise<Opt<GoogleApiClientUtils.Docs.ImportResult>> => { - const Docs = GoogleApiClientUtils.Docs; - const document = await Docs.retrieve({ documentId }); + const document = await GoogleApiClientUtils.Docs.retrieve({ documentId }); if (!document) { return undefined; } const title = document.title!; - const { text, runs } = Docs.Utils.extractText(document); - const segments = runs[Symbol.iterator](); - + const { text, paragraphs } = GoogleApiClientUtils.Docs.Utils.extractText(document); let state = FormattedTextBox.blankState(); - const schema = state.schema; - const nodes: Node[] = []; - - let result = segments.next(); - while (!result.done) { - let run = result.value; - if (run.content!.hasNewline()) { - addParagraph(nodes, schema, textNode(schema, run)); - result = segments.next(); - } else { - const inner: Node[] = []; - inner.push(textNode(schema, run)); - result = segments.next(); - while (!result.done) { - run = result.value; - inner.push(textNode(schema, run)); - result = segments.next(); - if (run.content!.hasNewline()) { - addParagraph(nodes, schema, inner); - break; - } - } - if (result.done) { - break; - } - } - } + + const nodes = paragraphs.map(paragraph => paragraphNode(state.schema, paragraph)); state = state.apply(state.tr.replaceWith(0, 2, nodes)); + return { title, text, state }; }; - const addParagraph = (list: Node[], schema: any, content?: Node[] | Node) => { - list.push(schema.node("paragraph", null, content ? Fragment.from(content) : null)); + const paragraphNode = (schema: any, content: GoogleApiClientUtils.Docs.Utils.DeconstructedParagraph) => { + let children = content.runs.map(run => textNode(schema, run)); + let complete = children.every(child => child !== undefined); + let fragment = complete ? Fragment.from(children) : undefined; + return schema.node("paragraph", null, fragment); }; const textNode = (schema: any, run: docs_v1.Schema$TextRun) => { |