Làm cách nào để phân tích một tập hợp con nhỏ của Markdown thành các thành phần React?


9

Tôi có một tập hợp con Markdown rất nhỏ cùng với một số html tùy chỉnh mà tôi muốn phân tích thành các thành phần React. Ví dụ, tôi muốn chuyển chuỗi sau đây:

hello *asdf* *how* _are_ you !doing! today

Vào mảng sau:

[ "hello ", <strong>asdf</strong>, " ", <strong>how</strong>, " ", <em>are</em>, " you ", <MyComponent onClick={this.action}>doing</MyComponent>, " today" ]

và sau đó trả lại từ chức năng kết xuất React (React sẽ kết xuất mảng đúng như định dạng HTML)

Về cơ bản, tôi muốn cung cấp cho người dùng tùy chọn sử dụng một bộ Markdown rất hạn chế để biến văn bản của họ thành các thành phần được tạo kiểu (và trong một số trường hợp, các thành phần của riêng tôi!)

Thật không khôn ngoan khi nguy hiểm SetInnerHTML và tôi không muốn mang đến sự phụ thuộc bên ngoài, vì tất cả chúng đều rất nặng và tôi chỉ cần chức năng rất cơ bản.

Tôi hiện đang làm một cái gì đó như thế này, nhưng nó rất dễ vỡ và không hoạt động cho tất cả các trường hợp. Tôi đã tự hỏi nếu có một cách tốt hơn:

function matchStrong(result, i) {
  let match = result[i].match(/(^|[^\\])\*(.*)\*/);
  if (match) { result[i] = <strong key={"ms" + i}>{match[2]}</strong>; }
  return match;
}

function matchItalics(result, i) {
  let match = result[i].match(/(^|[^\\])_(.*)_/); // Ignores \_asdf_ but not _asdf_
  if (match) { result[i] = <em key={"mi" + i}>{match[2]}</em>; }
  return match;
}

function matchCode(result, i) {
  let match = result[i].match(/(^|[^\\])```\n?([\s\S]+)\n?```/);
  if (match) { result[i] = <code key={"mc" + i}>{match[2]}</code>; }
  return match;
}

