Skip to content

Commit

Permalink
Merge branch 'main' into @Skalakid/remove-nbsp-from-inline-code-blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
Skalakid committed Jan 13, 2025
2 parents aa3193f + 569c1e5 commit 8aba3ef
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 22 deletions.
38 changes: 21 additions & 17 deletions __tests__/ExpensiMark-HTML-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -472,29 +472,29 @@ test('Test inline code blocks', () => {
expect(parser.replace(inlineCodeStartString)).toBe('My favorite language is <code>JavaScript</code>. How about you?');
});

test('Test inline code blocks with double backticks', () => {
const inlineCodeStartString = 'My favorite language is ``JavaScript``. How about you?';
expect(parser.replace(inlineCodeStartString)).toBe('My favorite language is <code>&#x60;JavaScript&#x60;</code>. How about you?');
test('Test double backticks', () => {
const testString = 'My favorite language is ``JavaScript``. How about you?';
expect(parser.replace(testString)).toBe('My favorite language is &#x60;&#x60;JavaScript&#x60;&#x60;. How about you?');
});

test('Test inline code blocks with triple backticks', () => {
const inlineCodeStartString = 'My favorite language is ```JavaScript```. How about you?';
expect(parser.replace(inlineCodeStartString)).toBe('My favorite language is <code>&#x60;&#x60;JavaScript&#x60;&#x60;</code>. How about you?');
expect(parser.replace(inlineCodeStartString)).toBe('My favorite language is &#x60;&#x60;<code>JavaScript</code>&#x60;&#x60;. How about you?');
});

test('Test multiple inline codes in one line', () => {
const inlineCodeStartString = 'My favorite language is `JavaScript`. How about you? I also like `Python`.';
expect(parser.replace(inlineCodeStartString)).toBe('My favorite language is <code>JavaScript</code>. How about you? I also like <code>Python</code>.');
});

test('Test inline code with one backtick as content', () => {
const inlineCodeStartString = '```';
expect(parser.replace(inlineCodeStartString)).toBe('&#x60;&#x60;&#x60;');
test('Test triple backticks', () => {
const testString = '```';
expect(parser.replace(testString)).toBe('&#x60;&#x60;&#x60;');
});

test('Test inline code with multiple backtick symbols as content', () => {
const inlineCodeStartString = '``````';
expect(parser.replace(inlineCodeStartString)).toBe('&#x60;&#x60;&#x60;&#x60;&#x60;&#x60;');
test('Test multiple backtick symbols', () => {
const testString = '``````';
expect(parser.replace(testString)).toBe('&#x60;&#x60;&#x60;&#x60;&#x60;&#x60;');
});

test('Test inline code blocks with ExpensiMark syntax inside', () => {
Expand All @@ -508,9 +508,9 @@ test('Test inline code blocks inside ExpensiMark', () => {
expect(parser.replace(testString)).toBe(resultString);
});

test('Test inline code blocks with two backticks', () => {
test('Test words enclosed in double backticks', () => {
const testString = '``JavaScript``';
expect(parser.replace(testString)).toBe('<code>&#x60;JavaScript&#x60;</code>');
expect(parser.replace(testString)).toBe('&#x60;&#x60;JavaScript&#x60;&#x60;');
});

test('Test code fencing with ExpensiMark syntax inside', () => {
Expand Down Expand Up @@ -1240,10 +1240,9 @@ test('Test for backticks with complete escaped backtick characters inside it', (
expect(parser.replace(testString)).toBe(resultString);
});

// Backticks with only tab characters inside it are not replaced with <code>
test('Test for backticks only tab characters inside it', () => {
test('Test for inline code blocks with only tab characters as content', () => {
const testString = '`\u0009`';
const resultString = '&#x60;\u0009&#x60;';
const resultString = '<code> </code>';
expect(parser.replace(testString)).toBe(resultString);
});

Expand All @@ -1254,10 +1253,15 @@ test('Test for backticks with only space characters as content', () => {
expect(parser.replace(testString)).toBe(resultString);
});

// Code-fence with spaces as content
test('Test for inline code block with triple backtick with spaces as content', () => {
const testString = '``` ```';
const resultString = '<code>&#x60;&#x60; &#x60;&#x60;</code>';
const resultString = '&#x60;&#x60;<code>&nbsp;&nbsp;&nbsp;</code>&#x60;&#x60;';
expect(parser.replace(testString)).toBe(resultString);
});

test('Test for a normal code block, an empty code block, followed by a word and a backtick', () => {
const testString = '`hello` `` hi`';
const resultString = '<code>hello</code> &#x60;&#x60; hi&#x60;';
expect(parser.replace(testString)).toBe(resultString);
});

Expand Down
6 changes: 5 additions & 1 deletion __tests__/ExpensiMark-HTMLToText-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,11 @@ test('Mention report html to text', () => {
expect(parser.htmlToText(testString, extras)).toBe('#room-name');
});

test('Test replacement for <img> tags', () => {
test('Test replacement for attachment tags', () => {
const testString = '<img src="https://example.com/image.png" alt="Image description" />';
const testString2 = '<video data-expensify-source="https://www.expensify.com/chat-attachments/123/test.mp4" data-expensify-width=720 data-expensify-height=1640 data-expensify-duration=20>test.mp4</video>';
const testString3 = '<a href="https://www.expensify.com/chat-attachments/123/test.csv" data-expensify-source="https://www.expensify.com/chat-attachments/123/test.csv">test.csv</a>';
expect(parser.htmlToText(testString)).toBe('[Attachment]');
expect(parser.htmlToText(testString2)).toBe('[Attachment]');
expect(parser.htmlToText(testString3)).toBe('[Attachment]');
});
15 changes: 14 additions & 1 deletion lib/ExpensiMark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,12 @@ export default class ExpensiMark {
// but we should not replace backtick symbols if they include <pre> tags between them.
// At least one non-whitespace character or a specific whitespace character (" " and "\u00A0")
// must be present inside the backticks.
regex: /(\B|_|)&#x60;((?:&#x60;)*(?!&#x60;).*?[\S| |\u00A0]+?.*?(?<!&#x60;)(?:&#x60;)*)&#x60;(\B|_|)(?!&#x60;|(?!<pre>)[^<]*(?:<(?!pre>)[^<]*)*<\/pre>|[^<]*<\/video>)/gm,
regex: /(\B|_|)&#x60;(.*?)&#x60;(\B|_|)(?!(?!<pre>)[^<]*(?:<(?!pre>)[^<]*)*<\/pre>|[^<]*<\/video>)/gm,
replacement: (_extras, _match, g1, g2, g3) => {
const g2Value = g2.trim() === '' ? g2.replaceAll(' ', '&nbsp;') : g2;
if (!g2Value) {
return _match;
}
return `${g1}<code>${g2Value}</code>${g3}`;
},
rawInputReplacement: (_extras, _match, g1, g2, g3) => `${g1}<code>${g2}</code>${g3}`,
Expand Down Expand Up @@ -802,6 +805,16 @@ export default class ExpensiMark {
regex: /<img[^><]*src\s*=\s*(['"])(.*?)\1(?:[^><]*alt\s*=\s*(['"])(.*?)\3)?[^><]*>*(?![^<][\s\S]*?(<\/pre>|<\/code>))/gi,
replacement: '[Attachment]',
},
{
name: 'video',
regex: /<video[^><]*data-expensify-source\s*=\s*(['"])(\S*?)\1(.*?)>([^><]*)<\/video>*(?![^<][\s\S]*?(<\/pre>|<\/code>))/gi,
replacement: '[Attachment]',
},
{
name: 'otherAttachments',
regex: /<a[^><]*data-expensify-source\s*=\s*(['"])(\S*?)\1(.*?)>([^><]*)<\/a>*(?![^<][\s\S]*?(<\/pre>|<\/code>))/gi,
replacement: '[Attachment]',
},
{
name: 'reportMentions',
regex: /<mention-report reportID="(\d+)" *\/>/gi,
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "expensify-common",
"version": "2.0.110",
"version": "2.0.114",
"author": "Expensify, Inc.",
"description": "Expensify libraries and components shared across different repos",
"homepage": "https://expensify.com",
Expand Down

0 comments on commit 8aba3ef

Please sign in to comment.