From c85e6370b128db76aed5d570d45ef50907e8bd3d Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Tue, 30 Aug 2022 11:30:50 +0800 Subject: [PATCH] Add some new test cases for SSML generation --- packages/text-to-speech/src/htmlToSsml.ts | 9 +- .../text-to-speech/test/htmlToSsml.test.ts | 128 ++++++++++++++++-- yarn.lock | 10 ++ 3 files changed, 129 insertions(+), 18 deletions(-) diff --git a/packages/text-to-speech/src/htmlToSsml.ts b/packages/text-to-speech/src/htmlToSsml.ts index 79d02b053..d3b282355 100644 --- a/packages/text-to-speech/src/htmlToSsml.ts +++ b/packages/text-to-speech/src/htmlToSsml.ts @@ -49,8 +49,9 @@ function parseDomTree(pageNode: Element) { visitedNodeList.shift() visitedNodeList.forEach((node, index) => { - // start from index 1, index 0 reserved for anchor unknown. - node.setAttribute('data-omnivore-anchor-idx', (index + 1).toString()) + // We start at index 2, because the frontend starts one node above us + // on the #readability-content element that wraps the entire content. + node.setAttribute('data-omnivore-anchor-idx', (index + 2).toString()) }) return visitedNodeList } @@ -161,12 +162,14 @@ export const htmlToSsml = (html: string, options: SSMLOptions): SSMLItem[] => { console.log('creating ssml with options', options) const dom = parseHTML(html) - const body = dom.document.querySelector('#readability-page-1') + const body = dom.document.querySelector('#readability-content') if (!body) { throw new Error('Unable to parse HTML document') } const parsedNodes = parseDomTree(body) + Array.from(parsedNodes).map((n) => console.log(n.nodeName, n.getAttribute('data-omnivore-anchor-idx'), n.getAttribute('class'))) + if (parsedNodes.length < 1) { throw new Error('No HTML nodes found') } diff --git a/packages/text-to-speech/test/htmlToSsml.test.ts b/packages/text-to-speech/test/htmlToSsml.test.ts index c751058de..b7e335341 100644 --- a/packages/text-to-speech/test/htmlToSsml.test.ts +++ b/packages/text-to-speech/test/htmlToSsml.test.ts @@ -16,9 +16,11 @@ describe('htmlToSsml', () => { describe('a simple html file', () => { it('should convert Html to SSML', async () => { const ssml = htmlToSsml(` -
+
+

this is some text

+
`, TEST_OPTIONS ) const text = ssml[0].textItems.join('').trim() @@ -28,31 +30,127 @@ describe('htmlToSsml', () => { }) }) describe('a file with nested elements', () => { - it('should convert Html to SSML', async () => { + it('should collapse spans into the parent paragraph', async () => { const ssml = htmlToSsml(` -
-

-this is in the first paragraph -this is in the second span -this is also in the first paragraph -

-
+
+
+

+ this is in the first paragraph + this is in the second span + this is also in the first paragraph +

+
+
`, TEST_OPTIONS ) const text = ssml[0].textItems.join('').trim() expect(text).to.equal( - `

this is in the first paragraph this is in the second span this is also in the first paragraph

`.trim() + `

this is in the first paragraph this is in the second span this is also in the first paragraph

`.trim() + ) + }) + it('should extract child paragraphs to the top level', async () => { + const ssml = htmlToSsml(` +
+
+

+ this is in the first paragraph +

this is in the second paragraph

+ this is also in the first paragraph +

+
+
+ `, TEST_OPTIONS + ) + const text = ssml[0].textItems.join('').trim() + expect(text).to.equal( + `

this is in the first paragraph

+

this is in the second paragraph

+

this is also in the first paragraph

`.trim() + ) + }) + it('should hoist paragraphs in spans to the top level', async () => { + const ssml = htmlToSsml(` +
+
+

+ this is in the first paragraph +

this is in the second paragraph

+ this is also in the first paragraph +

+
+
+ `, TEST_OPTIONS + ) + const text = ssml[0].textItems.join('').trim() + expect(text).to.equal( + `TBD`.trim() + ) + }) + it('should hoist lists to the top level', async () => { + const ssml = htmlToSsml(` +
+
+

+ this is in the first paragraph +

  • this is the first item in a list
+ this is also in the first paragraph +

+
+
+ `, TEST_OPTIONS + ) + const text = ssml[0].textItems.join('').trim() + expect(text).to.equal( + `TBD`.trim() + ) + }) + it('should hoist headers to the top level', async () => { + const ssml = htmlToSsml(` +
+
+

+ this is in the first paragraph +

this is a header

+ this is also in the first paragraph +

+
+
+ `, TEST_OPTIONS + ) + const text = ssml[0].textItems.join('').trim() + expect(text).to.equal( + `TBD`.trim() + ) + }) + it('should hoist blockquotes to the top level', async () => { + const ssml = htmlToSsml(` +
+
+

+ this is in the first paragraph +

this is a blockquote
+ this is also in the first paragraph +

+
+
+ `, TEST_OPTIONS + ) + const text = ssml[0].textItems.join('').trim() + expect(text).to.equal( + `TBD`.trim() ) }) }) describe('a file with blockquotes', () => { it('should convert Html to SSML with complimentary voices', async () => { const ssml = htmlToSsml(` -
-

first

-
second
-

third

-
+
+
+

first

+
second
+

third

+
+
`, TEST_OPTIONS ) const first = ssml[0].textItems.join('').trim() diff --git a/yarn.lock b/yarn.lock index 6cbf70c34..09a7d55a3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8178,6 +8178,11 @@ dependencies: source-map "^0.6.1" +"@types/underscore@^1.11.4": + version "1.11.4" + resolved "https://registry.yarnpkg.com/@types/underscore/-/underscore-1.11.4.tgz#62e393f8bc4bd8a06154d110c7d042a93751def3" + integrity sha512-uO4CD2ELOjw8tasUrAhvnn2W4A0ZECOvMjCivJr4gA9pGgjv+qxKWY9GLTMVEK8ej85BxQOocUyE7hImmSQYcg== + "@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": version "2.0.6" resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d" @@ -24313,6 +24318,11 @@ undefsafe@^2.0.5: resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== +underscore@^1.13.4: + version "1.13.4" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.4.tgz#7886b46bbdf07f768e0052f1828e1dcab40c0dee" + integrity sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ== + undici@^4.9.3: version "4.14.1" resolved "https://registry.yarnpkg.com/undici/-/undici-4.14.1.tgz#7633b143a8a10d6d63335e00511d071e8d52a1d9"