कैसे प्रतिक्रिया घटकों में Markdown के एक छोटे सबसेट को पार्स करने के लिए?


9

मेरे पास कुछ कस्टम html के साथ Markdown का एक बहुत छोटा उपसमूह है जिसे मैं रिएक्ट घटकों में पार्स करना चाहूंगा। उदाहरण के लिए, मैं इस निम्नलिखित स्ट्रिंग को चालू करना चाहूंगा:

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

निम्नलिखित सरणी में:

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

और फिर इसे एक रिएक्ट रेंडर फ़ंक्शन से वापस करें (रिएक्ट फॉर्मेटेड HTML के रूप में एरे को ठीक से रेंडर करेगा)

मूल रूप से, मैं उपयोगकर्ताओं को अपने पाठ को स्टाइल वाले घटकों (और कुछ मामलों में मेरे अपने घटकों!) में बदलने के लिए मार्कडाउन के एक बहुत सीमित सेट का उपयोग करने का विकल्प देना चाहता हूं।

यह खतरनाक रूप से InSHTML के लिए नासमझ है, और मैं बाहरी निर्भरता में नहीं लाना चाहता, क्योंकि वे सभी बहुत भारी हैं, और मुझे केवल बहुत ही बुनियादी कार्यक्षमता की आवश्यकता है।

मैं वर्तमान में ऐसा कुछ कर रहा हूं, लेकिन यह बहुत भंगुर है, और सभी मामलों के लिए काम नहीं करता है। मैं सोच रहा था कि क्या कोई बेहतर तरीका था:

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;
}

यहाँ मेरा पिछला प्रश्न है जिसके कारण यह एक है।


1
क्या होगा अगर इनपुट में नेस्टेड आइटम हैं, जैसे font _italic *and bold* then only italic_ and normal? अपेक्षित परिणाम क्या होगा? या यह कभी भी नेस्टेड नहीं होगा?
19 को ट्रिनकोट

1
घोंसले के शिकार के बारे में चिंता करने की कोई जरूरत नहीं है। इसका उपयोग करने के लिए उपयोगकर्ताओं के लिए बस बहुत ही बुनियादी मार्कडाउन है। जो भी लागू करना सबसे आसान है वह मेरे साथ ठीक है। आपके उदाहरण में, यह पूरी तरह से ठीक होगा यदि आंतरिक बन्धन काम नहीं करता है। लेकिन अगर यह घोंसले को लागू करने की तुलना में आसान है, तो यह ठीक नहीं है।
रयान पेस्केल

1
शायद यह संभव है कि बस ऑफ-द-शेल्फ समाधान जैसे कि npmjs.com/package/react-markdown-it
mb21

1
मैं हालांकि मार्कडाउन का उपयोग नहीं कर रहा हूं। यह इसका एक बहुत ही समान / छोटा उपसमूह है (जो गैर-नेस्टेड बोल्ड, इटैलिक, कोड, अंडरलाइन के साथ-साथ युगल कस्टम घटकों का समर्थन करता है)। स्निपेट मैंने कुछ काम किए हैं, लेकिन बहुत आदर्श नहीं लगते हैं, और कुछ तुच्छ मामलों में विफल रहते हैं, (जैसे आप इस तरह एक भी क्षुद्रग्रह नहीं टाइप कर सकते हैं: asdf*यह गायब होने के बिना)
रयान पेस्केल

1
अच्छी तरह से ... मार्कशीट या मार्कडाउन जैसी किसी चीज़ को पार्स करना बिल्कुल आसान काम नहीं है ... रेगेक्स ने इसे नहीं काटा ... html के संबंध में इसी तरह के सवाल के लिए, stackoverflow.com/questions/1732348/…
mb21

जवाबों:


1

यह काम किस प्रकार करता है?

यह चंक द्वारा एक स्ट्रिंग चंक को पढ़कर काम करता है, जो वास्तव में लंबे तार के लिए सबसे अच्छा समाधान नहीं हो सकता है।

