{"version":3,"file":"TrimSpacesTransform.js","sourceRoot":"","sources":["../../src/transforms/TrimSpacesTransform.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\r\n// See LICENSE in the project root for license information.\r\n\r\nimport { DocParagraph, type DocNode, DocNodeKind, DocPlainText } from '../nodes';\r\n\r\n/**\r\n * Implementation of DocNodeTransforms.trimSpacesInParagraphNodes()\r\n */\r\nexport class TrimSpacesTransform {\r\n public static transform(docParagraph: DocParagraph): DocParagraph {\r\n const transformedNodes: DocNode[] = [];\r\n\r\n // Whether the next nonempty node to be added needs a space before it\r\n let pendingSpace: boolean = false;\r\n\r\n // The DocPlainText node that we're currently accumulating\r\n const accumulatedTextChunks: string[] = [];\r\n const accumulatedNodes: DocNode[] = [];\r\n\r\n // We always trim leading whitespace for a paragraph. This flag gets set to true\r\n // as soon as nonempty content is encountered.\r\n let finishedSkippingLeadingSpaces: boolean = false;\r\n\r\n for (const node of docParagraph.nodes) {\r\n switch (node.kind) {\r\n case DocNodeKind.PlainText:\r\n const docPlainText: DocPlainText = node as DocPlainText;\r\n\r\n const text: string = docPlainText.text;\r\n\r\n const startedWithSpace: boolean = /^\\s/.test(text);\r\n const endedWithSpace: boolean = /\\s$/.test(text);\r\n const collapsedText: string = text.replace(/\\s+/g, ' ').trim();\r\n\r\n if (startedWithSpace && finishedSkippingLeadingSpaces) {\r\n pendingSpace = true;\r\n }\r\n\r\n if (collapsedText.length > 0) {\r\n if (pendingSpace) {\r\n accumulatedTextChunks.push(' ');\r\n pendingSpace = false;\r\n }\r\n\r\n accumulatedTextChunks.push(collapsedText);\r\n accumulatedNodes.push(node);\r\n\r\n finishedSkippingLeadingSpaces = true;\r\n }\r\n\r\n if (endedWithSpace && finishedSkippingLeadingSpaces) {\r\n pendingSpace = true;\r\n }\r\n break;\r\n case DocNodeKind.SoftBreak:\r\n if (finishedSkippingLeadingSpaces) {\r\n pendingSpace = true;\r\n }\r\n accumulatedNodes.push(node);\r\n break;\r\n default:\r\n if (pendingSpace) {\r\n accumulatedTextChunks.push(' ');\r\n pendingSpace = false;\r\n }\r\n\r\n // Push the accumulated text\r\n if (accumulatedTextChunks.length > 0) {\r\n // TODO: We should probably track the accumulatedNodes somehow, e.g. so we can map them back to the\r\n // original excerpts. But we need a developer scenario before we can design this API.\r\n transformedNodes.push(\r\n new DocPlainText({\r\n configuration: docParagraph.configuration,\r\n text: accumulatedTextChunks.join('')\r\n })\r\n );\r\n accumulatedTextChunks.length = 0;\r\n accumulatedNodes.length = 0;\r\n }\r\n\r\n transformedNodes.push(node);\r\n finishedSkippingLeadingSpaces = true;\r\n }\r\n }\r\n\r\n // Push the accumulated text\r\n if (accumulatedTextChunks.length > 0) {\r\n transformedNodes.push(\r\n new DocPlainText({\r\n configuration: docParagraph.configuration,\r\n text: accumulatedTextChunks.join('')\r\n })\r\n );\r\n accumulatedTextChunks.length = 0;\r\n accumulatedNodes.length = 0;\r\n }\r\n\r\n const transformedParagraph: DocParagraph = new DocParagraph({\r\n configuration: docParagraph.configuration\r\n });\r\n transformedParagraph.appendNodes(transformedNodes);\r\n return transformedParagraph;\r\n }\r\n}\r\n"]}