Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
4828825
chore: some work
gmsgowtham Sep 5, 2024
22ac96f
Merge remote-tracking branch 'origin/main' into marked/next
gmsgowtham Nov 12, 2024
986b065
Merge remote-tracking branch 'origin/main' into marked/next
gmsgowtham Feb 1, 2025
2f291ec
fix: tsc issues
gmsgowtham Feb 1, 2025
a57a546
chore: update marked to latest
gmsgowtham Feb 1, 2025
ccf8a51
chore: remove tsc gen files
gmsgowtham Feb 1, 2025
423f00f
fix: support custom token rendering
gmsgowtham Feb 1, 2025
199ed33
fix: link display
gmsgowtham Feb 1, 2025
8cccdac
Merge branch 'main' into marked/next
gmsgowtham Feb 1, 2025
ef3634b
chore: upgrade sample app deps
gmsgowtham Feb 1, 2025
590f399
fix: remove unused imports
gmsgowtham Feb 1, 2025
3212112
feat(minor): migrate to react-native-reanimated-table
gmsgowtham Feb 1, 2025
a02df1e
test: update snapshot
gmsgowtham Feb 1, 2025
1e2343b
fix(breaking): require and use react-native v0.76.0 and above
gmsgowtham Feb 1, 2025
f6fd049
Merge remote-tracking branch 'origin/main' into marked/next
gmsgowtham Feb 1, 2025
15ddd86
Merge branch 'main' into marked/next
gmsgowtham Feb 1, 2025
ea284e5
test: fix test runner issues
gmsgowtham Feb 1, 2025
b38d011
Merge branch 'main' into marked/next
gmsgowtham Feb 1, 2025
8a075f7
chore: remove dep @babel/traverse
gmsgowtham Feb 1, 2025
8d2b89d
docs: update readme
gmsgowtham Feb 2, 2025
060de63
docs: update readme and links
gmsgowtham Feb 2, 2025
65215b4
Merge remote-tracking branch 'origin/main' into marked/next
gmsgowtham Feb 4, 2025
a61d49b
chore: fix format
gmsgowtham Feb 4, 2025
4d11eeb
chore: release 7.0.0-alpha.0
gmsgowtham Feb 4, 2025
4874f47
Merge remote-tracking branch 'origin/main' into marked/next
gmsgowtham Mar 19, 2025
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
90 changes: 37 additions & 53 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,16 @@ Markdown renderer for React Native powered by

## Installation

#### For React Native 0.76 and above, please use the latest version.
```sh
yarn add react-native-marked react-native-svg
```

#### For React Native 0.75 and below, please use version 6.
```sh
yarn add [email protected] react-native-svg
```

## Usage

### Using Component
Expand All @@ -40,13 +46,13 @@ export default ExampleComponent;
#### [Props](https://github.com/gmsgowtham/react-native-marked/blob/main/src/lib/types.ts#L17)

