Skip to content

Commit

Permalink
Merge pull request #9 from laorange/dev
Browse files Browse the repository at this point in the history
v1.2.0 (2023-02-19)

新增:启用/禁用"语法检查"的状态按钮

新增:规范中文排版 [(#7)](#7)

新增:删除引用角标 (如: <sup>[1]</sup>, <sup>[2, 3]</sup>, <sup>[4-7]</sup>)

优化:自动复制、自动清空的触发机制

调整:功能按钮的样式 [(来自评论区)](https://www.bilibili.com/video/BV1ZG4y1N7oM/#reply152210013200)

调整:将全角括号从全角字符集合中移出 [(#8)](#8)

调整:“标点符号后添加空格”功能效果 [(#8)](#8 (comment))
  • Loading branch information
laorange authored Feb 19, 2023
2 parents 45cd39c + 822e311 commit 55946cb
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 43 deletions.
49 changes: 41 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,62 @@
<h1 align="center">论文工具</h1>

<p align="center">
<a href="https://laorange.github.io/paper-assistant/">在线使用(GitHub)</a>
<a href="https://laorange.github.io/paper-assistant/" target="_blank">在线使用(GitHub)</a>
|
<a href="https://laorange.gitee.io/paper-assistant">在线使用(Gitee)</a>
<a href="https://laorange.gitee.io/paper-assistant" target="_blank">在线使用(Gitee)</a>
|
<a href="https://www.bilibili.com/video/BV1ZG4y1N7oM/">视频介绍</a>
<a href="https://www.bilibili.com/video/BV1ZG4y1N7oM/" target="_blank">视频介绍</a>
|
<a href="/src/assets/UpdatedLogs.md">更新日志</a>
<a href="/src/assets/UpdatedLogs.md" target="_blank">更新日志</a>
|
<a href="http://qny.quoi.top/img/sponsor-qr.jpg" target="_blank">鼓励作者</a>
</p>

## 功能

### (1) 文本复制工具
#### (1) 文本复制工具

在复制PDF中的文字时,有时会出现莫名其妙的空格、换行、全角字符
在复制PDF中的文字时,有时会出现莫名其妙的空格、换行、全角字符或乱码

如果手动删改,工作量巨大;如果直接全文替换,可能会误删英文单词间的空格。

因此,可以使用本程序去除空行空格。详细文档请在[网页](https://laorange.gitee.io/paper-assistant)中点击"使用说明"。

### (2) 英文语法检查
#### (2) 英文语法检查

如果您在电脑上在线使用,在输入英文时,将为您检查语法✍ (基于[Grammarly](https://developer.grammarly.com/))。

## Q&A

#### 为什么不直接查找替换?

出现的若是空格的话,直接替换会误删英文单词中的空格;因此需要用到正则表达式来替换,有较高门槛。

#### 仅粘贴文本,复制到文本文档/记事本?

仅粘贴文本、复制到记事本是**去除格式**,但并不能去除空行空格乱码这样的干扰内容,因为这些是"内容"而不是"格式"。

#### 复制到浏览器地址栏?

浏览器地址栏本质上是一个**单行无格式输入框**,确实可以去除换行符,但并不能处理空格、乱码和全角字符。

#### 为什么不推荐使用OCR?

有条件复制粘贴的话还是不太建议用OCR,识别不准确的话会产生新的麻烦。

#### 未来考虑加入翻译功能吗?

不考虑。若需PDF翻译功能,建议使用[知云文献](http://www.zhiyunwenxian.cn/)

#### 空行空格乱码等痛点是在哪些软件出现的?

空行素材来自**Acrobat**,空格素材来自**Zotero**,乱码素材来源于**CAJViewer**,全角字符素材来自**知云文献**,重复换行素材来源于**Typora**

#### 还有哪些具有相似功能的程序?

1. 若使用quicker,可搜索安装**英文规范粘贴****中文规范粘贴**插件。
2. **copy++**[项目地址](https://github.com/CopyPlusPlus/CopyPlusPlus) | [官方网站](https://copyplusplus.tk/)

## 致开发者

😉为方便看代码的朋友,我把文本处理的方法都单独整理成了[一个文件](https://github.com/laorange/paper-assistant/blob/master/src/assets/ts/article-copy-tool/handlers.ts),并写了注释、规范了接口:
Expand All @@ -37,4 +70,4 @@ export interface TextHandler {
}
```

如您有好的想法,可以在以上内容的基础上修改,欢迎在GitHub仓库上发起 [`pull request`](https://github.com/laorange/paper-assistant/pulls)😊
若您有好的想法,可以在以上内容的基础上修改,欢迎在GitHub仓库上发起 [`pull request`](https://github.com/laorange/paper-assistant/pulls)😊
2 changes: 0 additions & 2 deletions components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ declare module '@vue/runtime-core' {
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
NDrawer: typeof import('naive-ui')['NDrawer']
NDrawerContent: typeof import('naive-ui')['NDrawerContent']
NGi: typeof import('naive-ui')['NGi']
NGrid: typeof import('naive-ui')['NGrid']
NIcon: typeof import('naive-ui')['NIcon']
NInput: typeof import('naive-ui')['NInput']
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"private": false,
"author": "laorange",
"license": "AGPL-3.0",
"version": "1.1.0",
"version": "1.2.0",
"type": "module",
"scripts": {
"dev": "vite --host",
Expand All @@ -16,6 +16,7 @@
"axios": "^1.3.2",
"intro.js": "^6.0.0",
"markdown-it": "^13.0.1",
"pangu": "^4.0.7",
"pinia": "^2.0.28",
"vue": "^3.2.37",
"vue-clipboard3": "^2.0.0",
Expand Down
7 changes: 7 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions src/assets/UpdatedLogs.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
### v1.2.0 (2023-02-19)

新增:启用/禁用"语法检查"的状态按钮

新增:规范中文排版 [(#7)](https://github.com/laorange/paper-assistant/issues/7)

新增:删除引用角标 (如: <sup>[1]</sup>, <sup>[2, 3]</sup>, <sup>[4-7]</sup>)

优化:自动复制、自动清空的触发机制

调整:功能按钮的样式 [(来自评论区)](https://www.bilibili.com/video/BV1ZG4y1N7oM/#reply152210013200)

调整:将全角括号从全角字符集合中移出 [(#8)](https://github.com/laorange/paper-assistant/issues/8)

调整:“标点符号后添加空格”功能效果 [(#8)](https://github.com/laorange/paper-assistant/issues/8#issuecomment-1432508145)

### v1.1.0 (2023-02-08)

新增:自动清空输入、复制输出的可选功能
Expand Down
49 changes: 33 additions & 16 deletions src/assets/ts/article-copy-tool/handlers.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// @ts-ignore
import pangu from "pangu";

export interface TextHandler {
activate: boolean, // 默认是否启用
description: string, // 对该功能的描述
Expand Down Expand Up @@ -59,6 +62,12 @@ export const textHandlers: TextHandlers = {
},
},

deleteReferenceBadge:{
description: "删除引用角标 (如: <sup>[1]</sup>, <sup>[2, 3]</sup>, <sup>[4-7]</sup>)",
activate: true,
executor: text => text.replaceAll(/\[[\d,\-\s]+]/g, "")
},

/** 全角转半角, 参考:
* 1. https://www.cnblogs.com/html55/p/10298569.html
* 2. https://unicode-table.com/cn/search/?q=%E5%85%A8%E5%BD%A2%E6%95%B0%E5%AD%97 */
Expand All @@ -71,14 +80,14 @@ export const textHandlers: TextHandlers = {
let char = text.charCodeAt(i);
// 中文空格替换为英文空格
if (char == 12288) {
result += String.fromCharCode(char - 12256);
continue;
}
if (char > 65280 && char < 65375
// 对,:;·!#¥%…这样的全角字符不做转换
&& [...",:;·!#¥%…"].indexOf(text[i]) === -1) {
result += " ";
} else if (char > 65280 && char < 65375
// 对以下全角字符不做转换
&& [...",:;·!#¥%…()"].indexOf(text[i]) === -1) {
result += String.fromCharCode(char - 65248);
} else result += String.fromCharCode(text.charCodeAt(i));
} else {
result += String.fromCharCode(text.charCodeAt(i));
}
}
return result;
},
Expand Down Expand Up @@ -111,18 +120,12 @@ export const textHandlers: TextHandlers = {
.replaceAll(/ +([^A-Za-z"':])/g, "$1"),
},

addSpacesBetweenEnglishLettersAndNumbers: {
activate: true,
description: "在字母与数字之间添加空格",
executor: (text: string) => text
.replaceAll(/(\d)([A-Za-z])/g, "$1 $2")
.replaceAll(/([A-Za-z])(\d)/g, "$1 $2"),
},

addSpaceAfterEnglishPunctuation: {
activate: true,
description: "在标点符号后添加空格",
executor: (text: string) => text.replaceAll(/([,.?:;)])([^,.?:;)\s])/g, "$1 $2"),
executor: (text: string) => text
.replaceAll(/([,.?:;])([^,.?:;\s])/g, "$1 $2")
.replaceAll(/(\))([a-zA-Z\d])/g, "$1 $2"),
},

deleteSpaceBetweenDotAndNumber: {
Expand All @@ -131,9 +134,23 @@ export const textHandlers: TextHandlers = {
executor: (text: string) => text.replaceAll(/(\.)\s+(\d)/g, "$1$2"),
},

addSpacesBetweenEnglishLettersAndNumbers: {
activate: false,
description: "在字母与数字之间添加空格",
executor: (text: string) => text
.replaceAll(/(\d)([A-Za-z])/g, "$1 $2")
.replaceAll(/([A-Za-z])(\d)/g, "$1 $2"),
},

deleteSpaceBetweenColonAndNumber: {
activate: false,
description: "删除冒号和数字之间的空格",
executor: (text: string) => text.replaceAll(/(:)\s+(\d)/g, "$1$2"),
},

addWhiteOfPanGu: {
description: `规范中文排版 <a href='https://sspai.com/post/37815' target='_blank'>(参考文章)</a>`,
activate: false,
executor: (text: string) => pangu.spacing(text),
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,22 @@ const THRESHOLD_WIDTH = 600;
const hasNotEnoughWidth = document.body.clientWidth < THRESHOLD_WIDTH;
function onLeavePage() {
if (document.hidden) {
if (store.storage.copy.copyOutputWhenLeave && store.copy.outputText) {
toClipboard(store.copy.outputText).then(() => message.success("复制输出文本: 成功"));
}
if (store.storage.copy.clearInputWhenLeave) store.copy.inputText = "";
if (store.storage.copy.copyOutputWhenLeave && store.copy.outputText) {
toClipboard(store.copy.outputText).then(() => message.success("复制输出文本: 成功"));
}
if (store.storage.copy.clearInputWhenLeave) store.copy.inputText = "";
}
onMounted(() => {
document.addEventListener("visibilitychange", onLeavePage);
window.addEventListener("blur", onLeavePage);
if (hasNotEnoughWidth) {
store.storage.copy.horizontalLayout = false;
}
});
onBeforeUnmount(() => {
document.removeEventListener("visibilitychange", onLeavePage);
window.removeEventListener("blur", onLeavePage);
});
</script>

Expand All @@ -40,6 +38,9 @@ onBeforeUnmount(() => {
<ConfigSwitchButton class="clear-input-when-leave-switch" label="自动清空输入" v-model:status="store.storage.copy.clearInputWhenLeave"/>
<ConfigSwitchButton class="copy-output-when-leave-switch" label="自动复制输出" v-model:status="store.storage.copy.copyOutputWhenLeave"/>
</n-space>

<ConfigSwitchButton class="auto-output-switch" label="英语语法纠错" v-model:status="store.storage.copy.activeGrammarly"/>

<n-space>
<ConfigSwitchButton class="auto-output-switch" label="实时输出" v-model:status="store.storage.copy.autoOutput"/>
<ConfigSwitchButton class="horizontal-layout-switch" label="布局方式" v-model:status="store.storage.copy.horizontalLayout"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const statusString = computed(() => statusLocal.value ? props.trueLabel : props.
<template>
<n-button @click="statusLocal = !statusLocal"
tertiary
size="small"
:disabled="!!disabled"
:type="statusLocal ? `primary` : `default`">
{{ label }}:{{ statusString }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {textHandlers, TextHandlerWithName} from "../../../../../assets/ts/articl
import {ref, watch} from "vue";
import {useStore} from "../../../../../store/useStore";
import Draggable from "vuedraggable";
import {SettingsSharp, HelpCircle} from "@vicons/ionicons5";
import {SettingsSharp, HelpCircle, MoveSharp} from "@vicons/ionicons5";
import useIntroducer from "../../../../../assets/ts/article-copy-tool/useIntroducer";
const store = useStore();
Expand Down Expand Up @@ -44,7 +44,7 @@ function turnOffAllTextHandler() {
</n-badge>
</div>

<n-drawer v-model:show="showConfigDrawer" :height="`min(${Object.keys(textHandlers).length * 50 + 125}px, 100vh)`" placement="bottom">
<n-drawer v-model:show="showConfigDrawer" :height="`min(${Object.keys(textHandlers).length * 50 + 135}px, 100vh)`" placement="bottom">
<n-drawer-content :closable="true">
<template #header>
<n-space align="center">
Expand All @@ -63,10 +63,13 @@ function turnOffAllTextHandler() {
<n-space style="height: 100%" :vertical="true" justify="center" align="end" :size="2">
<Draggable v-model="refTextHandlerArray" item-key="handlerName">
<template #item="{element}">
<div class="text-handler-card" @click="element.activate = !element.activate">
<n-space :size="10" justify="start">
<n-switch :value="element.activate"/>
<div> {{ element.description }}</div>
<div class="text-handler-card" :class="{active: element.activate}">
<n-icon :size="16" style="margin-right: 10px">
<MoveSharp/>
</n-icon>
<n-space :size="10" justify="start" align="center">
<n-switch v-model:value="element.activate"/>
<div v-html="element.description"/>
</n-space>
</div>
</template>
Expand All @@ -86,9 +89,15 @@ function turnOffAllTextHandler() {

<style scoped>
.text-handler-card {
border: #efefef solid 1px;
border: #808080 dashed 1px;
margin: 5px;
padding: 10px 25px;
padding: 10px;
cursor: move;
display: flex;
align-items: center;
}
.text-handler-card.active {
border: green solid 1px;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {useStore} from "../../../../../store/useStore";
import GrammarlyEditor from "./components/GrammarlyEditor.vue";
import {watch} from "vue";
import InputFuncButtons from "./InputFuncButtons.vue";
import TextInput from "./components/TextInput.vue";
const store = useStore();
Expand All @@ -13,7 +14,8 @@ watch(() => store.copy.inputText, () => {

<template>
<div class="input-area">
<GrammarlyEditor v-model:value="store.copy.inputText" placeholder="在此输入文本" focus handle-selection/>
<GrammarlyEditor v-if="store.storage.copy.activeGrammarly" v-model:value="store.copy.inputText" placeholder="在此输入文本" focus handle-selection/>
<TextInput v-else placeholder="在此输入文本" v-model:value="store.copy.inputText" focus handle-selection/>
<InputFuncButtons/>
</div>
</template>
Expand Down
2 changes: 2 additions & 0 deletions src/store/useStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface Storage {
clearInputWhenLeave: boolean,
copyOutputWhenLeave: boolean,
horizontalLayout: boolean,
activeGrammarly: boolean,
},
version: string,
darkMode: boolean,
Expand Down Expand Up @@ -49,6 +50,7 @@ export const useStore = defineStore("store", {
clearInputWhenLeave: false,
copyOutputWhenLeave: true,
horizontalLayout: true,
activeGrammarly: true,
},
version: "",
darkMode: useOsTheme().value === "dark",
Expand Down

0 comments on commit 55946cb

Please sign in to comment.