pangu
Version:
Opinionated paranoid text spacing: automatically inserts whitespace between CJK (Chinese, Japanese, Korean) and ANS (alphabetical letters, numerical digits and symbols)
62 lines (61 loc) • 3.19 kB
JavaScript
import pangu, { ANY_CJK } from "../../shared/index.js";
//#region src/browser/dom/boundary-spacing.ts
var QUOTE = /["\u201c\u201d]/;
function decideBoundarySpacing(boundarySpacingContext) {
if (boundarySpacingContext.currentEndsWithSpace || boundarySpacingContext.nextStartsWithSpace || boundarySpacingContext.whitespaceBetween || boundarySpacingContext.spaceLikeBetween) return "none";
if (boundarySpacingContext.contentBetween) return "none";
if (!needsBoundarySpace(boundarySpacingContext.currentTail, boundarySpacingContext.nextFirst)) return "none";
if (boundarySpacingContext.blockEdgeBetween) return "none";
if (!boundarySpacingContext.nextBoundaryIsSpaceSensitive) {
if (boundarySpacingContext.nextBoundaryIsIgnored || boundarySpacingContext.precedingNodeHidden()) return "none";
return "prepend-next";
}
if (!boundarySpacingContext.currentBoundaryIsSpaceSensitive) {
if (boundarySpacingContext.currentNodeHidden() || boundarySpacingContext.nextNodeHidden()) return "none";
return "append-current";
}
if (boundarySpacingContext.currentNodeHidden() || boundarySpacingContext.nextNodeHidden()) return "none";
if (boundarySpacingContext.inGridOrFlexContainer()) return "none";
return "insert-element";
}
function decideTextNodeSpacing(textNodeSpacingContext) {
const textNodeSpacingDecisions = [];
let { text } = textNodeSpacingContext;
if (text.startsWith(" ") && textNodeSpacingContext.precedingNodeHidden()) {
textNodeSpacingDecisions.push("trim-leading-space");
text = text.substring(1);
}
if (isStandaloneQuote(text)) {
if (textNodeSpacingContext.previousElementLastChar !== null && ANY_CJK.test(textNodeSpacingContext.previousElementLastChar)) textNodeSpacingDecisions.push("prepend-space");
} else textNodeSpacingDecisions.push("apply-text-spacing");
return textNodeSpacingDecisions;
}
var spacedJunctionCache = /* @__PURE__ */ new Map();
var SPACED_JUNCTION_CACHE_MAX = 4096;
function spaceJunction(currentTail, nextFirst) {
const junction = `${currentTail}${nextFirst}`;
const cached = spacedJunctionCache.get(junction);
if (cached !== void 0) return cached;
const spacedJunction = pangu.spaceText(junction);
if (spacedJunctionCache.size >= SPACED_JUNCTION_CACHE_MAX) spacedJunctionCache.clear();
spacedJunctionCache.set(junction, spacedJunction);
return spacedJunction;
}
function needsBoundarySpace(currentTail, nextFirst) {
return spaceJunction(currentTail, nextFirst).endsWith(` ${nextFirst}`) && !isQuoteNextToCjk(currentTail.slice(-1), nextFirst);
}
function respaceCurrentTail(currentTail, nextFirst) {
const spacedJunction = spaceJunction(currentTail, nextFirst);
if (!spacedJunction.endsWith(` ${nextFirst}`)) return null;
const spacedTail = spacedJunction.slice(0, -2);
return spacedTail === currentTail ? null : spacedTail;
}
function isQuoteNextToCjk(currentLast, nextFirst) {
return QUOTE.test(currentLast) && ANY_CJK.test(nextFirst) || ANY_CJK.test(currentLast) && /["\u201d]/.test(nextFirst);
}
function isStandaloneQuote(text) {
return text.length === 1 && QUOTE.test(text);
}
//#endregion
export { decideBoundarySpacing, decideTextNodeSpacing, respaceCurrentTail };
//# sourceMappingURL=boundary-spacing.js.map