// Very brittle and inefficient
export function convertMarkdownToComponents(message) {
  let result = message.match(/(\\?([!*_`+-]{1,3})([\s\S]+?)\2)|\s|([^\\!*_`+-]+)/g);

  if (result == null) { return message; }

  for (let i = 0; i < result.length; i++) {
    if (matchCode(result, i)) { continue; }
    if (matchStrong(result, i)) { continue; }
    if (matchItalics(result, i)) { continue; }
  }

  return result;
}

Đây là câu hỏi trước đây của tôi dẫn đến câu hỏi này.


1
Điều gì nếu đầu vào có các mục lồng nhau, như thế font _italic *and bold* then only italic_ and normalnào? Kết quả mong đợi là gì? Hay nó sẽ không bao giờ được lồng nhau?
trincot

1
Không cần phải lo lắng về việc làm tổ. Nó chỉ là đánh dấu rất cơ bản cho người dùng sử dụng. Bất cứ điều gì là dễ dàng nhất để thực hiện là tốt với tôi. Trong ví dụ của bạn, sẽ hoàn toàn ổn nếu phần bên trong không hoạt động. Nhưng nếu việc thực hiện lồng nhau dễ dàng hơn là không có nó thì cũng không sao.
Ryan Peschel

1
Có lẽ dễ dàng nhất là chỉ sử dụng một giải pháp sẵn có như npmjs.com/package/react-markdown-it
mb21

1
Tôi không sử dụng markdown mặc dù. Nó chỉ là một tập hợp con rất giống / nhỏ của nó (hỗ trợ một vài thành phần tùy chỉnh, cùng với chữ in đậm không in nghiêng, chữ nghiêng, mã, gạch chân). Đoạn trích tôi đã đăng một số công việc, nhưng có vẻ không lý tưởng lắm, và thất bại trong một số trường hợp tầm thường, (như bạn không thể gõ một dấu sao như thế này: asdf*mà không biến mất)
Ryan Peschel

1
tốt ... phân tích cú pháp đánh dấu hoặc một cái gì đó như đánh dấu không chính xác là một nhiệm vụ dễ dàng ... regexes không cắt nó ... cho một câu hỏi tương tự liên quan đến html, xem stackoverflow.com/questions/1732348/,
mb21

Câu trả lời:


1

Làm thế nào nó hoạt động?

Nó hoạt động bằng cách đọc một chuỗi chunk bởi chunk, đây có thể không phải là giải pháp tốt nhất cho các chuỗi thực sự dài.

Bất cứ khi nào trình phân tích cú pháp phát hiện một đoạn quan trọng đang được đọc, tức là '*'hoặc bất kỳ thẻ đánh dấu nào khác, nó sẽ bắt đầu phân tích cú pháp các phần tử này cho đến khi trình phân tích cú pháp tìm thấy thẻ đóng của nó.

Nó hoạt động trên các chuỗi nhiều dòng, xem mã chẳng hạn.

Hãy cẩn thận

Bạn chưa chỉ định hoặc tôi có thể hiểu sai nhu cầu của bạn, nếu cần phải phân tích các thẻ vừa in đậm vừa in nghiêng , giải pháp hiện tại của tôi có thể không hoạt động trong trường hợp này.

Tuy nhiên, nếu bạn cần làm việc với các điều kiện trên, chỉ cần bình luận ở đây và tôi sẽ điều chỉnh mã.

Cập nhật đầu tiên: điều chỉnh cách xử lý thẻ markdown

Các thẻ không còn được mã hóa cứng, thay vào đó chúng là một bản đồ nơi bạn có thể dễ dàng mở rộng để phù hợp với nhu cầu của mình.

Đã sửa các lỗi bạn đã đề cập trong các nhận xét, cảm ơn vì đã chỉ ra vấn đề này = p

Cập nhật thứ hai: thẻ đánh dấu nhiều chiều dài

Cách dễ nhất để đạt được điều này: thay thế ký tự nhiều chiều dài bằng một unicode hiếm khi được sử dụng

Mặc dù phương thức parseMarkdownnày chưa hỗ trợ các thẻ nhiều độ dài, nhưng chúng ta có thể dễ dàng thay thế các thẻ nhiều độ dài đó một cách đơn giản string.replace khi gửi rawMarkdownprop của chúng tôi .

Để xem một ví dụ về điều này trong thực tế, hãy nhìn vào ReactDOM.render, nằm ở cuối mã.

Thậm chí nếu ứng dụng của bạn không hỗ trợ nhiều ngôn ngữ, có các ký tự unicode không hợp lệ mà JavaScript vẫn phát hiện, ex .: "\uFFFF"chưa là unicode hợp lệ, nếu tôi nhớ chính xác, nhưng JS vẫn sẽ có thể so sánh nó ( "\uFFFF" === "\uFFFF" = true)

Ban đầu có vẻ như hack-y, nhưng tùy thuộc vào trường hợp sử dụng của bạn, tôi không thấy bất kỳ vấn đề lớn nào khi sử dụng tuyến đường này.

Một cách khác để đạt được điều này

Chà, chúng ta có thể dễ dàng theo dõi đoạn cuối N(trong đó Ntương ứng với độ dài của các đoạn nhiều chiều dài nhất).

Sẽ có một số điều chỉnh được thực hiện theo cách vòng lặp bên trong phương thức parseMarkdownhoạt động, tức là kiểm tra xem đoạn hiện tại có phải là một phần của thẻ nhiều độ dài hay không, nếu nó được sử dụng làm thẻ; mặt khác, trong các trường hợp như ``k, chúng ta cần đánh dấu nó là notMultiLengthhoặc một cái gì đó tương tự và đẩy đoạn đó thành nội dung.

// Instead of creating hardcoded variables, we can make the code more extendable
// by storing all the possible tags we'll work with in a Map. Thus, creating
// more tags will not require additional logic in our code.
const tags = new Map(Object.entries({
  "*": "strong", // bold
  "!": "button", // action
  "_": "em", // emphasis
  "\uFFFF": "pre", // Just use a very unlikely to happen unicode character,
                   // We'll replace our multi-length symbols with that one.
}));
// Might be useful if we need to discover the symbol of a tag
const tagSymbols = new Map();
tags.forEach((v, k) => { tagSymbols.set(v, k ); })

const rawMarkdown = `
  This must be *bold*,

  This also must be *bo_ld*,

  this _entire block must be
  emphasized even if it's comprised of multiple lines_,

  This is an !action! it should be a button,

  \`\`\`
beep, boop, this is code
  \`\`\`

  This is an asterisk\\*
`;

class App extends React.Component {
  parseMarkdown(source) {
    let currentTag = "";
    let currentContent = "";

    const parsedMarkdown = [];

    // We create this variable to track possible escape characters, eg. "\"
    let before = "";

    const pushContent = (
      content,
      tagValue,
      props,
    ) => {
      let children = undefined;

      // There's the need to parse for empty lines
      if (content.indexOf("\n\n") >= 0) {
        let before = "";
        const contentJSX = [];

        let chunk = "";
        for (let i = 0; i < content.length; i++) {
          if (i !== 0) before = content[i - 1];

          chunk += content[i];

          if (before === "\n" && content[i] === "\n") {
            contentJSX.push(chunk);
            contentJSX.push(<br />);
            chunk = "";
          }

          if (chunk !== "" && i === content.length - 1) {
            contentJSX.push(chunk);
          }
        }

        children = contentJSX;
      } else {
        children = [content];
      }
      parsedMarkdown.push(React.createElement(tagValue, props, children))
    };

    for (let i = 0; i < source.length; i++) {
      const chunk = source[i];
      if (i !== 0) {
        before = source[i - 1];
      }

      // Does our current chunk needs to be treated as a escaped char?
      const escaped = before === "\\";

      // Detect if we need to start/finish parsing our tags

      // We are not parsing anything, however, that could change at current
      // chunk
      if (currentTag === "" && escaped === false) {
        // If our tags array has the chunk, this means a markdown tag has
        // just been found. We'll change our current state to reflect this.
        if (tags.has(chunk)) {
          currentTag = tags.get(chunk);

          // We have simple content to push
          if (currentContent !== "") {
            pushContent(currentContent, "span");
          }

          currentContent = "";
        }
      } else if (currentTag !== "" && escaped === false) {
        // We'll look if we can finish parsing our tag
        if (tags.has(chunk)) {
          const symbolValue = tags.get(chunk);

          // Just because the current chunk is a symbol it doesn't mean we
          // can already finish our currentTag.
          //
          // We'll need to see if the symbol's value corresponds to the
          // value of our currentTag. In case it does, we'll finish parsing it.
          if (symbolValue === currentTag) {
            pushContent(
              currentContent,
              currentTag,
              undefined, // you could pass props here
            );

            currentTag = "";
            currentContent = "";
          }
        }
      }

      // Increment our currentContent
      //
      // Ideally, we don't want our rendered markdown to contain any '\'
      // or undesired '*' or '_' or '!'.
      //
      // Users can still escape '*', '_', '!' by prefixing them with '\'
      if (tags.has(chunk) === false || escaped) {
        if (chunk !== "\\" || escaped) {
          currentContent += chunk;
        }
      }

      // In case an erroneous, i.e. unfinished tag, is present and the we've
      // reached the end of our source (rawMarkdown), we want to make sure
      // all our currentContent is pushed as a simple string
      if (currentContent !== "" && i === source.length - 1) {
        pushContent(
          currentContent,
          "span",
          undefined,
        );
      }
    }

    return parsedMarkdown;
  }

  render() {
    return (
      <div className="App">
        <div>{this.parseMarkdown(this.props.rawMarkdown)}</div>
      </div>
    );
  }
}

ReactDOM.render(<App rawMarkdown={rawMarkdown.replace(/```/g, "\uFFFF")} />, document.getElementById('app'));

Liên kết đến mã (TypeScript) https://codepen.io/ludanin/pen/GRgNWPv

Liên kết đến mã (vanilla / babel) https://codepen.io/ludanin/pen/eYmBvXw


Tôi cảm thấy giải pháp này đang đi đúng hướng, nhưng dường như có vấn đề với việc đưa các nhân vật đánh dấu khác vào bên trong những nhân vật khác. Ví dụ: thử thay thế This must be *bold*bằng This must be *bo_ld*. Nó khiến cho HTML kết quả bị sai
lệch

Thiếu kiểm tra thích hợp sản xuất này = p, xấu của tôi. Tôi đã sửa nó và sẽ đăng kết quả ở đây, có vẻ như là một vấn đề đơn giản để khắc phục.
Lukas Danin

Vâng, cảm ơn. Tôi thực sự thích giải pháp này mặc dù. Nó có vẻ rất mạnh mẽ và sạch sẽ. Tôi nghĩ rằng nó có thể được tái cấu trúc một chút mặc dù cho sự thanh lịch hơn nữa. Tôi có thể thử làm rối tung nó lên một chút.
Ryan Peschel

Nhân tiện, tôi đã điều chỉnh mã để hỗ trợ cách xác định thẻ đánh dấu linh hoạt hơn và các giá trị JSX tương ứng của chúng linh hoạt hơn nhiều.
Lukas Danin

Hey cảm ơn điều này có vẻ tuyệt vời. Chỉ một điều cuối cùng và tôi nghĩ nó sẽ hoàn hảo. Trong bài viết gốc của tôi, tôi cũng có một chức năng cho các đoạn mã (liên quan đến ba backticks). Nó sẽ có thể có hỗ trợ cho điều đó là tốt? Vì vậy, các thẻ có thể tùy chọn có nhiều ký tự? Một câu trả lời khác đã thêm hỗ trợ bằng cách thay thế các thể hiện của `` `bằng một ký tự hiếm khi được sử dụng. Đó sẽ là một cách dễ dàng để làm điều đó, nhưng không chắc đó có phải là lý tưởng hay không.
Ryan Peschel

4

Có vẻ như bạn đang tìm kiếm một giải pháp nhỏ rất cơ bản. Không phải "siêu quái vật" như react-markdown-it:)

Tôi muốn giới thiệu cho bạn https://github.com/developit/snarkdown trông khá nhẹ và đẹp! Chỉ cần 1kb và cực kỳ đơn giản, bạn có thể sử dụng nó & mở rộng nó nếu bạn cần bất kỳ tính năng cú pháp nào khác.

Danh sách thẻ được hỗ trợ https://github.com/developit/snarkdown/blob/master/src/index.js#L1

Cập nhật

Chỉ cần chú ý về các thành phần phản ứng, bỏ qua nó ngay từ đầu. Vì vậy, điều đó thật tuyệt vời đối với bạn Tôi tin rằng hãy lấy thư viện làm ví dụ và triển khai các thành phần bắt buộc tùy chỉnh của bạn để hoàn thành nó mà không cần thiết lập HTML một cách nguy hiểm. Thư viện khá nhỏ và rõ ràng. Hãy vui vẻ với nó! :)


3
var table = {
  "*":{
    "begin":"<strong>",
    "end":"</strong>"
    },
  "_":{
    "begin":"<em>",
    "end":"</em>"
    },
  "!":{
    "begin":"<MyComponent onClick={this.action}>",
    "end":"</MyComponent>"
    },

  };

var myMarkdown = "hello *asdf* *how* _are_ you !doing! today";
var tagFinder = /(?<item>(?<tag_begin>[*|!|_])(?<content>\w+)(?<tag_end>\k<tag_begin>))/gm;

//Use case 1: direct string replacement
var replaced = myMarkdown.replace(tagFinder, replacer);
function replacer(match, whole, tag_begin, content, tag_end, offset, string) {
  return table[tag_begin]["begin"] + content + table[tag_begin]["end"];
}
alert(replaced);

//Use case 2: React components
var pieces = [];
var lastMatchedPosition = 0;
myMarkdown.replace(tagFinder, breaker);
function breaker(match, whole, tag_begin, content, tag_end, offset, string) {
  var piece;
  if (lastMatchedPosition < offset)
  {
    piece = string.substring(lastMatchedPosition, offset);
    pieces.push("\"" + piece + "\"");
  }
  piece = table[tag_begin]["begin"] + content + table[tag_begin]["end"];
  pieces.push(piece);
  lastMatchedPosition = offset + match.length;

}
alert(pieces);

Kết quả: Kết quả chạy

Kết quả kiểm tra

Giải trình:

/(?<item>(?<tag_begin>[*|!|_])(?<content>\w+)(?<tag_end>\k<tag_begin>))/
  • Bạn có thể xác định các thẻ của mình trong phần này : [*|!|_], một khi một trong số chúng được khớp, nó sẽ được ghi lại thành một nhóm và được đặt tên là "tag_begin".

  • Và sau đó (?<content>\w+)chụp nội dung được bao bọc bởi thẻ.

  • Thẻ kết thúc phải giống với thẻ đã khớp trước đó, vì vậy ở đây sử dụng \k<tag_begin>và nếu nó vượt qua bài kiểm tra thì hãy chụp nó thành một nhóm và đặt tên là "tag_end", đó là những gì (?<tag_end>\k<tag_begin>))đang nói.

Trong JS bạn đã thiết lập một bảng như thế này:

var table = {
  "*":{
    "begin":"<strong>",
    "end":"</strong>"
    },
  "_":{
    "begin":"<em>",
    "end":"</em>"
    },
  "!":{
    "begin":"<MyComponent onClick={this.action}>",
    "end":"</MyComponent>"
    },

  };

Sử dụng bảng này để thay thế các thẻ phù hợp.

Sting.replaceString.replace quá tải (regrec, hàm) có thể lấy các nhóm bị bắt làm tham số, chúng tôi sử dụng các mục đã bắt này để tra cứu bảng và tạo chuỗi thay thế.

[Cập nhật]
Tôi đã cập nhật mã, tôi giữ mã đầu tiên trong trường hợp người khác không cần các thành phần phản ứng và bạn có thể thấy có rất ít sự khác biệt giữa chúng. Thành phần phản ứng


Thật không may, tôi không chắc chắn nếu điều này làm việc. Bởi vì tôi cần các thành phần và thành phần React thực tế, chứ không phải các chuỗi của chúng. Nếu bạn nhìn vào bài viết gốc của tôi, bạn sẽ thấy rằng tôi đang tự thêm các yếu tố thực tế vào một mảng, chứ không phải các chuỗi của chúng. Và việc sử dụng nguy hiểmSetInnerHTML rất nguy hiểm vì người dùng có thể nhập các chuỗi độc hại.
Ryan Peschel

May mắn thay, rất đơn giản để chuyển đổi chuỗi thay thế thành các thành phần React, tôi đã cập nhật mã.
Simon

Hửm Tôi phải đang thiếu một cái gì đó, bởi vì chúng vẫn còn là chuỗi của tôi. Tôi thậm chí đã thực hiện một fiddle với mã của bạn. Nếu bạn đọc console.logđầu ra, bạn sẽ thấy mảng có đầy đủ các chuỗi, không phải là các thành phần React thực tế: jsfiddle.net/xraftwh41
Ryan Peschel

Thành thật tôi không biết React, vì vậy tôi không thể làm mọi thứ theo nhu cầu của bạn một cách hoàn hảo, nhưng tôi nghĩ thông tin về cách giải quyết câu hỏi của bạn là đủ, bạn cần đưa chúng vào máy React của mình và nó có thể đi được.
Simon

Lý do tại sao chủ đề này tồn tại là vì dường như khó phân tích chúng thành các thành phần React (do đó tiêu đề chủ đề xác định nhu cầu chính xác đó). Phân tích chúng thành các chuỗi khá tầm thường và bạn chỉ có thể sử dụng chức năng thay thế chuỗi. Các chuỗi không phải là một giải pháp lý tưởng vì chúng chậm và dễ bị XSS do phải gọi một cách nguy hiểm
SetInnerHTML

0

bạn có thể làm như thế này:

//inside your compoenet

   mapData(myMarkdown){
    return myMarkdown.split(' ').map((w)=>{

        if(w.startsWith('*') && w.endsWith('*') && w.length>=3){
           w=w.substr(1,w.length-2);
           w=<strong>{w}</strong>;
         }else{
             if(w.startsWith('_') && w.endsWith('_') && w.length>=3){
                w=w.substr(1,w.length-2);
                w=<em>{w}</em>;
              }else{
                if(w.startsWith('!') && w.endsWith('!') && w.length>=3){
                w=w.substr(1,w.length-2);
                w=<YourComponent onClick={this.action}>{w}</YourComponent>;
                }
            }
         }
       return w;
    })

}


 render(){
   let content=this.mapData('hello *asdf* *how* _are_ you !doing! today');
    return {content};
  }

0

A working solution purely using Javascript and ReactJs without dangerouslySetInnerHTML.

Tiếp cận

Nhân vật bằng cách tìm kiếm nhân vật cho các yếu tố đánh dấu. Ngay khi bắt gặp, hãy tìm kiếm thẻ kết thúc cho cùng và sau đó chuyển đổi nó thành html.

Các thẻ được hỗ trợ trong đoạn trích

  • Dũng cảm
  • chữ in nghiêng
  • em
  • trước

Đầu vào và đầu ra từ đoạn trích:

JsFiddle: https://jsfiddle.net/sunil12738/wg7emcz1/58/

Mã số:

const preTag = "đ"
const map = {
      "*": "b",
      "!": "i",
      "_": "em",
      [preTag]: "pre"
    }

class App extends React.Component {
    constructor(){
      super()
      this.getData = this.getData.bind(this)
    }

    state = {
      data: []
    }
    getData() {
      let str = document.getElementById("ta1").value
      //If any tag contains more than one char, replace it with some char which is less frequently used and use it
      str = str.replace(/```/gi, preTag)
      const tempArr = []
      const tagsArr = Object.keys(map)
      let strIndexOf = 0;
      for (let i = 0; i < str.length; ++i) {
        strIndexOf = tagsArr.indexOf(str[i])
        if (strIndexOf >= 0 && str[i-1] !== "\\") {
          tempArr.push(str.substring(0, i).split("\\").join("").split(preTag).join(""))
          str = str.substr(i + 1);
          i = 0;
          for (let j = 0; j < str.length; ++j) {
            strIndexOf = tagsArr.indexOf(str[j])
            if (strIndexOf >= 0 && str[j-1] !== "\\") {
              const Tag = map[str[j]];
              tempArr.push(<Tag>{str.substring(0, j).split("\\").join("")}</Tag>)
              str = str.substr(j + 1);
              i = 0;
              break
             }
          }
        }
      }
      tempArr.push(str.split("\\").join(""))
      this.setState({
        data: tempArr,
      })
    }
    render() {
      return (
        <div>
          <textarea rows = "10"
            cols = "40"
           id = "ta1"
          /><br/>
          <button onClick={this.getData}>Render it</button><br/> 
          {this.state.data.map(x => x)} 
        </div>
      )
    }
  }

ReactDOM.render(
  <App/>,
  document.getElementById('root')
);
<body>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.production.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.production.min.js"></script>
  <div id="root"></div>
</body>

Giải thích chi tiết (với ví dụ):

Giả sử nếu chuỗi là How are *you* doing? Giữ ánh xạ cho các ký hiệu cho các thẻ

map = {
 "*": "b"
}
  • Lặp lại cho đến khi bạn tìm thấy đầu tiên *, văn bản trước đó là chuỗi bình thường
  • Đẩy mảng bên trong. Mảng trở thành ["How are "]và bắt đầu vòng lặp bên trong cho đến khi bạn tìm thấy tiếp theo *.
  • Now next between * and * needs to be bold, chúng tôi chuyển đổi chúng trong phần tử html bằng văn bản và trực tiếp đẩy vào mảng trong đó Tag = b từ bản đồ. Nếu bạn làm như vậy <Tag>text</Tag>, phản ứng nội bộ chuyển đổi thành văn bản và đẩy vào mảng. Bây giờ mảng là ["như thế nào", bạn ]. Phá vỡ từ vòng lặp bên trong
  • Bây giờ chúng ta bắt đầu vòng lặp bên ngoài từ đó và không có thẻ nào được tìm thấy, vì vậy hãy đẩy phần còn lại trong mảng. Mảng trở thành: ["thế nào", bạn , "đang làm"].
  • Kết xuất trên giao diện người dùng How are <b>you</b> doing?
    Note: <b>you</b> is html and not text

Lưu ý : Làm tổ cũng có thể. Chúng ta cần gọi logic trên trong đệ quy

Để thêm thẻ mới hỗ trợ

  • Nếu chúng là một ký tự như * hoặc !, Hãy thêm chúng vào mapđối tượng với khóa là ký tự và giá trị làm thẻ tương ứng
  • Nếu chúng có nhiều hơn một ký tự, chẳng hạn như `` `, hãy tạo một bản đồ một với một số char ít được sử dụng và sau đó chèn (Lý do: hiện tại, cách tiếp cận dựa trên ký tự theo tìm kiếm ký tự và vì vậy nhiều hơn một char sẽ bị hỏng. Tuy nhiên , điều đó cũng có thể được quan tâm bằng cách cải thiện logic)

Nó có hỗ trợ làm tổ không? Không
Nó có hỗ trợ tất cả các trường hợp sử dụng được đề cập bởi OP không? Đúng

Hy vọng nó giúp.


Xin chào, xem qua điều này bây giờ. Điều này có thể được sử dụng với hỗ trợ ba backtick là tốt? Vậy `` `asdf``` sẽ hoạt động tốt như thế nào đối với các khối mã?
Ryan Peschel

Nó sẽ nhưng một số sửa đổi có thể cần thiết. Hiện tại, chỉ có một ký tự khớp duy nhất là có cho * hoặc!. Điều đó cần phải được sửa đổi một chút. Khối mã về cơ bản có nghĩa là asdfsẽ được hiển thị <pre>asdf</pre>với nền tối, phải không? Hãy cho tôi biết điều này và tôi sẽ thấy. Ngay cả bạn có thể thử ngay bây giờ. Một cách tiếp cận đơn giản là: Trong giải pháp trên, thay thế `` `trong văn bản bằng một ký tự đặc biệt như ^ hoặc ~ và ánh xạ nó vào thẻ trước. Sau đó, nó sẽ hoạt động tốt. Cách tiếp cận khác cần thêm một số công việc
Sunil Chaudhary

Vâng, chính xác, thay thế `` `asdf``` bằng <pre>asdf</pre>. Cảm ơn!
Ryan Peschel

@RyanPeschel Xin chào! Đã thêm prehỗ trợ thẻ là tốt. Hãy cho tôi biết nếu nó hoạt động
Sunil Chaudhary

Giải pháp thú vị (sử dụng ký tự hiếm). Một vấn đề tôi vẫn thấy là thiếu sự hỗ trợ cho việc thoát (chẳng hạn như \ * asdf * không được in đậm), mà tôi đã bao gồm hỗ trợ cho mã trong bài viết gốc của mình (cũng đã đề cập đến nó trong phần chi tiết được liên kết của tôi ở cuối phần bài đăng). Điều đó sẽ rất khó để thêm?
Ryan Peschel
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.