Skip to content

Instantly share code, notes, and snippets.

@ianwcarlson
Last active November 18, 2020 19:14
Show Gist options
  • Save ianwcarlson/c9a6b55abb5cae8579ad08997eda0be0 to your computer and use it in GitHub Desktop.
Save ianwcarlson/c9a6b55abb5cae8579ad08997eda0be0 to your computer and use it in GitHub Desktop.
Convert serialized html to react elements
// This is actually a nodejs script using string templates to demonstrate feasibility
// The potential use case for something like this is dynamically generating react
// element at run time while only supported a small subset of valid HTML elements.
// A full-blown HTML parser is also much larger and complex.
const supportedTags = [
{
tag: 'sup',
regex: /<sup>[^<>].*?<\/sup>/,
createReactElement: content => `<sup>${content}</sup>`,
},
];
function convertStringIntoReactElements(inputStr) {
const stringFragments = [];
const inputArray = inputStr.split('');
let idx = 0;
let lastFoundIdx = 0;
while (idx < inputArray.length) {
const stringToTest = inputArray.slice(idx).join('');
let matchFound = false;
for (const tagObj of supportedTags) {
const { regex, tag, createReactElement } = tagObj;
const matchResult = stringToTest.match(regex);
if (matchResult) {
// setup pointers
const foundIndex = matchResult.index;
const matchLength = matchResult[0].length;
const previousSegmentEndIdx = lastFoundIdx + foundIndex;
// store the stuff prior to the search token
const previousContent = inputArray
.slice(lastFoundIdx, previousSegmentEndIdx)
.join('');
stringFragments.push(`<span>${previousContent}</span>`);
// store the converted elements
const matchedString = matchResult[0];
const innerContent = extractStringBetweenTwoTags(matchedString, tag);
const createdElement = createReactElement(innerContent);
stringFragments.push(createdElement);
// update pointers
idx = idx + foundIndex + matchLength;
lastFoundIdx = idx;
matchFound = true;
break;
}
}
if (!matchFound) {
idx += 1;
// store the remaining content
if (idx >= inputArray.length) {
const remainingContent = inputArray.slice(lastFoundIdx).join('');
stringFragments.push(`<span>${remainingContent}</span>`);
}
}
}
// wrap the whole thing in a parent element
return `<span>${stringFragments.join('')}</span>`;
}
function extractStringBetweenTwoTags(inputStr, tag) {
const startTag = `<${tag}>`;
const endTag = `</${tag}>`;
const insideStr = inputStr.substring(
startTag.length,
inputStr.length - endTag.length,
);
return insideStr;
}
const result = convertStringIntoReactElements(
'sdfasdf asdfas<sup>3</sup> sdfasdfdflskj <sup>2345gdf</sup> asdfasd',
);
console.log('result: ', result);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment