diff --git a/README.md b/README.md index e19c3f2..5f67ac8 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ - 🖼️ Inline and block image rendering - 🌙 Dark Mode support - ⚙️ Custom renderers and styles for flexible UI customization +- 🧩 Supports Remark plugins to enhance capabilities ## Installation @@ -62,33 +63,33 @@ This is a **Markdown** example with [a link](https://reactnative.dev). export default function App() { return ( - ( - {node.value} - ), - ThematicBreakRenderer: () => ( - - ), - }} - customStyles={{ - // Override default styles - // Checkout https://github.com/imwithye/react-native-remark/blob/main/src/themes/default.tsx - // for the default styles. - inlineCode: { - color: "red", - }, - text: { - color: "red", - }, - }} - onCodeCopy={(code) => Clipboard.setStringAsync(code)} - onLinkPress={(url) => Linking.openURL(url)} - /> + ( + {node.value} + ), + ThematicBreakRenderer: () => ( + + ), + }} + customStyles={{ + // Override default styles + // Checkout https://github.com/imwithye/react-native-remark/blob/main/src/themes/default.tsx + // for the default styles. + inlineCode: { + color: "red", + }, + text: { + color: "red", + }, + }} + onCodeCopy={(code) => Clipboard.setStringAsync(code)} + onLinkPress={(url) => Linking.openURL(url)} + /> ); } ``` @@ -110,9 +111,11 @@ index?: number; Checkout [renderers](./src/renderers/) for the default implementations. To ensure type safety when creating custom renderers, you can use the `RendererArgs` props interface. +Note that the library ships with renderers for the `remark-gfm` plugin since we think it is often used. You don't need to pass custom renderers (though you can!) for this plugin. + ## Supported Themes -Themes are pre-defined style collections that provide consistent visual styling for markdown content. Currently, we support two built-in themes: +Themes are pre-defined style collections that provide consistent visual styling for markdown content. Currently, we support two built-in themes: 1. default 2. serif @@ -124,7 +127,7 @@ To use a theme, you can follow this pattern: import { themes } from "react-native-remark" const { serifTheme } = themes; -// Thene you can use it with +// Then you can use it with ``` @@ -134,28 +137,45 @@ Custom styles will override the selected theme's default styles. Checkout [default.tsx](./src/themes/default.tsx) for default styles. -| Style Key | Description | Example Markdown Element | -|-------------------|---------------------------------------|-------------------------------| -| `blockquote` | Styles for blockquotes | `> This is a blockquote` | -| `borderColor` | Default border color used globally | Borders, thematic breaks | -| `break` | Line break styling (empty by default) | Line breaks | -| `codeBlock` | Styles for code blocks | ```code``` blocks | -| `container` | Container layout spacing | Root container layout | -| `delete` | Deleted text style | ~~strikethrough~~ text | -| `emphasis` | Italic text style | *italic* or _italic_ | -| `footnoteReference` | Style for footnote references | Footnote markers | -| `heading` | Heading styles (h1, h2, h3...) | # Heading | -| `image` | Image styling | Inline or block images | -| `inlineCode` | Inline code styling | `inline code` | -| `link` | Link styling | [link](url) | -| `linkReference` | Reference-style links | [reference][id] | -| `list` | List container styling | Lists (`- item` or `1. item`) | -| `listItem` | List item styling | Each list item | -| `paragraph` | Paragraph text styling | Normal paragraphs | -| `strong` | Bold text style | **bold** | -| `tableCell` | Table cell text styling | Table cell contents | -| `text` | General text style | Plain text | -| `thematicBreak` | Horizontal rule styling | --- | +| Style Key | Description | Example Markdown Element | +| ------------------- | ------------------------------------- | ----------------------------- | +| `blockquote` | Styles for blockquotes | `> This is a blockquote` | +| `borderColor` | Default border color used globally | Borders, thematic breaks | +| `break` | Line break styling (empty by default) | Line breaks | +| `codeBlock` | Styles for code blocks | `code` blocks | +| `container` | Container layout spacing | Root container layout | +| `delete` | Deleted text style | ~~strikethrough~~ text | +| `emphasis` | Italic text style | *italic* or _italic_ | +| `footnoteReference` | Style for footnote references | Footnote markers | +| `heading` | Heading styles (h1, h2, h3...) | # Heading | +| `image` | Image styling | Inline or block images | +| `inlineCode` | Inline code styling | `inline code` | +| `link` | Link styling | [link](url) | +| `linkReference` | Reference-style links | [reference][id] | +| `list` | List container styling | Lists (`- item` or `1. item`) | +| `listItem` | List item styling | Each list item | +| `paragraph` | Paragraph text styling | Normal paragraphs | +| `strong` | Bold text style | **bold** | +| `tableCell` | Table cell text styling | Table cell contents | +| `text` | General text style | Plain text | +| `thematicBreak` | Horizontal rule styling | --- | + +## Remark plugins usage + +You can inject Remark plugins _via_ the `remarkPlugins` prop. For example, you can use `remark-cjk-friendly` to add support for bold (`**`) with Chinese, Japanese and Korean alphabets by doing the following: + +```jsx +import remarkCjkFriendly from "remark-cjk-friendly"; +import remarkGfm from "remark-gfm"; + +; +``` + +Note that: + +- though `remark-gfm` is supported out of the box, you'll need to add the plugin manually when injecting other Remark plugins +- when using plugins that add support for additional nodes, you'll need to inject the required renderers using the `customRenderers` prop +- ⚠️ asynchronous plugins aren't supported yet; passing any asynchronous plugin will result in a crash ⚠️ ## Quick Look @@ -177,4 +197,3 @@ By interacting with this repository, organization, or community you agree to abi Star History Chart - diff --git a/example/App.tsx b/example/App.tsx index 3275499..6ddd2f9 100644 --- a/example/App.tsx +++ b/example/App.tsx @@ -2,15 +2,14 @@ import { ActionSheetProvider, useActionSheet, } from "@expo/react-native-action-sheet"; -import { Markdown } from "@react-native-remark"; -import { themes } from "@react-native-remark"; +import { Markdown, themes } from "@react-native-remark"; import { createStaticNavigation, useNavigation, } from "@react-navigation/native"; import { createNativeStackNavigator } from "@react-navigation/native-stack"; import { StatusBar } from "expo-status-bar"; -import { useEffect, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { ActivityIndicator, Alert, @@ -19,6 +18,8 @@ import { ScrollView, useColorScheme, } from "react-native"; +import remarkCjkFriendly from "remark-cjk-friendly"; +import remarkGfm from "remark-gfm"; const { defaultTheme, githubTheme, serifTheme } = themes; @@ -30,11 +31,23 @@ const HomeScreen = () => { const colorScheme = useColorScheme(); const navigation = useNavigation(); const { showActionSheetWithOptions } = useActionSheet(); - const [url, setUrl] = useState(URL); const [markdown, setMarkdown] = useState(""); const [theme, setTheme] = useState(defaultTheme); const [loading, setLoading] = useState(false); + const loadMarkdown = useCallback((url: string) => { + setLoading(true); + + const controller = new AbortController(); + + fetch(url, { signal: controller.signal }) + .then((res) => res.text()) + .then((text) => setMarkdown(text)) + .finally(() => setTimeout(() => setLoading(false), 1000)); + + return controller; + }, []); + useEffect(() => { navigation.setOptions({ headerTintColor: colorScheme === "dark" ? "white" : "black", @@ -103,7 +116,11 @@ const HomeScreen = () => { url: `${BASE_URL}/04_pytorch.md`, }, { - title: "5. Load from URL", + title: "5. Bug fixing with CJK plugin", + url: `${BASE_URL}/05_cjk_plugin_example.md`, + }, + { + title: "6. Load from URL", url: "", }, ]; @@ -115,28 +132,34 @@ const HomeScreen = () => { }, (idx?: number) => { if (!idx || idx === cancelButtonIndex) return; + if (idx === options.length - 1) { Alert.prompt("Load Markdown from URL", "", (url) => { - setUrl(url); + loadMarkdown(url); }); return; } - setUrl(options[idx].url); + + loadMarkdown(options[idx].url); }, ); }} /> ), }); - }, [colorScheme, navigation, showActionSheetWithOptions, setTheme, setUrl]); + }, [ + colorScheme, + navigation, + showActionSheetWithOptions, + setTheme, + loadMarkdown, + ]); useEffect(() => { - setLoading(true); - fetch(url) - .then((res) => res.text()) - .then((text) => setMarkdown(text)) - .finally(() => setTimeout(() => setLoading(false), 1000)); - }, [url]); + const controller = loadMarkdown(URL); + + return () => controller.abort(); + }, [loadMarkdown]); return ( { Linking.openURL(url)} /> )} diff --git a/example/package.json b/example/package.json index 8afba21..73f6741 100644 --- a/example/package.json +++ b/example/package.json @@ -16,7 +16,8 @@ "expo-status-bar": "~2.2.3", "react": "19.0.0", "react-native": "0.79.4", - "react-native-remark": "file:../" + "react-native-remark": "file:../", + "remark-cjk-friendly": "^2.0.1" }, "devDependencies": { "@babel/core": "^7.25.2", diff --git a/example/pnpm-lock.yaml b/example/pnpm-lock.yaml index e7d759b..58347a9 100644 --- a/example/pnpm-lock.yaml +++ b/example/pnpm-lock.yaml @@ -19,7 +19,7 @@ importers: version: 7.3.16(@react-navigation/native@7.1.11(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native-safe-area-context@5.4.1(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native-screens@4.11.1(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) expo: specifier: ~53.0.12 - version: 53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) + version: 53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) expo-status-bar: specifier: ~2.2.3 version: 2.2.3(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) @@ -31,7 +31,10 @@ importers: version: 0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0) react-native-remark: specifier: file:../ - version: file:..(expo-font@13.3.1(expo@53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) + version: file:..(expo-font@13.3.1(expo@53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) + remark-cjk-friendly: + specifier: ^2.0.1 + version: 2.0.1(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(unified@11.0.5) devDependencies: '@babel/core': specifier: ^7.25.2 @@ -554,18 +557,30 @@ packages: '@expo/config-plugins@10.0.3': resolution: {integrity: sha512-fjCckkde67pSDf48x7wRuPsgQVIqlDwN7NlOk9/DFgQ1hCH0L5pGqoSmikA1vtAyiA83MOTpkGl3F3wyATyUog==} + '@expo/config-plugins@10.1.2': + resolution: {integrity: sha512-IMYCxBOcnuFStuK0Ay+FzEIBKrwW8OVUMc65+v0+i7YFIIe8aL342l7T4F8lR4oCfhXn7d6M5QPgXvjtc/gAcw==} + '@expo/config-types@53.0.4': resolution: {integrity: sha512-0s+9vFx83WIToEr0Iwy4CcmiUXa5BgwBmEjylBB2eojX5XAMm9mJvw9KpjAb8m7zq2G0Q6bRbeufkzgbipuNQg==} + '@expo/config-types@53.0.5': + resolution: {integrity: sha512-kqZ0w44E+HEGBjy+Lpyn0BVL5UANg/tmNixxaRMLS6nf37YsDrLk2VMAmeKMMk5CKG0NmOdVv3ngeUjRQMsy9g==} + '@expo/config@11.0.10': resolution: {integrity: sha512-8S8Krr/c5lnl0eF03tA2UGY9rGBhZcbWKz2UWw5dpL/+zstwUmog8oyuuC8aRcn7GiTQLlbBkxcMeT8sOGlhbA==} + '@expo/config@11.0.13': + resolution: {integrity: sha512-TnGb4u/zUZetpav9sx/3fWK71oCPaOjZHoVED9NaEncktAd0Eonhq5NUghiJmkUGt3gGSjRAEBXiBbbY9/B1LA==} + '@expo/devcert@1.2.0': resolution: {integrity: sha512-Uilcv3xGELD5t/b0eM4cxBFEKQRIivB3v7i+VhWLV/gL98aw810unLKKJbGAxAIhY6Ipyz8ChWibFsKFXYwstA==} '@expo/env@1.0.5': resolution: {integrity: sha512-dtEZ4CAMaVrFu2+tezhU3FoGWtbzQl50xV+rNJE5lYVRjUflWiZkVHlHkWUlPAwDPifLy4TuissVfScGGPWR5g==} + '@expo/env@1.0.7': + resolution: {integrity: sha512-qSTEnwvuYJ3umapO9XJtrb1fAqiPlmUUg78N0IZXXGwQRt+bkp0OBls+Y5Mxw/Owj8waAM0Z3huKKskRADR5ow==} + '@expo/fingerprint@0.13.1': resolution: {integrity: sha512-MgZ5uIvvwAnjWeQoj4D3RnBXjD1GNOpCvhp2jtZWdQ8yEokhDEJGoHjsMT8/NCB5m2fqP5sv2V5nPzC7CN1YjQ==} hasBin: true @@ -573,9 +588,15 @@ packages: '@expo/image-utils@0.7.4': resolution: {integrity: sha512-LcZ82EJy/t/a1avwIboeZbO6hlw8CvsIRh2k6SWPcAOvW0RqynyKFzUJsvnjWlhUzfBEn4oI7y/Pu5Xkw3KkkA==} + '@expo/image-utils@0.7.6': + resolution: {integrity: sha512-GKnMqC79+mo/1AFrmAcUcGfbsXXTRqOMNS1umebuevl3aaw+ztsYEFEiuNhHZW7PQ3Xs3URNT513ZxKhznDscw==} + '@expo/json-file@9.1.4': resolution: {integrity: sha512-7Bv86X27fPERGhw8aJEZvRcH9sk+9BenDnEmrI3ZpywKodYSBgc8lX9Y32faNVQ/p0YbDK9zdJ0BfAKNAOyi0A==} + '@expo/json-file@9.1.5': + resolution: {integrity: sha512-prWBhLUlmcQtvN6Y7BpW2k9zXGd3ySa3R6rAguMJkp1z22nunLN64KYTUWfijFlprFoxm9r2VNnGkcbndAlgKA==} + '@expo/metro-config@0.20.15': resolution: {integrity: sha512-m8i58IQ7I8iOdVRfOhFmhPMHuhgeTVfQp1+mxW7URqPZaeVbuDVktPqOiNoHraKBoGPLKMUSsD+qdUuJVL3wMg==} @@ -589,6 +610,9 @@ packages: '@expo/plist@0.3.4': resolution: {integrity: sha512-MhBLaUJNe9FQDDU2xhSNS4SAolr6K2wuyi4+A79vYuXLkAoICsbTwcGEQJN5jPY6D9izO/jsXh5k0h+mIWQMdw==} + '@expo/plist@0.3.5': + resolution: {integrity: sha512-9RYVU1iGyCJ7vWfg3e7c/NVyMFs8wbl+dMWZphtFtsqyN9zppGREU3ctlD3i8KUE0sCUTVnLjCWr+VeUIDep2g==} + '@expo/prebuild-config@9.0.7': resolution: {integrity: sha512-1w5MBp6NdF51gPGp0HsCZt0QC82hZWo37wI9HfxhdQF/sN/92Mh4t30vaY7gjHe71T5QNyab00oxZH/wP0MDgQ==} @@ -1354,8 +1378,8 @@ packages: exec-async@2.2.0: resolution: {integrity: sha512-87OpwcEiMia/DeiKFzaQNBNFeN3XkkpYIh9FyOqq5mS2oKv3CBE67PXoEKcr6nodWdXNogTiQ0jE2NGuoffXPw==} - expo-asset@11.1.5: - resolution: {integrity: sha512-GEQDCqC25uDBoXHEnXeBuwpeXvI+3fRGvtzwwt0ZKKzWaN+TgeF8H7c76p3Zi4DfBMFDcduM0CmOvJX+yCCLUQ==} + expo-asset@11.1.7: + resolution: {integrity: sha512-b5P8GpjUh08fRCf6m5XPVAh7ra42cQrHBIMgH2UXP+xsj4Wufl6pLy6jRF5w6U7DranUMbsXm8TOyq4EHy7ADg==} peerDependencies: expo: '*' react: '*' @@ -1367,6 +1391,12 @@ packages: expo: '*' react-native: '*' + expo-constants@17.1.7: + resolution: {integrity: sha512-byBjGsJ6T6FrLlhOBxw4EaiMXrZEn/MlUYIj/JAd+FS7ll5X/S4qVRbIimSJtdW47hXMq0zxPfJX6njtA56hHA==} + peerDependencies: + expo: '*' + react-native: '*' + expo-file-system@18.1.10: resolution: {integrity: sha512-SyaWg+HitScLuyEeSG9gMSDT0hIxbM9jiZjSBP9l9zMnwZjmQwsusE6+7qGiddxJzdOhTP4YGUfvEzeeS0YL3Q==} peerDependencies: @@ -1494,6 +1524,10 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + get-east-asian-width@1.5.0: + resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} + engines: {node: '>=18'} + get-package-type@0.1.0: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} @@ -1508,11 +1542,12 @@ packages: glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} @@ -1962,6 +1997,25 @@ packages: micromark-core-commonmark@2.0.3: resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + micromark-extension-cjk-friendly-util@3.0.1: + resolution: {integrity: sha512-GcbXqTTHOsiZHyF753oIddP/J2eH8j9zpyQPhkof6B2JNxfEJabnQqxbCgzJNuNes0Y2jTNJ3LiYPSXr6eJA8w==} + engines: {node: '>=18'} + peerDependencies: + micromark-util-types: '*' + peerDependenciesMeta: + micromark-util-types: + optional: true + + micromark-extension-cjk-friendly@2.0.1: + resolution: {integrity: sha512-OkzoYVTL1ChbvQ8Cc1ayTIz7paFQz8iS9oIYmewncweUSwmWR+hkJF9spJ1lxB90XldJl26A1F4IkPOKS3bDXw==} + engines: {node: '>=18'} + peerDependencies: + micromark: ^4.0.0 + micromark-util-types: ^2.0.0 + peerDependenciesMeta: + micromark-util-types: + optional: true + micromark-extension-gfm-autolink-literal@2.1.0: resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} @@ -2370,6 +2424,12 @@ packages: react: '*' react-native: '*' + react-native-webview@13.16.0: + resolution: {integrity: sha512-Nh13xKZWW35C0dbOskD7OX01nQQavOzHbCw9XoZmar4eXCo7AvrYJ0jlUfRVVIJzqINxHlpECYLdmAdFsl9xDA==} + peerDependencies: + react: '*' + react-native: '*' + react-native@0.79.4: resolution: {integrity: sha512-CfxYMuszvnO/33Q5rB//7cU1u9P8rSOvzhE2053Phdb8+6bof9NLayCllU2nmPrm8n9o6RU1Fz5H0yquLQ0DAw==} engines: {node: '>=18'} @@ -2418,6 +2478,16 @@ packages: resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==} hasBin: true + remark-cjk-friendly@2.0.1: + resolution: {integrity: sha512-6WwkoQyZf/4j5k53zdFYrR8Ca+UVn992jXdLUSBDZR4eBpFhKyVxmA4gUHra/5fesjGIxrDhHesNr/sVoiiysA==} + engines: {node: '>=18'} + peerDependencies: + '@types/mdast': ^4.0.0 + unified: ^11.0.0 + peerDependenciesMeta: + '@types/mdast': + optional: true + remark-gfm@4.0.1: resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} @@ -3615,8 +3685,29 @@ snapshots: transitivePeerDependencies: - supports-color + '@expo/config-plugins@10.1.2': + dependencies: + '@expo/config-types': 53.0.5 + '@expo/json-file': 9.1.5 + '@expo/plist': 0.3.5 + '@expo/sdk-runtime-versions': 1.0.0 + chalk: 4.1.2 + debug: 4.4.1 + getenv: 2.0.0 + glob: 10.4.5 + resolve-from: 5.0.0 + semver: 7.7.2 + slash: 3.0.0 + slugify: 1.6.6 + xcode: 3.0.1 + xml2js: 0.6.0 + transitivePeerDependencies: + - supports-color + '@expo/config-types@53.0.4': {} + '@expo/config-types@53.0.5': {} + '@expo/config@11.0.10': dependencies: '@babel/code-frame': 7.10.4 @@ -3635,6 +3726,24 @@ snapshots: transitivePeerDependencies: - supports-color + '@expo/config@11.0.13': + dependencies: + '@babel/code-frame': 7.10.4 + '@expo/config-plugins': 10.1.2 + '@expo/config-types': 53.0.5 + '@expo/json-file': 9.1.5 + deepmerge: 4.3.1 + getenv: 2.0.0 + glob: 10.4.5 + require-from-string: 2.0.2 + resolve-from: 5.0.0 + resolve-workspace-root: 2.0.0 + semver: 7.7.2 + slugify: 1.6.6 + sucrase: 3.35.0 + transitivePeerDependencies: + - supports-color + '@expo/devcert@1.2.0': dependencies: '@expo/sudo-prompt': 9.3.2 @@ -3653,6 +3762,16 @@ snapshots: transitivePeerDependencies: - supports-color + '@expo/env@1.0.7': + dependencies: + chalk: 4.1.2 + debug: 4.4.1 + dotenv: 16.4.7 + dotenv-expand: 11.0.7 + getenv: 2.0.0 + transitivePeerDependencies: + - supports-color + '@expo/fingerprint@0.13.1': dependencies: '@expo/spawn-async': 1.7.2 @@ -3682,11 +3801,28 @@ snapshots: temp-dir: 2.0.0 unique-string: 2.0.0 + '@expo/image-utils@0.7.6': + dependencies: + '@expo/spawn-async': 1.7.2 + chalk: 4.1.2 + getenv: 2.0.0 + jimp-compact: 0.16.1 + parse-png: 2.1.0 + resolve-from: 5.0.0 + semver: 7.7.2 + temp-dir: 2.0.0 + unique-string: 2.0.0 + '@expo/json-file@9.1.4': dependencies: '@babel/code-frame': 7.10.4 json5: 2.2.3 + '@expo/json-file@9.1.5': + dependencies: + '@babel/code-frame': 7.10.4 + json5: 2.2.3 + '@expo/metro-config@0.20.15': dependencies: '@babel/core': 7.27.4 @@ -3731,6 +3867,12 @@ snapshots: base64-js: 1.5.1 xmlbuilder: 15.1.1 + '@expo/plist@0.3.5': + dependencies: + '@xmldom/xmldom': 0.8.10 + base64-js: 1.5.1 + xmlbuilder: 15.1.1 + '@expo/prebuild-config@9.0.7': dependencies: '@expo/config': 11.0.10 @@ -3760,9 +3902,9 @@ snapshots: '@expo/sudo-prompt@9.3.2': {} - '@expo/vector-icons@14.1.0(expo-font@13.3.1(expo@53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0)': + '@expo/vector-icons@14.1.0(expo-font@13.3.1(expo@53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0)': dependencies: - expo-font: 13.3.1(expo@53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react@19.0.0) + expo-font: 13.3.1(expo@53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react@19.0.0) react: 19.0.0 react-native: 0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0) @@ -4621,39 +4763,48 @@ snapshots: exec-async@2.2.0: {} - expo-asset@11.1.5(expo@53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0): + expo-asset@11.1.7(expo@53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0): dependencies: - '@expo/image-utils': 0.7.4 - expo: 53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) - expo-constants: 17.1.6(expo@53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0)) + '@expo/image-utils': 0.7.6 + expo: 53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) + expo-constants: 17.1.7(expo@53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0)) react: 19.0.0 react-native: 0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0) transitivePeerDependencies: - supports-color - expo-constants@17.1.6(expo@53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0)): + expo-constants@17.1.6(expo@53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0)): dependencies: '@expo/config': 11.0.10 '@expo/env': 1.0.5 - expo: 53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) + expo: 53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) react-native: 0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0) transitivePeerDependencies: - supports-color - expo-file-system@18.1.10(expo@53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0)): + expo-constants@17.1.7(expo@53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0)): dependencies: - expo: 53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) + '@expo/config': 11.0.13 + '@expo/env': 1.0.7 + expo: 53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) react-native: 0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0) + transitivePeerDependencies: + - supports-color - expo-font@13.3.1(expo@53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react@19.0.0): + expo-file-system@18.1.10(expo@53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0)): dependencies: - expo: 53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) + expo: 53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) + react-native: 0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0) + + expo-font@13.3.1(expo@53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react@19.0.0): + dependencies: + expo: 53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) fontfaceobserver: 2.3.0 react: 19.0.0 - expo-keep-awake@14.1.4(expo@53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react@19.0.0): + expo-keep-awake@14.1.4(expo@53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react@19.0.0): dependencies: - expo: 53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) + expo: 53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) react: 19.0.0 expo-modules-autolinking@2.1.12: @@ -4677,7 +4828,7 @@ snapshots: react-native-edge-to-edge: 1.6.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) react-native-is-edge-to-edge: 1.1.7(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) - expo@53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0): + expo@53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0): dependencies: '@babel/runtime': 7.27.6 '@expo/cli': 0.24.15 @@ -4685,19 +4836,21 @@ snapshots: '@expo/config-plugins': 10.0.3 '@expo/fingerprint': 0.13.1 '@expo/metro-config': 0.20.15 - '@expo/vector-icons': 14.1.0(expo-font@13.3.1(expo@53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) + '@expo/vector-icons': 14.1.0(expo-font@13.3.1(expo@53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) babel-preset-expo: 13.2.1(@babel/core@7.27.4) - expo-asset: 11.1.5(expo@53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) - expo-constants: 17.1.6(expo@53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0)) - expo-file-system: 18.1.10(expo@53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0)) - expo-font: 13.3.1(expo@53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react@19.0.0) - expo-keep-awake: 14.1.4(expo@53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react@19.0.0) + expo-asset: 11.1.7(expo@53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) + expo-constants: 17.1.6(expo@53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0)) + expo-file-system: 18.1.10(expo@53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0)) + expo-font: 13.3.1(expo@53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react@19.0.0) + expo-keep-awake: 14.1.4(expo@53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react@19.0.0) expo-modules-autolinking: 2.1.12 expo-modules-core: 2.4.0 react: 19.0.0 react-native: 0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0) react-native-edge-to-edge: 1.6.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) whatwg-url-without-unicode: 8.0.0-3 + optionalDependencies: + react-native-webview: 13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) transitivePeerDependencies: - '@babel/core' - babel-plugin-react-compiler @@ -4776,6 +4929,8 @@ snapshots: get-caller-file@2.0.5: {} + get-east-asian-width@1.5.0: {} + get-package-type@0.1.0: {} getenv@1.0.0: {} @@ -5438,6 +5593,25 @@ snapshots: micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 + micromark-extension-cjk-friendly-util@3.0.1(micromark-util-types@2.0.2): + dependencies: + get-east-asian-width: 1.5.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + optionalDependencies: + micromark-util-types: 2.0.2 + + micromark-extension-cjk-friendly@2.0.1(micromark-util-types@2.0.2)(micromark@4.0.2): + dependencies: + devlop: 1.1.0 + micromark: 4.0.2 + micromark-extension-cjk-friendly-util: 3.0.1(micromark-util-types@2.0.2) + micromark-util-chunked: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + optionalDependencies: + micromark-util-types: 2.0.2 + micromark-extension-gfm-autolink-literal@2.1.0: dependencies: micromark-util-character: 2.1.1 @@ -5882,9 +6056,9 @@ snapshots: react: 19.0.0 react-native: 0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0) - react-native-remark@file:..(expo-font@13.3.1(expo@53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0): + react-native-remark@file:..(expo-font@13.3.1(expo@53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0): dependencies: - '@expo/vector-icons': 14.1.0(expo-font@13.3.1(expo@53.0.12(@babel/core@7.27.4)(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) + '@expo/vector-icons': 14.1.0(expo-font@13.3.1(expo@53.0.12(@babel/core@7.27.4)(react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react@19.0.0))(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) '@types/mdast': 4.0.4 react: 19.0.0 react-native: 0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0) @@ -5910,6 +6084,14 @@ snapshots: react-native-is-edge-to-edge: 1.1.7(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) warn-once: 0.1.1 + react-native-webview@13.16.0(react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0): + dependencies: + escape-string-regexp: 4.0.0 + invariant: 2.2.4 + react: 19.0.0 + react-native: 0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0) + optional: true + react-native@0.79.4(@babel/core@7.27.4)(@types/react@19.0.14)(react@19.0.0): dependencies: '@jest/create-cache-key-function': 29.7.0 @@ -6001,6 +6183,16 @@ snapshots: dependencies: jsesc: 3.0.2 + remark-cjk-friendly@2.0.1(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(unified@11.0.5): + dependencies: + micromark-extension-cjk-friendly: 2.0.1(micromark-util-types@2.0.2)(micromark@4.0.2) + unified: 11.0.5 + optionalDependencies: + '@types/mdast': 4.0.4 + transitivePeerDependencies: + - micromark + - micromark-util-types + remark-gfm@4.0.1: dependencies: '@types/mdast': 4.0.4 diff --git a/markdown/05_cjk_plugin_example.md b/markdown/05_cjk_plugin_example.md new file mode 100644 index 0000000..1a51398 --- /dev/null +++ b/markdown/05_cjk_plugin_example.md @@ -0,0 +1,13 @@ +_The following is an extract of the `remark-cjk-friendly` plugin's README file_ + +## Problem / 問題 / 问题 / 문제 + +CommonMark has a problem that the following emphasis marks `**` are not recognized as emphasis marks in Japanese, Chinese, and Korean. + +**このアスタリスクは強調記号として認識されず、そのまま表示されます。**この文のせいで。 + +**该星号不会被识别,而是直接显示。**这是因为它没有被识别为强调符号。 + +**이 별표는 강조 표시로 인식되지 않고 그대로 표시됩니다(이 괄호 때문에)**이 문장 때문에. + +This problem occurs because the character just inside the `**` is a (Japanese or Chinese) punctuation mark (。) or parenthesis and the character just outside is not a space or punctuation mark. diff --git a/src/markdown.tsx b/src/markdown.tsx index 22c7aef..fd7b540 100644 --- a/src/markdown.tsx +++ b/src/markdown.tsx @@ -3,7 +3,7 @@ import { useMemo, useState } from "react"; import { LayoutChangeEvent, View, useColorScheme } from "react-native"; import remarkGfm from "remark-gfm"; import remarkParse from "remark-parse"; -import { unified } from "unified"; +import { type PluggableList, unified } from "unified"; import { visit } from "unist-util-visit"; import { MarkdownContextProvider } from "./context"; @@ -13,7 +13,7 @@ import { RootRenderer } from "./renderers/root"; import { Theme, defaultTheme } from "./themes"; import { Styles, mergeStyles } from "./themes/themes"; -const parser = unified().use(remarkParse).use(remarkGfm); +const defaultRemarkPlugins: PluggableList = [remarkGfm]; function extractDefinitions(tree: Root): Record { const definitions: Record = {}; @@ -30,6 +30,7 @@ export type MarkdownProps = { customStyles?: Partial; onCodeCopy?: (code: string) => void; onLinkPress?: (url: string) => void; + remarkPlugins?: PluggableList; }; export const Markdown = ({ @@ -39,8 +40,18 @@ export const Markdown = ({ customStyles, onCodeCopy, onLinkPress, + remarkPlugins = defaultRemarkPlugins, }: MarkdownProps) => { - const tree = useMemo(() => parser.parse(markdown), [markdown]); + const processor = useMemo( + () => unified().use(remarkParse).use(remarkPlugins), + [remarkPlugins], + ); + + const tree: Root = useMemo(() => { + // We use runSync to synchronously apply plugins. If a user tries to use an async plugin, it will throw an error. + // This is intended to avoid silently failing since we can't render async react components on the client. + return processor.runSync(processor.parse(markdown)) as Root; + }, [markdown, processor]); const activeTheme = theme ?? defaultTheme; const renderers = useMemo(