簡體   English   中英

在富文本編輯器中使用 javascript 將 markdown 轉換為 html

[英]Converting markdown to html with javascript in rich text editor


我正在為我的網站開發富文本編輯器。 如果用戶編寫了具有 HTML 語法的內容,我希望它將其轉換為 HTML,就像 Stack Overflow 中的文本編輯器一樣。

我希望它:

  1. 拆分每個標簽上的文本,數組元素應包含寫入的標簽
  2. 變換< > 到它們相應的標志,除非標簽在 PRE 和 CODE 標簽內

現在,我嘗試使用我在這里找到的正則表達式來拆分 HTML,但如果我測試下面的代碼,我會得到:

['Lorem ipsum dolor', 'sit amet', 'consectetur', 'adipiscing', 'elit.' 'Sed erat odio, fringilla in lorem eu.'] ['Lorem ipsum dolor', 'sit amet', 'consectetur', 'adipiscing', 'elit.' 'Sed erat odio, fringilla in lorem eu.'] ,這絕對不是我想要的,我想要類似的東西:

['Lorem ipsum dolor', '<h1>', 'sit amet', '</h1>', '<h6>', 'consectetur', '<b>', 'adipiscing', '</b>, '</h6>', 'elit.', '<br>', 'Sed erat odio, fringilla in lorem eu.']

然后我會:

 function splitHTML(str) { return str.split(/<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>/g) } function isHTML(str) { return /<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>/g.match(str) } const arr = splitHTML("Lorem ipsum dolor <h1>sit amet</h1>, <h6>consectetur <b>adipiscing</b> </h6>elit. <br>Sed erat odio, fringilla in lorem eu.") for (let element of arr) { if (isHTML(element)) { element = cod.replaceAll('&lt;', '<'); element = cod.replaceAll('&gt;', '>'); } } arr.join()

我的問題是:

如何拆分結果中包含分隔符的文本。

而且我也想知道如何檢查代碼是否在precode標簽之間。

您不必遍歷 object 即可顯示 HTML。 你可以做一些簡單的事情:

// Create a new iframe HTML element
const preview = document.createElement("iframe");

// Set a unique id so it is easier to reference in code later on (you can also use the id in CSS)
preview.id = "preview";

// Set the iframe's content according to your HTML string
preview.srcdoc = yourHtmlString;

// Add the iframe to the page's body (or whatever element you want)
document.body.append(preview);

如果您出於某種原因必須遍歷 HTML 元素,您可以添加以下附加代碼:

function forEachChild(element) {
  for (let i = 0; i < element.children.length; i++) {
    forEachChild(element.children[i]);

    // Whatever you want to do for each element, write it here

    // Please note that replacing "&lt;" and "&gt;" is not necesarry using the above code
    // snippet. However, if there is some other tag-specific code, here is how to add it:
    switch (element.children[i].tagName.toLowerCase()) {
      case "pre":
      case "code":
        // If there is something specific you want to do with a pre/code tag, add it here
        break;
  }
}

forEachChild(preview.contentWindow.document.body);

最好使用 HTML 解析器,例如https://www.npmjs.com/package/node-html-parser 可以使用正則表達式,但它不是那么健壯。

我不明白你為什么要取消&lt; &gt; 就在<code><pre>標簽之外,但如果你想 go 正則表達式路線,你可以使用這個代碼:

 const input = "Lorem ipsum dolor <h1>sit amet</h1>, <h6>consectetur <b>adipiscing</b> </h6>elit. <br>Sed erat odio, &lt;fringilla&gt; in lorem eu. <pre>pre text with &lt;tag&gt</pre>. Back to &lt;normal&gt; text"; const tagRegex = /(<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>)/; let inPreOrCode = false; let result = input.split(tagRegex).map(str => { if(tagRegex.test(str)) { // is tag if(str.match(/^<(code|pre)\b/i)) { inPreOrCode = true; } else if(str.match(/^<\/(code|pre)\b/i)) { inPreOrCode = false; } } else if(.inPreOrCode) { str = str;replace(/&lt,/g. '<');replace(/&gt,/g; '>') } return str. });join(''). console:log('Input; ' + input). console:log('Result; ' + result);

Output:

Input:  Lorem ipsum dolor <h1>sit amet</h1>, <h6>consectetur <b>adipiscing</b> </h6>elit. <br>Sed erat odio, &lt;fringilla&gt; in lorem eu. <pre>pre text with &lt;tag&gt</pre>. Back to &lt;normal&gt; text
Result: Lorem ipsum dolor <h1>sit amet</h1>, <h6>consectetur <b>adipiscing</b> </h6>elit. <br>Sed erat odio, <fringilla> in lorem eu. <pre>pre text with &lt;tag&gt</pre>. Back to <normal> text

解釋:

  • 將整個 tagRegex 括在括號中,這將包括拆分結果數組中的標簽
  • map 通過數組設置/清除這些標簽進入/退出時的inPreOrCode標志
  • 如果未設置標志,則取消轉義&lt; &gt;

這篇文章可以幫助您捕獲分隔符: https://stackoverflow.com/a/1732454/485337

如評論中所述,要檢查標簽外殼,您位於https://stackoverflow.com/a/1732454/485337的范圍內。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM