Skip to content

Commit 964267e

Browse files
committed
Merge branch 'main' into prepare-version-3.16
2 parents 4bfa964 + 34fc00b commit 964267e

File tree

1 file changed

+42
-14
lines changed

1 file changed

+42
-14
lines changed

src/components/GlossaryInjector.tsx

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@ const GlossaryInjector: React.FC<GlossaryInjectorProps> = ({ children }) => {
1212
useEffect(() => {
1313
const url = window.location.pathname;
1414
let glossaryPath = '/docs/glossary.json'; // Use the English version as the default glossary.
15+
const isJapaneseSite = url.startsWith('/ja-jp/docs');
1516

1617
if (process.env.NODE_ENV === 'production') { // The glossary tooltip works only in production environments.
17-
glossaryPath = url.startsWith('/ja-jp/docs') ? '/ja-jp/glossary.json' : '/docs/glossary.json';
18+
glossaryPath = isJapaneseSite ? '/ja-jp/glossary.json' : '/docs/glossary.json';
1819
} else {
19-
glossaryPath = url.startsWith('/ja-jp/docs') ? '/ja-jp/glossary.json' : '/docs/glossary.json';
20+
glossaryPath = isJapaneseSite ? '/ja-jp/glossary.json' : '/docs/glossary.json';
2021
}
2122

2223
fetch(glossaryPath)
@@ -50,7 +51,7 @@ const GlossaryInjector: React.FC<GlossaryInjectorProps> = ({ children }) => {
5051
useEffect(() => {
5152
if (Object.keys(glossary).length === 0 || isVersionIndexPage()) return;
5253

53-
// Sort terms in descending order by length to prioritize multi-word terms.
54+
// Sort terms in descending order to prioritize multi-word terms.
5455
const terms = Object.keys(glossary).sort((a, b) => b.length - a.length);
5556
const processedTerms = new Set<string>(); // Set to track processed terms.
5657

@@ -93,26 +94,52 @@ const GlossaryInjector: React.FC<GlossaryInjectorProps> = ({ children }) => {
9394
const newNodes: Node[] = [];
9495
let hasReplacements = false;
9596

96-
// Create a regex pattern to match both exact terms and their plural forms.
97+
// Check if the visitor is on the Japanese version of the site.
98+
const isJapaneseSite = window.location.pathname.startsWith('/ja-jp/');
99+
100+
// Create a regex pattern based on the language.
97101
const regexPattern = terms.map(term => {
98102
const escapedTerm = term.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
99-
// Match exact term or term followed by 's' or 'es' at word boundary.
100-
return `(\\b${escapedTerm}(s|es)?\\b)`;
103+
104+
// For the Japanese version of the site, don't use word boundaries that don't work well with Japanese characters.
105+
if (isJapaneseSite) {
106+
// For Japanese text, we can't use word boundaries, so just match the exact term.
107+
return `(${escapedTerm})`;
108+
}
109+
110+
// For English site, match exact term or term followed by 's' or 'es' at word boundary.
111+
return `(\\b${escapedTerm}\\b|\\b${escapedTerm}s\\b|\\b${escapedTerm}es\\b)`;
101112
}).join('|');
102-
const regex = new RegExp(regexPattern, 'gi'); // The 'i' flag is for case-insensitive matching.
113+
114+
const regex = new RegExp(regexPattern, 'gi'); // Use case-insensitive matching.
103115

104116
let lastIndex = 0;
105117
let match: RegExpExecArray | null;
106118

107119
while ((match = regex.exec(currentText))) {
108120
const matchedText = match[0]; // The full matched text (may include plural suffix).
109121

110-
// Find the base term from the glossary that matches (without plural).
111-
const baseTerm = terms.find(term =>
112-
matchedText.toLowerCase() === term.toLowerCase() ||
113-
matchedText.toLowerCase() === `${term.toLowerCase()}s` ||
114-
matchedText.toLowerCase() === `${term.toLowerCase()}es`
115-
);
122+
// For Japanese, remove any non-word characters that were captured by the regex.
123+
const actualMatch = isJapaneseSite
124+
? matchedText.replace(/^[^\p{L}\p{N}_]+|[^\p{L}\p{N}_]+$/gu, '')
125+
: matchedText;
126+
127+
// Find the base term from the glossary that matches.
128+
let baseTerm: string | undefined;
129+
130+
if (isJapaneseSite) {
131+
// For Japanese, look for an exact match only.
132+
baseTerm = terms.find(term =>
133+
actualMatch === term
134+
);
135+
} else {
136+
// For English, check both singular and plural forms too.
137+
baseTerm = terms.find(term =>
138+
actualMatch.toLowerCase() === term.toLowerCase() ||
139+
actualMatch.toLowerCase() === `${term.toLowerCase()}s` ||
140+
actualMatch.toLowerCase() === `${term.toLowerCase()}es`
141+
);
142+
}
116143

117144
if (!baseTerm) {
118145
// Skip if no matching base term found.
@@ -138,7 +165,8 @@ const GlossaryInjector: React.FC<GlossaryInjectorProps> = ({ children }) => {
138165
let textToUnderline = matchedText;
139166
let suffix = '';
140167

141-
if (matchedText.toLowerCase() !== baseTerm.toLowerCase()) {
168+
// Only apply pluralization logic for the English version of the site.
169+
if (!isJapaneseSite && matchedText.toLowerCase() !== baseTerm.toLowerCase()) {
142170
// This is a plural form - only underline the base part.
143171
const baseTermLength = baseTerm.length;
144172
textToUnderline = matchedText.substring(0, baseTermLength);

0 commit comments

Comments
 (0)