जब भी पार्सर पता लगाता है कि एक महत्वपूर्ण हिस्सा पढ़ा जा रहा है, '*'या किसी अन्य मार्कडाउन टैग को पढ़ा जा रहा है , तो वह इस तत्व के अंशों को पार्स करना शुरू कर देता है जब तक कि पार्सर को उसका समापन टैग नहीं मिल जाता।

यह मल्टी-लाइन स्ट्रिंग्स पर काम करता है, उदाहरण के लिए कोड देखें।

चेतावनियां

आपने निर्दिष्ट नहीं किया है, या मैं आपकी आवश्यकताओं को गलत समझ सकता हूं, यदि उन टैगों को पार्स करने की आवश्यकता है जो बोल्ड और इटैलिक दोनों हैं , तो मेरा वर्तमान समाधान इस मामले में काम नहीं कर सकता है।

यदि आपको उपरोक्त शर्तों के साथ काम करने की आवश्यकता है, तो यहां टिप्पणी करें और मैं कोड को ट्विक कर दूंगा।

पहला अपडेट: यह बताता है कि मार्कडाउन टैग कैसे व्यवहार किए जाते हैं

टैग अब हार्डकोड नहीं हैं, इसके बजाय वे एक मानचित्र हैं जहां आप आसानी से अपनी आवश्यकताओं को पूरा कर सकते हैं।

टिप्पणियों में आपके द्वारा बताए गए बगों को निश्चित करें, इस मुद्दे को इंगित करने के लिए धन्यवाद = पी

दूसरा अपडेट: मल्टी-लेंथ मार्कडाउन टैग

इसे प्राप्त करने का सबसे आसान तरीका: बहु-लंबाई वाले वर्णों को शायद ही कभी यूनिकोड के साथ बदलना

हालाँकि विधि parseMarkdownअभी तक बहु-लंबाई टैग का समर्थन नहीं करती है, हम आसानी से उन बहु-लंबाई टैग को string.replace हमारे rawMarkdownप्रस्ताव को भेजते समय बदल सकते हैं ।

व्यवहार में इसका एक उदाहरण देखने के लिए ReactDOM.render, कोड के अंत में स्थित को देखें।

यहां तक ​​कि अगर आपका आवेदन कई भाषाओं का समर्थन करता है , तो अमान्य यूनिकोड वर्ण हैं जो जावास्क्रिप्ट अभी भी पता लगाता है, पूर्व: "\uFFFF"एक वैध यूनिकोड नहीं है, अगर मैं सही ढंग से याद करता हूं, लेकिन जेएस अभी भी इसकी तुलना करने में सक्षम होगा ( "\uFFFF" === "\uFFFF" = true)

यह पहली बार में हैक-वाई प्रतीत हो सकता है, लेकिन आपके उपयोग-मामले के आधार पर, मैं इस मार्ग का उपयोग करके किसी भी प्रमुख मुद्दों को नहीं देखता हूं।

इसे प्राप्त करने का दूसरा तरीका

ठीक है, हम आसानी से अंतिम ट्रैक कर सकते हैं N(जहां Nसबसे लंबी बहु-लंबाई टैग की लंबाई से मेल खाती है) विखंडू।

विधि के अंदर लूप जिस तरह से parseMarkdownव्यवहार करता है, उसे करने के लिए कुछ ट्विक्स होंगे , अर्थात यदि वर्तमान चंक एक बहु-लंबाई टैग का हिस्सा है, अगर यह इसे टैग के रूप में उपयोग करता है; अन्यथा, जैसे मामलों में ``k, हमें इसे notMultiLengthया कुछ समान के रूप में चिह्नित करना होगा और उस चंक को सामग्री के रूप में धकेलना होगा।

कोड

// 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'));

कोड का लिंक (टाइपस्क्रिप्ट) https://codepen.io/ludanin/pen/GRgNWPv

कोड के लिए लिंक (वेनिला / बेबल) https://codepen.io/ludanin/pen/eYmBvXw


मुझे ऐसा लगता है कि यह समाधान सही रास्ते पर है, लेकिन ऐसा लगता है कि अन्य मार्केड के पात्रों को अन्य लोगों के अंदर रखने के मुद्दे हैं। उदाहरण के लिए, के This must be *bold*साथ प्रतिस्थापित करने का प्रयास करें This must be *bo_ld*। यह परिणामी HTML को विकृत
बनाता है

उचित परीक्षण के अभाव ने यह = p, मेरा बुरा उत्पादन किया। मैं पहले से ही इसे ठीक कर रहा हूं और यहां परिणाम पोस्ट करने जा रहा हूं, ऐसा लगता है कि ठीक करने के लिए एक सरल समस्या है।
लुकास डेनिन

हाँ धन्यवाद। मैं वास्तव में इस समाधान को पसंद करता हूं। यह बहुत मजबूत और साफ लगता है। मुझे लगता है कि यह थोड़ा और अधिक लालित्य के लिए फिर से बनाया जा सकता है। मैं इसके साथ थोड़ा गड़बड़ करने की कोशिश कर सकता हूं।
रयान पेसकेल

हो गया, वैसे, मैंने मार्कडाउन टैग्स और उनके संबंधित JSX मानों को परिभाषित करने के अधिक लचीले तरीके का समर्थन करने के लिए कोड को ट्विक किया है।
लुकास डेनिन

हे धन्यवाद यह बहुत अच्छा लग रहा है। बस एक आखिरी बात और मुझे लगता है कि यह सही होगा। मेरे मूल पोस्ट में मेरे पास कोड स्निपेट के लिए एक फ़ंक्शन भी है (जिसमें ट्रिपल बैकटिक्स शामिल हैं)। क्या उसके लिए भी समर्थन संभव होगा? ताकि टैग वैकल्पिक रूप से कई वर्ण हो सकें? एक अन्य उत्तर ने शायद ही कभी इस्तेमाल किए गए चरित्र के साथ `` के उदाहरणों को बदलकर समर्थन जोड़ा। यह ऐसा करने का एक आसान तरीका होगा, लेकिन यह निश्चित नहीं है कि यह आदर्श है।
रयान पेशेल

4

ऐसा लगता है कि आप एक छोटे से मूल समाधान की तलाश कर रहे हैं। "सुपर-राक्षस" की तरह नहीं react-markdown-it:)

मैं आपको https://github.com/developit/snarkdown की सलाह देना चाहूंगा जो बहुत हल्का और अच्छा लग रहा है! बस 1kb और अत्यंत सरल, आप इसका उपयोग कर सकते हैं और इसे बढ़ा सकते हैं यदि आपको किसी अन्य सिंटैक्स सुविधाओं की आवश्यकता है।

समर्थित टैग सूची https://github.com/developit/snarkdown/blob/master/src/index.js#L1

अपडेट करें

बस प्रतिक्रिया घटकों के बारे में देखा, शुरुआत में यह याद किया। तो यह आपके लिए बहुत अच्छा है, मेरा मानना ​​है कि पुस्तकालय को एक उदाहरण के रूप में लेना और HTML को खतरनाक तरीके से सेट किए बिना इसे प्राप्त करने के लिए अपने कस्टम आवश्यक घटकों को लागू करना है। पुस्तकालय बहुत छोटा और स्पष्ट है। इसके साथ मजे करो! :)


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);

परिणाम: परिणाम चल रहा है

Regexp परीक्षा परिणाम

स्पष्टीकरण:

/(?<item>(?<tag_begin>[*|!|_])(?<content>\w+)(?<tag_end>\k<tag_begin>))/
  • आप इस अनुभाग में अपने टैग्स को परिभाषित कर सकते हैं: [*|!|_]एक बार उनमें से एक का मिलान हो जाने के बाद, इसे एक समूह के रूप में कैप्चर किया जाएगा और "tag_begin" नाम दिया जाएगा।

  • और फिर (?<content>\w+)टैग द्वारा लिपटी हुई सामग्री को कैप्चर करता है।

  • समाप्त होने वाला टैग पहले से मिलान किए गए के समान होना चाहिए, इसलिए यहां उपयोग किया गया है \k<tag_begin>, और यदि यह परीक्षण पास कर गया है, तो इसे एक समूह के रूप में कैप्चर करें और इसे "tag_end" नाम दें, यही (?<tag_end>\k<tag_begin>))कह रहा है।

