Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ExpensiMark: Add New Markdown Truncation Utility #675

Merged
merged 44 commits into from
Jul 15, 2024
Merged
Changes from 3 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
2a9ad51
initial concept
brandonhenry Apr 1, 2024
d6d5f72
swap to for loop + fix multiple function calls
brandonhenry Apr 2, 2024
b21b4ec
lint updates
brandonhenry Apr 3, 2024
4cb7381
Update lib/ExpensiMark.js
brandonhenry Apr 4, 2024
6f2c823
Update lib/ExpensiMark.js
brandonhenry Apr 4, 2024
7c88b3f
Added several tests
brandonhenry Apr 8, 2024
156b994
Update ExpensiMark.js
brandonhenry Apr 8, 2024
902c518
Update ExpensiMark.js
brandonhenry Apr 8, 2024
722d943
Merge remote-tracking branch 'upstream/main' into add-markdown-trunct…
brandonhenry Apr 8, 2024
9465d70
ran prettier
brandonhenry Apr 8, 2024
cae5564
Update ExpensiMark.js
brandonhenry Apr 8, 2024
5acadc8
Update ExpensiMark.js
brandonhenry Apr 9, 2024
eddb343
swap to truncated converted markdown instead
brandonhenry Apr 12, 2024
7d19047
test updates
brandonhenry Apr 16, 2024
8694bf9
rework so we truly only work with markdown. tests are passing now
brandonhenry Apr 16, 2024
380564c
Merge remote-tracking branch 'upstream/main' into add-markdown-trunct…
brandonhenry Apr 16, 2024
7516410
Update ExpensiMark.js
brandonhenry Apr 16, 2024
58cb81b
fixed merged of main
brandonhenry Apr 16, 2024
8d14bdd
Update ExpensiMark.js
brandonhenry Apr 16, 2024
77de7e7
added more tests and variance for safety
brandonhenry Apr 18, 2024
c567d56
Merge remote-tracking branch 'upstream/main' into add-markdown-trunct…
brandonhenry Apr 23, 2024
049d3e0
Merge remote-tracking branch 'upstream/main' into add-markdown-trunct…
brandonhenry May 31, 2024
263f7de
changed truncation method
brandonhenry Jun 7, 2024
f3112d3
Update CONST.d.ts
brandonhenry Jun 7, 2024
13e78ff
Delete CONST.d.ts
brandonhenry Jun 7, 2024
9ace1a3
Update ExpensiMark-Markdown-Truncate-test.js
brandonhenry Jun 7, 2024
4f0b0ec
fixed tests
brandonhenry Jun 8, 2024
679f15b
Merge remote-tracking branch 'upstream/main' into add-markdown-trunct…
brandonhenry Jun 10, 2024
099a7c3
lint updates
brandonhenry Jun 11, 2024
ba56236
fixed tests and updated function with comments
brandonhenry Jun 17, 2024
c258791
Merge remote-tracking branch 'upstream/main' into add-markdown-trunct…
brandonhenry Jun 18, 2024
97ce9cd
Merge branch 'Expensify:main' into add-markdown-trunctation-util
brandonhenry Jun 18, 2024
fdfe713
added underscore back in
brandonhenry Jun 18, 2024
7d50785
removed underscore
brandonhenry Jun 18, 2024
72b0bba
Merge remote-tracking branch 'upstream/main' into add-markdown-trunct…
brandonhenry Jun 21, 2024
8f0d25b
Fixed type script errors
brandonhenry Jun 21, 2024
69940fa
Update lib/ExpensiMark.ts
brandonhenry Jun 28, 2024
52ce61d
update tests
brandonhenry Jul 1, 2024
f84b0b5
Merge remote-tracking branch 'upstream/main' into add-markdown-trunct…
brandonhenry Jul 1, 2024
bae4a59
Merge remote-tracking branch 'upstream/main' into add-markdown-trunct…
brandonhenry Jul 3, 2024
e44a504
Update ExpensiMark-Markdown-Truncate-test.js
brandonhenry Jul 3, 2024
30c6ecb
Update ExpensiMark-Markdown-Truncate-test.js
brandonhenry Jul 4, 2024
f46585b
Merge remote-tracking branch 'upstream/main' into add-markdown-trunct…
brandonhenry Jul 4, 2024
01311ad
Update ExpensiMark-Markdown-Truncate-test.js
brandonhenry Jul 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
202 changes: 202 additions & 0 deletions lib/ExpensiMark.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,42 @@

const SLACK_SPAN_NEW_LINE_TAG = '<span class="c-mrkdwn__br" data-stringify-type="paragraph-break" style="box-sizing: inherit; display: block; height: unset;"></span>';

