stream-chat-react-native-core
Version:
The official React Native and Expo components for Stream Chat, a service for building chat applications
62 lines (49 loc) • 2.23 kB
text/typescript
import truncate from 'lodash/truncate';
import { parseLinksFromText } from './parseLinks';
import { escapeRegExp } from '../../../../utils/utils';
export const generateMarkdownText = (text?: string) => {
if (!text) {
return null;
}
const normalizedText = text.replace(/\uFFFC/g, ' ');
// Trim the extra spaces from the text.
let resultText = normalizedText.trim();
// List of all the links present in the text.
const linkInfos = parseLinksFromText(resultText);
for (const linkInfo of linkInfos) {
const displayLink = truncate(linkInfo.raw, {
length: 200,
omission: '...',
});
// Convert raw links/emails in the text to respective markdown syntax.
// Eg: Hi @getstream.io -> Hi @[getstream.io](getstream.io).
const normalRegEx = new RegExp(escapeRegExp(linkInfo.raw), 'g');
const markdown = `[${displayLink}](${linkInfo.url})`;
resultText = normalizedText.replace(normalRegEx, markdown);
// After previous step, in some cases, the mentioned user after `@` might have a link/email so we convert it back to normal raw text.
// Eg: Hi, @[test.user@gmail.com](mailto:test.user@gmail.com) to @test.user@gmail.com.
const mentionsRegex = new RegExp(
`@\\[${escapeRegExp(displayLink)}\\]\\(${escapeRegExp(linkInfo.url)}\\)`,
'g',
);
resultText = resultText.replace(mentionsRegex, `@${displayLink}`);
}
// Escape the " and ' characters, except in code blocks where we deem this allowed.
resultText = resultText.replace(/(```[\s\S]*?```|`.*?`)|[<"']/g, (match, code) => {
if (code) {
return code;
}
return `\\${match}`;
});
// Remove whitespaces that come directly after newlines except in code blocks where we deem this allowed.
resultText = resultText.replace(/(```[\s\S]*?```|`.*?`)|\n[ ]{2,}/g, (_, code) => {
if (code) {
return code;
}
return '\n';
});
// Always replace \n``` with \n\n``` to force the markdown state machine to treat it as a separate block. Otherwise, code blocks inside of list
// items for example were broken. We clean up the code block closing state within the rendering itself.
resultText = resultText.replace(/\n```/g, '\n\n```');
return resultText;
};