जेएस में आपने इस तरह एक तालिका स्थापित की है:

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

  };

मिलान किए गए टैग को बदलने के लिए इस तालिका का उपयोग करें।

Sting.replace में एक अधिभार String.replace (regexp, function) है, जो कैप्चर किए गए समूहों को पैरामीटर के रूप में ले सकता है, हम तालिका को देखने के लिए और बदले हुए स्ट्रिंग को उत्पन्न करने के लिए इन कैप्चर की गई वस्तुओं का उपयोग करते हैं।

[अपडेट]
मैंने कोड को अपडेट किया है, मैंने पहले एक को रखा है अगर किसी और को प्रतिक्रिया घटकों की आवश्यकता नहीं है, और आप देख सकते हैं कि उनके बीच बहुत कम अंतर है। प्रतिक्रिया घटक


दुर्भाग्य से मुझे यकीन नहीं है कि अगर यह काम करता है। क्योंकि मुझे वास्तविक प्रतिक्रिया घटकों और तत्वों की आवश्यकता है, न कि उनमें से तार की। यदि आप मेरे मूल पोस्ट को देखते हैं तो आप देखेंगे कि मैं वास्तविक तत्वों को एक सरणी में जोड़ रहा हूँ, उनमें से तार नहीं। और खतरनाक तरीके से उपयोग करना InnerHTML खतरनाक है क्योंकि उपयोगकर्ता इनपुट कर सकता है दुर्भावनापूर्ण तार।
रयान पेशेल

सौभाग्य से यह स्ट्रिंग प्रतिस्थापन को रिएक्ट घटकों में बदलने के लिए बहुत सरल है, मैंने कोड को अपडेट किया है।
साइमन

हम्म? मुझे कुछ याद आ रहा है, क्योंकि वे अभी भी मेरे अंत में हैं। मैंने आपके कोड के साथ एक फील भी किया। यदि आप console.logआउटपुट पढ़ते हैं, तो आप देखेंगे कि सरणी स्ट्रिंग्स से भरी हुई है, वास्तविक प्रतिक्रिया घटक नहीं: jsfiddle.net/xftswh41
रयान पेस्केल

ईमानदारी से मैं रिएक्ट नहीं जानता, इसलिए मैं आपकी आवश्यकताओं के अनुसार पूरी तरह से सब कुछ नहीं बना सकता, लेकिन मुझे लगता है कि आपके प्रश्न को हल करने के बारे में जानकारी पर्याप्त है, आपको उन्हें अपनी प्रतिक्रिया मशीन में डालने की आवश्यकता है और यह बस जा सकता है।
साइमन

यह धागा क्यों मौजूद है इसका कारण यह है कि उन्हें रिएक्ट घटकों में पार्स करने के लिए काफी कठिन प्रतीत होता है (इसलिए थ्रेड शीर्षक यह निर्दिष्ट करता है कि यह आवश्यक है)। उन्हें स्ट्रिंग में पार्स करना काफी तुच्छ है और आप स्ट्रिंग को बदले हुए फ़ंक्शन का उपयोग कर सकते हैं। स्ट्रिंग्स एक आदर्श समाधान नहीं है क्योंकि वे खतरनाक रूप से XSS के कारण धीमी गति से और अतिसंवेदनशील होते हैं
।SetInnerHTML

0

आप इसे इस तरह से कर सकते हैं:

//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.

पहुंच

चरित्र के आधार पर चिह्नक तत्वों की खोज करें। जैसे ही एक सामना होता है, उसी के लिए समाप्त होने वाले टैग की खोज करें और फिर इसे html में परिवर्तित करें।

स्निपेट में समर्थित टैग

  • साहसिक
  • इटैलिक
  • एम
  • पूर्व

स्निपेट से इनपुट और आउटपुट:

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

कोड:

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>

विस्तृत विवरण (उदाहरण के साथ):

मान लीजिए अगर स्ट्रिंग How are *you* doing? टैग्स के प्रतीकों के लिए एक मैपिंग है

