diff --git a/.eslintrc b/.eslintrc index 0807290..f9939df 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,23 +1,31 @@ { - "root": true, - "parser": "@typescript-eslint/parser", - "env": { "node": true }, - "plugins": [ - "@typescript-eslint" - ], - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended" - ], - "parserOptions": { - "sourceType": "module" - }, - "rules": { - "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": ["error", { "args": "none" }], - "@typescript-eslint/ban-ts-comment": "off", - "no-prototype-builtins": "off", - "@typescript-eslint/no-empty-function": "off" - } - } \ No newline at end of file + "root": true, + "parser": "@typescript-eslint/parser", + "env": { + "node": true + }, + "plugins": [ + "@typescript-eslint" + ], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended" + ], + "parserOptions": { + "sourceType": "module" + }, + "rules": { + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": [ + "error", + { + "args": "none" + } + ], + "@typescript-eslint/ban-ts-comment": "off", + "no-prototype-builtins": "off", + "@typescript-eslint/no-empty-function": "off", + "@typescript-eslint/semi": ["error", "always"] + } +} diff --git a/src/ClassShape.ts b/src/ClassShape.ts index 5db0f79..a73a457 100644 --- a/src/ClassShape.ts +++ b/src/ClassShape.ts @@ -1,7 +1,7 @@ import {Graph} from '@antv/x6'; -import {Utils} from './Utils' +import {Utils} from './Utils'; -const myUtils = new Utils() +const myUtils = new Utils(); // 類名稱區塊高度 const classNameBoxHeight = 30; @@ -21,11 +21,11 @@ Graph.registerPortLayout( y: classNameBoxHeight + index * funcNameBoxHeight, }, angle: 0, - } - }) + }; + }); }, //true, -) +); /** * 類聲明 圖形定義 @@ -135,7 +135,7 @@ Graph.registerNode( }, }, true, -) +); class ClassShape { @@ -148,14 +148,14 @@ class ClassShape { public createClassShape(className: string, funcNames: string[]) { // 計算 類聲明 圖形寬度 - let maxWidth = 100 - maxWidth = Math.max(maxWidth, myUtils.getTextWidth(className, "14px bold") + 60) + let maxWidth = 100; + maxWidth = Math.max(maxWidth, myUtils.getTextWidth(className, "14px bold") + 60); funcNames.forEach((funcName: string) => { - maxWidth = Math.max(maxWidth, myUtils.getTextWidth(funcName, "13px") + 20) - }) + maxWidth = Math.max(maxWidth, myUtils.getTextWidth(funcName, "13px") + 20); + }); // 定義頂部類名稱方塊 - let classShape = { + const classShape = { "id": myUtils.getClassShapeId(className, '', 'class'), "shape": 'clazz-shape', "label": className, @@ -167,15 +167,15 @@ class ClassShape { "y": 100 }, "ports": [{}] - } - classShape.ports = [] + }; + classShape.ports = []; // 定義下方函數名稱方塊 funcNames.forEach((funcName: string) => { // 代碼塊 連接桩 - let port = { + const port = { "id": myUtils.getClassShapeId(className, funcName, 'function'), "group": "list", "attrs": { @@ -215,12 +215,12 @@ class ClassShape { targetCodeBlock: myUtils.getCodeBlockShapeId(className, funcName), } } - } - classShape.ports.push(port) - }) + }; + classShape.ports.push(port); + }); - return classShape + return classShape; } } -export {ClassShape} +export {ClassShape}; diff --git a/src/CodeBlockShape.ts b/src/CodeBlockShape.ts index fec38aa..8fb5d49 100644 --- a/src/CodeBlockShape.ts +++ b/src/CodeBlockShape.ts @@ -1,12 +1,12 @@ import hljs from 'highlight.js'; -import {CodeData, Utils} from './Utils' +import {CodeData, Utils} from './Utils'; -const myUtils = new Utils() +const myUtils = new Utils(); type CodeBlockContent = { language: string, // 程式語言 code: string // 具體代碼 -} +}; class CodeBlockShape { @@ -18,23 +18,23 @@ class CodeBlockShape { public createCodeBlockShape(codeData: CodeData) { // 結果對象集合 - let result = [] + const result = []; // 將 CodeData 中的每個 func 的 code 轉換成 AntV 的 HTML 對象 - let codeDataFuncs = codeData.funcs + const codeDataFuncs = codeData.funcs; for (const codeDataFunc of codeDataFuncs) { // 獲取 代碼塊字串,並分割成行 - let codeText = codeDataFunc.code - let codeTextLines = codeText.split('\n') + const codeText = codeDataFunc.code; + const codeTextLines = codeText.split('\n'); // 獲取 代碼塊所需高度 - let blockHeight = myUtils.getTextHeight(codeDataFunc.code) + 30; + const blockHeight = myUtils.getTextHeight(codeDataFunc.code) + 30; // 計算代碼塊所需寬度 - let blockWidth = 0 + let blockWidth = 0; for (let i = 0; i < codeTextLines.length; i++) { - blockWidth = Math.max(blockWidth, myUtils.getTextWidth(codeTextLines[i], "13px") + 60) + blockWidth = Math.max(blockWidth, myUtils.getTextWidth(codeTextLines[i], "13px") + 60); } // 構建 HTML 對象 @@ -52,14 +52,14 @@ class CodeBlockShape { } }, html() { - const wrap = document.createElement('div') - wrap.innerHTML = '
' + hljs.highlight(codeText, {language: codeDataFunc.language}).value + ''
- return wrap
+ const wrap = document.createElement('div');
+ wrap.innerHTML = '' + hljs.highlight(codeText, {language: codeDataFunc.language}).value + '';
+ return wrap;
},
- }
+ };
// 將 HTML 對象加入到返回結果中
- result.push(htmlShape)
+ result.push(htmlShape);
}
return result;
diff --git a/src/Edge.ts b/src/Edge.ts
index 3c51014..73fd3a1 100644
--- a/src/Edge.ts
+++ b/src/Edge.ts
@@ -1,7 +1,7 @@
import { Shape } from '@antv/x6';
-import { CodeData, Utils } from './Utils'
+import { CodeData, Utils } from './Utils';
-const myUtils = new Utils()
+const myUtils = new Utils();
class Edge {
@@ -12,7 +12,7 @@ class Edge {
*/
public createFuncToCodeEdges(codeData: CodeData) {
- let result = [];
+ const result = [];
// 遍歷所有的 函數對象,替每個 函數 與 代碼塊圖形 創建 連線對象
for (const func of codeData.funcs) {
@@ -44,10 +44,10 @@ class Edge {
},
},
},
- })
+ });
// 將 連線對象 加入到 返回結果 中
- result.push(edge)
+ result.push(edge);
}
return result;
@@ -60,7 +60,7 @@ class Edge {
*/
public createFuncCallEdges(codeData: CodeData) {
- let result = [];
+ const result = [];
// 遍歷 CodeData 中的每個 函數對象
for (const func of codeData.funcs) {
@@ -103,10 +103,10 @@ class Edge {
stroke: "#2bb37b",
},
},
- })
+ });
// 將 連線對象 加入到 返回結果 中
- result.push(edge)
+ result.push(edge);
}
}
@@ -115,4 +115,4 @@ class Edge {
}
-export { Edge }
+export { Edge };
diff --git a/src/Graph.ts b/src/Graph.ts
index 51f48a6..9c2a7db 100644
--- a/src/Graph.ts
+++ b/src/Graph.ts
@@ -1,15 +1,15 @@
-import {Cell, Graph, Shape} from '@antv/x6';
+import {Cell, Graph} from '@antv/x6';
import {CodeBlockContent, CodeBlockShape} from './CodeBlockShape';
import {ClassShape} from './ClassShape';
import {CLASS_SHAPE_ID_TAG, CODE_BLOCK_ID_TAG, CodeData, Utils} from './Utils';
-import {Edge} from './Edge'
+import {Edge} from './Edge';
-const myUtils = new Utils()
-const codeBlockShape = new CodeBlockShape()
-const classShape = new ClassShape()
-const edge = new Edge()
+const myUtils = new Utils();
+const codeBlockShape = new CodeBlockShape();
+const classShape = new ClassShape();
+const edge = new Edge();
-export let initGraph = function (codeBlocks: CodeBlockContent[]) {
+export const initGraph = function (codeBlocks: CodeBlockContent[]) {
// 創建畫布
const graph = new Graph({
@@ -26,30 +26,30 @@ export let initGraph = function (codeBlocks: CodeBlockContent[]) {
});
// 將 代碼塊字串 集合 解析成 CodeData 對象集合,並將相同 className 的對象進行合併
- let codeDatas: CodeData[] = []
+ let codeDatas: CodeData[] = [];
codeBlocks.forEach((codeBlock: CodeBlockContent) => {
- let codeData: CodeData = myUtils.parseCodeData(codeBlock)
- codeDatas.push(codeData)
- })
- codeDatas = myUtils.mergeCodeDatas(codeDatas)
+ const codeData: CodeData = myUtils.parseCodeData(codeBlock);
+ codeDatas.push(codeData);
+ });
+ codeDatas = myUtils.mergeCodeDatas(codeDatas);
// 將 CodeData 對象列表 繪製成 類圖形、代碼塊圖形
for (const codeData of codeDatas) {
// 將 類圖形、代碼塊圖形 加入到 畫布 中
- let funcNames = codeData.funcs.map(item => item.name)
- graph.addNode(classShape.createClassShape(codeData.className, funcNames))
- graph.addNodes(codeBlockShape.createCodeBlockShape(codeData))
+ const funcNames = codeData.funcs.map(item => item.name);
+ graph.addNode(classShape.createClassShape(codeData.className, funcNames));
+ graph.addNodes(codeBlockShape.createCodeBlockShape(codeData));
// 創建 函數名稱 與 代碼塊圖形 的 連線
- graph.addEdges(edge.createFuncToCodeEdges(codeData))
+ graph.addEdges(edge.createFuncToCodeEdges(codeData));
}
// 繪製 CodeData 中的 函數調用 連線
for (const codeData of codeDatas) {
- graph.addEdges(edge.createFuncCallEdges(codeData))
+ graph.addEdges(edge.createFuncCallEdges(codeData));
}
// 綁定 開啟/關閉 代碼塊圖形 事件
@@ -57,46 +57,46 @@ export let initGraph = function (codeBlocks: CodeBlockContent[]) {
graph.on('toggle:codeBlock', ({e}) => {
// 獲取 代碼塊圖形、開關文字 對象
- let codeBlock = graph.getCellById(e.currentTarget.getAttribute('target-code-block'))
- let toggleText = e.currentTarget.parentNode.childNodes[5].children[0]
+ const codeBlock = graph.getCellById(e.currentTarget.getAttribute('target-code-block'));
+ const toggleText = e.currentTarget.parentNode.childNodes[5].children[0];
// 如果當前 代碼塊圖形 正在顯示,則關閉。反之則開啟
if (codeBlock.getProp().visible) {
- codeBlock.hide()
- toggleText.textContent = '+'
- toggleText.setAttribute('dy', '0.3em')
+ codeBlock.hide();
+ toggleText.textContent = '+';
+ toggleText.setAttribute('dy', '0.3em');
} else {
// 計算 代碼塊 顯示位置
- const intervalX = 100
- const posX = e.offsetX + intervalX
- const posY = e.offsetY - (codeBlock.getProp().size.height / 2)
- codeBlock.prop("position", {x: posX, y: posY})
+ const intervalX = 100;
+ const posX = e.offsetX + intervalX;
+ const posY = e.offsetY - (codeBlock.getProp().size.height / 2);
+ codeBlock.prop("position", {x: posX, y: posY});
// 顯示 代碼塊,並更新按鈕內容
- codeBlock.show()
- toggleText.textContent = '-'
- toggleText.setAttribute('dy', '0.3em')
+ codeBlock.show();
+ toggleText.textContent = '-';
+ toggleText.setAttribute('dy', '0.3em');
}
- })
+ });
// 最大的 類圖形 的寬度
let maxClassShapeWidth = 0;
// 所有的 類圖形 集合
- let classShapes: Cell[] = [];
+ const classShapes: Cell[] = [];
// 遍歷 所有的圖形
for (const node of graph.getCells()) {
// 默認隱藏所有的 代碼塊
if (node.id.startsWith(CODE_BLOCK_ID_TAG)) {
- node.hide()
+ node.hide();
}
// 計算 類圖形 最大寬度、加入到集合中
if (node.id.startsWith(CLASS_SHAPE_ID_TAG)) {
- maxClassShapeWidth = Math.max(maxClassShapeWidth, node.getProp().size.width)
- classShapes.push(node)
+ maxClassShapeWidth = Math.max(maxClassShapeWidth, node.getProp().size.width);
+ classShapes.push(node);
}
}
@@ -104,23 +104,23 @@ export let initGraph = function (codeBlocks: CodeBlockContent[]) {
* 計算 類圖形 的 座標
*/
// 左側保留寬度
- const marginLeftWidth = 100
+ const marginLeftWidth = 100;
// 類圖形的 Y 座標
- let curY = 200
+ let curY = 200;
// 多個 類圖形 的 上下間格
- const intervalY = 150
+ const intervalY = 150;
// 所有 類圖形 的 中線 X 座標
- const midX = marginLeftWidth + (maxClassShapeWidth / 2)
+ const midX = marginLeftWidth + (maxClassShapeWidth / 2);
for (const classShape of classShapes) {
// 計算 類圖形 的 左上X 座標,並設置
- const posX = midX - (classShape.getProp().size.width / 2)
- classShape.prop("position", {x: posX, y: curY})
+ const posX = midX - (classShape.getProp().size.width / 2);
+ classShape.prop("position", {x: posX, y: curY});
// 下個 類圖形 的 Y 座標 = 當前 類圖形 高度 + 間隔
- curY = curY + classShape.getProp().size.height + intervalY
+ curY = curY + classShape.getProp().size.height + intervalY;
}
-}
+};
diff --git a/src/SourceCodeView.ts b/src/SourceCodeView.ts
index d1f27e3..1535c11 100644
--- a/src/SourceCodeView.ts
+++ b/src/SourceCodeView.ts
@@ -6,7 +6,7 @@ import {CodeBlockContent} from "./CodeBlockShape";
export default class SourceCodeView extends ItemView {
// 代碼塊內容 集合
- codeBlocks: CodeBlockContent[]
+ codeBlocks: CodeBlockContent[];
constructor(codeBlocks: CodeBlockContent[], leaf: WorkspaceLeaf) {
super(leaf);
@@ -28,7 +28,7 @@ export default class SourceCodeView extends ItemView {
container.empty();
// 創建 AntV 需要的容器
- const div = document.createElement("div")
+ const div = document.createElement("div");
div.id = 'container';
container.appendChild(div);
diff --git a/src/Utils.ts b/src/Utils.ts
index 2b49407..3e452cc 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -4,22 +4,22 @@ import {CodeBlockContent} from "./CodeBlockShape";
type CodeData = {
className: string, // 類名稱
funcs: CodeDataFunc[] // 函數名稱 與 代碼塊字串 集合
-}
+};
type CodeDataFunc = {
language: string, // 程式語言
name: string, // 函數名稱
code: string, // 代碼塊字串
calls: CodeDataFuncCall[] // 調用的函數集合
-}
+};
type CodeDataFuncCall = {
className: string, // 類名稱
functionName: string // 函數名稱
-}
+};
-export const CLASS_SHAPE_ID_TAG: string = "class-";
-export const CODE_BLOCK_ID_TAG: string = 'code-block-';
+export const CLASS_SHAPE_ID_TAG = "class-";
+export const CODE_BLOCK_ID_TAG = 'code-block-';
class Utils {
@@ -43,12 +43,12 @@ class Utils {
public getTextHeight(codeText: string) {
// 創建一個新容器,將 HTML 代碼加入到容器中
- let node = document.createElement('div');
+ const node = document.createElement('div');
node.innerHTML = '' + hljs.highlight(codeText, {language: 'java'}).value + '';
document.body.appendChild(node);
// 計算 容器高度
- let height: number = parseInt(global.getComputedStyle(node).height.split('px')[0]);
+ const height: number = parseInt(global.getComputedStyle(node).height.split('px')[0]);
// 移除容器
document.body.removeChild(node);
@@ -67,61 +67,61 @@ class Utils {
const content = codeBlockContent.code;
// 類名、方法名 的 標示符
- const classTag = '@class'
- const functionTag = '@function'
- const callTag = '@call'
+ const classTag = '@class';
+ const functionTag = '@function';
+ const callTag = '@call';
- let codeLines = content.split('\n')
+ const codeLines = content.split('\n');
// 取得 註釋塊 的代碼
- let commentLines = []
+ const commentLines = [];
for (let i = 0; i < codeLines.length; i++) {
- let codeLine = codeLines[i]
+ const codeLine = codeLines[i];
// 找到註釋開頭,則從當前行開始,加入到註釋塊列表中
if (codeLine.indexOf('/**') != -1) {
- commentLines.push(codeLine)
+ commentLines.push(codeLine);
} else if (commentLines.length > 0) {
- commentLines.push(codeLine)
+ commentLines.push(codeLine);
}
// 當碰到第一個多行註釋的結尾,則跳出循環
if (codeLine.indexOf('*/') != -1) {
- break
+ break;
}
}
// 從 註釋塊 中獲取 類名、方法名、調用的函數集合
- let className = ''
- let functionName = ''
- let calls: CodeDataFuncCall[] = []
+ let className = '';
+ let functionName = '';
+ const calls: CodeDataFuncCall[] = [];
commentLines.forEach((comment) => {
// 獲取 類名
if (comment.indexOf(classTag) != -1) {
- className = comment.substring(comment.indexOf(classTag) + classTag.length).trim()
+ className = comment.substring(comment.indexOf(classTag) + classTag.length).trim();
}
// 獲取 方法名
if (comment.indexOf(functionTag) != -1) {
- functionName = comment.substring(comment.indexOf(functionTag) + functionTag.length).trim()
+ functionName = comment.substring(comment.indexOf(functionTag) + functionTag.length).trim();
}
// 獲取 調用的函數
if (comment.indexOf(callTag) != -1) {
- let callStr = comment.substring(comment.indexOf(callTag) + callTag.length).trim()
+ const callStr = comment.substring(comment.indexOf(callTag) + callTag.length).trim();
calls.push({
className: callStr.substring(0, callStr.indexOf('@')).trim(),
functionName: callStr.substring(callStr.indexOf('@') + 1).trim()
- })
+ });
}
- })
+ });
// 封裝結果
- let result: CodeData = {
+ const result: CodeData = {
className: className,
funcs: [{
language: lang,
@@ -129,9 +129,9 @@ class Utils {
code: content,
calls: calls
}]
- }
+ };
- return result
+ return result;
}
/**
@@ -143,11 +143,11 @@ class Utils {
*/
public getClassShapeId(className: string, functionName: string, type: 'class' | 'function'): string {
if (type == 'class') {
- return CLASS_SHAPE_ID_TAG + className
+ return CLASS_SHAPE_ID_TAG + className;
} else if (type == 'function') {
- return CLASS_SHAPE_ID_TAG + className + '-' + functionName
+ return CLASS_SHAPE_ID_TAG + className + '-' + functionName;
}
- return ''
+ return '';
}
/**
@@ -157,7 +157,7 @@ class Utils {
* @returns 圖形Id
*/
public getCodeBlockShapeId(className: string, functionName: string): string {
- return CODE_BLOCK_ID_TAG + className + '-' + functionName
+ return CODE_BLOCK_ID_TAG + className + '-' + functionName;
}
/**
@@ -168,27 +168,27 @@ class Utils {
public mergeCodeDatas(codeDatas: CodeData[]): CodeData[] {
// 對有相同 className 的 CodeData 的 func 進行合併
- let classNameToCodeData = new Map()
+ const classNameToCodeData = new Map();
codeDatas.forEach((codeData: CodeData) => {
// 如果在 Map 中已存在相應的 CodeData,則將 func 進行合併
if (classNameToCodeData.has(codeData.className)) {
- let tempCodeData = classNameToCodeData.get(codeData.className) as CodeData
- tempCodeData.funcs.push(codeData.funcs[0])
+ const tempCodeData = classNameToCodeData.get(codeData.className) as CodeData;
+ tempCodeData.funcs.push(codeData.funcs[0]);
}
// 如果在 Map 中還沒有相應的 CodeData,則將當前 CodeData 加入到 Map 中
else {
- classNameToCodeData.set(codeData.className, codeData)
+ classNameToCodeData.set(codeData.className, codeData);
}
- })
+ });
// 封裝返回結果
- let result: CodeData[] = []
- for (let codeData of Array.from(classNameToCodeData.values())) {
- result.push(codeData)
+ const result: CodeData[] = [];
+ for (const codeData of Array.from(classNameToCodeData.values())) {
+ result.push(codeData);
}
- return result
+ return result;
}
}
diff --git a/src/main.ts b/src/main.ts
index 1c70a7f..ce46a57 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,13 +1,13 @@
-import {Plugin, Workspace, WorkspaceLeaf} from 'obsidian';
+import {Plugin, WorkspaceLeaf} from 'obsidian';
import SourceCodeView from "./SourceCodeView";
import {CodeBlockContent} from "./CodeBlockShape";
-export const SOURCE_CODE_VIEW_TYPE = 'source-code-view'
+export const SOURCE_CODE_VIEW_TYPE = 'source-code-view';
export default class SourceCodeViewPlugin extends Plugin {
// Obsidian 中 Markdown 的 代碼塊內容 集合
- codeBlockContents: CodeBlockContent[] = []
+ codeBlockContents: CodeBlockContent[] = [];
/**
* 載入插件時,註冊相關組件
@@ -22,7 +22,7 @@ export default class SourceCodeViewPlugin extends Plugin {
// 註冊 Obsidian 左側的按鈕
this.addRibbonIcon("file-json", "Show Resource Code View", () => {
- this.initView()
+ this.initView();
});
}
@@ -45,7 +45,7 @@ export default class SourceCodeViewPlugin extends Plugin {
this.app.vault.process(activeFile, (data) => {
// 清理數據
- this.codeBlockContents = []
+ this.codeBlockContents = [];
// 獲取文件內所有的 Markdown 代碼塊
const regex = /```(\w+)\s([\s\S]*?)```/gm;
@@ -53,16 +53,16 @@ export default class SourceCodeViewPlugin extends Plugin {
while ((match = regex.exec(data)) !== null) {
const lang = match[1]; // 程式語言
const content = match[2]; // 代碼塊內容
- this.codeBlockContents.push({language: lang, code: content})
+ this.codeBlockContents.push({language: lang, code: content});
}
// 開啟分頁
- const preview = this.app.workspace.getLeaf('split', 'vertical')
+ const preview = this.app.workspace.getLeaf('split', 'vertical');
const mmPreview = new SourceCodeView(this.codeBlockContents, preview);
- preview.open(mmPreview)
+ preview.open(mmPreview);
// 不更改文件內容
- return data
+ return data;
});
}