Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ npm install @expensify/react-native-live-markdown react-native-worklets expensif
npx expo install @expensify/react-native-live-markdown react-native-worklets expensify-common html-entities@2.5.3
```

React Native Live Markdown requires [react-native-worklets](https://github.com/software-mansion/react-native-reanimated/tree/main/packages/react-native-worklets) 0.7.0 or newer as well as [expensify-common](https://github.com/Expensify/expensify-common) 2.0.115 and [html-entities](https://github.com/mdevils/html-entities) 2.5.3 exactly if using the default built-in ExpensiMark parser.
React Native Live Markdown requires [react-native-worklets](https://github.com/software-mansion/react-native-reanimated/tree/main/packages/react-native-worklets) 0.7.0 or newer as well as [expensify-common](https://github.com/Expensify/expensify-common) 2.0.201 or newer and [html-entities](https://github.com/mdevils/html-entities) 2.5.3 exactly if using the default built-in ExpensiMark parser.

> [!IMPORTANT]
> Please follow the `react-native-worklets` [Getting Started](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/getting-started/#react-native-community-cli) guide to avoid issues.
Expand Down Expand Up @@ -55,6 +55,16 @@ export default function App() {
}
```

The built-in `parseExpensiMark` parser accepts an optional maximum input length. It defaults to 4,000 characters and returns no formatting ranges when the input is longer than the configured limit. To use a different limit, wrap the parser in a worklet function:

```ts
function parser(input: string) {
'worklet';

return parseExpensiMark(input, 5000);
}
```

## Styling

`MarkdownTextInput` can be styled using `style` prop just like regular `TextInput` component.
Expand Down
10 changes: 5 additions & 5 deletions package-lock.json

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

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-react-native": "^5.0.0",
"eslint-plugin-tsdoc": "^0.2.17",
"expensify-common": "2.0.189",
"expensify-common": "2.0.201",
"jest": "^29.6.3",
"jest-environment-jsdom": "^29.7.0",
"nodemon": "^3.1.3",
Expand All @@ -109,7 +109,7 @@
"typescript": "^5.8.3"
},
"peerDependencies": {
"expensify-common": ">=2.0.189",
"expensify-common": ">=2.0.201",
"react": "*",
"react-native": "*",
"react-native-worklets": ">=0.7.0"
Expand Down
22 changes: 22 additions & 0 deletions src/__tests__/parseExpensiMark.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,28 @@ test('no formatting', () => {
expect('Hello, world!').toBeParsedAs([]);
});

describe('maximum parsable length', () => {
const createBoldMarkdown = (length: number) => `*${'a'.repeat(length - 2)}*`;
const getBoldRanges = (length: number): MarkdownRange[] => [
{type: 'syntax', start: 0, length: 1},
{type: 'bold', start: 1, length: length - 2},
{type: 'syntax', start: length - 1, length: 1},
];

test('keeps the default 4000-character limit', () => {
expect(parseExpensiMark(createBoldMarkdown(4000))).toEqual(getBoldRanges(4000));
expect(parseExpensiMark(createBoldMarkdown(4001))).toEqual([]);
});

test('uses the caller-provided maximum length', () => {
const markdown = createBoldMarkdown(5000);

expect(parseExpensiMark(markdown)).toEqual([]);
expect(parseExpensiMark(markdown, 5000)).toEqual(getBoldRanges(5000));
expect(parseExpensiMark(`${markdown}a`, 5000)).toEqual([]);
});
});

describe('parsing error', () => {
expect(`> [exa\nmple.com](https://example.com)`).toBeParsedAs([
{type: 'blockquote', start: 0, length: 6},
Expand Down
11 changes: 9 additions & 2 deletions src/parseExpensiMark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,15 @@ function parseTreeToTextAndRanges(tree: StackItem): [string, MarkdownRange[]] {
return [text, ranges];
}

function parseExpensiMark(markdown: string): MarkdownRange[] {
if (markdown.length > MAX_PARSABLE_LENGTH) {
/**
* Parses Markdown text into formatting ranges using ExpensiMark.
*
* @param markdown - The raw Markdown string to parse.
* @param maxLength - Maximum input length to parse; longer input returns `[]` without parsing. Defaults to 4000.
* @returns The list of formatting ranges, or `[]` if input exceeds `maxLength` or fails to parse.
*/
function parseExpensiMark(markdown: string, maxLength = MAX_PARSABLE_LENGTH): MarkdownRange[] {
Comment thread
Uzaifm127 marked this conversation as resolved.
if (markdown.length > maxLength) {
return [];
}
const html = parseMarkdownToHTML(markdown);
Expand Down
Loading