diff --git a/src/components/menus/MainMenu.vue b/src/components/menus/MainMenu.vue
index 9aaedb06..d552072b 100644
--- a/src/components/menus/MainMenu.vue
+++ b/src/components/menus/MainMenu.vue
@@ -21,10 +21,10 @@
{{currentWorkspace.name}} 与 CouchDB 数据库同步。
- {{currentWorkspace.name}} 与 GitHub repo 同步。
+ {{currentWorkspace.name}} 与 GitHub 仓库 同步。
- {{currentWorkspace.name}} 与 Gitee repo 同步。
+ {{currentWorkspace.name}} 与 Gitee 仓库 同步。
{{currentWorkspace.name}} 与 GitLab 项目同步。
diff --git a/src/components/modals/WorkspaceImgPathModal.vue b/src/components/modals/WorkspaceImgPathModal.vue
index ca1c6191..eb78d8c0 100644
--- a/src/components/modals/WorkspaceImgPathModal.vue
+++ b/src/components/modals/WorkspaceImgPathModal.vue
@@ -36,9 +36,11 @@ export default modalTemplate({
},
methods: {
resolve() {
- const path = this.path && this.path.replace(/^\//, '');
+ if (!this.path) {
+ this.setError('path');
+ }
this.config.resolve({
- path: path || '/imgs/{YYYY}-{MM}-{DD}',
+ path: this.path || '/imgs/{YYYY}-{MM}-{DD}',
});
},
},
diff --git a/src/data/defaults/defaultSettings.yml b/src/data/defaults/defaultSettings.yml
index 5a64e9a3..27e6ea0f 100644
--- a/src/data/defaults/defaultSettings.yml
+++ b/src/data/defaults/defaultSettings.yml
@@ -38,6 +38,7 @@ shortcuts:
mod+shift+s: strikethrough
mod+shift+t: table
mod+shift+u: ulist
+ mod+shift+f: inlineformula
'= = > space':
method: expand
params:
diff --git a/src/libs/pagedown.js b/src/libs/pagedown.js
index 272edea4..c46345ad 100644
--- a/src/libs/pagedown.js
+++ b/src/libs/pagedown.js
@@ -40,7 +40,9 @@ var defaultsStrings = {
undo: "Undo - Ctrl/Cmd+Z",
redo: "Redo - Ctrl/Cmd+Y",
- help: "Markdown Editing Help"
+ help: "Markdown Editing Help",
+
+ formulaexample: "这里输入Latex表达式",
};
// options, if given, can have the following properties:
@@ -465,6 +467,7 @@ function UIManager(input, commandManager) {
buttons.bold = bindCommand("doBold");
buttons.italic = bindCommand("doItalic");
buttons.strikethrough = bindCommand("doStrikethrough");
+ buttons.inlineformula = bindCommand("doInlinkeFormula");
buttons.imageUploading = bindCommand("doImageUploading");
buttons.link = bindCommand(function (chunk, postProcessing) {
return this.doLinkOrImage(chunk, postProcessing, false);
@@ -618,6 +621,49 @@ commandProto.doStrikethrough = function (chunk, postProcessing) {
return;
};
+commandProto.doInlinkeFormula = function (chunk, postProcessing) {
+
+ // Get rid of whitespace and fixup newlines.
+ chunk.trimWhitespace();
+ chunk.selection = chunk.selection.replace(/\n{2,}/g, "\n");
+
+ // Look for stars before and after. Is the chunk already marked up?
+ // note that these regex matches cannot fail
+ var starsBefore = /(\$*$)/.exec(chunk.before)[0];
+ var starsAfter = /(^\$*)/.exec(chunk.after)[0];
+
+ var prevStars = Math.min(starsBefore.length, starsAfter.length);
+
+ var nStars = 2;
+
+ // Remove stars if we have to since the button acts as a toggle.
+ if ((prevStars >= nStars) && (prevStars != 2 || nStars != 1)) {
+ chunk.before = chunk.before.replace(re("[\$]{" + nStars + "}$", ""), "");
+ chunk.after = chunk.after.replace(re("^[\$]{" + nStars + "}", ""), "");
+ } else if (!chunk.selection && starsAfter) {
+ // It's not really clear why this code is necessary. It just moves
+ // some arbitrary stuff around.
+ chunk.after = chunk.after.replace(/^(\$*)/, "");
+ chunk.before = chunk.before.replace(/(\s?)$/, "");
+ var whitespace = re.$1;
+ chunk.before = chunk.before + starsAfter + whitespace;
+ } else {
+
+ // In most cases, if you don't have any selected text and click the button
+ // you'll get a selected, marked up region with the default text inserted.
+ if (!chunk.selection && !starsAfter) {
+ chunk.selection = this.getString("formulaexample");
+ }
+
+ // Add the true markup.
+ var markup = "$"; // shouldn't the test be = ?
+ chunk.before = chunk.before + markup;
+ chunk.after = markup + chunk.after;
+ }
+
+ return;
+};
+
commandProto.doImageUploading = function (chunk, postProcessing) {
var enteredCallback = function (imgId) {
if (imgId !== null) {
diff --git a/src/services/editorSvc.js b/src/services/editorSvc.js
index b5731987..bed2e8d5 100644
--- a/src/services/editorSvc.js
+++ b/src/services/editorSvc.js
@@ -46,16 +46,10 @@ class SectionDesc {
const pathUrlMap = Object.create(null);
-const getCurrAbsolutePath = () => {
- const fileId = store.getters['file/current'].id;
- const fileSyncData = store.getters['data/syncDataByItemId'][fileId] || { id: '' };
- const fileAbsolutePath = `${store.getters['workspace/currentWorkspace'].path || ''}${fileSyncData.id}`;
- return fileAbsolutePath.substring(0, fileAbsolutePath.lastIndexOf('/'));
-};
-
const getImgUrl = async (uri) => {
if (uri.indexOf('http://') !== 0 && uri.indexOf('https://') !== 0) {
- const absoluteImgPath = utils.getAbsoluteFilePath(getCurrAbsolutePath(), uri);
+ const currDirNode = store.getters['explorer/selectedNodeFolder'];
+ const absoluteImgPath = utils.getAbsoluteFilePath(currDirNode, uri);
if (pathUrlMap[absoluteImgPath]) {
return pathUrlMap[absoluteImgPath];
}
diff --git a/src/services/imageSvc.js b/src/services/imageSvc.js
index 757eceea..dbb9601c 100644
--- a/src/services/imageSvc.js
+++ b/src/services/imageSvc.js
@@ -7,14 +7,7 @@ import giteaHelper from '../services/providers/helpers/giteaHelper';
import githubHelper from '../services/providers/helpers/githubHelper';
import customHelper from '../services/providers/helpers/customHelper';
-function getCurrAbsolutePath() {
- const fileId = store.getters['file/current'].id;
- const fileSyncData = store.getters['data/syncDataByItemId'][fileId] || { id: '' };
- const fileAbsolutePath = `${store.getters['workspace/currentWorkspace'].path || ''}${fileSyncData.id}`;
- return fileAbsolutePath.substring(0, fileAbsolutePath.lastIndexOf('/'));
-}
-
-function getImagePath(confPath, imgType) {
+const getImagePath = (confPath, imgType) => {
const time = new Date();
const date = time.getDate();
const month = time.getMonth() + 1;
@@ -22,7 +15,7 @@ function getImagePath(confPath, imgType) {
const path = confPath.replace('{YYYY}', year).replace('{MM}', `0${month}`.slice(-2))
.replace('{DD}', `0${date}`.slice(-2)).replace('{MDNAME}', store.getters['file/current'].name);
return `${path}${path.endsWith('/') ? '' : '/'}${utils.uid()}.${imgType.split('/')[1]}`;
-}
+};
export default {
// 上传图片 返回图片链接
@@ -38,13 +31,14 @@ export default {
const path = getImagePath(currStorage.sub, imgFile.type);
// 保存到indexeddb
const base64 = await utils.encodeFiletoBase64(imgFile);
- const absolutePath = utils.getAbsoluteFilePath(getCurrAbsolutePath(), path);
+ const currDirNode = store.getters['explorer/selectedNodeFolder'];
+ const absolutePath = utils.getAbsoluteFilePath(currDirNode, path);
await localDbSvc.saveImg({
id: md5(absolutePath),
path: absolutePath,
content: base64,
});
- return { url: path.replace(' ', '%20') };
+ return { url: path.replaceAll(' ', '%20') };
}
if (!currStorage.provider) {
return { error: '暂无已选择的图床!' };
diff --git a/src/services/optional/shortcuts.js b/src/services/optional/shortcuts.js
index eebd022d..b81f7b97 100644
--- a/src/services/optional/shortcuts.js
+++ b/src/services/optional/shortcuts.js
@@ -32,7 +32,9 @@ const methods = {
ulist: pagedownHandler('ulist'),
clist: pagedownHandler('clist'),
heading: pagedownHandler('heading'),
+ inline: pagedownHandler('heading'),
hr: pagedownHandler('hr'),
+ inlineformula: pagedownHandler('inlineformula'),
sync() {
if (syncSvc.isSyncPossible()) {
syncSvc.requestSync();
diff --git a/src/services/utils.js b/src/services/utils.js
index b8dc52e0..a2c512c3 100644
--- a/src/services/utils.js
+++ b/src/services/utils.js
@@ -383,21 +383,35 @@ export default {
elt.parentNode.removeChild(elt);
});
},
+ getAbsoluteDir(currDirNode) {
+ if (!currDirNode) {
+ return '';
+ }
+ let path = currDirNode.item.name;
+ if (currDirNode.parentNode) {
+ const parentPath = this.getAbsoluteDir(currDirNode.parentNode);
+ if (parentPath) {
+ path = `${parentPath}/${path}`;
+ }
+ }
+ return path || '';
+ },
// 根据当前绝对路径 与 文件路径计算出文件绝对路径
- getAbsoluteFilePath(currAbsolutePath, filePath) {
+ getAbsoluteFilePath(currDirNode, filePath) {
+ const currAbsolutePath = this.getAbsoluteDir(currDirNode);
// "/"开头说明已经是绝对路径
if (filePath.indexOf('/') === 0) {
- return this.encodeUrlPath(filePath);
+ return filePath.replaceAll(' ', '%20');
}
let path = filePath;
// 相对上级路径
if (path.indexOf('../') === 0) {
- return this.getAbsoluteFilePath(currAbsolutePath.substring(0, currAbsolutePath.lastIndexOf('/')), path.replace('../', ''));
+ return this.getAbsoluteFilePath(currDirNode && currDirNode.parentNode, path.replace('../', ''));
} else if (path.indexOf('./') === 0) {
path = `${currAbsolutePath}/${path.replace('./', '')}`;
} else {
path = `${currAbsolutePath}/${path}`;
}
- return (path.indexOf('/') === 0 ? path : `/${path}`).replace(' ', '%20');
+ return (path.indexOf('/') === 0 ? path : `/${path}`).replaceAll(' ', '%20');
},
};