Skip to content

Commit

Permalink
chore(visual-engine): add text adaptation (#54)
Browse files Browse the repository at this point in the history
* chore(visual-engine): add text adaptation

* v1.4.1
  • Loading branch information
aradjdi authored Sep 23, 2022
1 parent 30d7bc5 commit 7fb325c
Show file tree
Hide file tree
Showing 14 changed files with 198 additions and 28 deletions.
10 changes: 5 additions & 5 deletions apps/chrome-extension/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "chrome-extension",
"version": "1.4.0",
"version": "1.4.1",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
Expand All @@ -14,10 +14,10 @@
"postinstall": "node scripts/init-env"
},
"dependencies": {
"@readapt/settings": "^1.4.0",
"@readapt/shared-components": "^1.4.0",
"@readapt/text-engine": "^1.4.0",
"@readapt/visual-engine": "^1.4.0",
"@readapt/settings": "^1.4.1",
"@readapt/shared-components": "^1.4.1",
"@readapt/text-engine": "^1.4.1",
"@readapt/visual-engine": "^1.4.1",
"@vue/composition-api": "~1.4.5",
"bootstrap": "~4.6.1",
"bootstrap-vue": "~2.22.0",
Expand Down
10 changes: 5 additions & 5 deletions apps/ms-word-addin/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ms-word-addin",
"version": "1.4.0",
"version": "1.4.1",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
Expand All @@ -19,10 +19,10 @@
"postinstall": "node scripts/init-env"
},
"dependencies": {
"@readapt/settings": "^1.4.0",
"@readapt/shared-components": "^1.4.0",
"@readapt/text-engine": "^1.4.0",
"@readapt/visual-engine": "^1.4.0",
"@readapt/settings": "^1.4.1",
"@readapt/shared-components": "^1.4.1",
"@readapt/text-engine": "^1.4.1",
"@readapt/visual-engine": "^1.4.1",
"@vue/composition-api": "~1.4.5",
"bootstrap": "~4.6.1",
"bootstrap-vue": "~2.22.0",
Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "1.4.0",
"version": "1.4.1",
"npmClient": "yarn",
"useWorkspaces": true
}
2 changes: 1 addition & 1 deletion packages/dictionaries/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@readapt/dictionaries",
"version": "1.4.0",
"version": "1.4.1",
"types": "dist/index.d.ts",
"main": "",
"targets": {
Expand Down
2 changes: 1 addition & 1 deletion packages/settings/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@readapt/settings",
"version": "1.4.0",
"version": "1.4.1",
"main": "dist/readapt-settings.js",
"module": "dist/readapt-settings.esm.js",
"types": "dist/types/index.d.ts",
Expand Down
6 changes: 3 additions & 3 deletions packages/shared-components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@readapt/shared-components",
"version": "1.4.0",
"version": "1.4.1",
"main": "dist/readapt-shared-components.common.js",
"module": "dist/readapt-shared-components.common.js",
"types": "dist/types.d.ts",
Expand All @@ -26,8 +26,8 @@
"url": "git+https://github.com/ContentSquare/readapt.git"
},
"dependencies": {
"@readapt/settings": "^1.4.0",
"@readapt/visual-engine": "^1.4.0",
"@readapt/settings": "^1.4.1",
"@readapt/visual-engine": "^1.4.1",
"bootstrap": "~4.6.1",
"bootstrap-vue": "~2.22.0",
"core-js": "^3.8.3"
Expand Down
4 changes: 2 additions & 2 deletions packages/text-engine/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@readapt/text-engine",
"version": "1.4.0",
"version": "1.4.1",
"main": "dist/readapt-text-engine.js",
"module": "dist/readapt-text-engine.esm.js",
"types": "dist/index.d.ts",
Expand All @@ -25,6 +25,6 @@
"src/*"
],
"dependencies": {
"@readapt/dictionaries": "^1.4.0"
"@readapt/dictionaries": "^1.4.1"
}
}
6 changes: 3 additions & 3 deletions packages/visual-engine/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@readapt/visual-engine",
"version": "1.4.0",
"version": "1.4.1",
"main": "dist/readapt-visual-engine.js",
"module": "dist/readapt-visual-engine.esm.js",
"types": "dist/types/visual-engine/src/index.d.ts",
Expand All @@ -22,8 +22,8 @@
"src/*"
],
"dependencies": {
"@readapt/settings": "^1.4.0",
"@readapt/text-engine": "^1.4.0",
"@readapt/settings": "^1.4.1",
"@readapt/text-engine": "^1.4.1",
"lodash": "^4.17.21"
},
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions packages/visual-engine/src/adaptHtmlElementStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ const fontStyles = (settings: Settings, scope: string): string => {
return `${scope} .readapt-content { ${globalStyles} } .readapt-content > span { font-size: inherit } ${scope} .readapt-bold { font-weight: bold }`
}

