Skip to content

Commit

Permalink
fix: marks and bold replacements errors
Browse files Browse the repository at this point in the history
  • Loading branch information
terwer committed Apr 10, 2024
1 parent 10b37c1 commit 27d43dd
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 95 deletions.
5 changes: 3 additions & 2 deletions src/adaptors/base/baseExtendApi.ts
Expand Up @@ -298,14 +298,15 @@ class BaseExtendApi extends WebApi implements IBlogApi, IWebApi {
// #691 闪卡标记渲染成Markdown之后去除==
// md = md.replace(/==([^=]+)==/g, '<span style="font-weight: bold;" class="mark">$1</span>')
// md = MdUtils.replaceSign(md, "=", "mark", "color: red;")
md = MdUtils.replaceSignToAnother(md, "=", "*", "*")
// md = MdUtils.replaceSignToAnother(md, "=", "*", "*")
md = MdUtils.replaceSignToAnother(md, "==", "**", "**")

// 处理加粗
// #821 html发布的时候会出现有些格式没有转化
// **这里是加粗**
// <span data-type="strong">这里是加粗</span>
// md = md.replace(/\*\*(.*?)\*\*/g, '<span style="font-weight: bold;" data-type="strong">$1</span>')
md = MdUtils.replaceSign(md, "\\*", "bold", "font-weight: bold;")
md = MdUtils.replaceSignToAnother(md, "**", " **", "** ")

// 处理外链
const { getReadOnlyPublishPreferenceSetting } = usePreferenceSettingStore()
Expand Down
56 changes: 46 additions & 10 deletions src/utils/mdUtils.spec.ts
Expand Up @@ -28,26 +28,62 @@ import { MdUtils } from "~/src/utils/mdUtils.ts"

describe("test mdUtils", () => {
it("test replaceSign", () => {
const text = `# 测试 23
const content = `
## 核心要点
csdn测试2
daima\`vdvd==sdcdsc==sdcd\`​
\`\`\`js
sdvsdv=sdcdscds==dsvdsvsd==
==sdvdsv==
sdvdsvsv==dsvs==
sdvdsvd**sdvsdv**==
sdfdsfdsf
\`\`\`
这是公式
$aaa==bbb==sdvfdvf**dsvfdv**$​
$$
E=mc2 ==dfd== vfvfvdvdfdfvfdvf**dvf**vdfvdfdv
$$
​![image](https://pic4.zhimg.com/v2-23281fd6a2541c5e37024d691911da18)​
* 自定义持久层框架的核心要点是什么?
1. 解析配置文件
==这里再看==看**加粗**能用不
* 数据库配置信息
* sql **的**封装
2. 构建 SqlSessionFactory,注==意这里的 openS==ession 方法
3. 拿到 SqlSesion
啊啊啊啊啊
`
* 定义 SqlSession 基**本方**法,水**电费**。
* 封装具体的执行**逻辑**,Executor
Execute 的 query 方法就对应 jdbc 操作
* 优化,使用 JDK 动态**代理**避免 st**atem**entId 的硬编码
4. 将 SqlSession 的操作封装到 DAO 层
`
let md = content
md = MdUtils.replaceSignToAnother(md, "==", " **", "** ")
const result = md
console.log(result)
})

it("test replaceSignToAnother2", () => {
const text = "这是一个示例文本,包含标记符号 ==标记文字==,需要替换为开头和结尾的内容。$A$ 这里是另一个示例 ==。"
const processedText = MdUtils.replaceSignToAnother(text, "==", "**", "**")
console.log(processedText)
})

const replacedText = MdUtils.replaceSign(text, "=", "mark", "color: red;")
console.log(replacedText)
it("test replaceSignToAnother3", () => {
const text = "这是一个示例文本,包含标记符号**test**,需要替换为开头和结尾的内容。$A$ 这里是另一个示例 **。"
const processedText = MdUtils.replaceSignToAnother(text, "**", " **", "** ")
console.log(processedText)
})
})
87 changes: 40 additions & 47 deletions src/utils/mdUtils.ts
Expand Up @@ -31,59 +31,52 @@
* @version 1.21.0
*/
class MdUtils {
// 创建正则表达式,匹配标记符号开头和结尾的内容,假设这个内容为 A,,那么排除行内公式、多行公式、行内代码和多行代码里面的 A
// 要求:
// 1、开头前面不是反引号 `
// 2、开头前面不是三个反引号 + 任意字符(包括换行)
// 3、开头前面不是 $ + 任意字符
// 4、开头前面不是 $$ + 任意字符(包括换行)
// 4、结尾后面不是 任意字符)+反引号 `
// 4、结尾后面不是 任意字符(包括换行)+三个反引
// 4、结尾后面不是 任意字符(包括换行)+$$
// 4、结尾后面不是 任意字符)+$
/**
* 替换标记
* 该正则表达式用于匹配指定标记符号之间的内容,并且在匹配时考虑了特定的限制条件。在匹配时,会确保标记符号前后不是特定的字符,同时也会避免匹配到特定的字符条件之后。
*
* @param text 文本
* @param sign 标记符号,例如:=、\*
* @param open 起始字符
* @param close 结束字符
*/
public static replaceSignToAnother(text: string, sign: string, open: string, close: string): string {
const regex = new RegExp("``[^`]*``|" + sign + "[^" + sign + "]*?" + sign + "|`[^`]*`", "g")
let inCodeBlock = false
let result = ""
let lastIndex = 0

text.replace(regex, ((match: string, index: number) => {
if (match.startsWith("``")) {
inCodeBlock = !inCodeBlock
} else if (!inCodeBlock && (match.startsWith(sign) || match.startsWith("`"))) {
result += text.slice(lastIndex, index) + `${open}${match.slice(1, -1)}${close}`
lastIndex = index + match.length
}
}) as any)

result += text.slice(lastIndex)
return result
}

/**
* 替换标记
* 针对 sign 为 == 和 ** 的情况,我们需要特殊处理 * 字符。由于 * 在正则表达式中有特殊含义,需要进行转义处理。
*
* 以下是每个字符的详细解释:
*
* @param text 文本
* @param sign 标记符号,例如:=、\*
* @param className 类名
* @param style css 样式
* (?<!\): 负向后行断言,确保匹配的内容前面不是反引号(`)。
* (?<!\``[\s\S])`: 负向后行断言,确保匹配的内容前面不是三个反引号后跟任意字符(包括换行)。
* (?<!\$[\s\S]): 负向后行断言,确保匹配的内容前面不是 $ 后跟任意字符(包括换行)。
* ${escapedSign}: 匹配转义后的标记符号。
* (.*?[^${escapedSign}]): 非贪婪匹配任意字符,直到遇到不是标记符号的字符。
* ${escapedSign}: 匹配转义后的标记符号。
* (?![\s\S]*?\): 负向前行断言,确保匹配的内容后面不是反引号(`)。
* (?![\s\S]*?\``)`: 负向前行断言,确保匹配的内容后面不是三个反引号。
* (?![\s\S]*?\$): 负向前行断言,确保匹配的内容后面不是 $。
* (?![\s\S]*?\$\$): 负向前行断言,确保匹配的内容后面不是两个 $。
*
* @param {string} text - 待处理的文本
* @param {string} sign - 要替换的标记符号
* @param {string} open - 替换后的开头内容
* @param {string} close - 替换后的结尾内容
* @returns {string} 处理后的文本
*/
public static replaceSign(text: string, sign: string, className: string, style: string): string {
const regex = new RegExp("``[^`]*``|" + sign + "[^" + sign + "]*?" + sign + "|`[^`]*`", "g")
let inCodeBlock = false
let result = ""
let lastIndex = 0
public static replaceSignToAnother(text: string, sign: string, open: string, close: string): string {
// 对于 * 字符进行转义处理
const escapedSign = sign.replace(/\*/g, "\\*")

text.replace(regex, ((match: string, index: number) => {
if (match.startsWith("``")) {
inCodeBlock = !inCodeBlock
} else if (!inCodeBlock && (match.startsWith(sign) || match.startsWith("`"))) {
result +=
text.slice(lastIndex, index) + `<span class="${className}" style="${style}">${match.slice(1, -1)}</span>`
lastIndex = index + match.length
}
}) as any)
const regex = new RegExp(
`(?<!\`)(?<!\`\`\`[\s\S])(?<!\$[\s\S])${escapedSign}(.*?[^${escapedSign}])${escapedSign}(?![\s\S]*?\`)(?![\s\S]*?\`\`\`)(?![\s\S]*?\$)(?![\s\S]*?\$\$)`,
"g"
)

result += text.slice(lastIndex)
return result
return text.replace(regex, (match, group) => {
return `${open}${group}${close}`
})
}
}

Expand Down
75 changes: 39 additions & 36 deletions vite.config.ts
Expand Up @@ -148,20 +148,23 @@ export default defineConfig(() => ({
},
}),

// {
// name: "add-query-param",
// transformIndexHtml(html) {
// const timestamp = Date.now()
// html = html.replace(/(<script.+src=")([^"]+\.js)"/g, `$1$2?v=${timestamp}"`)
// html = html.replace(/(<link[^>]+href=")([^"]+(\.css|\.js))"/g, (match, p1, p2) => `${p1}${p2}?v=${timestamp}"`)
// // html = html.replace(/(<link rel=")modulepreload(" crossorigin href=")([^"]+\.js)"/g, `$1preload$2$3?v=${timestamp}"`);
// html = html.replace(/(<link rel=")modulepreload(" crossorigin href=")([^"]+\.js)"/g, `$1preload$2$3?v=${timestamp}" as="script"`);
// html = html.replace(/(<link[^>]+href=")([^"]+(\.css))"/g, (match, p1, p2) => `${p1}${p2}?v=${timestamp}"`)
// html = html.replace(/(<link[^>]+href=")([^"]+\.svg)"/g, `$1$2?v=${timestamp}"`)
// html = html.replace(/(<img[^>]+src=")([^"]+\.(jpe?g|gif|webp|bmp|png))"/g, `$1$2?v=${timestamp}"`)
// return html
// },
// },
{
name: "add-query-param",
transformIndexHtml(html) {
const timestamp = Date.now()
html = html.replace(/(<script.+src=")([^"]+\.js)"/g, `$1$2?v=${timestamp}"`)
html = html.replace(/(<link[^>]+href=")([^"]+(\.css|\.js))"/g, (match, p1, p2) => `${p1}${p2}?v=${timestamp}"`)
// html = html.replace(/(<link rel=")modulepreload(" crossorigin href=")([^"]+\.js)"/g, `$1preload$2$3?v=${timestamp}"`);
html = html.replace(
/(<link rel=")modulepreload(" crossorigin href=")([^"]+\.js)"/g,
`$1preload$2$3?v=${timestamp}" as="script"`
)
html = html.replace(/(<link[^>]+href=")([^"]+(\.css))"/g, (match, p1, p2) => `${p1}${p2}?v=${timestamp}"`)
html = html.replace(/(<link[^>]+href=")([^"]+\.svg)"/g, `$1$2?v=${timestamp}"`)
html = html.replace(/(<img[^>]+src=")([^"]+\.(jpe?g|gif|webp|bmp|png))"/g, `$1$2?v=${timestamp}"`)
return html
},
},

// 在浏览器中polyfill node
// https://github.com/davidmyersdev/vite-plugin-node-polyfills/blob/main/test/src/main.ts
Expand Down Expand Up @@ -227,28 +230,28 @@ export default defineConfig(() => ({
// make sure to externalize deps that shouldn't be bundled into your library
external: [],

// output: {
// // add a query parameter to all JS and CSS file URLs
// chunkFileNames: "chunks/chunk.[name].js",
// entryFileNames: "entry.[name].js",
// assetFileNames: "assets/[name].[ext]",
// // manualChunks(id) {
// // if (id.includes("node_modules")) {
// // let arr = id.toString().split("node_modules/")[1].split("/")
// // // pnpm单独处理
// // if (id.includes(".pnpm")) {
// // arr = id.toString().split(".pnpm/")[1].split("/")
// // }
// // const dep = arr[0].split("@")[0].replace(/\./g, "-")
// // // console.log("id=>", id)
// // // console.log("dep=>", dep)
// // if (dep !== "") {
// // return "vendor_" + dep
// // }
// // return "vendor"
// // }
// // },
// },
output: {
// add a query parameter to all JS and CSS file URLs
chunkFileNames: "chunks/chunk.[name].js",
entryFileNames: "entry.[name].js",
assetFileNames: "assets/[name].[ext]",
manualChunks(id) {
if (id.includes("node_modules")) {
let arr = id.toString().split("node_modules/")[1].split("/")
// pnpm单独处理
if (id.includes(".pnpm")) {
arr = id.toString().split(".pnpm/")[1].split("/")
}
const dep = arr[0].split("@")[0].replace(/\./g, "-")
// console.log("id=>", id)
// console.log("dep=>", dep)
if (dep !== "") {
return "vendor_" + dep
}
return "vendor"
}
},
},
},
},

Expand Down

0 comments on commit 27d43dd

Please sign in to comment.