Skip to content

Commit

Permalink
feat: replace pangu.js to reg exp
Browse files Browse the repository at this point in the history
  • Loading branch information
Natumsol committed Mar 6, 2021
1 parent 74d9be4 commit 4fcb8be
Show file tree
Hide file tree
Showing 4 changed files with 262 additions and 31 deletions.
22 changes: 12 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
## Obsidian Pangu Plugin

A small plugin aims to add space between Chinese Characters and English Alphabet, powered by [pangu.js](https://github.com/vinta/pangu.js).

For Example:
A small plugin aims to add space between Chinese Characters and English Alphabet, For Example:

```diff
- 大多数人在20到30岁就已经过完自己的一生;一过了这个年龄段,他们就变成自己的影子。
+ 大多数人在 20 到 30 岁就已经过完自己的一生;一过了这个年龄段,他们就变成自己的影子。
```
### How to use

- Clone this repo.
- `npm i` or `yarn` to install dependencies
- `npm run dev` to start compilation in watch mode.
## Manual installation
Download zip archive from [GitHub releases page](https://github.com/natumsol/obsidian-pangu/releases).
Extract the archive into `<vault>/.obsidian/plugins`.

### Manually installing the plugin
Alternatively, using bash:
```bash
OBSIDIAN_VAULT_DIR=/path/to/your/obsidian/vault
mkdir -p $OBSIDIAN_VAULT_DIR/.obsidian/plugins
unzip ~/Downloads/obsidian-pangu_v1.1.0.zip -d $OBSIDIAN_VAULT_DIR/.obsidian/plugins
```

- Copy over `main.js`, `styles.css`, `manifest.json` to your vault `VaultFolder/.obsidian/plugins/your-plugin-id/`.
### Thanks

Thanks to [pangu.vim](https://github.com/hotoo/pangu.vim), [writing4cn](https://marketplace.visualstudio.com/items?itemName=twocucao.writing4cn) and [pangu-markdown-vscode ](https://github.com/zhuyuanxiang/pangu-markdown-vscode)
208 changes: 208 additions & 0 deletions formatUtil.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
export default {
condenseContent(content: string): string {
// 将 制表符 改成 四个空格
content = content.replace(/\t/g, " ");

// 删除超过2个的回车
// Unix 的只有 LF,Windows 的需要 CR LF
content = content.replace(/(\n){3,}/g, "$1$1");
content = content.replace(/(\r\n){3,}/g, "$1$1");
return content;
},
deleteSpaces(content: string): string {
// 去掉「`()[]{}<>'"`」: 前后多余的空格
content = content.replace(/\s+([\(\)\[\]\{\}<>'":])\s+/g, ' $1 ');

// 去掉连续括号增加的空格,例如:「` ( [ { < > } ] ) `」
content = content.replace(/([<\(\{\[])\s([<\(\{\[])\s/g, "$1$2 ");
content = content.replace(/([<\(\{\[])\s([<\(\{\[])\s/g, "$1$2 ");
content = content.replace(/([<\(\{\[])\s([<\(\{\[])\s/g, "$1$2 ");
content = content.replace(/([<\(\{\[])\s([<\(\{\[])\s/g, "$1$2 ");
content = content.replace(/\s([>\)\]\}])\s([>\)\]\}])/g, " $1$2");
content = content.replace(/\s([>\)\]\}])\s([>\)\]\}])/g, " $1$2");
content = content.replace(/\s([>\)\]\}])\s([>\)\]\}])/g, " $1$2");
content = content.replace(/\s([>\)\]\}])\s([>\)\]\}])/g, " $1$2");

// 去掉 「`$ () $`」, 「`$ [] $`」, 「`$ {} $`」 里面增加的空格
// 去掉开始 $ 后面增加的空格,结束 $ 前面增加的空格
// 去掉包裹代码的符号里面增加的空格
// 去掉开始 ` 后面增加的空格,结束 ` 前面增加的空格
content = content.replace(/([`\$])\s*([<\(\[\{])([^\$]*)\s*([`\$])/g, "$1$2$3$4");
content = content.replace(/([`\$])\s*([^\$]*)([>\)\]\}])\s*([`\$])/g, "$1$2$3$4");

// 去掉「`) _`」、「`) ^`」增加的空格
content = content.replace(/\)\s([_\^])/g, ")$1");

// 去掉 [^footnote,2002] 中的空格
content = content.replace(/\[\s*\^([^\]\s]*)\s*\]/g, "[^$1]");

// 将链接的格式中文括号“[]()”改成英文括号“[]()”,去掉增加的空格
content = content.replace(/\s*\[\s*([^\]]+)\s*\]\s*[((]\s*([^\s\)]*)\s*[))]\s*/g, " [$1]($2) ");

// 将图片链接的格式中的多余空格“! []()”去掉,变成“![]()”
content = content.replace(/!\s*\[\s*([^\]]+)\s*\]\s*[((]\s*([^\s\)]*)\s*[))]\s*/g, "![$1]($2) ");

// 将网络地址中“ : // ”符号改成“:https://”
content = content.replace(/\s*:\s*\/\s*\/\s*/g, ":https://");

// 去掉行末空格
content = content.replace(/(\S*)\s*$/g, '$1');

// 去掉「123 °」和 「15 %」中的空格
content = content.replace(/([0-9])\s*([°%])/g, '$1$2');

// 去掉 2020 - 04 - 20, 08 : 00 : 00 这种日期时间表示的数字内的空格
content = content.replace(/([0-9])\s*-\s*([0-9])/g, "$1-$2");
content = content.replace(/([0-9])\s*:\s*([0-9])/g, "$1:$2");

// 去掉 1 , 234 , 567 这种千分位表示的数字内的空格
content = content.replace(/([0-9])\s*,\s*([0-9])/g, "$1,$2");

// 全角標點與其他字符之間不加空格
// 将无序列表的-后面的空格保留
// 将有序列表的-后面的空格保留
content = content.replace(/^(?<![-|\d.]\s*)\s*([,。、《》?『』「」;∶【】{}—!@¥%…()])\s*/g, "$1");
return content;
},

insertSpace(content: string): string {
// 在 “中文English” 之间加入空格 “中文 English”
// 在 “中文123” 之间加入空格 “中文 123”
content = content.replace(/([\u4e00-\u9fa5\u3040-\u30FF])([a-zA-Z0-9`])/g, '$1 $2');

// 在 “English中文” 之间加入空格 “English 中文”
// 在 “123中文” 之间加入空格 “123 中文”
content = content.replace(/([a-zA-Z0-9%`])([*]*[\u4e00-\u9fa5\u3040-\u30FF])/g, "$1 $2");

// 在 「I said:it's a good news」的冒号与英文之间加入空格 「I said: it's a good news」
content = content.replace(/([:])\s*([a-zA-z])/g, "$1 $2");
return content;
},
replacePunctuations(content: string): string {
// `, \ . : ; ? !` 改成 `,、。:;?!`
// 必须在结尾或者有空格的点才被改成句号
content = content.replace(/([\u4e00-\u9fa5\u3040-\u30FF])\.($|\s*)/g, '$1。');
content = content.replace(/([\u4e00-\u9fa5\u3040-\u30FF]),/g, '$1,');
content = content.replace(/([\u4e00-\u9fa5\u3040-\u30FF]);/g, '$1;');
content = content.replace(/([\u4e00-\u9fa5\u3040-\u30FF])!/g, '$1!');
content = content.replace(/([\u4e00-\u9fa5\u3040-\u30FF])\?/g, '$1?');
content = content.replace(/([\u4e00-\u9fa5\u3040-\u30FF])\\/g, '$1、');
content = content.replace(/([\u4e00-\u9fa5\u3040-\u30FF])\s*\:/g, '$1:');

// 簡體中文使用直角引號
content = content.replace(//g, "『");
content = content.replace(//g, "』");
content = content.replace(//g, "「");
content = content.replace(//g, "」");
// 括号使用半角标点
// 半角括号的两边都有空格就不在这里处理了,放到行中处理
content = content.replace(/\s*[((]\s*/g, " ( ");
content = content.replace(/\s*[))]\s*/g, " ) ");

// 英文和数字内部的全角标点 `,。;‘’“”:?!@#%&-=+{}【】|\~`改成半角标点
content = content.replace(/(\w)\s*,\s*(\w)/g, "$1, $2");
content = content.replace(/(\w)\s*。\s*(\w)/g, "$1. $2");
content = content.replace(/(\w)\s*;\s*(\w)/g, "$1; $2");
content = content.replace(/(\w)\s*‘\s*(\w)/g, "$1 '$2");
content = content.replace(/(\w)\s*’\s*(\w)/g, "$1' $2");
content = content.replace(/(\w)\s*“\s*(\w)/g, '$1 "$2');
content = content.replace(/(\w)\s*”\s*(\w)/g, '$1" $2');
content = content.replace(/(\w)\s*:\s*(\w)/g, "$1: $2");
content = content.replace(/(\w)\s*?\s*(\w)/g, "$1? $2");
content = content.replace(/(\w)\s*!\s*(\w)/g, "$1! $2");
content = content.replace(/(\w)\s*@\s*(\w)/g, "$1@$2");
content = content.replace(/(\w)\s*#\s*(\w)/g, "$1#$2");
content = content.replace(/(\w)\s*%\s*(\w)/g, "$1 % $2");
content = content.replace(/(\w)\s*&\s*(\w)/g, "$1 & $2");
content = content.replace(/(\w)\s*-\s*(\w)/g, "$1 - $2");
content = content.replace(/(\w)\s*=\s*(\w)/g, "$1 = $2");
content = content.replace(/(\w)\s*+\s*(\w)/g, "$1 + $2");
content = content.replace(/(\w)\s*{\s*(\w)/g, "$1 {$2");
content = content.replace(/(\w)\s*}\s*(\w)/g, "$1} $2");
content = content.replace(/(\w)\s*[【\[]\s*(\w)/g, "$1 [$2");
content = content.replace(/(\w)\s*[】\]]\s*(\w)/g, "$1] $2");
content = content.replace(/(\w)\s*|\s*(\w)/g, "$1 | $2");
content = content.replace(/(\w)\s*\\s*(\w)/g, "$1 \ $2");
content = content.replace(/(\w)\s*~\s*(\w)/g, "$1~$2");
// 连续三个以上的 `。` 改成 `......`
content = content.replace(/[。]{3,}/g, '……');
// 截断连续超过一个的 ?和! 为一个,「!?」也算一个
content = content.replace(/([!?]+)\1{1,}/g, '$1');
// 截断连续超过一个的 。,;:、“”『』〖〗《》 为一个
content = content.replace(/([。,;:、“”『』〖〗《》【】])\1{1,}/g, '$1');
return content;
},

replaceFullNumbers(content: string): string {
" 全角数字。";
content = content.replace(//g, "0");
content = content.replace(//g, "1");
content = content.replace(//g, "2");
content = content.replace(//g, "3");
content = content.replace(//g, "4");
content = content.replace(//g, "5");
content = content.replace(//g, "6");
content = content.replace(//g, "7");
content = content.replace(//g, "8");
content = content.replace(//g, "9");
return content;
},

replaceFullChars(content: string): string {
" 全角英文和标点。";
content = content.replace(//g, "A");
content = content.replace(//g, "B");
content = content.replace(//g, "C");
content = content.replace(//g, "D");
content = content.replace(//g, "E");
content = content.replace(//g, "F");
content = content.replace(//g, "G");
content = content.replace(//g, "H");
content = content.replace(//g, "I");
content = content.replace(//g, "J");
content = content.replace(//g, "K");
content = content.replace(//g, "L");
content = content.replace(//g, "M");
content = content.replace(//g, "N");
content = content.replace(//g, "O");
content = content.replace(//g, "P");
content = content.replace(//g, "Q");
content = content.replace(//g, "R");
content = content.replace(//g, "S");
content = content.replace(//g, "T");
content = content.replace(//g, "U");
content = content.replace(//g, "V");
content = content.replace(//g, "W");
content = content.replace(//g, "X");
content = content.replace(//g, "Y");
content = content.replace(//g, "Z");
content = content.replace(//g, "a");
content = content.replace(//g, "b");
content = content.replace(//g, "c");
content = content.replace(//g, "d");
content = content.replace(//g, "e");
content = content.replace(//g, "f");
content = content.replace(//g, "g");
content = content.replace(//g, "h");
content = content.replace(//g, "i");
content = content.replace(//g, "j");
content = content.replace(//g, "k");
content = content.replace(//g, "l");
content = content.replace(//g, "m");
content = content.replace(//g, "n");
content = content.replace(//g, "o");
content = content.replace(//g, "p");
content = content.replace(//g, "q");
content = content.replace(//g, "r");
content = content.replace(//g, "s");
content = content.replace(//g, "t");
content = content.replace(//g, "u");
content = content.replace(//g, "v");
content = content.replace(//g, "w");
content = content.replace(//g, "x");
content = content.replace(//g, "y");
content = content.replace(//g, "z");
return content;
},

}
59 changes: 41 additions & 18 deletions main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { App, Modal, Notice, Plugin, PluginSettingTab, Setting, MarkdownView } from 'obsidian';
import { spacing } from 'pangu';
import formatUtil from './formatUtil';

interface MyPluginSettings {
autoSpacing: boolean;
Expand All @@ -14,10 +14,49 @@ export default class MyPlugin extends Plugin {

format(cm: CodeMirror.Editor): void {
const cursor = cm.getCursor();
cm.setValue(spacing(cm.getValue().trim()));
let content = cm.getValue().trim();

content = content + "\n\n";

// 替换所有的全角数字为半角数字
content = formatUtil.replaceFullNumbers(content);

// 替换所有的全角英文和@标点 为 半角的英文和@标点
content = formatUtil.replaceFullChars(content);

// 删除多余的内容(回车)
content = formatUtil.condenseContent(content);

// 每行操作
content = content.split("\n").map((line) => {
// 中文内部使用全角标点
line = formatUtil.replacePunctuations(line);

// 删除多余的空格
line = formatUtil.deleteSpaces(line);

// 插入必要的空格
line = formatUtil.insertSpace(line);

// 将有编号列表的“1. ”改成 “1. ”
line = line.replace(/^(\s*)(\d\.)\s+(\S)/, '$1$2 $3');

// 将无编号列表的“* ”改成 “- ”
// 将无编号列表的“- ”改成 “- ”
line = line.replace(/^(\s*)[-\*]\s+(\S)/, '$1- $2');

return line;
}).join("\n");

// 结束文档整理前再删除最后一个回车
content = content.replace(/(\n){2,}$/g, '$1');
content = content.replace(/(\r\n){2,}$/g, '$1');

cm.setValue(content);
cm.setCursor(cursor);
}


async onload() {
await this.loadSettings();

Expand Down Expand Up @@ -56,22 +95,6 @@ export default class MyPlugin extends Plugin {
}
}

class SampleModal extends Modal {
constructor(app: App) {
super(app);
}

onOpen() {
let { contentEl } = this;
contentEl.setText('Woah!');
}

onClose() {
let { contentEl } = this;
contentEl.empty();
}
}

class SampleSettingTab extends PluginSettingTab {
plugin: MyPlugin;

Expand Down
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,5 @@
"tslib": "^2.0.3",
"typescript": "^4.0.3"
},
"dependencies": {
"pangu": "^4.0.7"
}
"dependencies": {}
}

0 comments on commit 4fcb8be

Please sign in to comment.