react-furigana
Version:
A simple React component for handling Japanese text with furigana.
73 lines (72 loc) • 2.42 kB
JavaScript
import { jsxs as c, jsx as e, Fragment as h } from "react/jsx-runtime";
import u from "react";
function g(a) {
return /* @__PURE__ */ c("ruby", { children: [
a.kanji,
/* @__PURE__ */ e("rt", { children: a.furigana })
] });
}
function k(a) {
return a.token.furigana ? /* @__PURE__ */ e(g, { kanji: a.token.kanji, furigana: a.token.furigana }) : a.token.kanji;
}
class r {
//Source: http://www.rikai.com/library/kanjitables/kanji_codes.unicode.shtml
static hiraganaRanges = [[12352, 12447]];
static punctuationsMarksRanges = [
[12288, 12292],
[12294, 12351],
[65280, 65295],
[65306, 65381],
[65440, 65519]
];
text;
separator;
leftBracket;
rightBracket;
tokens = [];
currentKanji = "";
currentFurigana;
constructor(t, i = " ", n = "[", s = "]") {
this.text = t, this.separator = i, this.leftBracket = n, this.rightBracket = s;
}
parse() {
if (this.tokens.length > 0)
return this.tokens;
for (const t of this.text)
this.currentFurigana === void 0 ? this.parseKanji(t) : this.parseFurigana(t);
return this.addToken(), this.tokens;
}
parseKanji(t) {
t === this.leftBracket ? this.currentFurigana = "" : t === this.separator ? this.addToken() : (this.currentKanji += t, r.allowsFurigana(t) || this.addToken());
}
parseFurigana(t) {
t === this.rightBracket ? this.addToken() : this.currentFurigana += t;
}
static allowsFurigana(t) {
const i = t.charCodeAt(0);
return !r.isHiragana(i) && !r.isPunctuationMark(i);
}
static isHiragana(t) {
return r.isInRange(t, r.hiraganaRanges);
}
static isPunctuationMark(t) {
return r.isInRange(t, r.punctuationsMarksRanges);
}
static isInRange(t, i) {
return i.some((n) => t >= n[0] && t <= n[1]);
}
addToken() {
this.currentKanji && (this.tokens.push({
kanji: this.currentKanji,
furigana: this.currentFurigana
}), this.currentKanji = "", this.currentFurigana = void 0);
}
}
function l(a) {
const t = u.useMemo(() => new r(a.text, a.separator, a.leftBracket, a.rightBracket).parse(), [a.text, a.separator, a.leftBracket, a.rightBracket]), i = u.useCallback((n) => a.render ? a.render(n) : /* @__PURE__ */ e(k, { token: n }), [a.render]);
return /* @__PURE__ */ e(h, { children: t.map((n, s) => /* @__PURE__ */ e(u.Fragment, { children: i(n) }, s)) });
}
export {
l as default
};
//# sourceMappingURL=react-furigana.js.map