diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8acc9ce..55a4260 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,12 +11,12 @@ jobs: if: github.repository == 'doocs/md' steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: persist-credentials: false - name: Set up node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: 20 diff --git a/.github/workflows/preview-build.yml b/.github/workflows/preview-build.yml index fffd689..f05cd48 100644 --- a/.github/workflows/preview-build.yml +++ b/.github/workflows/preview-build.yml @@ -10,12 +10,12 @@ jobs: if: github.repository == 'doocs/md' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha }} - name: Set up node - uses: actions/setup-node@v2 + uses: actions/setup-node@v4 with: node-version: 20 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 342bbbe..0ec47c3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ jobs: if: github.repository == 'doocs/md' steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Create Release id: create_release uses: actions/create-release@v1 diff --git a/README.md b/README.md index c609247..4745393 100644 --- a/README.md +++ b/README.md @@ -8,14 +8,12 @@
-[![sync status](https://github.com/doocs/md/workflows/Sync/badge.svg)](https://github.com/doocs/md/actions) [![deploy status](https://github.com/doocs/md/workflows/Build%20and%20Deploy/badge.svg)](https://github.com/doocs/md/actions) [![prettier status](https://github.com/doocs/md/workflows/Prettier/badge.svg)](https://github.com/doocs/md/actions) [![users](https://badgen.net/badge/Who's/using/green)](#谁在使用) [![PRs Welcome](https://badgen.net/badge/PRs/welcome/green)](../../pulls)
[![github](https://badgen.net/badge/⭐/GitHub/blue)](https://github.com/doocs/md) [![gitee](https://badgen.net/badge/⭐/Gitee/blue)](https://gitee.com/doocs/md) [![gitee](https://badgen.net/badge/⭐/GitCode/blue)](https://gitcode.com/doocs/md) [![license](https://badgen.net/github/license/doocs/md)](./LICENSE) [![release](https://img.shields.io/github/v/release/doocs/md.svg)](../../releases) +[![deploy status](https://github.com/doocs/md/workflows/Build%20and%20Deploy/badge.svg)](https://github.com/doocs/md/actions) [![users](https://badgen.net/badge/Who's/using/green)](#谁在使用) [![PRs Welcome](https://badgen.net/badge/PRs/welcome/green)](../../pulls)
[![license](https://badgen.net/github/license/doocs/md)](./LICENSE) [![github](https://badgen.net/badge/⭐/GitHub/blue)](https://github.com/doocs/md) [![gitee](https://badgen.net/badge/⭐/Gitee/blue)](https://gitee.com/doocs/md) [![gitee](https://badgen.net/badge/⭐/GitCode/blue)](https://gitcode.com/doocs/md) [![release](https://img.shields.io/github/v/release/doocs/md.svg)](../../releases)
## 项目介绍 -> 本项目基于 [wechat-format](https://github.com/lyricat/wechat-format) 进行二次开发,感谢 [lyricat](https://github.com/lyricat) 的创意和贡献! - Markdown 文档自动即时渲染为微信图文,让你不再为微信文章排版而发愁!只要你会基本的 Markdown 语法,就能做出一篇样式简洁而又美观大方的微信图文。 ## 在线编辑器地址 diff --git a/src/utils/index.js b/src/utils/index.js index e9ef547..fe087ee 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -115,82 +115,52 @@ export function customCssWithTemplate(jsonString, color, theme) { } /** - * 将CSS形式的字符串转换为JSON + * 将 CSS 字符串转换为 JSON 对象 * - * @param {string} css - css字符串 + * @param {string} css - CSS 字符串 + * @returns {object} - JSON 格式的 CSS */ export function css2json(css) { - // 移除CSS所有注释 - let open, close - while ( - (open = css.indexOf(`/*`)) !== -1 - && (close = css.indexOf(`*/`)) !== -1 - ) { - css = css.substring(0, open) + css.substring(close + 2) - } + // 去除所有 CSS 注释 + css = css.replace(/\/\*[\s\S]*?\*\//g, ``) - // 初始化返回值 const json = {} - while (css.length > 0 && css.includes(`{`) && css.includes(`}`)) { - // 存储第一个左/右花括号的下标 + // 辅助函数:将声明数组转换为对象 + const toObject = array => + array.reduce((obj, item) => { + const [property, value] = item.split(`:`).map(part => part.trim()) + if (property) + obj[property] = value + return obj + }, {}) + + while (css.includes(`{`) && css.includes(`}`)) { const lbracket = css.indexOf(`{`) const rbracket = css.indexOf(`}`) - // 第一步:将声明转换为Object,如: - // `font: 'Times New Roman' 1em; color: #ff0000; margin-top: 1em;` - // ==> - // `{"font": "'Times New Roman' 1em", "color": "#ff0000", "margin-top": "1em"}` - - // 辅助方法:将array转为object - - function toObject(array) { - const ret = {} - array.forEach((e) => { - const index = e.indexOf(`:`) - const property = e.substring(0, index).trim() - ret[property] = e.substring(index + 1).trim() - }) - return ret - } - - // 切割声明块并移除空白符,然后放入数组中 - let declarations = css - .substring(lbracket + 1, rbracket) + // 获取声明块并转换为对象 + const declarations = css.substring(lbracket + 1, rbracket) .split(`;`) .map(e => e.trim()) - .filter(e => e.length > 0) // 移除所有""空值 + .filter(Boolean) - // 转为Object对象 - declarations = toObject(declarations) - - // 第二步:选择器处理,每个选择器会与它对应的声明相关联,如: - // `h1, p#bar {color: red}` - // ==> - // {"h1": {color: red}, "p#bar": {color: red}} - - const selectors = css - .substring(0, lbracket) - // 以,切割,并移除空格:`"h1, p#bar, span.foo"` => ["h1", "p#bar", "span.foo"] + // 获取选择器并去除空格 + const selectors = css.substring(0, lbracket) .split(`,`) .map(selector => selector.trim()) - // 迭代赋值 + const declarationObj = toObject(declarations) + + // 将声明对象关联到相应的选择器 selectors.forEach((selector) => { - // 若不存在,则先初始化 - if (!json[selector]) - json[selector] = {} - // 赋值到JSON - Object.keys(declarations).forEach((key) => { - json[selector][key] = declarations[key] - }) + json[selector] = { ...(json[selector] || {}), ...declarationObj } }) - // 继续下个声明块 + // 处理下一个声明块 css = css.slice(rbracket + 1).trim() } - // 返回JSON形式的结果串 return json } @@ -358,7 +328,7 @@ export function toBase64(file) { export function checkImage(file) { // 检查文件名后缀 - const isValidSuffix = /\.(gif|jpe?g|png)$/i.test(file.name) + const isValidSuffix = /\.(?:gif|jpe?g|png)$/i.test(file.name) if (!isValidSuffix) { return { ok: false, diff --git a/src/utils/tokenTools.js b/src/utils/tokenTools.js index 3d7f4df..a1fd291 100644 --- a/src/utils/tokenTools.js +++ b/src/utils/tokenTools.js @@ -1,33 +1,36 @@ export function utf16to8(str) { - let out, i, len, c - out = `` - len = str.length - for (i = 0; i < len; i++) { - c = str.charCodeAt(i) + let out = `` + const len = str.length + + for (let i = 0; i < len; i++) { + const c = str.charCodeAt(i) + if (c >= 0x0001 && c <= 0x007F) { out += str.charAt(i) } else if (c > 0x07FF) { out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F)) out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F)) - out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F)) + out += String.fromCharCode(0x80 | (c & 0x3F)) } else { out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F)) - out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F)) + out += String.fromCharCode(0x80 | (c & 0x3F)) } } + return out } export function utf8to16(str) { - let out, i, len, c - let char2, char3 - out = `` - len = str.length - i = 0 + let out = `` + let i = 0 + const len = str.length + while (i < len) { - c = str.charCodeAt(i++) + const c = str.charCodeAt(i++) + let char2, char3 + switch (c >> 4) { case 0: case 1: @@ -51,11 +54,12 @@ export function utf8to16(str) { char2 = str.charCodeAt(i++) char3 = str.charCodeAt(i++) out += String.fromCharCode( - ((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0), + ((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | (char3 & 0x3F), ) break } } + return out } @@ -193,77 +197,89 @@ const base64DecodeChars = [ ] export function base64encode(str) { - let out, i, len - let c1, c2, c3 - len = str.length - i = 0 - out = `` + let out = `` + let i = 0 + const len = str.length + while (i < len) { - c1 = str.charCodeAt(i++) & 0xFF - if (i == len) { + const c1 = str.charCodeAt(i++) & 0xFF + + if (i === len) { out += base64EncodeChars.charAt(c1 >> 2) out += base64EncodeChars.charAt((c1 & 0x3) << 4) out += `==` break } - c2 = str.charCodeAt(i++) - if (i == len) { + + const c2 = str.charCodeAt(i++) + + if (i === len) { out += base64EncodeChars.charAt(c1 >> 2) out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)) out += base64EncodeChars.charAt((c2 & 0xF) << 2) out += `=` break } - c3 = str.charCodeAt(i++) + + const c3 = str.charCodeAt(i++) + out += base64EncodeChars.charAt(c1 >> 2) out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)) out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6)) out += base64EncodeChars.charAt(c3 & 0x3F) } + return out } export function base64decode(str) { let c1, c2, c3, c4 - let i, len, out - len = str.length - i = 0 - out = `` + let i = 0 + const len = str.length + let out = `` + while (i < len) { /* c1 */ do { c1 = base64DecodeChars[str.charCodeAt(i++) & 0xFF] - } while (i < len && c1 == -1) - if (c1 == -1) + } while (i < len && c1 === -1) + if (c1 === -1) break + /* c2 */ do { c2 = base64DecodeChars[str.charCodeAt(i++) & 0xFF] - } while (i < len && c2 == -1) - if (c2 == -1) + } while (i < len && c2 === -1) + if (c2 === -1) break + out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4)) + /* c3 */ do { c3 = str.charCodeAt(i++) & 0xFF - if (c3 == 61) + if (c3 === 61) return out c3 = base64DecodeChars[c3] - } while (i < len && c3 == -1) - if (c3 == -1) + } while (i < len && c3 === -1) + if (c3 === -1) break + out += String.fromCharCode(((c2 & 0xF) << 4) | ((c3 & 0x3C) >> 2)) + /* c4 */ do { c4 = str.charCodeAt(i++) & 0xFF - if (c4 == 61) + if (c4 === 61) return out c4 = base64DecodeChars[c4] - } while (i < len && c4 == -1) - if (c4 == -1) + } while (i < len && c4 === -1) + if (c4 === -1) break + out += String.fromCharCode(((c3 & 0x03) << 6) | c4) } + return out }