Repository: platers/obsidian-linter
Pull request #481 (2022-11-08 01:15:18)

feat: space between CJK and English
#479 

The option name also needs to be modified.

What do you think?

pjkaufman: The code change looks fine. The version change is ok, but should be reserved for the creation of a release.

The name change needs to happen, but that will require mapping from the old rule name to the new one.
pjkaufman: Never mind my comment about version changes. It looks like that was done automatically.
iucario: Currently the rule name is "Space between Chinese and English or numbers". What name should we rename it to? "Space between CJK and English or numbers"?
pjkaufman: I would rename it to `Space between Chinese, Japanese, or Korean and English or numbers`. This will also require renaming the class and its file and test files. We will also need to update the description of the rule to match the changes.

We will also need to map the setting data similar to https://github.com/platers/obsidian-linter/blob/master/src/main.ts#L101-L113.
pjkaufman: Once the file name is updated, the import for the test needs to be updated as well.
pjkaufman: As for mapping the data, that is to preserve the current settings to keep it from accidentally losing people's settings. It is currently pretty brittle and I am working on thinking up a better way of storing settings so that they are not brittle and will better withstand wording changes and name changes.
pjkaufman: As for how to map it, it depends entirely on what changes: a rule name change requires mapping the old rule name to the new rule name. Changing a description, requires mapping the old description to the new description.

Here is an example: https://github.com/platers/obsidian-linter/blob/master/src/main.ts#L101-L113

If you would like, I can add the settings mapping.
iucario: `npx jest --clearCache` worked! Thanks.

I changed the file name to `space-between-chinese-japanese-or-korean-and-english-or-numbers.ts`. Please help adding the settings mapping.


pjkaufman: I have tried to update your branch with the necessary changes for the settings mapping and one other issue I noticed, but it seems I do not have permission to do so.

