This commit is contained in:
就眠儀式 2022-04-10 12:47:16 +08:00
commit 0060adc843
3 changed files with 56 additions and 6 deletions

View File

@ -24,6 +24,7 @@
"@types/markdown-it": "^12.2.3", "@types/markdown-it": "^12.2.3",
"@types/markdown-it-container": "^2.0.4", "@types/markdown-it-container": "^2.0.4",
"@types/node": "^16.11.9", "@types/node": "^16.11.9",
"@types/prettier": "^2.4.4",
"@vitejs/plugin-vue": "^2.3.1", "@vitejs/plugin-vue": "^2.3.1",
"@vue/compiler-sfc": "^3.2.31", "@vue/compiler-sfc": "^3.2.31",
"@vue/server-renderer": "^3.2.31", "@vue/server-renderer": "^3.2.31",

View File

@ -47,12 +47,12 @@ const toggle = function () {
show.value = !show.value; show.value = !show.value;
}; };
const onPlayground = function () { const onPlayground = async function () {
const foundCodes = meta.value.getElementsByClassName("language-html"); const foundCodes = meta.value.getElementsByClassName("language-html");
const foundCode = foundCodes[0]; const foundCode = foundCodes[0];
const SourceCode = foundCode.textContent || ""; const SourceCode = foundCode.textContent || "";
const { link } = usePlayGround(SourceCode, true); const { link } = await usePlayGround(SourceCode, true);
window.open(link); window.open(link);
}; };

View File

@ -1,3 +1,5 @@
import type { BuiltInParserName } from 'prettier'
const scriptRe = /<script[^>]*>([\s\S]*)<\/script>/; const scriptRe = /<script[^>]*>([\s\S]*)<\/script>/;
const exportDefaultRe = /export\s*default\s*\{([\s\S]*)\}\;?\s*<\/script>/; const exportDefaultRe = /export\s*default\s*\{([\s\S]*)\}\;?\s*<\/script>/;
const setupRe = /setup\s*\(\)\s*\{([\s\S]*)return\s*\{([\s\S]*)\}\;?\s*\}\;?/; const setupRe = /setup\s*\(\)\s*\{([\s\S]*)return\s*\{([\s\S]*)\}\;?\s*\}\;?/;
@ -14,13 +16,13 @@ const MAIN_FILE_NAME = "App.vue";
* @returns URI hsah playground * @returns URI hsah playground
} }
*/ */
export const usePlayGround = (source: string, convertSetupSugar: boolean) => { export const usePlayGround = async (source: string, convertSetupSugar: boolean) => {
const decodeCode = source; const decodeCode = source;
const scriptResult = decodeCode.match(scriptRe); const scriptResult = decodeCode.match(scriptRe);
// 替换 script 标签 // 替换 script 标签
// $1 正则第一个括号匹配的内容 // $1 正则第一个括号匹配的内容
let code: string = decodeCode; let code: string | undefined = decodeCode;
if (convertSetupSugar) { if (convertSetupSugar) {
if (scriptResult) { if (scriptResult) {
code = decodeCode.replace( code = decodeCode.replace(
@ -58,6 +60,8 @@ export const usePlayGround = (source: string, convertSetupSugar: boolean) => {
code = code.replace(layerRe, `import { layer } from "@layui/layui-vue"`); code = code.replace(layerRe, `import { layer } from "@layui/layui-vue"`);
// console.log("layer",code); // console.log("layer",code);
} }
code = await formatCode(MAIN_FILE_NAME, code);
const originCode = { const originCode = {
[MAIN_FILE_NAME]: code, [MAIN_FILE_NAME]: code,
}; };
@ -71,12 +75,57 @@ export const usePlayGround = (source: string, convertSetupSugar: boolean) => {
}; };
}; };
//编码 /**
*
* @param data
* @returns
*/
function utoa(data: string): string { function utoa(data: string): string {
return btoa(unescape(encodeURIComponent(data))); return btoa(unescape(encodeURIComponent(data)));
} }
// 去除字符串两端的空白行 /**
*
* @param str
* @returns
*/
function trimBr(str: string): string { function trimBr(str: string): string {
return str.replace(/(^[\r\n]*)|([\r\n]*$)/, ""); return str.replace(/(^[\r\n]*)|([\r\n]*$)/, "");
} }
/**
*
* @returns
*/
async function formatCode(filename: string, data: string) {
const { format } = await import('prettier/standalone')
const parserTypeScript = await import('prettier/parser-typescript').then(
(m) => m.default
)
const parserBabel = await import('prettier/parser-babel').then(
(m) => m.default
)
const parserHtml = await import('prettier/parser-html').then((m) => m.default)
let code = data;
let parser: BuiltInParserName
if (filename.endsWith('.vue')) {
parser = 'vue'
} else if (filename.endsWith('.js')) {
parser = 'babel'
} else if (filename.endsWith('.ts')) {
parser = 'typescript'
} else if (filename.endsWith('.json')) {
parser = 'json'
} else {
return
}
code = format(code, {
parser,
plugins: [parserHtml, parserTypeScript, parserBabel],
semi: false, // 语句末尾打印分号
singleQuote: true, // 使用单引号
vueIndentScriptAndStyle: false, // 是否缩进 Vue 文件中的 script 和 style 标签
})
return code;
}