Repository: yamatoiizuka/palt-typesetting
Pull request #79 (2024-02-11 12:59:55)

Update language transition
**四分アキスペースの挿入ルールのアップデート**

日本語と英数の間ではなく、日本語と**日本語でない言語**との間に四分アキスペースを入れるよう処理を変更しました。

この変更により、

- 英数
- キリル文字
- ギリシャ文字
- ハングル

と日本語との間に四分アキスペースが挿入されるようになります。
中国語と日本語の間にはスペースは入りません。


Patch:
diff --git a/src/util-text-classes.ts b/src/util-text-classes.ts
index f2798f5..592b41d 100644
--- a/src/util-text-classes.ts
+++ b/src/util-text-classes.ts
@@ -95,16 +95,14 @@ const LanguageClass = {
   },
 
   /**
-   * 2つのセグメントが異なる言語で構成されているかどうかを判定します。
-   * @param current - 現在のセグメント
-   * @param next - 次のセグメント
-   * @return 2つのセグメントが異なる言語がどうか
+   * 現在のセグメントと次のセグメントの言語が異なるかどうかを判定します。
+   * この関数は、一方が日本語で他方が非日本語の場合にtrueを返します。
+   * @param current - 現在のテキストセグメント
+   * @param next - 次のテキストセグメント
+   * @return 両セグメント間で言語が異なる場合にtrueを返す
    */
-  isDifferentLanguageClass: (current: string, next: string): boolean => {
-    return (
-      (LanguageClass.isJapanese(current) && LanguageClass.isLatin(next)) ||
-      (LanguageClass.isLatin(current) && LanguageClass.isJapanese(next))
-    )
+  hasLanguageTransition: (current: string, next: string): boolean => {
+    return LanguageClass.isJapanese(current) !== LanguageClass.isJapanese(next)
   },
 
   /**
@@ -114,7 +112,7 @@ const LanguageClass = {
    * @return 四分アキを追加すべきかどうか
    */
   shouldAddThinSpace: (current: string, next: string): boolean => {
-    return LanguageClass.isDifferentLanguageClass(current, next) && !CharClass.startsWithPunctuation(next)
+    return LanguageClass.hasLanguageTransition(current, next) && !CharClass.startsWithPunctuation(next)
   },
 }
 


Test patch:
diff --git a/tests/index.test.ts b/tests/index.test.ts
index 0912ff6..c9a464e 100644
--- a/tests/index.test.ts
+++ b/tests/index.test.ts
@@ -1,5 +1,5 @@
 import Typesetter from '../src/'
-import { createWbr, createThinSpace, applyWrapperStyle, applyLatinStyle, applyNoBreaksStyle } from '../src/util-tags'
+import { createThinSpace, applyWrapperStyle, applyLatinStyle, applyNoBreaksStyle } from '../src/util-tags'
 import win from '../src/win'
 import { describe, test, expect, beforeEach } from 'vitest'
 
@@ -9,10 +9,9 @@ describe('Typesetter', () => {
   const spaceWidth = options.thinSpaceWidth
   const space = createThinSpace(spaceWidth, true)
   const nbsp = createThinSpace(spaceWidth, false)
-  const wbr = createWbr()
   const srcHtml = `<p>──<b>こんにちは。</b>「日本語」とEnglish、晴れ・28度。</p>`
 
-  const expectedHtml = `<p>${applyWrapperStyle(`${applyNoBreaksStyle('──')}${wbr}`, true)}<b>${applyWrapperStyle(`こんにちは。${space}`, true)}</b>${applyWrapperStyle(`「日本語」${space}と${space}${applyLatinStyle('English')}、${space}晴れ${nbsp}・${space}${applyLatinStyle('28')}${space}度。`, true)}</p>`
+  const expectedHtml = `<p>${applyWrapperStyle(`${applyNoBreaksStyle('──')}${space}`, true)}<b>${applyWrapperStyle(`こんにちは。${space}`, true)}</b>${applyWrapperStyle(`「日本語」${space}と${space}${applyLatinStyle('English')}、${space}晴れ${nbsp}・${space}${applyLatinStyle('28')}${space}度。`, true)}</p>`
 
   const typeset = new Typesetter()
 
diff --git a/tests/insert-separators.test.ts b/tests/insert-separators.test.ts
index a902876..5de9f86 100644
--- a/tests/insert-separators.test.ts
+++ b/tests/insert-separators.test.ts
@@ -20,6 +20,34 @@ describe('insertSeparators', () => {
     const expected = `──${nbsp}「こんにちは。」${space}日本語${wbr}と${space}English、${space}晴れ${nbsp}・${space}28${space}度${space}à ${wbr}vous。${space}`
     expect(insertSeparatorsToText(currentText, nextText, options)).toEqual(expected)
   })
+
+  it('inserts a thin space between Japanese–Cyrillic', () => {
+    const currentText = 'こんにちはДобрий день'
+    const nextText = ''
+    const expected = `こんにちは${space}Добрий ${wbr}день`
+    expect(insertSeparatorsToText(currentText, nextText, options)).toEqual(expected)
+  })
+
+  it('inserts a thin space between Japanese–Greek', () => {
+    const currentText = 'こんにちはΚαλησπέρα σας'
+    const nextText = ''
+    const expected = `こんにちは${space}Καλησπέρα ${wbr}σας`
+    expect(insertSeparatorsToText(currentText, nextText, options)).toEqual(expected)
+  })
+
+  it('inserts a thin space between Japanese–Korean', () => {
+    const currentText = 'こんにちは안녕하세요'
+    const nextText = ''
+    const expected = `こんにちは${space}안녕하세요`
+    expect(insertSeparatorsToText(currentText, nextText, options)).toEqual(expected)
+  })
+
+  it('does not insert a thin space between Japanese–Chinese', () => {
+    const currentText = 'こんにちは下午好'
+    const nextText = ''
+    const expected = `こんにちは<wbr>下午<wbr>好`
+    expect(insertSeparatorsToText(currentText, nextText, options)).toEqual(expected)
+  })
 })
 
 describe('createSegments', () => {
diff --git a/tests/text-classification.test.ts b/tests/text-classification.test.ts
index fca81f6..42c1ebb 100644
--- a/tests/text-classification.test.ts
+++ b/tests/text-classification.test.ts
@@ -29,7 +29,7 @@ describe('CharClass.shouldAddThinSpace', () => {
 describe('LanguageClass.shouldAddThinSpace', () => {
   const tests = [
     { current: '─', next: '─', expected: false },
-    { current: '─', next: '「', expected: false },
+    { current: '─', next: '「', expected: true },
     { current: '「', next: 'こんにちは', expected: false },
     { current: 'こんにちは', next: '。', expected: false },
     { current: '。', next: '」', expected: false },