react-native-enriched-markdown 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,6 +16,58 @@
16
16
 
17
17
  require 'json'
18
18
 
19
+ module EnrichedMarkdownConfig
20
+ @warnings_emitted = {}
21
+
22
+ def self.warn_once(key, message)
23
+ return if @warnings_emitted[key]
24
+ @warnings_emitted[key] = true
25
+ Pod::UI.warn message
26
+ end
27
+
28
+ # The consumer app's package.json "enriched-markdown" block is the build-time
29
+ # source of truth for feature toggles (mirrors the Android build.gradle and
30
+ # react-native-worklets). It is read from the Podfile's installation root --
31
+ # "<app>/package.json", one level above the "<app>/ios" dir CocoaPods installs
32
+ # into -- so in a monorepo it resolves to the app being built, not the workspace
33
+ # root. Per-app config therefore works; the download side (postinstall) is a
34
+ # separate, install-time decision. ENV vars remain a deprecated fallback.
35
+ #
36
+ # A cheap accessor over the memoized package.json (see consumer_package_json), so both
37
+ # this file (code highlighting) and the main podspec (math) can read it without re-parsing.
38
+ def self.consumer_config
39
+ config = consumer_package_json['enriched-markdown']
40
+ config.is_a?(Hash) ? config : {}
41
+ end
42
+
43
+ # A filesystem-safe identifier for the app being built, derived from its package.json
44
+ # "name" (falling back to the app directory name). It keys the per-app generated
45
+ # code-highlight registry (generated-<slug>) so that, in a hoisted monorepo, two apps
46
+ # with different custom language sets each get their own registry instead of clobbering
47
+ # a single shared one.
48
+ def self.consumer_app_slug
49
+ name = consumer_package_json['name'].to_s
50
+ name = File.basename(File.dirname(Pod::Config.instance.installation_root.to_s)) if name.empty?
51
+ slug = name.gsub(%r{[^A-Za-z0-9._-]+}, '-').gsub(/\A-+|-+\z/, '')
52
+ slug.empty? ? 'app' : slug
53
+ end
54
+
55
+ def self.consumer_package_json
56
+ return @consumer_package_json if defined?(@consumer_package_json)
57
+ @consumer_package_json = load_consumer_package_json
58
+ end
59
+
60
+ def self.load_consumer_package_json
61
+ path = File.join(Pod::Config.instance.installation_root.to_s, '..', 'package.json')
62
+ return {} unless File.exist?(path)
63
+ JSON.parse(File.read(path))
64
+ rescue StandardError => e
65
+ Pod::UI.warn "[ReactNativeEnrichedMarkdown] could not read the app package.json " \
66
+ "(#{e.message}); using defaults."
67
+ {}
68
+ end
69
+ end
70
+
19
71
  module EnrichedMarkdownCodeHighlight
20
72
  # Locate grammar-versions.json in both layouts, mirroring how gen-registry.mjs
21
73
  # is resolved below: "<podspec_dir>/../../vendor" in the monorepo, and the copy
@@ -40,29 +92,70 @@ module EnrichedMarkdownCodeHighlight
40
92
  # podspec_dir is the directory of the including podspec; cpp is reached at
41
93
  # "<podspec_dir>/cpp" (a symlink in the monorepo, real files when published).
42
94
  def self.config(podspec_dir)
43
- return disabled if ENV['ENRICHED_MARKDOWN_ENABLE_CODE_HIGHLIGHT'] == '0'
95
+ config = EnrichedMarkdownConfig.consumer_config
96
+ env_enable = ENV['ENRICHED_MARKDOWN_ENABLE_CODE_HIGHLIGHT']
97
+
98
+ # Enable flag: package.json > ENV (deprecated) > default on. `explicit` tracks
99
+ # whether the consumer actively opted in (vs the implicit default), which decides
100
+ # the missing-asset behavior below.
101
+ if config.key?('enableCodeHighlight')
102
+ requested = config['enableCodeHighlight'] != false
103
+ explicit = requested
104
+ if env_enable
105
+ EnrichedMarkdownConfig.warn_once(:code_highlight_env, '[ReactNativeEnrichedMarkdown] DEPRECATED: ENV[\'ENRICHED_MARKDOWN_ENABLE_CODE_HIGHLIGHT\'] ' \
106
+ 'is ignored when "enriched-markdown".enableCodeHighlight is set in your package.json.')
107
+ end
108
+ elsif env_enable
109
+ EnrichedMarkdownConfig.warn_once(:code_highlight_env, '[ReactNativeEnrichedMarkdown] DEPRECATED: ENV[\'ENRICHED_MARKDOWN_ENABLE_CODE_HIGHLIGHT\'] ' \
110
+ 'will be removed in a future version. Configure via "enriched-markdown".enableCodeHighlight in your package.json instead.')
111
+ requested = env_enable != '0'
112
+ explicit = requested
113
+ else
114
+ requested = true
115
+ explicit = false
116
+ end
44
117
 
45
- # Code highlighting compiles the vendored tree-sitter runtime + grammar sources,
46
- # downloaded at postinstall. The grammars/.stamp marker is written only after every
47
- # grammar source is fully vendored, so gating on it (rather than the runtime lib.c,
48
- # which is fetched first) also falls back to the no-op stub on a partial/failed
49
- # download -- not just a `enriched-markdown`.enableCodeHighlight = false opt-out.
50
- return disabled unless File.exist?(File.join(podspec_dir, 'cpp/highlight/vendor/grammars/.stamp'))
118
+ return disabled unless requested
119
+
120
+ # The grammars/.stamp marker is written only after every grammar source is fully
121
+ # vendored at postinstall. If the consumer explicitly enabled highlighting but the
122
+ # grammars are absent (opted out of the download, or a partial/failed one), fail
123
+ # loud with the fix. If highlighting is merely on by default, degrade to the no-op
124
+ # stub so a missing download never breaks an otherwise-unconfigured build.
125
+ unless File.exist?(File.join(podspec_dir, 'cpp/highlight/vendor/grammars/.stamp'))
126
+ if explicit
127
+ raise '[ReactNativeEnrichedMarkdown] code highlighting is enabled but the tree-sitter ' \
128
+ 'grammars are not installed. Reinstall to fetch them: `npm rebuild react-native-enriched-markdown`. ' \
129
+ 'To disable, set "enriched-markdown".enableCodeHighlight = false in your app package.json. ' \
130
+ 'Troubleshooting: https://github.com/software-mansion/enriched-markdown/blob/main/docs/NATIVE_ASSETS.md'
131
+ end
132
+ return disabled
133
+ end
51
134
 
52
135
  defaults = default_languages(podspec_dir)
53
- langs = (ENV['ENRICHED_MARKDOWN_CODE_HIGHLIGHT_LANGUAGES'] || '')
54
- .split(',').map(&:strip).reject(&:empty?)
55
- langs = defaults.dup if langs.empty?
136
+ # Languages: package.json > ENV (deprecated) > manifest defaults. An explicit empty
137
+ # array disables all languages (return disabled below); only the default/ENV paths
138
+ # fall back to the manifest set.
139
+ if config['codeHighlightLanguages'].is_a?(Array)
140
+ langs = config['codeHighlightLanguages'].map { |l| l.to_s.strip }.reject(&:empty?)
141
+ elsif (env_langs = ENV['ENRICHED_MARKDOWN_CODE_HIGHLIGHT_LANGUAGES']) && !env_langs.empty?
142
+ EnrichedMarkdownConfig.warn_once(:code_highlight_languages_env, '[ReactNativeEnrichedMarkdown] DEPRECATED: ENV[\'ENRICHED_MARKDOWN_CODE_HIGHLIGHT_LANGUAGES\'] ' \
143
+ 'will be removed in a future version. Configure via "enriched-markdown".codeHighlightLanguages in your package.json instead.')
144
+ langs = env_langs.split(',').map(&:strip).reject(&:empty?)
145
+ langs = defaults.dup if langs.empty?
146
+ else
147
+ langs = defaults.dup
148
+ end
56
149
  return disabled if langs.empty?
57
150
 
58
151
  vendor = File.join(podspec_dir, 'cpp/highlight/vendor')
59
- # A custom language set regenerates its registry into a SEPARATE dir so it never
60
- # clobbers the committed default-set registry in vendor/generated. That committed
61
- # dir is the shared source of truth other default builds -- and the Android build
62
- # -- rely on staying the default set; overwriting it in place with a custom set
63
- # leaves the next default build linking a mismatched grammar list.
152
+ # A custom language set regenerates its registry into a per-app dir
153
+ # (generated-<app-slug>), never the committed default-set registry in vendor/generated.
154
+ # Keying by app (not by "generated-custom") means two apps in a hoisted monorepo with
155
+ # different custom sets each get their own registry instead of clobbering a single
156
+ # shared one -- which would leave the other app linking a mismatched grammar list.
64
157
  custom = langs.sort != defaults.sort
65
- generated_rel = custom ? 'cpp/highlight/vendor/generated-custom' : 'cpp/highlight/vendor/generated'
158
+ generated_rel = custom ? "cpp/highlight/vendor/generated-#{EnrichedMarkdownConfig.consumer_app_slug}" : 'cpp/highlight/vendor/generated'
66
159
  generated = File.join(podspec_dir, generated_rel)
67
160
  ensure_registry(podspec_dir, vendor, generated, langs, custom)