| Prop | Description | Type | Optional? |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------- |
|---------------|----------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
| value | Markdown value | string | false |
| flatListProps | Props for customizing the underlying FlatList used | `Omit<FlatListProps<ReactNode>, 'data' \| 'renderItem' \| 'horizontal'>`<br><br><br>(`'data'`, `'renderItem'`, and `'horizontal'` props are omitted and cannot be overridden.) | true |
| styles | Styles for parsed components | [MarkedStyles](https://github.com/gmsgowtham/react-native-marked/blob/main/src/theme/types.ts#L5) | true |
| theme | Props for customizing colors and spacing for all components,and it will get overridden with custom component style applied via 'styles' prop | [UserTheme](https://github.com/gmsgowtham/react-native-marked/blob/main/src/theme/types.ts#L28) | true |
| styles | Styles for parsed components | [MarkedStyles](src/theme/types.ts) | true |
| theme | Props for customizing colors and spacing for all components,and it will get overridden with custom component style applied via 'styles' prop | [UserTheme](src/theme/types.ts) | true |
| baseUrl | A prefix url for any relative link | string | true |
| renderer | Custom component Renderer | [RendererInterface](https://github.com/gmsgowtham/react-native-marked/blob/main/src/lib/types.ts#L25) | true |
| renderer | Custom component Renderer | [RendererInterface](src/lib/types.ts) | true |


### Using hook
Expand Down Expand Up @@ -76,19 +82,18 @@ const CustomComponent = () => {

#### Options

| Option | Description | Type | Optional? |
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | --------- |
| colorScheme | Device color scheme ("dark" or "light") | ColorSchemeName | false |
| styles | Styles for parsed components | [MarkedStyles](https://github.com/gmsgowtham/react-native-marked/blob/main/src/theme/types.ts#L5) | true |
| theme | Props for customizing colors and spacing for all components,and it will get overridden with custom component style applied via 'styles' prop | [UserTheme](https://github.com/gmsgowtham/react-native-marked/blob/main/src/theme/types.ts#L28) | true |
| baseUrl | A prefix url for any relative link | string | true |
| renderer | Custom component Renderer | [RendererInterface](https://github.com/gmsgowtham/react-native-marked/blob/main/src/lib/types.ts#L29) | true |
| tokenizer | Generate custom tokens | [MarkedTokenizer<CustomToken>](https://github.com/gmsgowtham/react-native-marked/blob/main/src/lib/types.ts#L24) | true |
| Option | Description | Type | Optional? |
|-------------|----------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------|-----------|
| colorScheme | Device color scheme ("dark" or "light") | ColorSchemeName | false |
| styles | Styles for parsed components | [MarkedStyles](src/theme/types.ts) | true |
| theme | Props for customizing colors and spacing for all components,and it will get overridden with custom component style applied via 'styles' prop | [UserTheme](src/theme/types.ts) | true |
| baseUrl | A prefix url for any relative link | string | true |
| renderer | Custom component Renderer | [RendererInterface](src/lib/types.ts) | true |
| tokenizer | Generate custom tokens | [MarkedTokenizer<CustomToken>](src/lib/types.ts) | true |


## Examples

- RN App: https://github.com/gmsgowtham/react-native-marked-test
- CodeSandbox: https://codesandbox.io/s/react-native-marked-l2hpi3?file=/src/App.js

## Supported elements
Expand Down Expand Up @@ -180,22 +185,12 @@ const ExampleComponentWithHook = () => {
export default ExampleComponent;
```

> Please refer to [RendererInterface](https://github.com/gmsgowtham/react-native-marked/blob/main/src/lib/types.ts#L2) for all the overrides
> Please refer to [RendererInterface](src/lib/types.ts) for all the overrides

> Note:
>
> For `key` property for a component, you can use the `getKey` method from Renderer class.

### Using tokenizer with custom components

Refer [marked](https://marked.js.org/using_pro#tokenizer)
> The tokenizer defines how to turn markdown text into tokens. If you supply a tokenizer object to the Marked options, it will be merged with the built-in tokenizer and any functions inside will override the default handling of that token type.

-------------

> The implementation requires you to return a token of type 'custom' (ref: [CustomToken](https://github.com/gmsgowtham/react-native-marked/blob/main/src/lib/types.ts#L83)) and the same needs to be implemented in the Renderer


#### Example

Overriding default codespan tokenizer to include LaTeX.
Expand All @@ -206,41 +201,28 @@ import React, { ReactNode } from "react";
import Markdown, { Renderer, MarkedTokenizer, MarkedLexer } from "react-native-marked";
import type { RendererInterface, CustomToken } from "react-native-marked";

class CustomTokenizer extends MarkedTokenizer<CustomToken> {
// Override
codespan(this: MarkedTokenizer<CustomToken>, src: string) {
class CustomTokenizer extends Tokenizer {
codespan(src: string): Tokens.Codespan | undefined {
const match = src.match(/^\$+([^\$\n]+?)\$+/);
if (match?.[1]) {
const text = match[1].trim();
const token: CustomToken = {
type: 'custom',
raw: match[0], // should be the exact regex pattern match
identifier: "latex", // Uniq identifier for the token
tokens: MarkedLexer(text), // optional, can be used if the markdown contains children
args: { // optional, can be used to send more information to the renderer
text: text,
}
return {
type: "codespan",
raw: match[0],
text: match[1].trim(),
};
return token;
}

return super.codespan(src)
return super.codespan(src);
}
}

class CustomRenderer extends Renderer implements RendererInterface {
// Custom Token implementation
custom(identifier: string, _raw: string, _children?: ReactNode[], args?: Record<string, unknown>): ReactNode {
const text = args?.text as string;
if (identifier === "latex") {
const styles = {
padding: 16,
minWidth: "100%",
backgroundColor: "#f6f8fa"
};
return this.code(text.trim(), "latex", styles);
}
return null;
codespan(text: string, styles?: TextStyle): ReactNode {
return (
<Text style={styles} key={"key-1"}>
{text}
</Text>
)
}
}

Expand All @@ -266,7 +248,7 @@ const ExampleComponent = () => {
## Screenshots

| Dark Theme | Light Theme |
| :-----------------------------------------------------------: | :--------------------------------------------------------------: |
|:-------------------------------------------------------------:|:----------------------------------------------------------------:|
| ![Dark theme](assets/dark-theme-01.png?raw=true 'Dark Theme') | ![Light theme](assets/light-theme-01.png?raw=true 'Light Theme') |

## Contributing
Expand All @@ -287,9 +269,11 @@ Made with

- [Marked](https://marked.js.org/)
- [@jsamr/react-native-li](https://github.com/jsamr/react-native-li)
- [react-native-table-component](https://github.com/Gil2015/react-native-table-component)
- [react-native-reanimated-table](https://github.com/dohooo/react-native-reanimated-table)
- [react-native-svg](https://github.com/software-mansion/react-native-svg)
- [svg-parser](https://github.com/Rich-Harris/svg-parser)
- [github-slugger](https://github.com/Flet/github-slugger)
- [html-entities](https://github.com/mdevils/html-entities)



<a href="https://www.buymeacoffee.com/gmsgowtham" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="width: 120px !important;" ></a>
2 changes: 1 addition & 1 deletion babel.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module.exports = {
presets: ["module:metro-react-native-babel-preset"],
presets: ["module:@react-native/babel-preset"],
};
34 changes: 6 additions & 28 deletions examples/react-native-marked-sample/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,19 @@ import Markdown, {
Renderer,
MarkedTokenizer,
type RendererInterface,
type CustomToken,
MarkedLexer,
type Tokens,
} from "react-native-marked";
import { MD_STRING } from "./const";

class CustomTokenizer extends MarkedTokenizer<CustomToken> {
codespan(this: MarkedTokenizer<CustomToken>, src: string) {
class CustomTokenizer extends MarkedTokenizer {
codespan(this: MarkedTokenizer, src: string): Tokens.Codespan | undefined {
const match = src.match(/^\$+([^\$\n]+?)\$+/);
if (match?.[1]) {
const token: CustomToken = {
type: "custom",
return {
type: "codespan",
raw: match[0],
identifier: "latex",
args: {
text: match[1].trim(),
},
text: match[1].trim(),
};
return token;
}

return super.codespan(src);
Expand All @@ -45,23 +40,6 @@ class CustomRenderer extends Renderer implements RendererInterface {
</Text>
);
}
custom(
identifier: string,
_raw: string,
_children: ReactNode[] = [],
args: Record<string, unknown> = {},
): ReactNode {
if (identifier === "latex" && args.text) {
return this.code(args.text as string, "latex", {
flex: 1,
width: "100%",
padding: 16,
minWidth: "100%",
backgroundColor: "#f6f8fa",
});
}
return null;
}
}

const renderer = new CustomRenderer();
Expand Down
8 changes: 4 additions & 4 deletions examples/react-native-marked-sample/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
"web": "expo start --web"
},
"dependencies": {
"@expo/metro-runtime": "~4.0.0",
"expo": "~52.0.24",
"expo-status-bar": "~2.0.0",
"@expo/metro-runtime": "~4.0.1",
"expo": "~52.0.28",
"expo-status-bar": "~2.0.1",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-native": "0.76.5",
"react-native": "0.76.6",
"react-native-svg": "15.8.0",
"react-native-web": "~0.19.13"
},
Expand Down
Loading