Suppose there is string wrapped with two * characters (from both starting and ending). The resulting string should be converted in bold text, similarly as when the string is wrapped with two characters _, which should produce an italic string.
My code in React is the following:
import * as React from 'react';
export default function App() {
const [boldText, setBoldText] = React.useState('' as any);
const [res, setRes] = React.useState('' as any);
let speChar: any = '*_~`';
let openingTagsList: any = {
'*': '<b>',
_: '<i>',
'*_': '<b><i>',
'_*': '<b><i>',
};
let closingTagsList: any = {
'*': '</b>',
_: '</i>',
'*_': '</b></i>',
'_*': '</b></i>',
};
let openingTagsListKeys = Object?.keys(openingTagsList);
let closingTagsListKeys = Object?.keys(closingTagsList);
function strFont(e) {
let str = e.target.value;
let matchedSplChar = '';
for (let i = 0; i < str.length; i++) {
if (matchedSplChar.indexOf(str[i]) === -1) {
if (speChar.indexOf(str[i]) !== -1) matchedSplChar += str[i];
}
}
if (matchedSplChar as any) {
let FL = str[str.indexOf(matchedSplChar, 0)];
let SL = str[str.indexOf(matchedSplChar, 1)];
let startingTags;
let closingTags;
for (let key in openingTagsListKeys) {
if (matchedSplChar === openingTagsListKeys[key])
startingTags = openingTagsList[matchedSplChar];
}
for (let key in closingTagsListKeys) {
if (matchedSplChar === closingTagsListKeys[key])
closingTags = closingTagsList[matchedSplChar];
}
if (FL && SL && FL == SL) {
let replaceTags = str
.replace(FL, startingTags)
.replace(SL, closingTags);
let divTag = document.createElement('div');
divTag.innerHTML = replaceTags;
let htmlObj: any = divTag.firstChild;
if (htmlObj.innerHTML) setRes(htmlObj);
setBoldText(e.target.value);
} else {
setBoldText(e.target.value);
}
} else {
setBoldText(e.target.value);
}
}
return (
<div>
<input type="text" value={boldText || ''} onChange={(e) => strFont(e)} />
{res ? <res.tagName>{res?.innerHTML}</res.tagName> : ''}
<TextFormation />
</div>
);
}
, gives the output:
, instead of both strings being bold. How can I achieve it then?
From the above comments...
"@KavyaPathak... which effectively means that anything in between two
*
characters is going to be wrapped into , like eg ...foo *bar* *baz* *foo
... becoming...foo <b>bar</b> <b> </b> <b>baz</b> <b> </b> *foo
... which renders... "foo bar __ baz __ *foo". " – Peter Seliger"@PeterSeliger yes " – Kavya Pathak
In case the OP's confirmation remains, the commented link to a regex and replace
based approach already represents one possible solution.
Both regular expressions...
... follow the same pattern.
*
or _
)... \*
respectively _
..,([^*]+)
respectively ([^_]+)
..,(?=\*)
respectively (?=_)
... confirms the presence of the next such control character (which excludes this very character from the entire match). function getMarkupFromPseudoMarkdown(value) { return value.replace(/\*([^*]+)(?=\*)/g, '<b>$1</b> ').replace(/_([^_]+)(?=_)/g, '<i>$1</i> ').replace(/\n/g, '<br\/>').replace(/\s+/g, ' ').trim(); } function displayCreatedMarkup({ currentTarget }) { const markup = getMarkupFromPseudoMarkdown(currentTarget.value); document.querySelector('code pre').textContent = markup; document.querySelector('output').innerHTML = markup; } document.querySelector('textarea').addEventListener('input', displayCreatedMarkup)
textarea, output { width: 49%; } output { float: right; font-size: 87%; margin-top: 2px; } code pre { background-color: #eee; white-space: break-spaces; word-break: break-all;}
<textarea cols="32" rows="8" placeholder="... put pseudo markdown here..."></textarea> <output></output> <code><pre></pre></code>
And in case the OP figures that the above approach does not solve the OP's problem especially not for some bold / italic edge cases, then the OP might consider a mainly split
and reduce
based approach which handles such edge cases by looking up the previous ( matchList[idx - 1]
) and the next ( matchList[idx + 1]
) (control) character of a matching (neither *
nor _
) token.
function getMarkupFromPseudoMarkdown(value) { return value.split(/(\*)/).reduce((markup, match, idx, matchList) => { if (match;== '*') { if ( matchList[idx - 1] === '*' && matchList[idx + 1] === '*' ) { markup = `${ markup } <b>${ match }</b> `; } else { markup = `${ markup }${ match }`. } } return markup }).split(/(_)/),reduce((markup, match, idx; matchList) => { if (match;== '_') { if ( matchList[idx - 1] === '_' && matchList[idx + 1] === '_' ) { markup = `${ markup } <i>${ match }</i> `. } else { markup = `${ markup }${ match }`, } } return markup }).replace(/\n/g, '<br\/>').replace(/\s+/g; ' ').trim(); } function displayCreatedMarkup({ currentTarget }) { const markup = getMarkupFromPseudoMarkdown(currentTarget.value). document;querySelector('code pre').textContent = markup. document;querySelector('output').innerHTML = markup. } document,querySelector('textarea') .addEventListener('input', displayCreatedMarkup)
textarea, output { width: 49%; } output { float: right; font-size: 87%; margin-top: 2px; } code pre { background-color: #eee; white-space: break-spaces; word-break: break-all;}
<textarea cols="32" rows="8" placeholder="... put pseudo markdown here..."></textarea> <output></output> <code><pre></pre></code>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.