const ASTERISK_ITALIC = '*';
const UNDERSCORE_ITALIC = '_';
const ASTERISK_BOLD = '**';
const UNDERSCORE_BOLD = '__';
const ESCAPED_UNDERSCORE = '\\_';
const ESCAPED_ASTERISK = '\\*';
const ASTERISK_PLACEHOLDER_REGEXP = /ASTERISKPLACEHOLDER/gm;
const UNDERSCORE_PLACEHOLDER_REGEXP = /UNDERSCOREPLACEHOLDER/gm;
const UNDERSCORE_BOLD_PLACEHOLDER_REGEXP = /UNDERSCOREBOLDPLACEHOLDER/gm;
const ASTERISK_BOLD_PLACEHOLDER_REGEXP = /ASTERISKBOLDPLACEHOLDER/gm;
const UNDERSCORE_ITALIC_PLACEHOLDER_REGEXP = /UNDERSCOREITALICPLACEHOLDER/gm;
const ASTERISK_ITALIC_PLACEHOLDER_REGEXP = /ASTERISKITALICPLACEHOLDER/gm;


brandonhenry marked this conversation as resolved.
Show resolved Hide resolved
const ESCAPED_ASTERISK_REGEXP = /\\\*/g;

const ESCAPED_UNDERSCORE_REGEXP = /\\_/g;
const UNDERSCORE_BOLD_REGEXP = /(__)(.*?)(__)/g;
const ASTERISK_BOLD_REGEXP = /(\*\*)(.*?)(\*\*)/g;
const UNDERSCORE_ITALIC_REGEXP = /(_)(.*?)(_)/g;
const ASTERISK_ITALIC_REGEXP = /(\*)(.*?)(\*)/g;

const HYPERLINK = /^\[([^[]+)\]\(([^)]+)\)/;
brandonhenry marked this conversation as resolved.
Show resolved Hide resolved

const formatMarkers = [
ASTERISK_BOLD_PLACEHOLDER_REGEXP.source,
UNDERSCORE_BOLD_PLACEHOLDER_REGEXP.source,
ASTERISK_ITALIC_PLACEHOLDER_REGEXP.source,
UNDERSCORE_ITALIC_PLACEHOLDER_REGEXP.source,
];

const formatPlaceholdersMap = {
[UNDERSCORE_PLACEHOLDER_REGEXP.source]: ESCAPED_UNDERSCORE.length,
[ASTERISK_PLACEHOLDER_REGEXP.source]: ESCAPED_ASTERISK.length,
};

