实时转换marked生成的结构中的latex为公式-mathjax v3

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<meta http-equiv="x-ua-compatible" content="ie=edge">
		<meta name="viewport" content="width=device-width">
		<title>MathJax v3 with TeX input and HTML output</title>
		<link rel="stylesheet" href="prism.css" />
		<style>
			code {
				font-size: 0.875em;
				color: #d63384;
				word-wrap: break-word;
			}

			body {
				background-color: #f1f1f1;
			}

			.diff {
				background: #ffffff;
				width: 800px;
				height: auto;
				padding: 10px 20px;
				margin: 0 auto;
			}
		</style>
		<script>
			MathJax = {
				tex: {
					inlineMath: [
						['$', '$'],
						['\\(', '\\)']
					],
					displayOverflow: 'linebreaks', // 允许缩放以进行换行
					displayWidth: 'container', // 自动选择容器宽度
					linebreaks: {
						width: '90%'
					} // 设置行宽
				},
				options: {
					// 禁用公式操作面板
					enableMenu: false
				}
			};
		</script>
		<script id="MathJax-script" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script>
		<script src="marked.js"></script>
		<script src="prism.js"></script>
		<script src="diffDOM.js"></script>
		<script src="jquery.js"></script>
	</head>
	<body>
		<div class="diff"></div>
	</body>