68
161
 
@@ -0,0 +1,87 @@
1
+ # Breaking changes
2
+
3
+ This file tracks breaking changes and how to migrate for each. Entries are newest first. Deprecations
4
+ (things that still work but are slated for removal) are noted alongside the change that introduces them.
5
+
6
+ ## Unreleased
7
+
8
+ ### The Expo config plugin was removed
9
+
10
+ The built-in Expo config plugin (`app.plugin.js` and the `plugin/` folder) has been removed. Feature
11
+ configuration now lives entirely in your app's `package.json`, read directly by the native build and by
12
+ `postinstall` — the same approach `react-native-worklets` uses for its static feature flags.
13
+
14
+ Why: the plugin only wrote the (now deprecated) Podfile `ENV` / `gradle.properties` channels, it could
15
+ never influence the install-time asset download (it runs during `expo prebuild`, *after* `npm install`),
16
+ and its option shape diverged from the `package.json` block. The `package.json` block supersedes it for
17
+ both the download and the build, and it survives `expo prebuild`.
18
+
19
+ **Migrate:** remove the plugin entry from `app.json` / `app.config.js` and move the options into the
20
+ `enriched-markdown` block of your `package.json`.
21
+
22
+ Before (`app.json`):
23
+
24
+ ```json
25
+ {
26
+ "expo": {
27
+ "plugins": [
28
+ ["react-native-enriched-markdown", {
29
+ "enableMath": false,
30
+ "codeHighlight": { "enabled": true, "languages": ["javascript", "tsx"] }
31
+ }]
32
+ ]
33
+ }
34
+ }
35
+ ```
36
+
37
+ After (`package.json`):
38
+
39
+ ```json
40
+ {
41
+ "enriched-markdown": {
42
+ "enableMath": false,
43
+ "enableCodeHighlight": true,
44
+ "codeHighlightLanguages": ["javascript", "tsx"]
45
+ }
46
+ }
47
+ ```
48
+
49
+ Note the key renames: the plugin's `codeHighlight.enabled` / `codeHighlight.languages` become
50
+ `enableCodeHighlight` / `codeHighlightLanguages`. Then run `pod install` (iOS) or rebuild (Android).
51
+ These are compile/link-time settings, so they apply only in builds you compile yourself (a custom dev
52
+ client or `expo prebuild`) — they cannot be changed in Expo Go, which ships a fixed prebuilt binary.
53
+
54
+ The `@expo/config-plugins` peer dependency was dropped as part of this removal.
55
+
56
+ ### Feature config moved to `package.json`; ENV vars and gradle properties are deprecated
57
+
58
+ The `enriched-markdown` block in your app's `package.json` is now the single source of truth for
59
+ `enableMath`, `enableCodeHighlight`, and `codeHighlightLanguages` on both platforms — the native build
60
+ reads it directly at `pod install` / Gradle configuration time. The previous build flags still work as a
61
+ fallback but are deprecated, print a warning, and are ignored when the matching `package.json` key is set:
62
+
63
+ | Deprecated flag | Replaced by (`package.json` `enriched-markdown`) |
64
+ |---|---|
65
+ | Podfile `ENV['ENRICHED_MARKDOWN_ENABLE_MATH']` / gradle `enrichedMarkdown.enableMath` | `enableMath` |
66
+ | Podfile `ENV['ENRICHED_MARKDOWN_ENABLE_CODE_HIGHLIGHT']` / gradle `enrichedMarkdown.enableCodeHighlight` | `enableCodeHighlight` |
67
+ | Podfile `ENV['ENRICHED_MARKDOWN_CODE_HIGHLIGHT_LANGUAGES']` / gradle `enrichedMarkdown.codeHighlightLanguages` | `codeHighlightLanguages` |
68
+
69
+ In a monorepo the *build* flag is read from the app's `package.json` (the one beside `ios/`/`android/`),
70
+ so each app configures independently. The *download* opt-out is read where the install runs — usually the
71
+ workspace root — so put it in the root `package.json` to skip a download for the whole repo. See
72
+ [Native assets](./NATIVE_ASSETS.md).
73
+
74
+ ### Explicitly enabling a feature whose assets are missing now fails the build
75
+
76
+ Previously, a missing native asset (the RaTeX XCFramework, or the tree-sitter grammars) always silently
77
+ disabled the feature. Now, if you **explicitly** set `enableMath: true` or `enableCodeHighlight: true` but
78
+ the asset was not downloaded (for example an install with `--ignore-scripts`, or a monorepo root opt-out
79
+ that an app overrides), the build fails with an actionable error instead of degrading. Features left on by
80
+ default still degrade to a clean build. To fix, restore the assets:
81
+
82
+ ```sh
83
+ node node_modules/react-native-enriched-markdown/postinstall.mjs
84
+ # or: npm rebuild react-native-enriched-markdown
85
+ ```
86
+
87
+ then re-run `pod install` (iOS) / rebuild (Android).
@@ -51,7 +51,7 @@ The copy label shown to assistive technologies is configurable via
51
51
 