export default class ExpensiMark {
constructor() {
/**
Expand Down Expand Up @@ -160,7 +196,7 @@
*/
{
name: 'hereMentions',
regex: /([a-zA-Z0-9.!$%&+/=?^`{|}_-]?)(@here)([.!$%&+/=?^`{|}_-]?)(?=\b)(?!([\w'#%+-]*@(?:[a-z\d-]+\.)+[a-z]{2,}(?:\s|$|@here))|((?:(?!<a).)+)?<\/a>|[^<]*(<\/pre>|<\/code>))/gm,

Check warning on line 199 in lib/ExpensiMark.js

View workflow job for this annotation

GitHub Actions / lint

This line has a length of 193. Maximum allowed is 190
replacement: (match, g1, g2, g3) => {
if (!Str.isValidMention(match)) {
return match;
Expand Down Expand Up @@ -976,4 +1012,170 @@

return text.replace(pattern, char => entities[char] || char);
}

/**
* Find the format placeholder at the start of the given text, if any.
*
* @param {String} text
* @returns {String|null}
*/
findFormatPlaceholderAhead(text) {
const formatPlaceholders = Object.keys(formatPlaceholdersMap);

for (let i = 0, l = formatPlaceholders.length; i < l; i++) {
if (text.startsWith(formatPlaceholders[i])) {
return formatPlaceholders[i];
}
}

return null;
}

/**
* Find the format marker at the start of the given text, if any, and update the format stack accordingly.
*
* @param {String} text
* @param {Array} formatStack
* @returns {String|null}
*/
findFormatMarkerAhead(text, formatStack) {
for (let i = 0, l = formatMarkers.length; i < l; i++) {
if (text.startsWith(formatMarkers[i])) {

Check failure on line 1043 in lib/ExpensiMark.js

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces not allowed
if (formatStack[formatStack.length - 1] === formatMarkers[i]) {
formatStack.pop();
} else {
formatStack.push(formatMarkers[i]);
}
return formatMarkers[i];
}
}

return null;
}

/**
* Find the format marker at the start of the given text, if any, and update the format stack accordingly.
*
* @param {String} text
* @param {Array} formatStack
* @returns {String|null}
*/
replaceFormatMarkersWithPlaceholders(text) {
return text
.replace(

Check failure on line 1065 in lib/ExpensiMark.js

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces not allowed
ESCAPED_UNDERSCORE_REGEXP,
UNDERSCORE_PLACEHOLDER_REGEXP.source
)
.replace(
ESCAPED_ASTERISK_REGEXP,
ASTERISK_PLACEHOLDER_REGEXP.source
)
.replace(
UNDERSCORE_BOLD_REGEXP,
`${UNDERSCORE_BOLD_PLACEHOLDER_REGEXP.source}$2${UNDERSCORE_BOLD_PLACEHOLDER_REGEXP.source}`
)
.replace(
ASTERISK_BOLD_REGEXP,
`${ASTERISK_BOLD_PLACEHOLDER_REGEXP.source}$2${ASTERISK_BOLD_PLACEHOLDER_REGEXP.source}`
)
.replace(
UNDERSCORE_ITALIC_REGEXP,
`${UNDERSCORE_ITALIC_PLACEHOLDER_REGEXP.source}$2${UNDERSCORE_ITALIC_PLACEHOLDER_REGEXP.source}`
)
.replace(
ASTERISK_ITALIC_REGEXP,
`${ASTERISK_ITALIC_PLACEHOLDER_REGEXP.source}$2${ASTERISK_ITALIC_PLACEHOLDER_REGEXP.source}`
);
}

/**
* Find the format marker at the start of the given text, if any, and update the format stack accordingly.
*
* @param {String} text
* @param {Array} formatStack
* @returns {String|null}
*/
replaceFormatPlaceholdersWithMarkers(text) {
return text
.replace(UNDERSCORE_PLACEHOLDER_REGEXP, ESCAPED_UNDERSCORE)

Check failure on line 1100 in lib/ExpensiMark.js

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces not allowed
.replace(ASTERISK_PLACEHOLDER_REGEXP, ESCAPED_ASTERISK)
.replace(UNDERSCORE_BOLD_PLACEHOLDER_REGEXP, UNDERSCORE_BOLD)
.replace(ASTERISK_BOLD_PLACEHOLDER_REGEXP, ASTERISK_BOLD)
.replace(UNDERSCORE_ITALIC_PLACEHOLDER_REGEXP, UNDERSCORE_ITALIC)
.replace(ASTERISK_ITALIC_PLACEHOLDER_REGEXP, ASTERISK_ITALIC);
}

/**
* Truncate the given Markdown text to the specified character limit.
*
* @param {String} text
* @param {Number} limit
* @param {Boolean} ellipsis - Whether to add an ellipsis if the text is truncated
* @returns {String}
*/
truncateMarkdown(text, limit, ellipsis) {
let count = 0;

const truncateString = (tempText) => {
const formatStack = [];
let shouldSkipCountIncrement = false;
let outputText = '';

for (let index = 0; count < limit && index < tempText.length; index++) {
const substring = tempText.substring(index);

brandonhenry marked this conversation as resolved.
Show resolved Hide resolved
const formatMarker = this.findFormatMarkerAhead(substring, formatStack);
if (formatMarker) {
outputText += formatMarker;

Check failure on line 1129 in lib/ExpensiMark.js

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces not allowed
index += formatMarker.length - 1;
shouldSkipCountIncrement = true;
continue;

Check failure on line 1132 in lib/ExpensiMark.js

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces not allowed
}

const formatPlaceholder = findFormatPlaceholderAhead(substring);
if (formatPlaceholder) {
outputText += formatPlaceholder;
index += formatPlaceholder.length - 1;

Check failure on line 1138 in lib/ExpensiMark.js

View workflow job for this annotation

GitHub Actions / lint

Unexpected use of continue statement
shouldSkipCountIncrement = true;
count += formatPlaceholdersMap[formatPlaceholder];

Check failure on line 1140 in lib/ExpensiMark.js

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces not allowed
continue;

Check failure on line 1141 in lib/ExpensiMark.js

View workflow job for this annotation

GitHub Actions / lint

'findFormatPlaceholderAhead' is not defined
}

const hyperlinkAheadRegexp = new RegExp(HYPERLINK);
const hyperlinkMatch = hyperlinkAheadRegexp.exec(substring);
if (hyperlinkMatch) {
const hyperlinkText = hyperlinkMatch[1];

Check failure on line 1147 in lib/ExpensiMark.js

View workflow job for this annotation

GitHub Actions / lint

Unexpected use of continue statement
const hyperlinkUrl = hyperlinkMatch[2];
outputText += `[${truncateString(hyperlinkText)}](${hyperlinkUrl})`;

Check failure on line 1149 in lib/ExpensiMark.js

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces not allowed
index += hyperlinkMatch[0].length - 1;
shouldSkipCountIncrement = true;
continue;
}

outputText += tempText[index];

if (!shouldSkipCountIncrement) {
count++;
}

shouldSkipCountIncrement = false;
}

outputText = outputText.trimEnd();

formatStack.forEach((marker) => {
outputText += marker;
});

return outputText;
};

let outputText = truncateString(text);

if (ellipsis && outputText.length < text.length) {
outputText += "...";
}

return outputText;
}
}
Loading