{"version":3,"file":"react-furigana.umd.cjs","sources":["../src/components/Ruby.tsx","../src/components/TokenDisplay.tsx","../src/tokenizer.ts","../src/ReactFurigana.tsx"],"sourcesContent":["type RubyProps = {\r\n    kanji: string,\r\n    furigana: string\r\n}\r\n\r\nexport default function Ruby(props: RubyProps) {\r\n    return (\r\n        <ruby>\r\n            {props.kanji}\r\n            <rt>\r\n                {props.furigana}\r\n            </rt>\r\n        </ruby>\r\n    );\r\n}\r\n","import {Token} from '../tokenizer';\r\nimport Ruby from './Ruby';\r\n\r\ntype TokenDisplayProps = {\r\n    token: Token;\r\n}\r\n\r\nexport default function TokenDisplay(props: TokenDisplayProps) {\r\n\r\n    if (props.token.furigana) {\r\n        return <Ruby kanji={props.token.kanji} furigana={props.token.furigana}/>;\r\n    }\r\n\r\n    return props.token.kanji;\r\n\r\n}\r\n","export type Token = {\r\n    kanji: string,\r\n    furigana?: string\r\n}\r\n\r\nexport class Tokenizer {\r\n\r\n    //Source: http://www.rikai.com/library/kanjitables/kanji_codes.unicode.shtml\r\n    private static readonly hiraganaRanges = [[0x3040, 0x309F]];\r\n    private static readonly punctuationsMarksRanges = [[0x3000, 0x3004], [0x3006, 0x303F], [0xFF00, 0xFF0F],\r\n        [0xFF1A, 0xFF65], [0xFFA0, 0xFFEF]];\r\n\r\n    private readonly text: string;\r\n    private readonly separator: string;\r\n    private readonly leftBracket: string;\r\n    private readonly rightBracket: string;\r\n\r\n    private readonly tokens: Token[] = [];\r\n    private currentKanji = '';\r\n    private currentFurigana: string | undefined;\r\n\r\n    constructor(text: string, separator: string = ' ', leftBracket: string = '[', rightBracket: string = ']') {\r\n        this.text = text;\r\n        this.separator = separator;\r\n        this.leftBracket = leftBracket;\r\n        this.rightBracket = rightBracket;\r\n    }\r\n\r\n    parse() {\r\n        if (this.tokens.length > 0) {\r\n            return this.tokens;\r\n        }\r\n\r\n        for (const character of this.text) {\r\n            if (this.currentFurigana === undefined) {\r\n                this.parseKanji(character);\r\n            } else {\r\n                this.parseFurigana(character);\r\n            }\r\n        }\r\n\r\n        this.addToken();\r\n\r\n        return this.tokens;\r\n    }\r\n\r\n    private parseKanji(character: string) {\r\n        if (character === this.leftBracket) {\r\n            this.currentFurigana = '';\r\n        } else if (character === this.separator) {\r\n            this.addToken();\r\n        } else {\r\n            this.currentKanji += character;\r\n            if (!Tokenizer.allowsFurigana(character)) {\r\n                this.addToken();\r\n            }\r\n        }\r\n    }\r\n\r\n    private parseFurigana(character: string) {\r\n        if (character === this.rightBracket) {\r\n            this.addToken();\r\n        } else {\r\n            this.currentFurigana += character;\r\n        }\r\n    }\r\n\r\n    private static allowsFurigana(character: string) {\r\n        const unicode = character.charCodeAt(0);\r\n        return !Tokenizer.isHiragana(unicode) && !Tokenizer.isPunctuationMark(unicode);\r\n    }\r\n\r\n    private static isHiragana(unicode: number) {\r\n        return Tokenizer.isInRange(unicode, Tokenizer.hiraganaRanges);\r\n    }\r\n\r\n    private static isPunctuationMark(unicode: number) {\r\n        return Tokenizer.isInRange(unicode, Tokenizer.punctuationsMarksRanges);\r\n    }\r\n\r\n    private static isInRange(unicode: number, ranges: number[][]) {\r\n        return ranges.some(range => unicode >= range[0] && unicode <= range[1]);\r\n    }\r\n\r\n    private addToken() {\r\n        if (!this.currentKanji) {\r\n            return;\r\n        }\r\n\r\n        this.tokens.push({\r\n            kanji: this.currentKanji,\r\n            furigana: this.currentFurigana\r\n        });\r\n        this.currentKanji = '';\r\n        this.currentFurigana = undefined;\r\n    }\r\n\r\n}\r\n","import React from 'react';\r\nimport TokenDisplay from './components/TokenDisplay';\r\nimport {Token, Tokenizer} from './tokenizer';\r\n\r\ntype ReactFuriganaProps = {\r\n    text: string,\r\n    separator?: string,\r\n    leftBracket?: string,\r\n    rightBracket?: string,\r\n    render?: (token: Token) => React.ReactNode\r\n}\r\n\r\nexport function ReactFurigana(props: ReactFuriganaProps) {\r\n\r\n    const tokens = React.useMemo(() => {\r\n        return new Tokenizer(props.text, props.separator, props.leftBracket, props.rightBracket).parse();\r\n    }, [props.text, props.separator, props.leftBracket, props.rightBracket]);\r\n\r\n    const render = React.useCallback((token: Token) => {\r\n        return props.render ? props.render(token) : <TokenDisplay token={token}/>\r\n    }, [props.render]);\r\n\r\n    return (\r\n        <>\r\n            {tokens.map((token, index) => (\r\n                <React.Fragment key={index}>\r\n                    {render(token)}\r\n                </React.Fragment>\r\n            ))}\r\n        </>\r\n    );\r\n\r\n}\r\n"],"names":["Ruby","props","jsx","TokenDisplay","_Tokenizer","text","separator","leftBracket","rightBracket","__publicField","character","unicode","ranges","range","Tokenizer","ReactFurigana","tokens","React","render","token","Fragment","index"],"mappings":"weAKA,SAAwBA,EAAKC,EAAkB,CAC3C,cACK,OACI,CAAA,SAAA,CAAMA,EAAA,MACPC,EAAAA,IAAC,KACI,CAAA,SAAAD,EAAM,QACX,CAAA,CAAA,EACJ,CAER,CCPA,SAAwBE,EAAaF,EAA0B,CAEvD,OAAAA,EAAM,MAAM,SACLC,MAACF,GAAK,MAAOC,EAAM,MAAM,MAAO,SAAUA,EAAM,MAAM,QAAS,CAAA,EAGnEA,EAAM,MAAM,KAEvB,CCVO,MAAMG,EAAN,MAAMA,CAAU,CAgBnB,YAAYC,EAAcC,EAAoB,IAAKC,EAAsB,IAAKC,EAAuB,IAAK,CATzFC,EAAA,aACAA,EAAA,kBACAA,EAAA,oBACAA,EAAA,qBAEAA,EAAA,cAAkB,CAAC,GAC5BA,EAAA,oBAAe,IACfA,EAAA,wBAGJ,KAAK,KAAOJ,EACZ,KAAK,UAAYC,EACjB,KAAK,YAAcC,EACnB,KAAK,aAAeC,CAAA,CAGxB,OAAQ,CACA,GAAA,KAAK,OAAO,OAAS,EACrB,OAAO,KAAK,OAGL,UAAAE,KAAa,KAAK,KACrB,KAAK,kBAAoB,OACzB,KAAK,WAAWA,CAAS,EAEzB,KAAK,cAAcA,CAAS,EAIpC,YAAK,SAAS,EAEP,KAAK,MAAA,CAGR,WAAWA,EAAmB,CAC9BA,IAAc,KAAK,YACnB,KAAK,gBAAkB,GAChBA,IAAc,KAAK,UAC1B,KAAK,SAAS,GAEd,KAAK,cAAgBA,EAChBN,EAAU,eAAeM,CAAS,GACnC,KAAK,SAAS,EAEtB,CAGI,cAAcA,EAAmB,CACjCA,IAAc,KAAK,aACnB,KAAK,SAAS,EAEd,KAAK,iBAAmBA,CAC5B,CAGJ,OAAe,eAAeA,EAAmB,CACvC,MAAAC,EAAUD,EAAU,WAAW,CAAC,EAC/B,MAAA,CAACN,EAAU,WAAWO,CAAO,GAAK,CAACP,EAAU,kBAAkBO,CAAO,CAAA,CAGjF,OAAe,WAAWA,EAAiB,CACvC,OAAOP,EAAU,UAAUO,EAASP,EAAU,cAAc,CAAA,CAGhE,OAAe,kBAAkBO,EAAiB,CAC9C,OAAOP,EAAU,UAAUO,EAASP,EAAU,uBAAuB,CAAA,CAGzE,OAAe,UAAUO,EAAiBC,EAAoB,CACnD,OAAAA,EAAO,KAAKC,GAASF,GAAWE,EAAM,CAAC,GAAKF,GAAWE,EAAM,CAAC,CAAC,CAAA,CAGlE,UAAW,CACV,KAAK,eAIV,KAAK,OAAO,KAAK,CACb,MAAO,KAAK,aACZ,SAAU,KAAK,eAAA,CAClB,EACD,KAAK,aAAe,GACpB,KAAK,gBAAkB,OAAA,CAG/B,EAzFIJ,EAHSL,EAGe,iBAAiB,CAAC,CAAC,MAAQ,KAAM,CAAC,GAC1DK,EAJSL,EAIe,0BAA0B,CAAC,CAAC,MAAQ,KAAM,EAAG,CAAC,MAAQ,KAAM,EAAG,CAAC,MAAQ,KAAM,EAClG,CAAC,MAAQ,KAAM,EAAG,CAAC,MAAQ,KAAM,CAAC,GALnC,IAAMU,EAANV,ECOA,SAASW,EAAcd,EAA2B,CAE/C,MAAAe,EAASC,EAAM,QAAQ,IAClB,IAAIH,EAAUb,EAAM,KAAMA,EAAM,UAAWA,EAAM,YAAaA,EAAM,YAAY,EAAE,MAAM,EAChG,CAACA,EAAM,KAAMA,EAAM,UAAWA,EAAM,YAAaA,EAAM,YAAY,CAAC,EAEjEiB,EAASD,EAAM,YAAaE,GACvBlB,EAAM,OAASA,EAAM,OAAOkB,CAAK,EAAIjB,MAACC,GAAa,MAAAgB,EAAa,EACxE,CAAClB,EAAM,MAAM,CAAC,EAEjB,OAESC,EAAA,IAAAkB,EAAA,SAAA,CAAA,SAAAJ,EAAO,IAAI,CAACG,EAAOE,IAChBnB,EAAAA,IAACe,EAAM,SAAN,CACI,SAAOC,EAAAC,CAAK,GADIE,CAErB,CACH,EACL,CAGR"}