map = {
 "*": "b"
}
  • लूप जब तक आप पहले *, पाठ से पहले सामान्य स्ट्रिंग है
  • उस सरणी के अंदर पुश करें। Array बन जाता है ["How are "]और तब तक आंतरिक लूप शुरू करें जब तक आप अगले * का पता न लगा लें।
  • Now next between * and * needs to be bold, हम उन्हें HTML एलिमेंट में टेक्स्ट द्वारा कन्वर्ट करते हैं और सीधे एरे में पुश करते हैं जहाँ मैप से टैग = बी। यदि आप करते हैं <Tag>text</Tag>, तो प्रतिक्रिया आंतरिक रूप से पाठ में परिवर्तित होती है और सरणी में धकेलती है। अब सरणी है ["आप कैसे हैं", आप ]। आंतरिक पाश से तोड़ो
  • अब हम वहां से बाहरी लूप शुरू करते हैं और कोई टैग नहीं मिलता है, इसलिए सरणी में शेष रहें। ऐरे बन जाते हैं: ["आप कैसे हैं", आप , "कर रहे हैं"]।
  • UI पर रेंडर करें How are <b>you</b> doing?
    Note: <b>you</b> is html and not text

नोट : घोंसला बनाना भी संभव है। हमें उपरोक्त तर्क को पुनरावृत्ति में बुलाने की आवश्यकता है

नए टैग समर्थन जोड़ने के लिए

  • यदि वे * या! जैसे एक वर्ण हैं, तो उन्हें mapवर्ण और मूल्य के अनुसार कुंजी के साथ ऑब्जेक्ट में जोड़ें
  • यदि वे `एक` जैसे एक से अधिक वर्ण हैं, तो कुछ कम उपयोग किए गए चार के साथ एक से एक मानचित्र बनाएं और फिर डालें (कारण: वर्तमान में, चरित्र खोज के आधार पर चरित्र पर आधारित दृष्टिकोण और इतने से अधिक एक वर्ण टूट जाएगा। हालांकि) , कि (तर्क में सुधार करके भी ध्यान रखा जा सकता है)

क्या यह घोंसले के शिकार का समर्थन करता है?
क्या यह ओपी द्वारा उल्लिखित सभी उपयोग के मामलों का समर्थन नहीं करता है? हाँ

आशा है ये मदद करेगा।


हाय, अब यह देख रहा हूँ। क्या ट्रिपल बैकटिक सपोर्ट के साथ भी इसका इस्तेमाल संभव है? तो `` `asdf``` कोड ब्लॉक के लिए भी काम करेगा?
रयान पेसचेल

यह होगा लेकिन कुछ संशोधनों की आवश्यकता हो सकती है। वर्तमान में, केवल एकल वर्ण मिलान * या के लिए है। इसे थोड़ा संशोधित करने की आवश्यकता है। मूल रूप से कोड ब्लॉक का मतलब है डार्क बैकग्राउंड के साथ asdfरेंडर <pre>asdf</pre>किया जाएगा ? मुझे यह पता है और मैं देखूंगा। यहां तक ​​कि अब आप कोशिश कर सकते हैं। एक सरल तरीका है: उपरोक्त समाधान में, पाठ में `` `को एक विशेष चरित्र जैसे ^ या ~ से बदलें और इसे पूर्व टैग में मैप करें। फिर ठीक चलेगा। अन्य दृष्टिकोण को कुछ और काम करने की आवश्यकता है
सुनील चौधरी

हाँ, बिल्कुल, `` asdf`` `के साथ की जगह <pre>asdf</pre>। धन्यवाद!
रयान पेशेल

@RyanPeschel हाय! preटैग समर्थन भी जोड़ा है । मुझे पता है कि यह काम करता है
सुनील चौधरी

दिलचस्प समाधान (दुर्लभ चरित्र का उपयोग करके)। एक मुद्दा जो मैं अभी भी देख रहा हूं वह बचने के लिए समर्थन की कमी है (जैसे कि * * asdf * बोल्ड नहीं है), जिसे मैंने अपने मूल पोस्ट में कोड के लिए समर्थन भी शामिल किया है (इसके लिंक में मेरे अंत में विस्तार से उल्लेख किया है) पद)। क्या इसे जोड़ना बहुत कठिन होगा?
रयान पेस्केल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.