From 8d4a4b19db7f20467ed89efdcf18291f120fb961 Mon Sep 17 00:00:00 2001 From: eee555 <2234208506@qq.com> Date: Mon, 27 May 2024 01:32:15 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=91=86=E9=9B=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- front_end/src/utils/common/cellSVGData.ts | 130 +++++++++++++ front_end/src/views/GuideView.vue | 225 ++++++++++++++++++++-- front_end/vue.config.js | 5 +- front_end/webpack.config.js | 2 + 4 files changed, 348 insertions(+), 14 deletions(-) create mode 100644 front_end/src/utils/common/cellSVGData.ts diff --git a/front_end/src/utils/common/cellSVGData.ts b/front_end/src/utils/common/cellSVGData.ts new file mode 100644 index 0000000..e079188 --- /dev/null +++ b/front_end/src/utils/common/cellSVGData.ts @@ -0,0 +1,130 @@ +// 此处变量名按照svg规范 +const cell1 = ` + + + +`; + +const cell2 = ` + + + +`; + +const cell3 = ` + + + +`; + +const cell4 = ` + + + +`; + +const cell5 = ` + + + +`; + +const cell6 = ` + + + +`; + +const cell7 = ` + + + +`; + +const cell8 = ` + + + +`; + +const celldown = ` + + +`; + +const cellflag = ` + + + + + + + +`; + +const cellmine = ` + + + + + + + + +`; + +const cellup = ` + + + +`; + +const blast = ` + + + + + + + + +`; + +const falsemine = ` + + + + + + + + + + +`; + +// 摆雷语法,原则上致敬扫雷网,兼顾已有的svg资源、修改部分不合理的设计 +export const cells: { [key: string]: string } = { + "1": cell1, + "2": cell2, + "3": cell3, + "4": cell4, + "5": cell5, + "6": cell6, + "7": cell7, + "8": cell8, + "0": celldown, + "!": cellflag, // 旗 + "*": cellmine, // 白雷 + "a": cellup, + "+": blast, // 红雷 + "x": falsemine, // 叉雷 +} + + + + + diff --git a/front_end/src/views/GuideView.vue b/front_end/src/views/GuideView.vue index cf5b497..d7e2144 100644 --- a/front_end/src/views/GuideView.vue +++ b/front_end/src/views/GuideView.vue @@ -12,12 +12,12 @@ @@ -31,12 +31,12 @@ @@ -50,12 +50,12 @@ @@ -69,12 +69,12 @@ @@ -97,6 +97,9 @@ const { proxy } = useCurrentInstance(); // https://mdit-plugins.github.io/zh/ import MarkdownIt from 'markdown-it'; +import type { RuleInline } from "markdown-it/lib/parser_inline.mjs"; +import type { RuleBlock } from "markdown-it/lib/parser_block.mjs"; + // 缩写悬停弹气泡 import { abbr } from "@mdit/plugin-abbr"; // 对齐方式 @@ -108,13 +111,146 @@ import mathjax3 from "markdown-it-mathjax3"; // 图片懒加载 import { imgLazyload } from "@mdit/plugin-img-lazyload"; +import { cells } from "@/utils/common/cellSVGData"; + const markdown = new MarkdownIt({ html: true, // 允许HTML语法 typographer: true, // 启用Typographer插件,可以更好地处理中文字符和标点符号 linkify: true // 自动将文本中的URL转换为链接 }).use(abbr).use(align).use(markdownItHighlight).use(mathjax3).use(imgLazyload); + + + +// 匹配 +// [[[ +// 0000 +// 1111 +// ]]] +// 之类的块状摆局面 +const parse_ms_board: RuleBlock = (state, startLine: number, endLine: number, silent: boolean) => { + // 如果silent为true,则只检查而不进行实际替换 + if (silent) return false; + // 获取文本块的开始和结束位置 + let token, pos, max; + let start = state.bMarks[startLine] + state.tShift[startLine]; + let end = state.eMarks[startLine]; + pos = start; + max = state.eMarks[endLine]; + + // 检查第一行是否以"[[["开始 + if (state.src.slice(start, start + 3) !== "[[[") return false; + pos += 3; + while(!/[0123456789+*ax!]/.test(state.src.charAt(pos))){ + pos++; + } + // 初始化一个token来存储处理后的内容 + state.push('parse_board_open', 'div', 1); + token = state.push('parse_board_open', 'board', 1); + while (true) { + if (pos > max) { + return false; + } + if (state.src.slice(pos, pos + 3) == "]]]") { + break; + } + let tag_key = state.src.charAt(pos); + state.push( + 'cell_token', + tag_key, + 0 + ); + pos++; + } + + // 添加段落结束token + state.push('parse_board_close', 'board', -1); + state.push('parse_board_close', 'div', -1); + + // 跳过已处理的行,这些内容会被隐藏 + let k = 1; + while(state.eMarks[startLine + k] < pos + 4){ + k++; + } + state.line = startLine + k; + + return true; + +} +markdown.block.ruler.before("code", "parse_board", parse_ms_board); + + +// 匹配[[0]]之类的行内摆雷 +const parse_ms_cell: RuleInline = (state, silent) => { + const max = state.posMax; + const start = state.pos; + if ( + state.src.charAt(start) !== "[" || + state.src.charAt(start + 1) !== "[" || + state.src.charAt(start + 3) !== "]" || + state.src.charAt(start + 4) !== "]" || + silent || + start + 4 > max + ) + return false; + const tag_key = state.src.charAt(start + 2); + if (!(tag_key in cells)) { + return false; + } + state.push( + 'cell_token', + tag_key, + 0 + ); + state.pos += 5; + return true; +}; +markdown.inline.ruler.push("parse_ms_cell", parse_ms_cell); +markdown.renderer.rules['cell_token'] = function (tokens, idx, options, env, renderer) { + let tag = tokens[idx].tag; + if (tag == "\n"){ + return "
"; + }else if(/[0123456789+*ax!]/.test(tag)){ + return cells[tokens[idx].tag]; + } else{ + return ""; + } +}; + + const js = ` +[[0]][[1]][[2]][[3]][[4]][[5]][[6]][[7]][[8]][[*]][[+]][[!]][[a]][[x]] + + +[[[ +a111aaa111aa +a111aaa111aa +a111aaa111aa +a111aaa111aa +a111aaa111aa +a111aaa111aa +]]] + +- 居中的摆雷 +::: center +[[[ + a111aa + aa2560 + a!!!xa +]]] +::: + + + import numpy as np + print(666) + +\`\`\` +print(666) +\`\`\` + +H\~2\~O + + 2. 气泡: *[3BV]: Bechtel's Board Benchmark Value,可进一步简称BV。3BV指仅使用左键解开当前局面,所需要的理论最少左击次数。 @@ -181,7 +317,7 @@ const other_list = ref([]) onMounted(() => { - // content.value = js;return + // content.value = js; return proxy.$axios.get('/article/articles/' ).then(function (response) { const articles: string[] = response.data; @@ -338,10 +474,12 @@ const show_content = (key: string, keyPath: string[]) => { word-break: normal; border-radius: 5px; } -a{ + +a { cursor: pointer; } -:deep(a):hover{ + +:deep(a):hover { color: #449cd6; } @@ -352,4 +490,69 @@ a{ background-color: #efefef; overflow: auto; } + +:deep(table) { + width: 100%; + border-collapse: collapse; + /* 合并相邻边框 */ + border-top: 2px solid #cbcbcb; + /* 顶部边框 */ + border-bottom: 2px solid #cbcbcb; + /* 底部边框 */ +} + +/* 表头样式 */ +:deep(thead) { + background-color: #f5f5f5; + /* 浅灰色背景 */ +} + +:deep(th, td) { + padding: 8px; + /* 单元格内边距 */ + text-align: center; + /* 文本左对齐 */ + border-bottom: 1px solid #cbcbcb; + /* 底部边框 */ +} + +:deep(td) { + text-align: center; + /* 文本左对齐 */ + padding: 5px; +} + +/* 第一个表头单元格样式(项目列) */ +:deep(th:first-child) { + font-weight: bold; + /* 加粗 */ + width: 30%; + /* 宽度为 30% */ +} + +/* 表格行悬停效果 */ +:deep(tr:hover) { + background-color: #f5f5f5; + /* 鼠标悬停时背景色 */ +} + +/* 雷的缩放倍数,原来是160像素 */ +:deep(.ms_cell) { + zoom: 0.16; + padding: 0; +} + +:deep(board) { + +} + +:deep(board br) { + vertical-align: middle; +} +:deep(board svg) { + vertical-align: middle; +} + + + \ No newline at end of file diff --git a/front_end/vue.config.js b/front_end/vue.config.js index dbd0c92..8d1d6f4 100644 --- a/front_end/vue.config.js +++ b/front_end/vue.config.js @@ -27,7 +27,6 @@ module.exports = { args[0].title = "元扫雷网"; return args }) - } - - + }, + } \ No newline at end of file diff --git a/front_end/webpack.config.js b/front_end/webpack.config.js index 09459ab..1bc620b 100644 --- a/front_end/webpack.config.js +++ b/front_end/webpack.config.js @@ -9,4 +9,6 @@ module.exports = { syncWebAssembly: true, topLevelAwait: true, }, + + }; \ No newline at end of file