You will need to add the following [here](https://github.com/iucario/obsidian-linter/blob/space-cjk/src/main.ts#L124):
``` TypeScript
const spaceBetweenChineseAndEnglishOrNumbers = this.settings.ruleConfigs['Space between Chinese and English or numbers'];
    if (spaceBetweenChineseAndEnglishOrNumbers) {
      const enabled = spaceBetweenChineseAndEnglishOrNumbers['Ensures that Chinese and English or numbers are separated by a single space. Follows these [guidelines](https://github.com/sparanoid/chinese-copywriting-guidelines)'];
      this.settings.ruleConfigs['Space between Chinese, Japanese, or Korean and English or numbers'] = {
        'Ensures that Chinese, Japanese, or Korean and English or numbers are separated by a single space. Follows these [guidelines](https://github.com/sparanoid/chinese-copywriting-guidelines)': enabled,
      };
      delete this.settings.ruleConfigs['Space between Chinese and English or numbers'];
    }
```
pjkaufman: Well, it looks like I was able to bypass my issue. I accidentally was trying to create a new branch instead of using the existing one. I will see about rebasing this branch and see if it fixes things.

Patch:
diff --git a/README.md b/README.md
index ca0eac5..99d3da5 100644
--- a/README.md
+++ b/README.md
@@ -97,7 +97,7 @@ Each rule is its own set of logic and is designed to be run independently. This
 - [remove-link-spacing](https://github.com/platers/obsidian-linter/blob/master/docs/rules.md#remove-link-spacing)
 - [remove-space-around-fullwidth-characters](https://github.com/platers/obsidian-linter/blob/master/docs/rules.md#remove-space-around-fullwidth-characters)
 - [space-after-list-markers](https://github.com/platers/obsidian-linter/blob/master/docs/rules.md#space-after-list-markers)
-- [space-between-chinese-and-english-or-numbers](https://github.com/platers/obsidian-linter/blob/master/docs/rules.md#space-between-chinese-and-english-or-numbers)
+- [space-between-chinese-japanese-or-korean-and-english-or-numbers](https://github.com/platers/obsidian-linter/blob/master/docs/rules.md#space-between-chinese-japanese-or-korean-and-english-or-numbers)
 - [trailing-spaces](https://github.com/platers/obsidian-linter/blob/master/docs/rules.md#trailing-spaces)
 
 ### Paste rules
diff --git a/docs/rules.md b/docs/rules.md
index d4cc510..3bd58c5 100644
--- a/docs/rules.md
+++ b/docs/rules.md
@@ -3370,11 +3370,11 @@ After:
 	- [ ] Item 3
 ``````
 
-### Space between Chinese and English or numbers
+### Space between Chinese Japanese or Korean and English or numbers
 
-Alias: `space-between-chinese-and-english-or-numbers`
+Alias: `space-between-chinese-japanese-or-korean-and-english-or-numbers`
 
-Ensures that Chinese and English or numbers are separated by a single space. Follows these [guidelines](https://github.com/sparanoid/chinese-copywriting-guidelines)
+Ensures that Chinese, Japanese, or Korean and English or numbers are separated by a single space. Follows these [guidelines](https://github.com/sparanoid/chinese-copywriting-guidelines)
 
 
 
@@ -3474,6 +3474,25 @@ After:
 [这是一个数学公式english](这是一个数学公式english.md)
 ![这是一个数学公式english](这是一个数学公式english.jpg)
 ``````
+Example: Space between CJK and English
+
+Before:
+
+``````markdown
+日本語englishひらがな
+カタカナenglishカタカナ
+ﾊﾝｶｸｶﾀｶﾅenglish１２３全角数字
+한글english한글
+``````
+
+After:
+
+``````markdown
+日本語 english ひらがな
+カタカナ english カタカナ
+ﾊﾝｶｸｶﾀｶﾅ english１２３全角数字
+한글 english 한글
+``````
 
 ### Trailing spaces
 
diff --git a/src/main.ts b/src/main.ts
index a35c865..1ebe5e7 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -124,6 +124,15 @@ export default class LinterPlugin extends Plugin {
       }
     }
 
+    const spaceBetweenChineseAndEnglishOrNumbers = this.settings.ruleConfigs['Space between Chinese and English or numbers'];
+    if (spaceBetweenChineseAndEnglishOrNumbers) {
+      const enabled = spaceBetweenChineseAndEnglishOrNumbers['Ensures that Chinese and English or numbers are separated by a single space. Follows these [guidelines](https://github.com/sparanoid/chinese-copywriting-guidelines)'];
+      this.settings.ruleConfigs['Space between Chinese, Japanese, or Korean and English or numbers'] = {
+        'Ensures that Chinese, Japanese, or Korean and English or numbers are separated by a single space. Follows these [guidelines](https://github.com/sparanoid/chinese-copywriting-guidelines)': enabled,
+      };
+      delete this.settings.ruleConfigs['Space between Chinese and English or numbers'];
+    }
+
     this.moveSettingsToCommonSettings();
 
     // make sure to load the defaults of any missing rules to make sure they do not cause issues on the settings page
diff --git a/src/rules/space-between-chinese-and-english-or-numbers.ts b/src/rules/space-between-chinese-japanese-or-korean-and-english-or-numbers.ts
similarity index 54%
rename from src/rules/space-between-chinese-and-english-or-numbers.ts
rename to src/rules/space-between-chinese-japanese-or-korean-and-english-or-numbers.ts
index 495876e..d1a7924 100644
--- a/src/rules/space-between-chinese-and-english-or-numbers.ts
+++ b/src/rules/space-between-chinese-japanese-or-korean-and-english-or-numbers.ts
@@ -4,39 +4,68 @@ import dedent from 'ts-dedent';
 import {ignoreListOfTypes, IgnoreTypes} from '../utils/ignore-types';
 import {updateBoldText, updateItalicsText} from '../utils/mdast';
 
-class SpaceBetweenChineseAndEnglishOrNumbersOptions implements Options {
-}
+class SpaceBetweenChineseJapaneseOrKoreanAndEnglishOrNumbersOptions
+implements Options {}
 
 @RuleBuilder.register
-export default class SpaceBetweenChineseAndEnglishOrNumbers extends RuleBuilder<SpaceBetweenChineseAndEnglishOrNumbersOptions> {
-  get OptionsClass(): new () => SpaceBetweenChineseAndEnglishOrNumbersOptions {
-    return SpaceBetweenChineseAndEnglishOrNumbersOptions;
+export default class SpaceBetweenChineseJapaneseOrKoreanAndEnglishOrNumbers extends RuleBuilder<SpaceBetweenChineseJapaneseOrKoreanAndEnglishOrNumbersOptions> {
+  get OptionsClass(): new () => SpaceBetweenChineseJapaneseOrKoreanAndEnglishOrNumbersOptions {
+    return SpaceBetweenChineseJapaneseOrKoreanAndEnglishOrNumbersOptions;
   }
   get name(): string {
-    return 'Space between Chinese and English or numbers';
+    return 'Space between Chinese, Japanese, or Korean and English or numbers';
   }
   get description(): string {
-    return 'Ensures that Chinese and English or numbers are separated by a single space. Follows these [guidelines](https://github.com/sparanoid/chinese-copywriting-guidelines)';
+    return 'Ensures that Chinese, Japanese, or Korean and English or numbers are separated by a single space. Follows these [guidelines](https://github.com/sparanoid/chinese-copywriting-guidelines)';
   }
   get type(): RuleType {
     return RuleType.SPACING;
   }
-  apply(text: string, options: SpaceBetweenChineseAndEnglishOrNumbersOptions): string {
-    const head = /([\u4e00-\u9fa5])( *)(\[[^[]*\]\(.*\)|`[^`]*`|\w+|[-+'"([{¥$]|\*[^*])/gm;
-    const tail = /(\[[^[]*\]\(.*\)|`[^`]*`|\w+|[-+;:'"°%$)\]}]|[^*]\*)( *)([\u4e00-\u9fa5])/gm;
-    const addSpaceAroundChineseAndEnglish = function(text: string): string {
+  apply(
+      text: string,
+      options: SpaceBetweenChineseJapaneseOrKoreanAndEnglishOrNumbersOptions,
+  ): string {
+    const head =
+      /(\p{sc=Han}|\p{sc=Katakana}|\p{sc=Hiragana}|\p{sc=Hangul})( *)(\[[^[]*\]\(.*\)|`[^`]*`|\w+|[-+'"([{¥$]|\*[^*])/gmu;
+    const tail =
+      /(\[[^[]*\]\(.*\)|`[^`]*`|\w+|[-+;:'"°%$)\]}]|[^*]\*)( *)(\p{sc=Han}|\p{sc=Katakana}|\p{sc=Hiragana}|\p{sc=Hangul})/gmu;
+    const addSpaceAroundChineseJapaneseKoreanAndEnglish = function(
+        text: string,
+    ): string {
       return text.replace(head, '$1 $3').replace(tail, '$1 $3');
     };
 
-    let newText = ignoreListOfTypes([IgnoreTypes.code, IgnoreTypes.inlineCode, IgnoreTypes.yaml, IgnoreTypes.image, IgnoreTypes.link, IgnoreTypes.wikiLink, IgnoreTypes.tag, IgnoreTypes.italics, IgnoreTypes.bold, IgnoreTypes.math, IgnoreTypes.inlineMath], text, addSpaceAroundChineseAndEnglish);
+    let newText = ignoreListOfTypes(
+        [
+          IgnoreTypes.code,
+          IgnoreTypes.inlineCode,
+          IgnoreTypes.yaml,
+          IgnoreTypes.image,
+          IgnoreTypes.link,
+          IgnoreTypes.wikiLink,
+          IgnoreTypes.tag,
+          IgnoreTypes.italics,
+          IgnoreTypes.bold,
+          IgnoreTypes.math,
+          IgnoreTypes.inlineMath,
+        ],
+        text,
+        addSpaceAroundChineseJapaneseKoreanAndEnglish,
+    );
 
-    newText = updateItalicsText(newText, addSpaceAroundChineseAndEnglish);
+    newText = updateItalicsText(
+        newText,
+        addSpaceAroundChineseJapaneseKoreanAndEnglish,
+    );
 
-    newText = updateBoldText(newText, addSpaceAroundChineseAndEnglish);
+    newText = updateBoldText(
+        newText,
+        addSpaceAroundChineseJapaneseKoreanAndEnglish,
+    );
 
     return newText;
   }
-  get exampleBuilders(): ExampleBuilder<SpaceBetweenChineseAndEnglishOrNumbersOptions>[] {
+  get exampleBuilders(): ExampleBuilder<SpaceBetweenChineseJapaneseOrKoreanAndEnglishOrNumbersOptions>[] {
     return [
       new ExampleBuilder({
         description: 'Space between Chinese and English',
@@ -77,7 +106,8 @@ export default class SpaceBetweenChineseAndEnglishOrNumbers extends RuleBuilder<
       }),
       new ExampleBuilder({
         // accounts for https://github.com/platers/obsidian-linter/issues/301
-        description: 'Make sure that spaces are not added between italics and chinese characters to preserve markdown syntax',
+        description:
+          'Make sure that spaces are not added between italics and chinese characters to preserve markdown syntax',
         before: dedent`
           _这是一个数学公式_
           *这是一个数学公式english*
@@ -113,9 +143,24 @@ export default class SpaceBetweenChineseAndEnglishOrNumbers extends RuleBuilder<
           ![这是一个数学公式english](这是一个数学公式english.jpg)
         `,
       }),
+      new ExampleBuilder({
+        description: 'Space between CJK and English',
+        before: dedent`
+          日本語englishひらがな
+          カタカナenglishカタカナ
+          ﾊﾝｶｸｶﾀｶﾅenglish１２３全角数字
+          한글english한글
+        `,
+        after: dedent`
+          日本語 english ひらがな
+          カタカナ english カタカナ
+          ﾊﾝｶｸｶﾀｶﾅ english１２３全角数字
+          한글 english 한글
+        `,
+      }),
     ];
   }
-  get optionBuilders(): OptionBuilderBase<SpaceBetweenChineseAndEnglishOrNumbersOptions>[] {
+  get optionBuilders(): OptionBuilderBase<SpaceBetweenChineseJapaneseOrKoreanAndEnglishOrNumbersOptions>[] {
     return [];
   }
 }


Test patch:
diff --git a/__tests__/space-between-chinese-and-english-or-numbers.test.ts b/__tests__/space-between-chinese-japanese-or-korean-and-english-or-numbers.test.ts
similarity index 78%
rename from __tests__/space-between-chinese-and-english-or-numbers.test.ts
rename to __tests__/space-between-chinese-japanese-or-korean-and-english-or-numbers.test.ts
index 678ae79..c20298a 100644
--- a/__tests__/space-between-chinese-and-english-or-numbers.test.ts
+++ b/__tests__/space-between-chinese-japanese-or-korean-and-english-or-numbers.test.ts
@@ -1,13 +1,14 @@
-import SpaceBetweenChineseAndEnglishOrNumbers from '../src/rules/space-between-chinese-and-english-or-numbers';
+import SpaceBetweenChineseJapaneseOrKoreanAndEnglishOrNumbers from '../src/rules/space-between-chinese-japanese-or-korean-and-english-or-numbers';
 import dedent from 'ts-dedent';
 import {ruleTest} from './common';
 
 ruleTest({
-  RuleBuilderClass: SpaceBetweenChineseAndEnglishOrNumbers,
+  RuleBuilderClass: SpaceBetweenChineseJapaneseOrKoreanAndEnglishOrNumbers,
   testCases: [
     {
       // accounts for https://github.com/platers/obsidian-linter/issues/303
-      testName: 'Make sure that spaces are added after a dollar sign if followed by Chinese characters',
+      testName:
+        'Make sure that spaces are added after a dollar sign if followed by Chinese characters',
       before: dedent`
         这是一个数学公式$f(x)=x^2$这是一个数学公式
       `,
@@ -35,6 +36,8 @@ ruleTest({
         \`测试_this_case\`
         \`this_测试-还*可以\`
         \`filepath = './知识_巴别图书馆.md'\`
+        \`テスト_ＴＥＳＴ\`
+        \`filepath = './ちしき_図書館.md'\`
       `,
       after: dedent`
         \`test\`
@@ -53,6 +56,8 @@ ruleTest({
         \`测试_this_case\`
         \`this_测试-还*可以\`
         \`filepath = './知识_巴别图书馆.md'\`
+        \`テスト_ＴＥＳＴ\`
+        \`filepath = './ちしき_図書館.md'\`
       `,
     },
     {