react-pdf
react-pdf copied to clipboard
Hyphenation does not disable for Japanese with React-pdf 1.0.0 using correct API code
React-pdf version: 1.0.0
Description: @diegomura, sorry found another bug with Japanese. Hyphenation does not turn off. Please check example below.
Replication: https://react-pdf.org/repl?code=1887b07602e07404e0a6073025819c271802800607a5c02403780ee4980098825400d880318086112e1400588680beb9a2c9035c00cdc0414b80359c24632140810476003400088802875ea45300b6496804f005cea011006959f2225ad3c025006e2d1f402f8c8d06001226000e1c706082e000c24cb4b400464c0c529824203014ea00bc007cea00daa9e900ba6e1e0ce068ea6826b4702859ea00ca1035708da170d00cf02c7098dabae8001e101603ba7ae28d48005e7016004c00acaa3a13f6c086c6e656b672e28eba3c4ea55ae56095008241410d98ce59b9986b003c00228c00ae066110d96bba178001498083815566704ca592e4b4b3fc26131780054e0232a8b56a99223556a28451a2203c6ca0000e5004266807f7940052ba00eedd00216e803b064017dea012c9d00c331800e98c03e02a0115350020be800fb372753e9ccf6773f942ca6d319acce6f3052f5c2a24608c47a851848c6b5b1b8ba81246c4a190d8532b17cb254a955fc0148eb76ab138cc7eb8644eca00251500a7a6804004c03183200cc1900410c8048865f601f41900f2f280441b4005a7a00ac1900c90c8003064022832012c18ad84b562335e8bd6eb9df8d751a860c5368b33aadb603edf9a76b48b84e25ca258ae5567ab1adaf3a0b0d835bbcbb2f142a05959b4e77020b05aa951f0637d7eff5380094e08908102dec05818428184c0bdaeb75c3654a40000
Hi!
I see that there are lines that get hyphenated, but that's just because there are some lines that does not fit in the page width. You want those lines to overflow the page?
What I did noticed is that Font.registerHyphenationCallback
is called with some fragments of lines. That's because the layout algorithm identified that some chars belong to a different unicode script` in the script itemization process
My apologizes that I don't know anything but latin languages 😅
Hi @diegomura, Yeah, as you said, I noticed about how the algorithm identifies the different chars and either considers each character a word depending on which unicode script it is of, too when I was debugging one of the previous problems. Probably the best solution as you suggested would be for all Han scripts ( Chinese/Japanese/Korean, etc..) to just overflow at the end of each line to the next, as hyphenation is not used in those languages.
My workaround is like this:
<View style={{ flexDirection: "row", flexWrap: "wrap" }}>
{Array.from(text).map((char) => <Text>{char}</Text>)}
</View>
https://react-pdf.org/repl?code=1887b07602e07404e0a6073025819c271802800607a5c02403780ee4980098825400d880318086112e1400588680beb9a2c9035c00cdc0414b80359c24632140810476003400088802875ea45300b6496804f005cea011006959f2225ad3c025006e2d5a1b834ead09da7028ea00bcea00ca10fe70611c7070d00cf02c7098daba000e4c08701669ba7ae26148005e39ea004c00acaa3af9f6c086c6e656b672e28eba3c4e6e1e5e603ee8001e102156804e4180f60c8040ca801e0c80960c80c6a680510c80360c80d10c80490c80884680320c806872800d51807a0c801c7a80560c80910c80010c8090e6805d0e80760c80a69a808e3a80537280a7a68051b180120c80660c80515b402c83200893500d191800d06400aa26009c1900410c806d064016832393cde1180105d2e951a619c21001f3a930b5000f00045180057031c12004daae94900052c9c17c25383052c18caa597c9100b04887e008a0a0996c8f019f97ca92006a483809065b2b940054e0c302400e440ea120806052260c04054ca293709aed632e5b84572b55b28552a555a00240ba6d230251086101e15a7dcefb63bdd76a678743dead4400900752349acd168a306e331f515ba391ecf86055161510f40141b9290f0062b1c0164b19a48960d088cb0998131d275923b7d2fc9e34af3ba2206260ed9314044668326003ce280183b984c03038a6fc70489a490d1057a6a0f5b33ce2e9abb30eb7686adacecaaaad94860d2e9f1ad0f4b4002538131abccf270160748a06098292588e2b80123d1000
I try this code is ok
Font.registerHyphenationCallback(word => word.length === 1 ? [word] : Array.from(word).map(char => char));
I try this code is ok
Font.registerHyphenationCallback(word => word.length === 1 ? [word] : Array.from(word).map(char => char));
I tried to use this one but it didn't work for me. Instead of, I create a new component for use this.
import React from "react";
import { View, Text } from "@react-pdf/renderer";
function AutoWrapLine(props) {
return (
<View style={{ flexDirection: "row", flexWrap: "wrap" }}>
{Array.from(props.text).map((char) => (
<Text>{char}</Text>
))}
</View>
);
}
export default AutoWrapLine;
Thank you so much
I tried this code. It work for me.
Font.registerHyphenationCallback((word) =>
Array.from(word).flatMap((char) => [char, ''])
)
I tried this code. It work for me.
Font.registerHyphenationCallback((word) => Array.from(word).flatMap((char) => [char, '']) )
It work for me too Thank you so much!
This is my workaround. It works for languages that don’t have word breaks with spacing, such as Thai , Japanese and Chinese.
IMPORTANT: If you want to use this code snippet, you will need to use the Intl.Segmenter API first to segment the text into words. You can then pass each word to the hyphenation callback to disable hyphenation. Here’s an example:
...
const result = Array.from(
new Intl.Segmenter("{locale_code}", { granularity: "word" }).segment(text),
);
return (
<View>
<Text style={styles.paragraph}>
{result.map(({ segment }) => segment)}
</Text>
</View>
);
...
Then using this snippet code at your config file
Font.registerHyphenationCallback((word) => {
return [word, ""];
});