52
52
  ## Supported languages
53
53
 
54
- Fence info strings map to a grammar (for example `js`, `jsx` -> JavaScript). The **curated default
54
+ Fence info strings map to a grammar (for example `js` and `jsx` both select JavaScript). The **curated default
55
55
  set** is compiled in unless you override it. It is defined by `default:true` in
56
56
  `vendor/grammar-versions.json` (the single source of truth the iOS podspec and Android build both
57
57
  derive from), so the table below tracks that manifest:
@@ -69,62 +69,38 @@ A block whose language is not compiled in simply renders as plain (uncolored) co
69
69
  Only the grammars you compile end up in your binary, so trimming the list is the main size lever.
70
70
  The seam degrades to plain code whenever a grammar is absent, so nothing breaks when you remove one.
71
71
 
72
- > [!TIP]
73
- > To also skip the install-time grammar download (not just the build-time linking), set
74
- > `"enriched-markdown": { "enableCodeHighlight": false }` in your app's `package.json`. This
75
- > auto-disables highlighting at build time too, so it's an alternative to the build flags below.
76
- > See [Skipping the download](./NATIVE_ASSETS.md#skipping-the-download-opt-out).
77
-
78
- ### iOS
79
-
80
- Add to your `Podfile` and re-run `pod install`:
81
-
82
- ```ruby
83
- # Compile a custom set (comma-separated; adds tsx to the trimmed set below):
84
- ENV['ENRICHED_MARKDOWN_CODE_HIGHLIGHT_LANGUAGES'] = 'javascript,tsx,json,bash'
85
-
86
- # ...or disable highlighting entirely (no tree-sitter code linked):
87
- ENV['ENRICHED_MARKDOWN_ENABLE_CODE_HIGHLIGHT'] = '0'
88
- ```
89
-
90
- ### Android
91
-
92
- Add to your project's `gradle.properties`:
93
-
94
- ```properties
95
- # Compile a custom set:
96
- enrichedMarkdown.codeHighlightLanguages=javascript,tsx,json,bash
97
-
98
- # ...or disable highlighting entirely:
99
- enrichedMarkdown.enableCodeHighlight=false
100
- ```
101
-
102
- Rebuild the app after changing either value.
103
-
104
- ### Expo config plugin
105
-
106
- Configure both platforms at once in `app.json` / `app.config.js`:
72
+ Configure everything through the `enriched-markdown` block of your app's `package.json` — it is the
73
+ single source of truth for both platforms and both the install-time download and the build:
107
74
 
108
75
  ```json
109
76
  {
110
- "expo": {
111
- "plugins": [
112
- [
113
- "react-native-enriched-markdown",
114
- {
115
- "codeHighlight": {
116
- "enabled": true,
117
- "languages": ["javascript", "tsx", "json", "bash"]
118
- }
119
- }
120
- ]
121
- ]
77
+ "enriched-markdown": {
78
+ "enableCodeHighlight": true,
79
+ "codeHighlightLanguages": ["javascript", "tsx", "json", "bash"]
122
80
  }
123
81
  }
124
82
  ```
125
83
 
126
- Set `"enabled": false` to disable it. Changes are applied during `npx expo prebuild`; if you change
127
- the set later, run `npx expo prebuild --clean` and rebuild.
84
+ How the two keys interact:
85
+
86
+ - **`enableCodeHighlight`** (default `true`) is the master switch. When `false`, the grammar download is
87
+ skipped **and** the tree-sitter runtime is excluded from the native build. In that state
88
+ **`codeHighlightLanguages` is ignored — it is a no-op**, because there is no highlighter compiled in for
89
+ languages to feed.
90
+ - **`codeHighlightLanguages`** selects which grammars to compile *when highlighting is enabled*. Omit it
91
+ for the curated default set, or pass a subset to shrink the binary. An empty array (`[]`) compiles no
92
+ grammars, which disables highlighting entirely — equivalent to `enableCodeHighlight: false`.
93
+
94
+ Re-run `pod install` (iOS) / rebuild (Android) after changing these. The same block works with Expo —
95
+ `node_modules` survives `npx expo prebuild`, so no config plugin is needed (highlighting is compiled in,
96
+ so it can't be changed in **Expo Go**; use a dev client or `expo prebuild`). See
97
+ [Skipping the download](./NATIVE_ASSETS.md#skipping-the-download-opt-out).
98
+
99
+ > [!NOTE]
100
+ > **Deprecated:** the `ENV['ENRICHED_MARKDOWN_*']` Podfile variables and the `enrichedMarkdown.*` gradle
101
+ > properties still work as a fallback but are deprecated and print a warning; they are ignored when the
102
+ > corresponding `package.json` key is set. The Expo config plugin was removed — see
103
+ > [Breaking changes](./BREAKING_CHANGES.md). Prefer the `package.json` block above.
128
104
 
129
105
  ## How it works
130
106
 
@@ -80,21 +80,27 @@ Set `latexMath: false` in `md4cFlags` so the parser treats `$` as plain text:
80
80
 
81
81
  This alone prevents math rendering without any native changes. The steps below go further by removing the native math libraries from your binary entirely.
82
82
 
83
- ### 2. Remove the native iOS dependency
83
+ ### 2. Remove the native dependency
84
84
 
85
- Add the following to your Podfile and re-run `pod install`:
85
+ Set `enableMath` to `false` in the `enriched-markdown` block of your app's `package.json`:
86
86
 
87
- ```ruby
88
- ENV['ENRICHED_MARKDOWN_ENABLE_MATH'] = '0'
87
+ ```json
88
+ {
89
+ "enriched-markdown": {
90
+ "enableMath": false
91
+ }
92
+ }
89
93
  ```
90
94
 
91
- This excludes **RaTeX** from the build. Rebuild the app after running `pod install`.
95
+ This is the single source of truth for both platforms: `postinstall` skips the install-time RaTeX
96
+ download, and the native build reads the same block directly to exclude **RaTeX** from the binary — no
97
+ Podfile or `gradle.properties` edit needed. Re-run `pod install` (iOS) / rebuild (Android) after
98
+ changing it. See [Skipping the download](./NATIVE_ASSETS.md#skipping-the-download-opt-out).
92
99
 
93
- > [!TIP]
94
- > To also skip the install-time RaTeX download (not just the build-time linking), set
95
- > `"enriched-markdown": { "enableMath": false }` in your app's `package.json`. Because the iOS build
96
- > auto-disables math when the framework is absent, this opt-out needs no Podfile edit. See
97
- > [Skipping the download](./NATIVE_ASSETS.md#skipping-the-download-opt-out).
100
+ > [!NOTE]
101
+ > **Deprecated:** the `ENV['ENRICHED_MARKDOWN_ENABLE_MATH']` Podfile variable and the
102
+ > `enrichedMarkdown.enableMath` gradle property still work as a fallback but are deprecated and print a
103
+ > warning; they are ignored when the `package.json` block sets `enableMath`.
98
104
 
99
105
  > [!NOTE]
100
106
  > When math is **enabled** (the default), no special Podfile configuration is required.
@@ -106,16 +112,15 @@ This excludes **RaTeX** from the build. Rebuild the app after running `pod insta
106
112
  > [!NOTE]
107
113
  > The RaTeX XCFramework is **not** bundled in the npm tarball — it is downloaded at install time by
108
114
  > a `postinstall` script (see [Native assets](./NATIVE_ASSETS.md)). If `ios/vendor/RaTeX.xcframework`
109
- > is missing (offline install, `--ignore-scripts`, pnpm, or a `package.json` opt-out), `pod install`
110
- > auto-disables math and prints a warning instead of failing. To restore math, run
111
- > `node node_modules/react-native-enriched-markdown/postinstall.mjs` and re-run `pod install`, or
112
- > force it with `ENV['ENRICHED_MARKDOWN_ENABLE_MATH'] = '1'` (which turns the missing framework back
113
- > into a hard error).
115
+ > is missing (offline install, `--ignore-scripts`, pnpm, or a `package.json` opt-out) and math is only
116
+ > on by default, `pod install` auto-disables math and prints a warning instead of failing. If you
117
+ > **explicitly** set `"enableMath": true`, a missing framework is a hard error instead. Either way, run
118
+ > `node node_modules/react-native-enriched-markdown/postinstall.mjs` and re-run `pod install` to restore it.
114
119
 
115
120
  > [!IMPORTANT]
116
121
  > **Upgrading from a version that used `use_frameworks! :linkage => :dynamic` for math?**
117
122
  > The pod changed from a dynamic framework to a static library. After `pod install`,
118
- > do a one-time clean build (Xcode: Product → Clean Build Folder, or delete the app's
123
+ > do a one-time clean build (Xcode: Product > Clean Build Folder, or delete the app's
119
124
  > DerivedData) — a stale build folder otherwise fails with
120
125
  > `ReactNativeEnrichedMarkdown.framework/Modules/module.modulemap not found`. Fresh
121
126
  > installs are unaffected.
@@ -126,37 +131,14 @@ This excludes **RaTeX** from the build. Rebuild the app after running `pod insta
126
131
  > no longer applies now that RaTeX is a vendored XCFramework with a macOS slice, so macOS
127
132
  > support is a possible future follow-up.
128
133
 
129
- ### 3. Remove the native Android dependency
130
-
131
- Add the following to your project's `gradle.properties`:
132
-
133
- ```properties
134
- enrichedMarkdown.enableMath=false
135
- ```
136
-
137
- This excludes **RaTeX** from the Android build. Rebuild the app after changing this property.
138
-
139
- ### 4. Expo config plugin
134
+ ### 3. Expo
140
135
 
141
- If you are using Expo, you can use the built-in config plugin to disable LaTeX math rendering on both platforms at once.
136
+ The `package.json` block above works with Expo too — `node_modules` (and the resolved config) survive
137
+ `npx expo prebuild`, so no config plugin is needed. Set `"enriched-markdown": { "enableMath": false }` in
138
+ your app's `package.json` and rebuild.
142
139
 
143
- Add the following to your `app.json` or `app.config.js`:
144
-
145
- ```json
146
- {
147
- "expo": {
148
- "plugins": [
149
- [
150
- "react-native-enriched-markdown",
151
- {
152
- "enableMath": false
153
- }
154
- ]
155
- ]
156
- }
157
- }
158
- ```
159
-
160
- This will automatically apply both the [iOS](#2-remove-the-native-ios-dependency) and [Android](#3-remove-the-native-android-dependency) native changes listed above during `npx expo prebuild`.
161
-
162
- If you later re-enable math (e.g. remove the plugin or set `enableMath: true`), run `npx expo prebuild --clean` so native projects are regenerated without the disable flags, then rebuild.
140
+ > [!NOTE]
141
+ > Because `enableMath` is a compile/link-time decision, it only applies in builds you compile yourself
142
+ > (a custom dev client or `expo prebuild`). It **cannot** be changed in **Expo Go**, which ships a fixed
143
+ > prebuilt binary. A dedicated config plugin was removed in favor of the `package.json` block — see
144
+ > [Breaking changes](./BREAKING_CHANGES.md).
@@ -34,16 +34,29 @@ them.
34
34
  Windows, but RaTeX is iOS-only so this only affects Windows dev machines and is non-fatal.
35
35
 
36
36
  The postinstall step **never fails the install**: if a download does not complete it prints a warning
37
- and exits successfully. When an asset is missing the native build treats the corresponding feature as
38
- disabled (code highlighting compiles a no-op stub; iOS math is skipped with a CocoaPods warning), so
39
- the build stays green. To turn a feature back on after fixing the download, re-run the recovery command
40
- below, or force it via its build flag (`ENV['ENRICHED_MARKDOWN_ENABLE_MATH'] = '1'` /
41
- `enrichedMarkdown.enableCodeHighlight=true`), which restores the actionable missing-asset error.
37
+ and exits successfully. What the native build does when an asset is missing depends on whether you
38
+ **explicitly enabled** the feature in your app `package.json`:
39
+
40
+ - **On by default** (no `enriched-markdown` entry for it): the build treats the feature as disabled —
41
+ code highlighting compiles a no-op stub, iOS math is skipped with a CocoaPods warning — so the build
42
+ stays green.
43
+ - **Explicitly enabled** (`"enableMath": true` / `"enableCodeHighlight": true`): the build **fails with
44
+ an actionable error** telling you to re-run postinstall, because you asked for a feature whose assets
45
+ are not present.
46
+
47
+ To fix a missing download, re-run the recovery command below.
42
48
 
43
49
  ## Re-running or recovering
44
50
 
45
- If installs happened offline, behind a firewall, or with scripts disabled, restore the assets by
46
- re-running the script from your project root:
51
+ If a download didn't complete (offline, behind a firewall, or with scripts disabled), reinstall the
52
+ package to re-fetch the assets:
53
+
54
+ ```sh
55
+ npm rebuild react-native-enriched-markdown
56
+ ```
57
+
58
+ If your package manager blocks or skips that (pnpm, Yarn PnP, `--ignore-scripts`), run the vendor script
59
+ directly from your project root as a fallback:
47
60
 
48
61
  ```sh
49
62
  node node_modules/react-native-enriched-markdown/postinstall.mjs
@@ -85,12 +98,25 @@ downloads its assets. Add an `enriched-markdown` block (both fields default to `
85
98
 
86
99
  `enableCodeHighlight: false` skips the tree-sitter runtime + grammar download (iOS and Android);
87
100
  `enableMath: false` skips the RaTeX download (iOS; Android math uses a Maven dependency and is
88
- unaffected). Because the native build keys off whether the assets are present on disk, a
89
- `package.json` opt-out **also disables the feature at build time** — no Podfile or `gradle.properties`
90
- edit needed. Re-run the install (or the recovery command above) after changing these values.
91
-
92
- This is read from the consumer project only (via `INIT_CWD`); it has no effect inside this repo's own
93
- monorepo development.
101
+ unaffected). The native build reads the same `enriched-markdown` block directly (iOS podspec /
102
+ Android `build.gradle`), so a `package.json` opt-out **also disables the feature at build time** — no
103
+ Podfile or `gradle.properties` edit needed. Disabling takes effect on the next `pod install` / native
104
+ rebuild; re-enabling also needs a reinstall so the assets download again.
105
+
106
+ > [!IMPORTANT]
107
+ > **Applying a change on iOS.** The podspec reads `package.json` at `pod install` time, not at build
108
+ > time, so a plain rebuild (`run-ios` / Xcode build) reuses the previously resolved pod — you must run
109
+ > `pod install` after editing the `enriched-markdown` block. And when you **change a feature that was
110
+ > already compiled in** (disabling it, or narrowing `codeHighlightLanguages`), also do a **clean build**
111
+ > (`Product > Clean Build Folder`, or delete the app's DerivedData): Xcode's incremental build does not
112
+ > reliably rebuild the pod's static library when only its source list changes, so it can otherwise link a
113
+ > stale copy that still contains the old code. Android reconfigures on every build and needs neither step.
114
+
115
+ **Which `package.json`?** The *download* opt-out is read from wherever the install runs (via `INIT_CWD`)
116
+ — in a monorepo that is the workspace root, and there is one shared `node_modules`, so the download
117
+ opt-out is global. The *build* flag is read from the **app's** `package.json` (the one beside `ios/` /
118
+ `android/`), so each app in a monorepo enables or disables features independently. Neither has any
119
+ effect inside this repo's own monorepo development.
94
120
 
95
121
  ## Disabling the features at build time
96
122
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-native-enriched-markdown",
3
- "version": "1.0.1",
4
- "description": "Markdown Text component for React Native",
3
+ "version": "1.0.2",
4
+ "description": "Markdown-based Rich Text solution for React Native",
5
5
  "main": "./lib/module/index",
6
6
  "module": "./lib/module/index",
7
7
  "source": "./src/index.tsx",
@@ -31,8 +31,6 @@
31
31
  "!**/__fixtures__",
32
32
  "!**/__mocks__",
33
33
  "!**/.*",
34
- "app.plugin.js",
35
- "plugin",
36
34
  "docs"
37
35
  ],
38
36
  "scripts": {
@@ -46,14 +44,13 @@
46
44
  "lint-clang:android:fix": "find android/ \\( -iname \"*.h\" -o -iname \"*.cpp\" \\) | grep -v -e build | xargs npx clang-format -i",
47
45
  "lint-clang": "yarn lint-clang:ios && yarn lint-clang:android",
48
46
  "lint-clang:fix": "yarn lint-clang:ios:fix && yarn lint-clang:android:fix",
49
- "clean": "del-cli android/build lib plugin/build",
47
+ "clean": "del-cli android/build lib",
50
48
  "sync-md4c": "bash ../../scripts/fetch-md4c.sh",
51
49
  "vendor-grammars": "node ../../vendor/vendor-grammars.mjs",
52
50
  "vendor-ratex": "node ../../vendor/vendor-ratex.mjs",
53
51
  "prepack": "bash ../../scripts/prepare-npm-publish.sh prepack",
54
52
  "postpack": "bash ../../scripts/prepare-npm-publish.sh postpack",
55
- "build:plugin": "tsc -p plugin/tsconfig.build.json",
56
- "prepare": "yarn vendor-grammars && yarn vendor-ratex && bob build && yarn build:plugin"
53
+ "prepare": "yarn vendor-grammars && yarn vendor-ratex && bob build"
57
54
  },
58
55
  "keywords": [
59
56
  "react-native",
@@ -67,35 +64,30 @@
67
64
  ],
68
65
  "repository": {
69
66
  "type": "git",
70
- "url": "git+https://github.com/software-mansion/react-native-enriched-markdown.git",
67
+ "url": "git+https://github.com/software-mansion/enriched-markdown.git",
71
68
  "directory": "packages/react-native-enriched-markdown"
72
69
  },
73
70
  "author": "Gregory Moskaliuk <mosckalyuck@gmail.com> (https://github.com/hryhoriiK97)",
74
71
  "license": "MIT",
75
72
  "bugs": {
76
- "url": "https://github.com/software-mansion/react-native-enriched-markdown/issues"
73
+ "url": "https://github.com/software-mansion/enriched-markdown/issues"
77
74
  },
78
75
  "homepage": "https://enriched.swmansion.com/markdown",
79
76
  "publishConfig": {
80
77
  "registry": "https://registry.npmjs.org/"
81
78
  },
82
79
  "peerDependencies": {
83
- "@expo/config-plugins": ">=50.0.0",
84
80
  "katex": ">=0.16.0",
85
81
  "react": "*",
86
82
  "react-native": "*"
87
83
  },
88
84
  "peerDependenciesMeta": {
89
- "@expo/config-plugins": {
90
- "optional": true
91
- },
92
85
  "katex": {
93
86
  "optional": true
94
87
  }
95
88
  },
96
89
  "devDependencies": {
97
90
  "@babel/core": "^7.25.0",
98
- "@expo/config-plugins": "^55.0.6",
99
91
  "@react-native/babel-preset": "0.85.0",
100
92
  "@react-native/jest-preset": "0.85.0",
101
93
  "@tree-sitter-grammars/tree-sitter-markdown": "0.3.2",
package/postinstall.mjs CHANGED
@@ -30,9 +30,14 @@ if (!fs.existsSync(grammarManifest)) {
30
30
  // Both features default to enabled (opt-out, not opt-in). Any resolution failure
31
31
  // (INIT_CWD unset, unreadable/malformed JSON, absent key) falls back to downloading
32
32
  // everything -- a skipped download is far cheaper to recover from than a silently
33
- // missing feature. The native build mirrors this by keying off asset presence on
34
- // disk (see the podspecs and android/build.gradle), so a package.json opt-out alone
35
- // yields a clean build with no Podfile/gradle edits.
33
+ // missing feature. In a monorepo INIT_CWD is the workspace root where the install
34
+ // ran, so the download opt-out lives in the root package.json (one shared node_modules).
35
+ //
36
+ // The native build reads the *app* package.json directly (via the podspec's
37
+ // installation root / gradle's build root -- see the podspecs and android/build.gradle),
38
+ // which is a separate per-app decision. It reconciles that flag with asset presence on
39
+ // disk: an explicit opt-in with the asset missing fails loud, a default-on with it
40
+ // missing degrades to a clean build.
36
41
  function resolveConsumerConfig() {
37
42
  const initCwd = process.env.INIT_CWD;
38
43
  if (!initCwd) {
@@ -48,8 +53,27 @@ function resolveConsumerConfig() {
48
53
  }
49
54
 
50
55
  const consumerConfig = resolveConsumerConfig();
51
- const enableCodeHighlight = consumerConfig.enableCodeHighlight !== false;
52
- const enableMath = consumerConfig.enableMath !== false;
56
+
57
+ // This script only decides what to DOWNLOAD into node_modules. The native build
58
+ // (podspec + build.gradle) reads the app package.json directly to decide what to
59
+ // compile/link, so nothing is written here for it to consume. The `codeHighlightLanguages`
60
+ // subset is a build-time concern (a language subset is selected from the full downloaded
61
+ // grammar set), so it is intentionally not read here. ENV vars are a deprecated fallback,
62
+ // honored only when package.json has no explicit value.
63
+ let enableCodeHighlight = consumerConfig.enableCodeHighlight;
64
+ let enableMath = consumerConfig.enableMath;
65
+
66
+ if (enableCodeHighlight === undefined && process.env.ENRICHED_MARKDOWN_ENABLE_CODE_HIGHLIGHT) {
67
+ console.warn(`${LOG} DEPRECATED: ENRICHED_MARKDOWN_ENABLE_CODE_HIGHLIGHT env var will be removed in a future version. Configure via "enriched-markdown".enableCodeHighlight in your package.json instead.`);
68
+ enableCodeHighlight = process.env.ENRICHED_MARKDOWN_ENABLE_CODE_HIGHLIGHT !== '0';
69
+ }
70
+ if (enableMath === undefined && process.env.ENRICHED_MARKDOWN_ENABLE_MATH) {
71
+ console.warn(`${LOG} DEPRECATED: ENRICHED_MARKDOWN_ENABLE_MATH env var will be removed in a future version. Configure via "enriched-markdown".enableMath in your package.json instead.`);
72
+ enableMath = process.env.ENRICHED_MARKDOWN_ENABLE_MATH !== '0';
73
+ }
74
+
75
+ enableCodeHighlight = enableCodeHighlight !== false;
76
+ enableMath = enableMath !== false;
53
77
 
54
78
  if (!enableCodeHighlight && !enableMath) {
55
79
  console.log(`${LOG} both code highlighting and math are disabled via package.json ("enriched-markdown"); skipping postinstall.`);
package/app.plugin.js DELETED
@@ -1,2 +0,0 @@
1
- module.exports =
2
- require('./plugin/build/withReactNativeEnrichedMarkdown').default;