From dba749c506f697347778cf7c0c4c2d3ac6014be5 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Sat, 20 Aug 2022 00:11:46 +0800 Subject: [PATCH 1/2] Fix some articles not converted to speech correctly --- packages/api/src/utils/textToSpeech.ts | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/packages/api/src/utils/textToSpeech.ts b/packages/api/src/utils/textToSpeech.ts index 42a057b3b..d34ecb7dc 100644 --- a/packages/api/src/utils/textToSpeech.ts +++ b/packages/api/src/utils/textToSpeech.ts @@ -229,7 +229,11 @@ export const htmlElementToSsml = ( emphasisElement.setAttribute('level', level) emphasisElement.innerHTML = element.innerHTML.trim() parent.appendChild(emphasisElement) - element?.parentNode?.replaceChild(parent, element) + const id = element.getAttribute('data-omnivore-anchor-idx') + if (id) { + const e = htmlElement.querySelector(`[data-omnivore-anchor-idx="${id}"]`) + e?.parentNode?.replaceChild(parent, e) + } } // create new ssml document @@ -251,11 +255,11 @@ export const htmlElementToSsml = ( htmlElement.querySelectorAll('*').forEach((e) => { switch (e.tagName.toLowerCase()) { case 's': - replaceEmphasisElement(e, 'reduced') + replaceEmphasisElement(e, 'moderate') break case 'sub': if (e.getAttribute('alias') === null) { - replaceEmphasisElement(e, 'reduced') + replaceEmphasisElement(e, 'moderate') } break case 'i': @@ -269,7 +273,7 @@ export const htmlElementToSsml = ( case 'summary': case 'caption': case 'figcaption': - replaceEmphasisElement(e, 'reduced') + replaceEmphasisElement(e, 'moderate') break case 'b': case 'strong': @@ -284,13 +288,22 @@ export const htmlElementToSsml = ( replaceEmphasisElement(e, 'moderate') break default: { + const parent = ssml.createDocumentFragment() as unknown as Element + appendBookmarkElement(parent, e) const text = (e as HTMLElement).innerText.trim() const textElement = ssml.createTextNode(text) - e.parentNode?.replaceChild(textElement, e) + parent.appendChild(textElement) + const id = e.getAttribute('data-omnivore-anchor-idx') + if (id) { + const element = htmlElement.querySelector( + `[data-omnivore-anchor-idx="${id}"]` + ) + element?.parentNode?.replaceChild(parent, element) + } } } }) prosodyElement.appendChild(htmlElement) - return speakElement.outerHTML.replace(/ /g, '') + return speakElement.outerHTML.replace(/ |\n/g, '') } From 85d8816e1e3e97e353d2560fe446cd084e7ec1bd Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Mon, 22 Aug 2022 12:39:06 +0800 Subject: [PATCH 2/2] Replace li element with a sentence element when converting HTML to SSML --- packages/api/src/utils/textToSpeech.ts | 45 +++++++++++++++----------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/packages/api/src/utils/textToSpeech.ts b/packages/api/src/utils/textToSpeech.ts index d34ecb7dc..edfde939e 100644 --- a/packages/api/src/utils/textToSpeech.ts +++ b/packages/api/src/utils/textToSpeech.ts @@ -213,6 +213,14 @@ export const htmlElementToSsml = ( rate = 1, volume = 100 ): string => { + const replaceElement = (newElement: Element, oldElement: Element) => { + const id = oldElement.getAttribute('data-omnivore-anchor-idx') + if (id) { + const e = htmlElement.querySelector(`[data-omnivore-anchor-idx="${id}"]`) + e?.parentNode?.replaceChild(newElement, e) + } + } + const appendBookmarkElement = (parent: Element, element: Element) => { const id = element.getAttribute('data-omnivore-anchor-idx') if (id) { @@ -222,18 +230,23 @@ export const htmlElementToSsml = ( } } - const replaceEmphasisElement = (element: Element, level: string) => { + const replaceWithEmphasis = (element: Element, level: string) => { const parent = ssml.createDocumentFragment() as unknown as Element appendBookmarkElement(parent, element) const emphasisElement = ssml.createElement('emphasis') emphasisElement.setAttribute('level', level) emphasisElement.innerHTML = element.innerHTML.trim() parent.appendChild(emphasisElement) - const id = element.getAttribute('data-omnivore-anchor-idx') - if (id) { - const e = htmlElement.querySelector(`[data-omnivore-anchor-idx="${id}"]`) - e?.parentNode?.replaceChild(parent, e) - } + replaceElement(parent, element) + } + + const replaceWithSentence = (element: Element) => { + const parent = ssml.createDocumentFragment() as unknown as Element + appendBookmarkElement(parent, element) + const sentenceElement = ssml.createElement('s') + sentenceElement.innerHTML = element.innerHTML.trim() + parent.appendChild(sentenceElement) + replaceElement(parent, element) } // create new ssml document @@ -255,11 +268,11 @@ export const htmlElementToSsml = ( htmlElement.querySelectorAll('*').forEach((e) => { switch (e.tagName.toLowerCase()) { case 's': - replaceEmphasisElement(e, 'moderate') + replaceWithEmphasis(e, 'moderate') break case 'sub': if (e.getAttribute('alias') === null) { - replaceEmphasisElement(e, 'moderate') + replaceWithEmphasis(e, 'moderate') } break case 'i': @@ -273,19 +286,21 @@ export const htmlElementToSsml = ( case 'summary': case 'caption': case 'figcaption': - replaceEmphasisElement(e, 'moderate') + replaceWithEmphasis(e, 'moderate') break case 'b': case 'strong': case 'dt': case 'dfn': case 'u': - case 'li': case 'mark': case 'th': case 'title': case 'var': - replaceEmphasisElement(e, 'moderate') + replaceWithEmphasis(e, 'moderate') + break + case 'li': + replaceWithSentence(e) break default: { const parent = ssml.createDocumentFragment() as unknown as Element @@ -293,13 +308,7 @@ export const htmlElementToSsml = ( const text = (e as HTMLElement).innerText.trim() const textElement = ssml.createTextNode(text) parent.appendChild(textElement) - const id = e.getAttribute('data-omnivore-anchor-idx') - if (id) { - const element = htmlElement.querySelector( - `[data-omnivore-anchor-idx="${id}"]` - ) - element?.parentNode?.replaceChild(parent, element) - } + replaceElement(parent, e) } } })