فهرست منبع

公式解析添加对更多的数学符号和希腊字母的支持

shmily1213 1 روز پیش
والد
کامیت
a97d8a163d
1فایلهای تغییر یافته به همراه101 افزوده شده و 10 حذف شده
  1. 101 10
      src/composables/useExam.ts

+ 101 - 10
src/composables/useExam.ts

@@ -42,9 +42,6 @@ export const decodeHtmlEntities = (str: string): string => {
     'atilde': 'ã',
     'otilde': 'õ',
     // 其他常用实体
-    'amp': '&',
-    'lt': '<',
-    'gt': '>',
     'quot': '"',
     'apos': "'",
     'nbsp': '\u00A0',
@@ -55,13 +52,105 @@ export const decodeHtmlEntities = (str: string): string => {
     'ndash': '–',
     'hellip': '…',
     // 数学符号
+    'amp': '&',
     'times': '×',
     'divide': '÷',
     'plusmn': '±',
+    'deg': '°',
+    'radic': '√',
+    'isin': '∈',
+    'infin': '∞',
+    'there4': '∴',
+    'because': '∵',
+    'forall': '∀',
+    'exists': '∃',
+    'nexists': '∄',
+    'notin': '∉',
+    'ni': '∋',
+    'prod': '∏',
+    'sum': '∑',
+    'prop': '∝',
+    'sim': '∼',
+    'simeq': '≃',
+    'approx': '≈',
+    'neq': '≠',
+    'equiv': '≡',
+    'ne': '≠',
+    'le': '≤',
+    'ge': '≥',
+    'll': '≪',
+    'gg': '≫',
+    'prec': '≺',
+    'succ': '≻',
+    'preceq': '≼',
+    'succeq': '≽',
+    'subset': '⊂',
+    'supset': '⊃',
+    'subseteq': '⊆',
+    'supseteq': '⊇',
+    'perp': '⊥',
+    'parallel': '∥',
+    'wedge': '∧',
+    'vee': '∨',
+    'cap': '∩',
+    'cup': '∪',
+    'int': '∫',
+    'oint': '∮',
+    'angle': '∠',
+    'mid': '∣',
+    'vdash': '⊢',
+    'dashv': '⊣',
+    'models': '⊨',
+    'vDash': '⊩',
+    'Vdash': '⊫',
+    'VDash': '⊬',
+    // 希腊字母
+    'alpha': 'α',
+    'beta': 'β',
+    'gamma': 'γ',
+    'delta': 'δ',
+    'epsilon': 'ε',
+    'zeta': 'ζ',
+    'eta': 'η',
+    'theta': 'θ',
+    'iota': 'ι',
+    'kappa': 'κ',
+    'lambda': 'λ',
+    'mu': 'μ',
+    'nu': 'ν',
+    'xi': 'ξ',
+    'omicron': 'ο',
+    'pi': 'π',
+    'rho': 'ρ',
+    'sigma': 'σ',
+    'tau': 'τ',
+    'upsilon': 'υ',
+    'phi': 'φ',
+    'chi': 'χ',
+    'psi': 'ψ',
+    'omega': 'ω',
+    'thetasym': 'ϑ',
+    'upsih': 'ϒ',
+    'piv': 'ϖ',
   };
 
   let result = str;
 
+  // 清除所有的特殊空格实体
+  result = result.replaceAll("&zwj;", "")
+    .replaceAll("&nbsp;", "")
+    .replaceAll("&zwnj;", "")
+    .replaceAll("&thinsp;", "")
+    .replaceAll("&emsp;", "")
+    .replaceAll("&ensp;", "")
+    .replaceAll("&#8203;", "");
+
+  // 0. 保护真正的 HTML 标签,转义文本中的 < 和 >
+  // 策略:< 后面如果不是字母或 /(标签开始),则转义为 &lt;
+  // 这样可以处理 x<2、1<x<5 等数学表达式
+  // result = result.replace(/<(?![a-zA-Z/])/g, '&lt;');  // < 后面不是字母或 / 的转义
+  // result = result.replace(/(?<![a-zA-Z0-9])>/g, '&gt;'); // > 前面不是字母数字的转义(避免破坏标签)
+
   // 1. 处理非标准的上标实体:&sup数字; → <sup>数字</sup>
   // 例如:&sup2; → <sup>2</sup>, &sup123; → <sup>123</sup>
   result = result.replace(/&sup(\d+);/gi, (match, digits) => {
@@ -74,8 +163,9 @@ export const decodeHtmlEntities = (str: string): string => {
     return `<sub>${digits}</sub>`;
   });
 
-  // 3. 处理标准命名实体(如 &iacute;)
-  result = result.replace(/&([a-z]+);/gi, (match, entity) => {
+  // 3. 处理标准命名实体(如 &iacute;、&there4;)
+  // 注意:正则需要支持字母和数字的组合
+  result = result.replace(/&([a-z0-9]+);/gi, (match, entity) => {
     const lowerEntity = entity.toLowerCase();
     if (entityMap[lowerEntity]) {
       return entityMap[lowerEntity];
@@ -456,12 +546,12 @@ export const useExam = () => {
   // 开始计时
   const startTiming = () => {
     startCount();
-    
+
     // 记录开始时间戳(毫秒)
     if (practiceStartTime === 0) {
       practiceStartTime = performance.now();
     }
-    
+
     // 使用 requestAnimationFrame 更新显示,更流畅且性能更好
     const updatePracticeDuration = () => {
       if (practiceStartTime > 0) {
@@ -472,20 +562,20 @@ export const useExam = () => {
         animationFrameId = requestAnimationFrame(updatePracticeDuration);
       }
     };
-    
+
     // 开始动画帧循环
     animationFrameId = requestAnimationFrame(updatePracticeDuration);
   }
   // 停止计时
   const stopTiming = () => {
     stopCount();
-    
+
     // 取消动画帧
     if (animationFrameId !== null) {
       cancelAnimationFrame(animationFrameId);
       animationFrameId = null;
     }
-    
+
     // 如果正在计时,累加经过的时间
     if (practiceStartTime > 0) {
       const elapsed = (performance.now() - practiceStartTime) / 1000;
@@ -586,6 +676,7 @@ export const useExam = () => {
     const transerQuestion = (item: Study.ExamineeQuestion, index: number): Study.Question => {
       return {
         ...item,
+        title: decodeHtmlEntities(item.title || ''),
         // 处理没有题型的大题,统一作为阅读题
         typeId: (item.typeId === null || item.typeId === undefined) ? EnumQuestionType.OTHER : item.typeId,
         answers: item.answers || [],