Fix whitespace normalization

- Normalize ASCII whitespace only
- Collapse sequence of *one* or more consecutive whitespace characters
This commit is contained in:
John Factotum
2023-03-21 12:03:39 +08:00
parent 9949000a9e
commit 45bfe6ee71
2 changed files with 14 additions and 6 deletions
+7 -3
View File
@@ -26,8 +26,12 @@ const MIME = {
// convert to camel case // convert to camel case
const camel = x => x.toLowerCase().replace(/[-:](.)/g, (_, g) => g.toUpperCase()) const camel = x => x.toLowerCase().replace(/[-:](.)/g, (_, g) => g.toUpperCase())
// remove leading, trailing, and excess internal whitespace // strip and collapse ASCII whitespace
const whitespacePreLine = str => str ? str.trim().replace(/\s{2,}/g, ' ') : '' // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
const normalizeWhitespace = str => str ? str
.replace(/[\t\n\f\r ]+/g, ' ')
.replace(/^[\t\n\f\r ]+/, '')
.replace(/[\t\n\f\r ]+$/, '') : ''
const filterAttribute = (attr, value, isList) => isList const filterAttribute = (attr, value, isList) => isList
? el => el.getAttribute(attr)?.split(/\s/)?.includes(value) ? el => el.getAttribute(attr)?.split(/\s/)?.includes(value)
@@ -38,7 +42,7 @@ const filterAttribute = (attr, value, isList) => isList
const getAttributes = (...xs) => el => const getAttributes = (...xs) => el =>
el ? Object.fromEntries(xs.map(x => [camel(x), el.getAttribute(x)])) : null el ? Object.fromEntries(xs.map(x => [camel(x), el.getAttribute(x)])) : null
const getElementText = el => whitespacePreLine(el?.textContent) const getElementText = el => normalizeWhitespace(el?.textContent)
const childGetter = (doc, ns) => { const childGetter = (doc, ns) => {
// ignore the namespace if it doesn't appear in document at all // ignore the namespace if it doesn't appear in document at all
+7 -3
View File
@@ -1,5 +1,8 @@
const trim = str => str?.trim()?.replace(/\s{2,}/g, ' ') const normalizeWhitespace = str => str ? str
const getElementText = el => trim(el?.textContent) .replace(/[\t\n\f\r ]+/g, ' ')
.replace(/^[\t\n\f\r ]+/, '')
.replace(/[\t\n\f\r ]+$/, '') : ''
const getElementText = el => normalizeWhitespace(el?.textContent)
const NS = { const NS = {
XLINK: 'http://www.w3.org/1999/xlink', XLINK: 'http://www.w3.org/1999/xlink',
@@ -287,7 +290,8 @@ export const makeFB2 = async blob => {
const str = template(el.outerHTML) const str = template(el.outerHTML)
const blob = new Blob([str], { type: MIME.XHTML }) const blob = new Blob([str], { type: MIME.XHTML })
const url = URL.createObjectURL(blob) const url = URL.createObjectURL(blob)
const title = trim(el.querySelector('.title, .subtitle, p')?.textContent const title = normalizeWhitespace(
el.querySelector('.title, .subtitle, p')?.textContent
?? (el.classList.contains('title') ? el.textContent : '')) ?? (el.classList.contains('title') ? el.textContent : ''))
return { return {
ids, title, titles, load: () => url, ids, title, titles, load: () => url,