Skip to content

Commit

Permalink
NEW: option: glosses = true
Browse files Browse the repository at this point in the history
  • Loading branch information
dwhieb committed Feb 23, 2024
1 parent 8a73281 commit 6feefc7
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 25 deletions.
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,14 @@ If the input is a string containing only whitespace, an empty string is returned

## Options

| Option | type | Default | Description |
| -------------- | ------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `analysisLang` | String | undefined | An [IETF language tag][lang-tags] to use as the default value of the `lang` attribute for any data in the analysis language (metadata, literal translation, free translation, glosses, literal word translation). If `undefined`, no `lang` tag is added, which means that browsers will assume that the analysis language is the same as the HTML document. |
| `classes` | Array<String> | `['igl']` | An array of classes to apply to the wrapper element. |
| `scription` | Object | `{}` | Options to pass to the `scription2dlx` library. See [scription2dlx][scription2dlx] for more details. |
| `tag` | String | `'div'` | The HTML tag to wrap each interlinear gloss in. Can also be a custom tag (useful for HTML custom elements). |
| `targetLang` | String | undefined | An [IETF language tag][lang-tags] to use as the default value of the `lang` attribute for any data in the target language. |
| Option | type | Default | Description |
| -------------- | -------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `analysisLang` | String | undefined | An [IETF language tag][lang-tags] to use as the default value of the `lang` attribute for any data in the analysis language (metadata, literal translation, free translation, glosses, literal word translation). If `undefined`, no `lang` tag is added, which means that browsers will assume that the analysis language is the same as the HTML document. |
| `classes` | Array<String> | `['igl']` | An array of classes to apply to the wrapper element. |
| `glosses` | Boolean \| Array \| Object | `false` | Options for wrapping glosses in `<abbr>` tags.<br><br>If set to `false` (default), no `<abbr>` tags are added to the glosses.<br><br>If set to `true`, an `<abbr>` tag is wrapped around any glosses in CAPS, and any numbers.<br><br>If set to an array, any glosses listed in the array will be wrapped in `<abbr>` tags. (This is useful if you'd certain glosses to be lowercase but still wrapped in an `<abbr>` tag, such as `sg` and `pl`, which are commonly lowercased.)<br><br>If set to an object hash, the keys of the object are treated as glosses, and the values of the object are treated as definitions for those glosses. Each gloss will be wrapped in an `<abbr>` tag with a `title` attribute set to the definition. |
| `scription` | Object | `{}` | Options to pass to the `scription2dlx` library. See [scription2dlx][scription2dlx] for more details. |
| `tag` | String | `'div'` | The HTML tag to wrap each interlinear gloss in. Can also be a custom tag (useful for HTML custom elements). |
| `targetLang` | String | undefined | An [IETF language tag][lang-tags] to use as the default value of the `lang` attribute for any data in the target language. |
## HTML Structure
Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import validateOptions from './options.js'

const defaultOptions = {
classes: [`igl`],
glosses: false,
scription: {},
tag: `div`,
}
Expand Down
33 changes: 25 additions & 8 deletions src/words/glosses.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,41 @@
import addEmphasis from '../utilities/addEmphasis.js'
import replaceHyphens from '../utilities/replaceHyphens.js'

export default function createGlosses(data, { analysisLang }) {
const glossRegExp = /(?<gloss>[1-4]|[A-Z]+)/gv

if (!data) return ``
function createGlossLine(glosses, language, option) {

if (typeof data === `string`) {
const lang = language ? `lang='${ language }'` : ``

if (option === true) glosses = wrapGlosses(glosses)
glosses = replaceHyphens(glosses)
glosses = addEmphasis(glosses)

return `<span class=glosses ${ lang }>${ glosses }</span>`

}

const lang = analysisLang ? `lang='${ analysisLang }'` : ``
const glosses = addEmphasis(replaceHyphens(data))
/**
* Finds all numbers and capitalized glosses in a string and wraps them in `<abbr>` tags.
* @param {string} glosses
* @returns {string}
*/
function wrapGlosses(glosses) {
return glosses.replaceAll(glossRegExp, `<abbr>$1</abbr>`)
}

return `<span class=w-gl ${ lang }>${ glosses }</span>`
export default function createGlosses(data, { analysisLang, glosses: glossesOption }) {

if (!data) return ``

if (typeof data === `string`) {
return createGlossLine(data, analysisLang, glossesOption)
}

let html = ``

for (const lang in data) {
const glosses = addEmphasis(replaceHyphens(data[lang]))
html += `<span class=w-gl lang='${ lang }'>${ glosses }</span>`
html += createGlossLine(data[lang], lang, glossesOption)
}

return html
Expand Down
4 changes: 2 additions & 2 deletions src/words/literal.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ export default function createLiteral(data, { analysisLang }) {

if (typeof data === `string`) {
const lang = analysisLang ? `lang='${ analysisLang }'` : ``
return `<span class=w-lit ${ lang }>${ addEmphasis(data) }</span>`
return `<span class=lit ${ lang }>${ addEmphasis(data) }</span>`
}

let html = ``

for (const lang in data) {
const tln = data[lang]
html += `<span class=w-lit lang='${ lang }'>${ addEmphasis(tln) }</span>`
html += `<span class=lit lang='${ lang }'>${ addEmphasis(tln) }</span>`
}

return html
Expand Down
2 changes: 1 addition & 1 deletion src/words/morphemes.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default function createMorphemes(data, { targetLang }) {

for (const ortho in data) {
const morphemes = addEmphasis(replaceHyphens(data[ortho]))
html += `<span class=w-m data-ortho='${ ortho }' ${ lang }>${ morphemes }</span>`
html += `<span class=morphemes data-ortho='${ ortho }' ${ lang }>${ morphemes }</span>`
}

return html
Expand Down
2 changes: 1 addition & 1 deletion src/words/transcription.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default function createTranscription(data, { targetLang }) {

for (const ortho in data) {
const txn = data[ortho]
html += `<span class=w-txn data-ortho='${ ortho }' ${ lang }>${ addEmphasis(txn) }</span>`
html += `<span class=w data-ortho='${ ortho }' ${ lang }>${ addEmphasis(txn) }</span>`
}

return html
Expand Down
83 changes: 77 additions & 6 deletions test/words.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import parse from './utilities/convertAndParse.js'

import {
findElement,
findElements,
getTagName,
} from '@web/parse5-utils'

Expand Down Expand Up @@ -149,7 +150,7 @@ describe(`words`, function() {
`

const { dom } = await parse(scription)
const morphemes = findElementByClass(dom, `w-m`)
const morphemes = findElementByClass(dom, `morphemes`)

expect(getTextContent(morphemes)).to.equal(`ni‑na‑ku‑pend‑a`) // non-breaking hyphens

Expand All @@ -164,7 +165,7 @@ describe(`words`, function() {
`

const { dom, html } = await parse(scription)
const [mod, swad] = findElementsByClass(dom, `w-m`)
const [mod, swad] = findElementsByClass(dom, `morphemes`)

expect(getTextContent(mod)).to.equal(`waxt‑qungu`) // non-breaking hypens
expect(getTextContent(swad)).to.equal(`wašt‑ʔungu`) // non-breaking hypens
Expand Down Expand Up @@ -200,16 +201,86 @@ describe(`words`, function() {
I love you
`

const { dom, html } = await parse(scription)
const morphemes = findElementByClass(dom, `w-gl`)
const { dom } = await parse(scription)
const morphemes = findElementByClass(dom, `glosses`)

expect(getTextContent(morphemes)).to.equal(`1SG.SUBJ‑PRES‑2SG.OBJ‑love‑IND`) // non-breaking hyphens

})

it(`supports multiple analysis languages`)
it(`supports multiple analysis languages`, async function() {

const scription = `
\\txn ninakupenda
\\m ni-na-ku-pend-a
\\gl-en 1SG.SUBJ-PRES-2SG.OBJ-love-IND
\\gl-sp 1SG.SJ-PRES-2SG.OJ-amar-IND
\\tln I love you
`

const { dom } = await parse(scription)
const [firstGloss, secondGloss] = findElementsByClass(dom, `glosses`)

expect(getTextContent(firstGloss)).to.include(`SUBJ`)
expect(getTextContent(secondGloss)).to.include(`SJ`)

})

it(`supports emphasis`, async function() {

const scription = `
ninakupenda
ni-na-ku-pend-a
1SG.SUBJ-PRES-*2SG.OBJ*-love-IND
I love you
`

const { dom } = await parse(scription)
const b = findElement(dom, el => getTagName(el) === `b`)

expect(getTextContent(b)).to.equal(`2SG.OBJ`)

})

it(`option: glosses = false (default)`, async function() {

const scription = `
ninakupenda
ni-na-ku-pend-a
1SG.SUBJ-PRES-2SG.OBJ-love-IND
I love you
`

const { dom } = await parse(scription)
const abbr = findElement(dom, el => getTagName(el) === `abbr`)

expect(abbr).not.to.exist

})

it(`option: glosses = true`, async function() {

const scription = `
ninakupenda
ni-na-ku-pend-a
1SG.SUBJ-PRES-2SG.OBJ-love-IND
I love you
`

const { dom } = await parse(scription, { glosses: true })
const glosses = findElements(dom, el => getTagName(el) === `abbr`)
const [num, caps] = glosses

expect(getTextContent(num)).to.equal(`1`)
expect(getTextContent(caps)).to.equal(`SG`)

expect(glosses).to.have.length(8)

})

it(`option: glosses = array`)

it(`supports emphasis`)
it(`option: glosses = object`)

})

Expand Down

0 comments on commit 6feefc7

Please sign in to comment.