const generateHtmlElementStyles = (settings: Settings, mainClass: string): string => {
const scope = `.${mainClass}`
const generateHtmlElementStyles = (settings: Settings, mainClass?: string): string => {
const scope = mainClass ? `.${mainClass}` : ''
return fontStyles(settings, scope)
}

Expand Down
46 changes: 46 additions & 0 deletions packages/visual-engine/src/adaptHtmlText.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { AnaliseTextFn } from '@readapt/text-engine'
import { Settings } from '@readapt/settings'

import { generateHtmlElementStyles } from './adaptHtmlElementStyle'
import { buildAdaptTextContentForText } from './adaptTextContent'
import { generateTextContentStyles } from './adaptTextContentStyle'
import { adaptShadeAlternateLinesForText } from './adaptShadeAlternateLines'

const adaptHtmlText =
(analyse: AnaliseTextFn) =>
(htmlText: string, settings: Settings): string => {
// General Settings do not require text analyse
let settingsStyles = generateHtmlElementStyles(settings)

// Settings with text analyse
const adaptTextContent = buildAdaptTextContentForText(analyse)

const liaisonsPhonemes = new Set<string>()
const langStyles = generateTextContentStyles(settings, '', liaisonsPhonemes)
settingsStyles += langStyles

if (settings.shadeAlternateLinesActive) {
const { className, style } = adaptShadeAlternateLinesForText(settings.shadeAlternateLinesOpacity)

return `<div>
<style>
${settingsStyles}
${style}
</style>
<span class="readapt-content ${className}">
${adaptTextContent(htmlText, settings, liaisonsPhonemes)}
</span>
</div>`
}

return `<div>
<style>
${settingsStyles}
</style>
<span class="readapt-content">
${adaptTextContent(htmlText, settings, liaisonsPhonemes)}
</span>
</div>`
}

export { adaptHtmlText }
33 changes: 32 additions & 1 deletion packages/visual-engine/src/adaptShadeAlternateLines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,37 @@ type ShadeAlternateLinesClass = `readapt-shade-alternate-lines-${LineHeight}`

const shadeLinesClasses = new Map<ShadeAlternateLinesClass, string>()

const adaptShadeAlternateLinesForText = (shadeLineOpacity: string) => {
const lineHeight = getLineHeightForText()
const { className, value } = buildShadeLineClass(lineHeight, shadeLineOpacity)

return { className, style: value }
}

const getLineHeightForText = (): number => {
const boundingRect = { height: 100 }

const computed = { fontSize: '16', lineHeight: '16' }

const fontSizeInt = parseInt(computed.fontSize, 10)

const lineHeight = computed.lineHeight === 'normal' ? 1.2 * fontSizeInt : parseFloat(computed.lineHeight)

// adjust lineHeight to element height
const elementHeight = boundingRect.height
let lineHeightFromLines = 0
if (!isNaN(elementHeight)) {
// line height can't be small than fontSize
const realLineHeight = Math.max(lineHeight, fontSizeInt)
const countLines = Math.round(elementHeight / realLineHeight)
if (countLines > 0) {
lineHeightFromLines = elementHeight / countLines
}
}

return Math.max(lineHeight, lineHeightFromLines)
}

const adaptShadeAlternateLines = (htmlElement: HTMLElement, shadeLineOpacity: string, scope: string) => {
if (htmlElement.tagName === 'P') {
addShadeAlternateLinesClass(htmlElement, shadeLineOpacity)
Expand Down Expand Up @@ -79,4 +110,4 @@ const cleanShadeAlternateLines = (htmlElement: HTMLElement) => {
}
}

export { adaptShadeAlternateLines, cleanShadeAlternateLines }
export { adaptShadeAlternateLines, cleanShadeAlternateLines, adaptShadeAlternateLinesForText }
83 changes: 81 additions & 2 deletions packages/visual-engine/src/adaptTextContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,85 @@ import { AnaliseTextFn, Liaison, Syllable } from '@readapt/text-engine'
import { ColoredItem, Settings } from '@readapt/settings'
import xor from 'lodash/xor'

const buildAdaptTextContentForText =
(analyse: AnaliseTextFn) =>
(htmlText: string, settings: Settings, liaisonsPhonemes: Set<string>): string => {
const adaptNodeForText = buildAdaptTextNodeForText(analyse, settings, liaisonsPhonemes)

return adaptNodeForText(htmlText)
}

/**
* build adaptTextNode
* adaptTextNode manipulates the DOM to add readapt styles and classes
*/
const buildAdaptTextNodeForText =
(analyse: AnaliseTextFn, settings: Settings, liaisonsPhonemes: Set<string>) =>
(textToAdapt: string): string => {
if (!hasTextRulesSettings(settings)) {
return `${textToAdapt}`
}

const textEngineResult = analyse(textToAdapt, settings.language)
const textAdapted = textToAdapt.split('').map((char: string, textIndex) => {
const classList = []

if (settings.syllableActive) {
const syllable = isSyllable(textIndex, textEngineResult.syllables)
if (syllable) {
classList.push(syllable)
}
}

if (settings.liaisonsActive && textEngineResult.liaisons) {
const liaison = findLiaison(textIndex, textEngineResult.liaisons)
if (liaison) {
const [start, end, phoneme] = liaison
liaisonsPhonemes.add(phoneme)
if (start === textIndex) {
classList.push('readapt-liaison-start', `readapt-liaison-${phoneme}`)
} else if (start + 1 === textIndex) {
classList.push('readapt-liaison-symbol')
} else if (end === textIndex) {
classList.push('readapt-liaison-end')
}
}
}

// phonemes
let hasPhonemes = false
const phoneme = textEngineResult.phonemes[textIndex]
if (settings.phonemesActive && typeof phoneme === 'number') {
const phonemeClasses = adaptPhoneme(settings, phoneme)
hasPhonemes = phonemeClasses.length > 0
classList.push(...phonemeClasses)
}

// letters
if (settings.lettersActive && !hasPhonemes) {
const letterClasses = adaptLetter(settings, char)
classList.push(...letterClasses)
}

// silentLetters
if (settings.silentLetterActive && textEngineResult.silentLetters.includes(textIndex)) {
classList.push('readapt-silent-letter')
}

if (classList.length > 0) {
return `<span class="${classList.join(' ')}">${char}</span>`
} else {
return char
}
})

return `${textAdapted.join('')}`
}

const hasSameList = (classList: string[], classListToCompare: string[]): boolean => {
return xor(classList, classListToCompare).length === 0
}

const buildAdaptTextContent =
(analyse: AnaliseTextFn) =>
(htmlElement: HTMLElement, settings: Settings, liaisonsPhonemes: Set<string>): void => {
Expand Down Expand Up @@ -31,7 +110,7 @@ const buildAdaptTextContent =
}

const hasSameClasses = (classList: string[], element: Element): boolean => {
return xor(classList, element.classList).length === 0
return hasSameList(classList, element.classList as any as string[])
}

const hasTextRulesSettings = (settings: Settings): boolean => {
Expand Down Expand Up @@ -183,4 +262,4 @@ const buildAdaptTextNode =
textNode.textContent = ''
}

export { buildAdaptTextContent }
export { buildAdaptTextContent, buildAdaptTextContentForText }
2 changes: 1 addition & 1 deletion packages/visual-engine/src/adaptTextContentStyle.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Settings } from '@readapt/settings'

const generateTextContentStyles = (settings: Settings, mainClass: string, liaisons: Set<string>): string => {
const scope = `.${mainClass}`
const scope = mainClass ? `.${mainClass}` : ''
let styles = syllableStyles(settings, scope)
styles += letterStyles(settings, scope)
styles += silentLettersStyles(settings, scope)
Expand Down
16 changes: 15 additions & 1 deletion packages/visual-engine/src/visualEngineFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { AnaliseTextFn } from '@readapt/text-engine'
import { Settings } from '@readapt/settings'

import { adaptHtmlElement } from './adaptHtmlElement'
import { adaptHtmlText } from './adaptHtmlText'

/**
* Adapt the html element passed by parameter using the settings. Css styles will be scoped using scope prefix.
Expand All @@ -17,4 +18,17 @@ const buildAdaptHtmlElement = (analyse: AnaliseTextFn): AdaptHtmlElementFn => {
return adaptHtmlElement(analyse)
}

export { buildAdaptHtmlElement }
/**
* Adapt the html text passed by parameter using the settings. Css styles will be scoped using scope prefix.
*/
export type AdaptHtmlTextFn = (htmlText: string, settings: Settings) => string

/**
* build a function to adapt an html text
* @param analyse the {@link AnaliseTextFn} used to adapt the text content
*/
const buildAdaptHtmlText = (analyse: AnaliseTextFn): AdaptHtmlTextFn => {
return adaptHtmlText(analyse)
}

export { buildAdaptHtmlElement, buildAdaptHtmlText }

0 comments on commit 7fb325c

Please sign in to comment.