{"version":3,"file":"react-furigana.umd.cjs","names":[],"sources":["../src/components/Ruby.tsx","../src/components/TokenDisplay.tsx","../src/tokenizer.ts","../src/ReactFurigana.tsx","../src/index.ts"],"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 type {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 type {Token} from './tokenizer';\r\nimport {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","export type {Token} from './tokenizer'\r\nimport {ReactFurigana} from './ReactFurigana';\r\n\r\nexport default ReactFurigana;\r\n"],"mappings":"myBAKA,SAAwB,EAAK,EAAkB,CAC3C,OACI,EAAA,EAAA,MAAC,OAAD,CAAA,SAAA,CACK,EAAM,OACP,EAAA,EAAA,KAAC,KAAD,CAAA,SACK,EAAM,SACN,CAAA,CACF,CAAA,CAAA,CCLf,SAAwB,EAAa,EAA0B,CAM3D,OAJI,EAAM,MAAM,UACL,EAAA,EAAA,KAAC,EAAD,CAAM,MAAO,EAAM,MAAM,MAAO,SAAU,EAAM,MAAM,SAAW,CAAA,CAGrE,EAAM,MAAM,MCRvB,IAAa,EAAb,MAAa,CAAU,CAGnB,OAAwB,eAAiB,CAAC,CAAC,MAAQ,MAAO,CAAC,CAC3D,OAAwB,wBAA0B,CAAC,CAAC,MAAQ,MAAO,CAAE,CAAC,MAAQ,MAAO,CAAE,CAAC,MAAQ,MAAO,CACnG,CAAC,MAAQ,MAAO,CAAE,CAAC,MAAQ,MAAO,CAAC,CAEvC,KACA,UACA,YACA,aAEA,OAAmC,EAAE,CACrC,aAAuB,GACvB,gBAEA,YAAY,EAAc,EAAoB,IAAK,EAAsB,IAAK,EAAuB,IAAK,CACtG,KAAK,KAAO,EACZ,KAAK,UAAY,EACjB,KAAK,YAAc,EACnB,KAAK,aAAe,EAGxB,OAAQ,CACJ,GAAI,KAAK,OAAO,OAAS,EACrB,OAAO,KAAK,OAGhB,IAAK,IAAM,KAAa,KAAK,KACrB,KAAK,kBAAoB,IAAA,GACzB,KAAK,WAAW,EAAU,CAE1B,KAAK,cAAc,EAAU,CAMrC,OAFA,KAAK,UAAU,CAER,KAAK,OAGhB,WAAmB,EAAmB,CAC9B,IAAc,KAAK,YACnB,KAAK,gBAAkB,GAChB,IAAc,KAAK,UAC1B,KAAK,UAAU,EAEf,KAAK,cAAgB,EAChB,EAAU,eAAe,EAAU,EACpC,KAAK,UAAU,EAK3B,cAAsB,EAAmB,CACjC,IAAc,KAAK,aACnB,KAAK,UAAU,CAEf,KAAK,iBAAmB,EAIhC,OAAe,eAAe,EAAmB,CAC7C,IAAM,EAAU,EAAU,WAAW,EAAE,CACvC,MAAO,CAAC,EAAU,WAAW,EAAQ,EAAI,CAAC,EAAU,kBAAkB,EAAQ,CAGlF,OAAe,WAAW,EAAiB,CACvC,OAAO,EAAU,UAAU,EAAS,EAAU,eAAe,CAGjE,OAAe,kBAAkB,EAAiB,CAC9C,OAAO,EAAU,UAAU,EAAS,EAAU,wBAAwB,CAG1E,OAAe,UAAU,EAAiB,EAAoB,CAC1D,OAAO,EAAO,KAAK,GAAS,GAAW,EAAM,IAAM,GAAW,EAAM,GAAG,CAG3E,UAAmB,CACV,KAAK,eAIV,KAAK,OAAO,KAAK,CACb,MAAO,KAAK,aACZ,SAAU,KAAK,gBAClB,CAAC,CACF,KAAK,aAAe,GACpB,KAAK,gBAAkB,IAAA,MCjF/B,SAAgB,EAAc,EAA2B,CAErD,IAAM,EAAS,EAAA,QAAM,YACV,IAAI,EAAU,EAAM,KAAM,EAAM,UAAW,EAAM,YAAa,EAAM,aAAa,CAAC,OAAO,CACjG,CAAC,EAAM,KAAM,EAAM,UAAW,EAAM,YAAa,EAAM,aAAa,CAAC,CAElE,EAAS,EAAA,QAAM,YAAa,GACvB,EAAM,OAAS,EAAM,OAAO,EAAM,EAAG,EAAA,EAAA,KAAC,EAAD,CAAqB,QAAQ,CAAA,CAC1E,CAAC,EAAM,OAAO,CAAC,CAElB,OACI,EAAA,EAAA,KAAA,EAAA,SAAA,CAAA,SACK,EAAO,KAAK,EAAO,KAChB,EAAA,EAAA,KAAC,EAAA,QAAM,SAAP,CAAA,SACK,EAAO,EAAM,CACD,CAFI,EAEJ,CACnB,CACH,CAAA"}