</html>
<script type="text/javascript">
	let domdiff = new diffDOM()
	// let str =  "常用的数学公式包括各种数学领域的重要表达式。以下是一些经典的数学公式:\n\n1. **代数公式:**\n   - 二次公式:求解 $ax^2 + bx + c = 0$ 的根:\n     $$\n     x = \\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}\n     $$\n   - 乘法公式:两个数的展开:\n     $$\n     (a + b)^2 = a^2 + 2ab + b^2\n     $$\n     $$\n     (a - b)^2 = a^2 - 2ab + b^2\n     $$\n     $$\n     (a + b)(a - b) = a^2 - b^2\n     $$\n\n2. **几何公式:**\n   - 圆的面积:\n     $$\n     A = \\pi r^2\n     $$\n   - 圆的周长:\n     $$\n     C = 2\\pi r\n     $$\n   - 直角三角形中,勾股定理:\n     $$\n     a^2 + b^2 = c^2\n     $$\n\n3. **微积分公式:**\n   - 导数:如果 $f(x)$ 是一个函数,则其导数 $f'(x)$ 是:\n     $$\n     f'(x) = \\lim_{\\Delta x \\to 0} \\frac{f(x + \\Delta x) - f(x)}{\\Delta x}\n     $$\n   - 不定积分(反导数):找到函数 $F(x)$,使得 $F'(x) = f(x)$:\n     $$\n     \\int f(x) \\, dx = F(x) + C\n     $$\n   - 定积分:求函数在区间 $[a, b]$ 上的面积:\n     $$\n     \\int_{a}^{b} f(x) \\, dx = F(b) - F(a)\n     $$\n\n4. **概率和统计公式:**\n   - 正态分布概率密度函数:\n     $$\n     f(x) = \\frac{1}{\\sigma\\sqrt{2\\pi}} e^{-\\frac{(x - \\mu)^2}{2\\sigma^2}}\n     $$\n   - 均值:\n     $$\n     \\bar{x} = \\frac{1}{n}\\sum_{i=1}^{n} x_i\n     $$\n   - 方差:\n     $$\n     \\sigma^2 = \\frac{1}{n}\\sum_{i=1}^{n} (x_i - \\bar{x})^2\n     $$\n\n5. **数列与级数:**\n   - 等差数列的第 $n$ 项与和:\n     $$\n     a_n = a_1 + (n-1)d\n     $$\n     $$\n     S_n = \\frac{n}{2}(a_1 + a_n)\n     $$\n   - 等比数列的第 $n$ 项与和:\n     $$\n     a_n = a_1 \\cdot r^{n-1}\n     $$\n     $$\n     S_n = a_1 \\frac{1 - r^n}{1 - r} \\quad (r \\neq 1)\n     $$\n\n这些公式在数学中具有广泛的应用和重要性。根据具体的数学领域和问题,可能会涉及到更多的专门公式。"
	// let str = "能力矩阵是一种有用的工具,用于系统地评估和分析个体或团队在多个关键能力或技能维度上的表现。为了构建一个有效的测试能力矩阵,您可以遵循以下步骤和指导方针:\n\n### 1. 确定评估维度\n\n首先,确定您希望评估的关键能力或技能。这些维度通常与行业标准、组织目标或角色要求密切相关。例如,在软件工程团队中,可能包括以下几个维度:\n\n- 编程技能\n- 项目管理\n- 沟通能力\n- 问题解决能力\n\n### 2. 定义能力级别\n\n为每个维度定义评估标准。标准可以是定性的(例如,基础、中级、熟练、专家)或定量的(例如,1到5的评分)。\n\n### 3. 选定评估对象\n\n选择需要测试的个体或团队,确保他们在被评估的领域中能够实际应用相关技能。\n\n### 4. 收集数据\n\n通过各种方法收集关于评估对象在每个维度上的表现数据。这些方法包括:\n\n- 客观测试和测验\n- 行为观察\n- 半结构化访谈\n- 绩效评估文档\n\n### 5. 评分并矩阵化\n\n根据收集的数据,将每个对象的能力表现进行评分,然后将结果以矩阵形式呈现,以便进行比较和分析。这种矩阵可以以表格形式展现。\n\n#### 示例能力矩阵\n\n以下是一个简单的能力矩阵示例:\n\n| 能力/技能    | 评估对象1 | 评估对象2 | 评估对象3 |\n|--------------"
	let str = "实现一个简单的轮播图效果可以使用JavaScript、HTML和CSS组合来完成。下面是一个基本的示例,展示了如何通过JavaScript定时器来自动切换图片。\n\n### HTML\n\n```html\n<div class=\"carousel\">\n  <div class=\"carousel-images\">\n    <img src=\"image1.jpg\" alt=\"Image 1\" />\n    <img src=\"image2.jpg\" alt=\"Image 2\" />\n    <img src=\"image3.jpg\" alt=\"Image 3\" />\n  </div>\n</div>\n```\n\n### CSS\n\n```css\n.carousel {\n  width: 300px;\n  overflow: hidden;\n  position: relative;\n}\n\n.carousel-images {\n  display: flex;\n  transition: transform 0.5s ease-in-out;\n}\n\n.carousel-images img {\n  width: 300px;\n  height: 200px;\n}\n```\n\n### JavaScript\n\n```javascript\nconst carouselImages = document.querySelector('.carousel-images');\nconst images = document.querySelectorAll('.carousel-images img');\nlet index = 0;\n\nfunction showNextImage() {\n  index++;\n  if (index >= images.length) {\n    index = 0;\n  }\n  // Calculate the offset to slide the images\n  const offset = -index * 300; // The width of each image\n  carouselImages.style.transform = `translateX(${offset}px)`;\n}\n\n// Set the interval to switch images every 3 seconds\nsetInterval(showNextImage, 3000);\n```\n\n### 说明\n\n1. **HTML部分**定义了一个容器`.carousel`,其中子元素`.carousel-images`包裹了多张图片。\n2. **CSS部分**设置了容器的大小,以及将图片横向并排。通过`overflow: hidden;`确保溢出的图片不会显示。\n3. **JavaScript部分**实现了图片的自动切换。使用`setInterval`函数每3秒切换到下一张图片。通过改变`.carousel-images`的位置实现图片切换,利用CSS的`transition`属性来平滑变换。\n\n这种方法适用于简单的轮播图效果,如果需要更多功能(如上一张/下一张按钮或指示器圆点),需要进一步扩展JavaScript代码和HTML/CSS样式。"
	// let str = "能力矩阵”通常是企业或组织用于评估员工技能和能力的工具。在这种矩阵中,通常列出了一组关键能力和技能,然后对每位员工进行评估,标记他们所具备的各项能力。\n\n能力矩阵的结构通常包括以下元素:\n\n1. **列头**:表示各种关键能力或技能。这些可以是技术能力、软技能、管理能力等。\n2. **行头**:表示组织中的员工或持有特定角色的人。\n3. **评分**:在矩阵的内部,每个单元格通常包含一个评分,用于表示该员工在该能力上的水平。评分可能是定性的(如“初级”、“中级”、“高级”)或定量的(如1到5的评分)。\n\n一个简单的能力矩阵示例如下:\n\n| 员工/能力   | 技术能力 | 沟通能力 | 领导能力 |\n|-------------|----------|----------|----------|\n| 员工A       | 中级     | 高级     | 初级     |\n| 员工B       | 初级     | 中级     | 中级     |\n| 员工C       | 高级     | 初级     | 高级     |\n\n能力矩阵的用途包括但不限于:\n- **识别培训需求**:通过能力矩阵,可以确定每个员工在哪些领域需要进一步的培训和发展。\n- **人才管理与开发**:矩阵可以帮助识别组织内部的人才,对高潜力员工进行重点培养。\n- **项目分配**:根据员工的能力情况,合理分配项目任务,确保各项工作由具备相应能力的员工进行。\n\n这种工具通常是在人力资源管理和组织发展中被广泛采用,以帮助提高团队整体的能力和工作效率。"
	// let str = "YAML 文件在设计上是为了表示简单的数据结构,并且通常用于配置文件。它支持以下主要数据类型:\n\n1. **标量(Scalars):** 字符串、布尔值、整数、浮点数等。\n2. **列表(Sequences):** 使用连字符“-”列表项。\n3. **字典(Mappings):** 键值对表示。\n\n以下是 YAML 的一些限制或不支持的内容:\n\n1. **循环引用:** YAML 不支持循环引用的数据结构。\n   \n2. **复杂对象:** 虽然 YAML 可以表示基本的数据类型和结构,但它无法直接表示复杂对象或数据结构(如二叉树,图等)。\n\n3. **指令或函数:** YAML 仅用于数据表示,不支持函数或方法的执行。\n\n4. **非字符串键** 如果键不是字符串,通常需要将其转为字符串表示。\n\n5. **注释不支持嵌套:** YAML 支持注释,但不能嵌套注释。\n\n6. **二进制数据:** 需转码(如 Base64)。\n\n如果要将 YAML 用于更复杂的场景,可能需要结合其他工具或语言来实现。"
	// let str =  "Python 中有多种内置的数据类型,每种类型在不同的情况下有不同的用途。以下是一些常见的 Python 数据类型:\n\n1. **整数(Integer)**:\n   - 用于表示整数值。例如:`1`, `42`, `-7`\n   - 没有大小限制,取决于可用内存。\n\n2. **浮点数(Float)**:\n   - 用于表示带有小数点的实数。例如:`3.14`, `-0.001`, `2.0`\n   - 通常使用双精度浮点数格式。\n\n3. **复数(Complex Number)**:\n   - 包含实部和虚部的数字。例如:`3 + 4j`, `5.0 - 2.3j`\n   - 使用 `j` 表示虚数单位。\n\n4. **字符串(String)**:\n   - 用于表示文本数据。例如:`\"hello\"`, `'Python'`, `\"\"\"This is a multi-line string\"\"\"`\n\n5. **布尔值(Boolean)**:\n   - 用于表示真值和假值。只有两个值:`True` 和 `False`\n\n6. **列表(List)**:\n   - 有序的可变集合,可以包含不同类型的数据。例如:`[1, 2, 3]`, `[\"apple\", \"banana\", 1, True]`\n\n7. **元组(Tuple)**:\n   - 有序的不可变集合,可以包含不同类型的数据。例如:`(1, 2, 3)`, `(\"a\", \"b\", 3)`\n\n8. **集合(Set)**:\n   - 无序的、不重复的元素集合。例如:`{1, 2, 3}`, `{\"apple\", \"banana\"}`\n\n9. **字典(Dictionary)**:\n   - 无序的键值对集合。例如:`{\"name\": \"Alice\", \"age\": 30}`\n\n10. **NoneType**:\n    - `None` 是唯一的值,表示空或无值对象。\n\n11. **字节(Bytes)**:\n    - 不可变的字节序列,用于处理二进制数据。例如:`b\"Hello\"`\n\n12. **字节数组(Bytearray)**:\n    - 可变的字节序列,与 `bytes` 类似,但可以被修改。\n\n13. **内存视图(Memoryview)**:\n    - 提供对字节数据的切片访问,而不复制数据。\n\n除了这些基本数据类型,Python 还支持一些高级的数据结构和类型,比如 `frozenset`(不可变集合)、`range`(可用于生成一系列数字的不可变序列)等。不过,上述是使用最广泛的基本数据类型。"
	// let str = "学习Python可以根据你的目标和兴趣来规划学习路径。以下是一个通用的Python学习路线,涵盖了从基础到高级的内容:\n\n### 1. 入门阶段\n\n#### 基础语法\n- **安装Python**: 了解如何在各种操作系统上安装Python。\n- **基本数据类型**: 如整数、浮点数、字符串、列表、元组、字典、集合等。\n- **操作符**: 算术、比较、逻辑和位运算符。\n- **控制结构**: 条件语句(`if`, `elif`, `else`),循环(`for`, `while`)。\n- **函数**: 定义和调用函数,参数传递,返回值。\n\n#### 基础工具\n- **开发环境**: 了解如何使用Jupyter Notebook, PyCharm, 或VS Code等工具编写和运行Python代码。\n- **Python标准库**: 认识一些常用模块如`os`, `sys`, `math`, `datetime`等。\n\n### 2. 中级阶段\n\n#### 数据结构和算法\n- **列表解析**: 高效处理列表的方式。\n- **生成器和迭代器**: 节省内存的迭代方法。\n- **排序与搜索算法**: 理解并实现基础算法。\n\n#### 面向对象编程\n- **类和对象**: 创建类,实例化对象和使用类属性与方法。\n- **继承和多态**: 理解类的继承关系和多态机制。\n- **封装和私有化**: 使用访问修饰符保护数据。\n\n#### 错误和异常处理\n- **异常捕获**: 使用`try`, `except`, `finally`, `raise`来处理异常。\n\n### 3. 高级阶段\n\n#### 模块和包管理\n- **模块导入**: 使用和创建自定义模块。\n- **虚拟环境**: 使用`venv`或`virtualenv`管理包依赖。\n- **第三方库**: 使用`pip`安装和管理外部库。\n\n#### 高级特性\n- **装饰器**: 修改函数行为的高级函数。\n- **上下文管理器**: 使用`with`语句管理资源。\n- **元编程**: 使用`meta`类和反射机制。\n\n### 4. 应用开发\n\n#### Web开发\n- **Django**或**Flask**: 学习使用这些框架构建Web应用。\n\n#### 数据科学与机器学习\n- **NumPy**和**Pandas**: 用于数据处理和分析。\n- **Matplotlib**和**Seaborn**: 数据可视化工具。\n- **Scikit-Learn**: 学习基础的机器学习算法。\n- **TensorFlow**或**PyTorch**: 深入学习框架。\n\n#### 数据库\n- **SQL和NoSQL**: 学习关系型数据库(如MySQL)和非关系型数据库(如MongoDB)。\n- **ORM**: 使用SQLAlchemy或Django ORM管理数据库。\n\n#### 网络编程\n- **Sockets**: 理解基础网络编程。\n- **HTTP请求**: 使用`requests`库进行网络请求。\n\n### 5. 项目和实践\n\n- **个人项目**: 开始一个小项目来应用所学知识。\n- **参与开源**: 在GitHub上寻找感兴趣的开源项目并贡献代码。\n\n### 6. 持续学习\n\n- **阅读文档**: 官方Python文档是非常重要的资源。\n- **社区和论坛**: 加入Python社区如Stack Overflow, Reddit的`learnpython`,以便解决问题和交流经验。\n\n通过以上步骤,以及不断练习和实际应用,你将能够掌握Python并应用于各种领域。记住,学习编程最重要的是动手实践和持续学习。"
	// let str = "Kubernetes 的 Horizonal Pod Autoscaler(HPA)根据集群中 Pod 的资源使用情况自动调整副本的数量。HPA 的核心计算公式是根据指定的指标(如 CPU 或内存使用率)来确定需要多少个 Pod,以达到目标使用率。\n\n假设我们使用 CPU 作为指标,HPA 的计算公式可以表示为:\n\n$$\n\\text{Desired Replicas} = \\left\\lceil \\frac{\\text{Current Total Usage}}{\\text{Target Usage per Pod}} \\right\\rceil\n$$\n\n其中:\n- \\(\\text{Desired Replicas}\\) 是 HPA 计算出的需要的 Pod 数量。\n- \\(\\text{Current Total Usage}\\) 是当前所有 Pod 的总使用量。例如,如果我们有 3 个 Pod,每个 Pod 的 CPU 使用量分别为 50m、60m 和 40m,总使用量就是 150m。\n- \\(\\text{Target Usage per Pod}\\) 是你设定的目标使用率。例如,如果期望 CPU 使用率为 50%,且每个 Pod 配置 200m CPU 资源,则目标是 100m 每 Pod(即 200m \\times 0.5)。\n\n通过这个公式,HPA 能够动态调整 Pod 的数量,以确保集群中资源的高效利用。"
	// let str = "二重积分和三重积分是多重积分的基本形式,用于计算二维和三维区域上的函数的累积。以下是五个常用的二重积分和三重积分公式:\n\n### 二重积分公式\n\n1. **笛卡尔坐标系中的二重积分**\n   - 对于一个在矩形区域 \\( R = [a, b] \\times [c, d] \\) 上的函数 \\( f(x, y) \\),二重积分的计算公式为:\n   $$\n   \\iint_R f(x, y) \\, dx \\, dy = \\int_c^d \\left( \\int_a^b f(x, y) \\, dx \\right) dy\n   $$\n\n2. **极坐标系中的二重积分**\n   - 对于一个在极坐标下表达的函数 \\( f(r, \\theta) \\),在区域 \\( D \\) 内的二重积分为:\n   $$\n   \\iint_D f(r, \\theta) \\, r \\, dr \\, d\\theta = \\int_{\\theta_1}^{\\theta_2} \\left( \\int_{r_1}^{r_2} f(r, \\theta) \\, r \\, dr \\right) d\\theta\n   $$\n\n3. **换序积分法则**\n   - 若 \\( f(x, y) \\) 在 \\( R = [a, b] \\times [c, d] \\) 上连续,则:\n   $$\n   \\iint_R f(x, y) \\, dx \\, dy = \\iint_R f(x, y) \\, dy \\, dx = \\int_a^b \\left( \\int_c^d f(x, y) \\, dy \\right) dx\n   $$\n\n### 三重积分公式\n\n4. **笛卡尔坐标系中的三重积分**\n   - 对于一个在立方体区域 \\( Q = [a, b] \\times [c, d] \\times [e, f] \\) 上的函数 \\( f(x, y, z) \\),三重积分的计算公式为:\n   $$\n   \\iiint_Q f(x, y, z) \\, dx \\, dy \\, dz = \\int_e^f \\left( \\int_c^d \\left( \\int_a^b f(x, y, z) \\, dx \\right) dy \\right) dz\n   $$\n\n5. **柱面坐标系中的三重积分**\n   - 对于一个在柱面坐标系下表达的函数 \\( f(r, \\theta, z) \\),在区域 \\( E \\) 中的三重积分为:\n   $$\n   \\iiint_E f(r, \\theta, z) \\, r \\, dr \\, d\\theta \\, dz = \\int_{z_1}^{z_2} \\left( \\int_{\\theta_1}^{\\theta_2} \\left( \\int_{r_1}^{r_2} f(r, \\theta, z) \\, r \\, dr \\right) d\\theta \\right) dz\n   $$\n\n这些公式在应用时,边界的确定和积分次序的选择需要根据具体问题的区域特性和函数的表达方式来做出调整。"



	let length = 0
	let strNew = ""
	let timer = setInterval(() => {
		length += 10
		if (length > str.length) {
			clearTimeout(timer);
			length = str.length
		}
		printHtml(length)
	}, 1)

	function printHtml(length) {
		// 所有下划线需要转义 否则marked会将它转换成em标签 导致公式渲染失败
		strNew = replaceUnderscoreInDollarString(str.substring(0, length))
		// 通过中间结构处理 防止页面高度频繁变化导致抖动
		let box = $(`<div class="diff">${replaceUnderscoreInDollarString1(marked.marked(strNew))}</div>`)
		MathJax.typesetPromise([box.get(0)]).catch((err) => console.log(err)).then(() => {
			const diff = domdiff.diff(
				$('.diff').get(0), // 更新后的DOM节点
				box.get(0), // 原始DOM节点
			)
			domdiff.apply($('.diff').get(0), diff)
			dealCodeCopy($('.diff'))
		});

	}

	/**
	 * 处理代码块
	 */
	function dealCodeCopy(el) {
		const pre = el.find('pre')
		if (pre) {
			pre.addClass('line-numbers')
			$.each(pre.find('code'), (i, v) => {
				try {
					Prism.highlightElement(v)
				} catch (e) {
					console.error(e.message)
				}
			})
		}
	}
    /**
     * 将公式内的_替换为占位符
     */
    function replaceUnderscoreInDollarString(input) {
		// 使用正则表达式匹配被$符号包裹的字符串
		return input.replace(/\$([^$]+)\$/g, function(match, p1) {
				// p1是被$包裹的内容,需要将下划线替换为你想要的字符,例如替换为空格
				return '$' + p1.replace(/\\_/g, '&#95;').replace(/\_/g, '&#95;').replace(/_/g, '&#95;').replace(/\\int/g, '\\int ').replace(/\hline/g, '\hline\n') + '$';
		});
    }
    /**
     * 将公式内的占位符替换为_
     */
    function replaceUnderscoreInDollarString1(input) {
		// 使用正则表达式匹配被$符号包裹的字符串
		return input.replace(/\$([^$]+)\$/g, function(match, p1) {
				// p1是被$包裹的内容,需要将下划线替换为你想要的字符,例如替换为空格
				return '$' + p1.replace(/&#95;/g, '_') + '$';
	    });
    }
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值