writr 4.1.3 → 4.2.0
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.
- package/README.md +170 -50
- package/dist/writr.d.ts +132 -18
- package/dist/writr.js +212 -57
- package/package.json +13 -14
package/README.md
CHANGED
|
@@ -1,21 +1,40 @@
|
|
|
1
1
|

|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## Markdown Rendering Simplified
|
|
3
|
+
# Markdown Rendering Simplified
|
|
6
4
|
[](https://github.com/jaredwray/writr/actions/workflows/tests.yml)
|
|
7
5
|
[](https://github.com/jaredwray/writr/blob/master/LICENSE)
|
|
8
6
|
[](https://codecov.io/gh/jaredwray/writr)
|
|
9
7
|
[](https://npmjs.com/package/writr)
|
|
10
8
|
[](https://npmjs.com/package/writr)
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
## Table of Contents
|
|
10
|
+
# Table of Contents
|
|
14
11
|
- [Features](#features)
|
|
12
|
+
- [ESM and Node Version Support](#esm-and-node-version-support)
|
|
15
13
|
- [Getting Started](#getting-started)
|
|
16
|
-
- [
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
- [API](#api)
|
|
15
|
+
- [`new Writr(arg?: string | WritrOptions, options?: WritrOptions)`](#new-writrarg-string--writroptions-options-writroptions)
|
|
16
|
+
- [`.content`](#content)
|
|
17
|
+
- [`.body`](#body)
|
|
18
|
+
- [`.options`](#options)
|
|
19
|
+
- [`.frontmatter`](#frontmatter)
|
|
20
|
+
- [`.frontMatterRaw`](#frontmatterraw)
|
|
21
|
+
- [`.cache`](#cache)
|
|
22
|
+
- [`.engine`](#engine)
|
|
23
|
+
- [`.render(options?: RenderOptions): Promise<string>`](#renderoptions-renderoptions-promisestring)
|
|
24
|
+
- [`.renderSync(options?: RenderOptions): string`](#rendersyncoptions-renderoptions-string)
|
|
25
|
+
- [`.renderToFile(filePath: string, options?: RenderOptions): Promise<void>`](#rendertofilefilepath-string-options-renderoptions-promisevoid)
|
|
26
|
+
- [`.renderToFileSync(filePath: string, options?: RenderOptions): void`](#rendertofilesyncfilepath-string-options-renderoptions-void)
|
|
27
|
+
- [`.renderReact(options?: RenderOptions, reactOptions?: HTMLReactParserOptions): Promise<React.JSX.Element />`](#renderreactoptions-renderoptions-reactoptions-htmlreactparseroptions-promise-reactjsxelement-)
|
|
28
|
+
- [`.renderReactSync( options?: RenderOptions, reactOptions?: HTMLReactParserOptions): React.JSX.Element`](#renderreactsync-options-renderoptions-reactoptions-htmlreactparseroptions-reactjsxelement)
|
|
29
|
+
- [`.loadFromFile(filePath: string): Promise<void>`](#loadfromfilefilepath-string-promisevoid)
|
|
30
|
+
- [`.loadFromFileSync(filePath: string): void`](#loadfromfilesyncfilepath-string-void)
|
|
31
|
+
- [`.saveToFile(filePath: string): Promise<void>`](#savetofilefilepath-string-promisevoid)
|
|
32
|
+
- [`.saveToFileSync(filePath: string): void`](#savetofilesyncfilepath-string-void)
|
|
33
|
+
- [Code of Conduct and Contributing](#code-of-conduct-and-contributing)
|
|
34
|
+
- [License](#license)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# Features
|
|
19
38
|
* Removes the remark / unified complexity and easy to use.
|
|
20
39
|
* Built in caching 💥 making it render very fast when there isnt a change
|
|
21
40
|
* Frontmatter support built in by default. :tada:
|
|
@@ -29,11 +48,11 @@
|
|
|
29
48
|
* Emoji Support (remark-emoji).
|
|
30
49
|
* MDX Support (remark-mdx).
|
|
31
50
|
|
|
32
|
-
|
|
51
|
+
# ESM and Node Version Support
|
|
33
52
|
|
|
34
53
|
This package is ESM only and tested on the current lts version and its previous. Please don't open issues for questions regarding CommonJS / ESM or previous Nodejs versions. To learn more about using ESM please read this from `sindresorhus`: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
|
35
54
|
|
|
36
|
-
|
|
55
|
+
# Getting Started
|
|
37
56
|
|
|
38
57
|
```bash
|
|
39
58
|
> npm install writr
|
|
@@ -64,6 +83,7 @@ An example passing in the options also via the constructor:
|
|
|
64
83
|
```javascript
|
|
65
84
|
import { Writr, WritrOptions } from 'writr';
|
|
66
85
|
const writrOptions = {
|
|
86
|
+
throwErrors: true,
|
|
67
87
|
renderOptions: {
|
|
68
88
|
emoji: true,
|
|
69
89
|
toc: true,
|
|
@@ -79,15 +99,16 @@ const writr = new Writr(`# Hello World ::-):\n\n This is a test.`, writrOptions)
|
|
|
79
99
|
const html = await writr.render(options); // <h1>Hello World ::-):</h1><p>This is a test.</p>
|
|
80
100
|
```
|
|
81
101
|
|
|
82
|
-
|
|
102
|
+
# API
|
|
83
103
|
|
|
84
|
-
|
|
104
|
+
## `new Writr(arg?: string | WritrOptions, options?: WritrOptions)`
|
|
85
105
|
|
|
86
106
|
By default the constructor takes in a markdown `string` or `WritrOptions` in the first parameter. You can also send in nothing and set the markdown via `.content` property. If you want to pass in your markdown and options you can easily do this with `new Writr('## Your Markdown Here', { ...options here})`. You can access the `WritrOptions` from the instance of Writr. Here is an example of WritrOptions.
|
|
87
107
|
|
|
88
108
|
```javascript
|
|
89
109
|
import { Writr, WritrOptions } from 'writr';
|
|
90
110
|
const writrOptions = {
|
|
111
|
+
throwErrors: true,
|
|
91
112
|
renderOptions: {
|
|
92
113
|
emoji: true,
|
|
93
114
|
toc: true,
|
|
@@ -102,7 +123,7 @@ const writrOptions = {
|
|
|
102
123
|
const writr = new Writr(writrOptions);
|
|
103
124
|
```
|
|
104
125
|
|
|
105
|
-
|
|
126
|
+
## `.content`
|
|
106
127
|
|
|
107
128
|
Setting the markdown content for the instance of Writr. This can be set via the constructor or directly on the instance and can even handle `frontmatter`.
|
|
108
129
|
|
|
@@ -116,60 +137,112 @@ title: Hello World
|
|
|
116
137
|
# Hello World ::-):\n\n This is a test.`;
|
|
117
138
|
```
|
|
118
139
|
|
|
119
|
-
|
|
140
|
+
## `.body`
|
|
120
141
|
|
|
121
|
-
|
|
142
|
+
gets the body of the markdown content. This is the content without the frontmatter.
|
|
122
143
|
|
|
123
|
-
|
|
144
|
+
```javascript
|
|
145
|
+
import { Writr } from 'writr';
|
|
146
|
+
const writr = new Writr();
|
|
147
|
+
writr.content = `---
|
|
148
|
+
title: Hello World
|
|
149
|
+
---
|
|
150
|
+
# Hello World ::-):\n\n This is a test.`;
|
|
151
|
+
console.log(writr.body); // '# Hello World ::-):\n\n This is a test.'
|
|
152
|
+
```
|
|
124
153
|
|
|
125
|
-
|
|
154
|
+
## `.options`
|
|
155
|
+
|
|
156
|
+
Accessing the default options for this instance of Writr. Here is the default settings for `WritrOptions`.
|
|
126
157
|
|
|
127
158
|
```javascript
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
159
|
+
{
|
|
160
|
+
throwErrors: false,
|
|
161
|
+
renderOptions: {
|
|
162
|
+
emoji: true,
|
|
163
|
+
toc: false,
|
|
164
|
+
slug: false,
|
|
165
|
+
highlight: false,
|
|
166
|
+
gfm: true,
|
|
167
|
+
math: false,
|
|
168
|
+
mdx: false,
|
|
169
|
+
caching: false,
|
|
170
|
+
}
|
|
132
171
|
}
|
|
133
|
-
const html = await writr.render(options); // <h1>Hello World ::-):</h1><p>This is a test.</p>
|
|
134
172
|
```
|
|
135
173
|
|
|
136
|
-
|
|
174
|
+
## `.frontmatter`
|
|
175
|
+
|
|
176
|
+
Accessing the frontmatter for this instance of Writr. This is a `Record<string, any>` and can be set via the `.content` property.
|
|
177
|
+
|
|
178
|
+
```javascript
|
|
179
|
+
import { Writr } from 'writr';
|
|
180
|
+
const writr = new Writr();
|
|
181
|
+
writr.content = `---
|
|
182
|
+
title: Hello World
|
|
183
|
+
---
|
|
184
|
+
# Hello World ::-):\n\n This is a test.`;
|
|
185
|
+
console.log(writr.frontmatter); // { title: 'Hello World' }
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
you can also set the front matter directly like this:
|
|
189
|
+
|
|
190
|
+
```javascript
|
|
191
|
+
import { Writr } from 'writr';
|
|
192
|
+
const writr = new Writr();
|
|
193
|
+
writr.frontmatter = { title: 'Hello World' };
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## `.frontMatterRaw`
|
|
197
|
+
|
|
198
|
+
Accessing the raw frontmatter for this instance of Writr. This is a `string` and can be set via the `.content` property.
|
|
199
|
+
|
|
200
|
+
```javascript
|
|
201
|
+
import { Writr } from 'writr';
|
|
202
|
+
const writr = new Writr();
|
|
203
|
+
writr.content = `---
|
|
204
|
+
title: Hello World
|
|
205
|
+
---
|
|
206
|
+
# Hello World ::-):\n\n This is a test.`;
|
|
207
|
+
console.log(writr.frontMatterRaw); // '---\ntitle: Hello World\n---'
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## `.cache`
|
|
211
|
+
|
|
212
|
+
Accessing the cache for this instance of Writr. By default this is an in memory cache and is disabled (set to false) by default. You can enable this by setting `caching: true` in the `RenderOptions` of the `WritrOptions` or when calling render passing the `RenderOptions` like here:
|
|
137
213
|
|
|
138
214
|
```javascript
|
|
139
215
|
import { Writr } from 'writr';
|
|
140
|
-
import Keyv from '@keyv/redis';
|
|
141
|
-
const keyvRedis = new Keyv('redis://user:pass@localhost:6379');
|
|
142
216
|
const writr = new Writr(`# Hello World ::-):\n\n This is a test.`);
|
|
143
|
-
|
|
217
|
+
const options = {
|
|
218
|
+
caching: true
|
|
219
|
+
}
|
|
220
|
+
const html = await writr.render(options); // <h1>Hello World ::-):</h1><p>This is a test.</p>
|
|
144
221
|
```
|
|
145
222
|
|
|
146
|
-
|
|
223
|
+
|
|
224
|
+
## `.engine`
|
|
147
225
|
|
|
148
226
|
Accessing the underlying engine for this instance of Writr. This is a `Processor<Root, Root, Root, undefined, undefined>` fro the unified `.use()` function. You can use this to add additional plugins to the engine.
|
|
149
227
|
|
|
150
|
-
|
|
228
|
+
## `.render(options?: RenderOptions): Promise<string>`
|
|
151
229
|
|
|
152
230
|
Rendering markdown to HTML. the options are based on RenderOptions. Which you can access from the Writr instance.
|
|
153
231
|
|
|
154
232
|
```javascript
|
|
155
|
-
import { Writr
|
|
233
|
+
import { Writr } from 'writr';
|
|
234
|
+
const writr = new Writr(`# Hello World ::-):\n\n This is a test.`);
|
|
235
|
+
const html = await writr.render(); // <h1>Hello World 🙂</h1><p>This is a test.</p>
|
|
156
236
|
|
|
157
|
-
|
|
237
|
+
//passing in with render options
|
|
238
|
+
const options = {
|
|
239
|
+
emoji: false
|
|
240
|
+
}
|
|
158
241
|
|
|
159
|
-
|
|
160
|
-
type RenderOptions = {
|
|
161
|
-
emoji?: boolean; // Emoji support (default: true)
|
|
162
|
-
toc?: boolean; // Table of contents generation (default: true)
|
|
163
|
-
slug?: boolean; // Slug generation (default: true)
|
|
164
|
-
highlight?: boolean; // Code highlighting (default: true)
|
|
165
|
-
gfm?: boolean; // Github flavor markdown (default: true)
|
|
166
|
-
math?: boolean; // Math support (default: true)
|
|
167
|
-
mdx?: boolean; // MDX support (default: true)
|
|
168
|
-
caching?: boolean; // Caching (default: true)
|
|
169
|
-
};
|
|
242
|
+
const html = await writr.render(options); // <h1>Hello World ::-):</h1><p>This is a test.</p>
|
|
170
243
|
```
|
|
171
244
|
|
|
172
|
-
|
|
245
|
+
## `.renderSync(options?: RenderOptions): string`
|
|
173
246
|
|
|
174
247
|
Rendering markdown to HTML synchronously. the options are based on RenderOptions. Which you can access from the Writr instance. The parameters are the same as the `.render()` function.
|
|
175
248
|
|
|
@@ -179,7 +252,27 @@ const writr = new Writr(`# Hello World ::-):\n\n This is a test.`);
|
|
|
179
252
|
const html = writr.renderSync(); // <h1>Hello World 🙂</h1><p>This is a test.</p>
|
|
180
253
|
```
|
|
181
254
|
|
|
182
|
-
|
|
255
|
+
## '.renderToFile(filePath: string, options?: RenderOptions): Promise<void>'
|
|
256
|
+
|
|
257
|
+
Rendering markdown to a file. The options are based on RenderOptions.
|
|
258
|
+
|
|
259
|
+
```javascript
|
|
260
|
+
import { Writr } from 'writr';
|
|
261
|
+
const writr = new Writr(`# Hello World ::-):\n\n This is a test.`);
|
|
262
|
+
await writr.renderToFile('path/to/file.html');
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## '.renderToFileSync(filePath: string, options?: RenderOptions): void'
|
|
266
|
+
|
|
267
|
+
Rendering markdown to a file synchronously. The options are based on RenderOptions.
|
|
268
|
+
|
|
269
|
+
```javascript
|
|
270
|
+
import { Writr } from 'writr';
|
|
271
|
+
const writr = new Writr(`# Hello World ::-):\n\n This is a test.`);
|
|
272
|
+
writr.renderToFileSync('path/to/file.html');
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## '.renderReact(options?: RenderOptions, reactOptions?: HTMLReactParserOptions): Promise<React.JSX.Element />'
|
|
183
276
|
|
|
184
277
|
Rendering markdown to React. The options are based on RenderOptions and now HTMLReactParserOptions from `html-react-parser`.
|
|
185
278
|
|
|
@@ -189,7 +282,7 @@ const writr = new Writr(`# Hello World ::-):\n\n This is a test.`);
|
|
|
189
282
|
const reactElement = await writr.renderReact(); // Will return a React.JSX.Element
|
|
190
283
|
```
|
|
191
284
|
|
|
192
|
-
|
|
285
|
+
## '.renderReactSync( options?: RenderOptions, reactOptions?: HTMLReactParserOptions): React.JSX.Element'
|
|
193
286
|
|
|
194
287
|
Rendering markdown to React. The options are based on RenderOptions and now HTMLReactParserOptions from `html-react-parser`.
|
|
195
288
|
|
|
@@ -199,7 +292,7 @@ const writr = new Writr(`# Hello World ::-):\n\n This is a test.`);
|
|
|
199
292
|
const reactElement = writr.renderReactSync(); // Will return a React.JSX.Element
|
|
200
293
|
```
|
|
201
294
|
|
|
202
|
-
|
|
295
|
+
## `.loadFromFile(filePath: string): Promise<void>`
|
|
203
296
|
|
|
204
297
|
Load your markdown content from a file path.
|
|
205
298
|
|
|
@@ -209,11 +302,11 @@ const writr = new Writr();
|
|
|
209
302
|
await writr.loadFromFile('path/to/file.md');
|
|
210
303
|
```
|
|
211
304
|
|
|
212
|
-
|
|
305
|
+
## `.loadFromFileSync(filePath: string): void`
|
|
213
306
|
|
|
214
307
|
Load your markdown content from a file path synchronously.
|
|
215
308
|
|
|
216
|
-
|
|
309
|
+
## `.saveToFile(filePath: string): Promise<void>`
|
|
217
310
|
|
|
218
311
|
Save your markdown and frontmatter (if included) content to a file path.
|
|
219
312
|
|
|
@@ -223,13 +316,40 @@ const writr = new Writr(`# Hello World ::-):\n\n This is a test.`);
|
|
|
223
316
|
await writr.saveToFile('path/to/file.md');
|
|
224
317
|
```
|
|
225
318
|
|
|
226
|
-
|
|
319
|
+
## `.saveToFileSync(filePath: string): void`
|
|
227
320
|
|
|
228
321
|
Save your markdown and frontmatter (if included) content to a file path synchronously.
|
|
229
322
|
|
|
230
|
-
|
|
323
|
+
# Caching On Render
|
|
324
|
+
|
|
325
|
+
Caching is built into Writr and is an in-memory cache using `CacheableMemory` from [Cacheable](https://cacheable.org). It is turned off by default and can be enabled by setting `caching: true` in the `RenderOptions` of the `WritrOptions` or when calling render passing the `RenderOptions` like here:
|
|
326
|
+
|
|
327
|
+
```javascript
|
|
328
|
+
import { Writr } from 'writr';
|
|
329
|
+
const writr = new Writr(`# Hello World ::-):\n\n This is a test.`, { renderOptions: { caching: true } });
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
or via `RenderOptions` such as:
|
|
333
|
+
|
|
334
|
+
```javascript
|
|
335
|
+
import { Writr } from 'writr';
|
|
336
|
+
const writr = new Writr(`# Hello World ::-):\n\n This is a test.`);
|
|
337
|
+
await writr.render({ caching: true});
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
If you want to set the caching options for the instance of Writr you can do so like this:
|
|
341
|
+
|
|
342
|
+
```javascript
|
|
343
|
+
// we will set the lruSize of the cache and the default ttl
|
|
344
|
+
import {Writr} from 'writr';
|
|
345
|
+
const writr = new Writr(`# Hello World ::-):\n\n This is a test.`, { renderOptions: { caching: true } });
|
|
346
|
+
writr.cache.store.lruSize = 100;
|
|
347
|
+
writr.cache.store.ttl = '5m'; // setting it to 5 minutes
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
# Code of Conduct and Contributing
|
|
231
351
|
[Code of Conduct](CODE_OF_CONDUCT.md) and [Contributing](CONTRIBUTING.md) guidelines.
|
|
232
352
|
|
|
233
|
-
|
|
353
|
+
# License
|
|
234
354
|
|
|
235
355
|
MIT © [Jared Wray](https://jaredwray.com)
|
package/dist/writr.d.ts
CHANGED
|
@@ -3,33 +3,42 @@ import * as hast from 'hast';
|
|
|
3
3
|
import * as mdast from 'mdast';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { HTMLReactParserOptions } from 'html-react-parser';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { Hookified } from 'hookified';
|
|
7
|
+
import { CacheableMemory } from 'cacheable';
|
|
8
8
|
|
|
9
9
|
declare class WritrCache {
|
|
10
|
-
private
|
|
11
|
-
private readonly _markdownStoreSync;
|
|
10
|
+
private readonly _store;
|
|
12
11
|
private readonly _hashStore;
|
|
13
|
-
get
|
|
14
|
-
get markdownStoreSync(): CacheableMemory;
|
|
12
|
+
get store(): CacheableMemory;
|
|
15
13
|
get hashStore(): CacheableMemory;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
setMarkdownSync(markdown: string, value: string, options?: RenderOptions): boolean;
|
|
20
|
-
get(key: string): Promise<string | undefined>;
|
|
21
|
-
getSync(key: string): string | undefined;
|
|
22
|
-
set(key: string, value: string): Promise<boolean>;
|
|
23
|
-
setSync(key: string, value: string): boolean;
|
|
24
|
-
clear(): Promise<void>;
|
|
25
|
-
setStorageAdapter(adapter: KeyvStoreAdapter): void;
|
|
14
|
+
get(markdown: string, options?: RenderOptions): string | undefined;
|
|
15
|
+
set(markdown: string, value: string, options?: RenderOptions): void;
|
|
16
|
+
clear(): void;
|
|
26
17
|
hash(markdown: string, options?: RenderOptions): string;
|
|
27
18
|
}
|
|
28
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Writr options.
|
|
22
|
+
* @typedef {Object} WritrOptions
|
|
23
|
+
* @property {RenderOptions} [renderOptions] - Default render options (default: undefined)
|
|
24
|
+
* @property {boolean} [throwErrors] - Throw error (default: false)
|
|
25
|
+
*/
|
|
29
26
|
type WritrOptions = {
|
|
30
|
-
openai?: string;
|
|
31
27
|
renderOptions?: RenderOptions;
|
|
28
|
+
throwErrors?: boolean;
|
|
32
29
|
};
|
|
30
|
+
/**
|
|
31
|
+
* Render options.
|
|
32
|
+
* @typedef {Object} RenderOptions
|
|
33
|
+
* @property {boolean} [emoji] - Emoji support (default: true)
|
|
34
|
+
* @property {boolean} [toc] - Table of contents generation (default: true)
|
|
35
|
+
* @property {boolean} [slug] - Slug generation (default: true)
|
|
36
|
+
* @property {boolean} [highlight] - Code highlighting (default: true)
|
|
37
|
+
* @property {boolean} [gfm] - Github flavor markdown (default: true)
|
|
38
|
+
* @property {boolean} [math] - Math support (default: true)
|
|
39
|
+
* @property {boolean} [mdx] - MDX support (default: true)
|
|
40
|
+
* @property {boolean} [caching] - Caching (default: false)
|
|
41
|
+
*/
|
|
33
42
|
type RenderOptions = {
|
|
34
43
|
emoji?: boolean;
|
|
35
44
|
toc?: boolean;
|
|
@@ -40,32 +49,137 @@ type RenderOptions = {
|
|
|
40
49
|
mdx?: boolean;
|
|
41
50
|
caching?: boolean;
|
|
42
51
|
};
|
|
43
|
-
declare class Writr {
|
|
52
|
+
declare class Writr extends Hookified {
|
|
44
53
|
engine: unified.Processor<mdast.Root, mdast.Root, hast.Root, hast.Root, string>;
|
|
45
54
|
private readonly _options;
|
|
46
55
|
private _content;
|
|
47
56
|
private readonly _cache;
|
|
57
|
+
/**
|
|
58
|
+
* Initialize Writr. Accepts a string or options object.
|
|
59
|
+
* @param {string | WritrOptions} [arguments1] If you send in a string, it will be used as the markdown content. If you send in an object, it will be used as the options.
|
|
60
|
+
* @param {WritrOptions} [arguments2] This is if you send in the content in the first argument and also want to send in options.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* const writr = new Writr('Hello, world!', {caching: false});
|
|
64
|
+
*/
|
|
48
65
|
constructor(arguments1?: string | WritrOptions, arguments2?: WritrOptions);
|
|
66
|
+
/**
|
|
67
|
+
* Get the options.
|
|
68
|
+
* @type {WritrOptions}
|
|
69
|
+
*/
|
|
49
70
|
get options(): WritrOptions;
|
|
71
|
+
/**
|
|
72
|
+
* Get the Content. This is the markdown content and front matter if it exists.
|
|
73
|
+
* @type {WritrOptions}
|
|
74
|
+
*/
|
|
50
75
|
get content(): string;
|
|
76
|
+
/**
|
|
77
|
+
* Set the Content. This is the markdown content and front matter if it exists.
|
|
78
|
+
* @type {WritrOptions}
|
|
79
|
+
*/
|
|
51
80
|
set content(value: string);
|
|
81
|
+
/**
|
|
82
|
+
* Get the cache.
|
|
83
|
+
* @type {WritrCache}
|
|
84
|
+
*/
|
|
52
85
|
get cache(): WritrCache;
|
|
86
|
+
/**
|
|
87
|
+
* Get the front matter raw content.
|
|
88
|
+
* @type {string} The front matter content including the delimiters.
|
|
89
|
+
*/
|
|
53
90
|
get frontMatterRaw(): string;
|
|
91
|
+
/**
|
|
92
|
+
* Get the body content without the front matter.
|
|
93
|
+
* @type {string} The markdown content without the front matter.
|
|
94
|
+
*/
|
|
54
95
|
get body(): string;
|
|
96
|
+
/**
|
|
97
|
+
* Get the markdown content. This is an alias for the body property.
|
|
98
|
+
* @type {string} The markdown content.
|
|
99
|
+
*/
|
|
55
100
|
get markdown(): string;
|
|
101
|
+
/**
|
|
102
|
+
* Get the front matter content as an object.
|
|
103
|
+
* @type {Record<string, any>} The front matter content as an object.
|
|
104
|
+
*/
|
|
56
105
|
get frontMatter(): Record<string, any>;
|
|
106
|
+
/**
|
|
107
|
+
* Set the front matter content as an object.
|
|
108
|
+
* @type {Record<string, any>} The front matter content as an object.
|
|
109
|
+
*/
|
|
57
110
|
set frontMatter(data: Record<string, any>);
|
|
111
|
+
/**
|
|
112
|
+
* Get the front matter value for a key.
|
|
113
|
+
* @param {string} key The key to get the value for.
|
|
114
|
+
* @returns {T} The value for the key.
|
|
115
|
+
*/
|
|
58
116
|
getFrontMatterValue<T>(key: string): T;
|
|
117
|
+
/**
|
|
118
|
+
* Render the markdown content to HTML.
|
|
119
|
+
* @param {RenderOptions} [options] The render options.
|
|
120
|
+
* @returns {Promise<string>} The rendered HTML content.
|
|
121
|
+
*/
|
|
59
122
|
render(options?: RenderOptions): Promise<string>;
|
|
123
|
+
/**
|
|
124
|
+
* Render the markdown content to HTML synchronously.
|
|
125
|
+
* @param {RenderOptions} [options] The render options.
|
|
126
|
+
* @returns {string} The rendered HTML content.
|
|
127
|
+
*/
|
|
60
128
|
renderSync(options?: RenderOptions): string;
|
|
129
|
+
/**
|
|
130
|
+
* Render the markdown content and save it to a file. If the directory doesn't exist it will be created.
|
|
131
|
+
* @param {string} filePath The file path to save the rendered markdown content to.
|
|
132
|
+
* @param {RenderOptions} [options] the render options.
|
|
133
|
+
*/
|
|
134
|
+
renderToFile(filePath: string, options?: RenderOptions): Promise<void>;
|
|
135
|
+
/**
|
|
136
|
+
* Render the markdown content and save it to a file synchronously. If the directory doesn't exist it will be created.
|
|
137
|
+
* @param {string} filePath The file path to save the rendered markdown content to.
|
|
138
|
+
* @param {RenderOptions} [options] the render options.
|
|
139
|
+
*/
|
|
140
|
+
renderToFileSync(filePath: string, options?: RenderOptions): void;
|
|
141
|
+
/**
|
|
142
|
+
* Render the markdown content to React.
|
|
143
|
+
* @param {RenderOptions} [options] The render options.
|
|
144
|
+
* @param {HTMLReactParserOptions} [reactParseOptions] The HTML React parser options.
|
|
145
|
+
* @returns {Promise<string | React.JSX.Element | React.JSX.Element[]>} The rendered React content.
|
|
146
|
+
*/
|
|
61
147
|
renderReact(options?: RenderOptions, reactParseOptions?: HTMLReactParserOptions): Promise<string | React.JSX.Element | React.JSX.Element[]>;
|
|
148
|
+
/**
|
|
149
|
+
* Render the markdown content to React synchronously.
|
|
150
|
+
* @param {RenderOptions} [options] The render options.
|
|
151
|
+
* @param {HTMLReactParserOptions} [reactParseOptions] The HTML React parser options.
|
|
152
|
+
* @returns {string | React.JSX.Element | React.JSX.Element[]} The rendered React content.
|
|
153
|
+
*/
|
|
62
154
|
renderReactSync(options?: RenderOptions, reactParseOptions?: HTMLReactParserOptions): string | React.JSX.Element | React.JSX.Element[];
|
|
155
|
+
/**
|
|
156
|
+
* Load markdown content from a file.
|
|
157
|
+
* @param {string} filePath The file path to load the markdown content from.
|
|
158
|
+
* @returns {Promise<void>}
|
|
159
|
+
*/
|
|
63
160
|
loadFromFile(filePath: string): Promise<void>;
|
|
161
|
+
/**
|
|
162
|
+
* Load markdown content from a file synchronously.
|
|
163
|
+
* @param {string} filePath The file path to load the markdown content from.
|
|
164
|
+
* @returns {void}
|
|
165
|
+
*/
|
|
64
166
|
loadFromFileSync(filePath: string): void;
|
|
167
|
+
/**
|
|
168
|
+
* Save the markdown content to a file. If the directory doesn't exist it will be created.
|
|
169
|
+
* @param {string} filePath The file path to save the markdown content to.
|
|
170
|
+
* @returns {Promise<void>}
|
|
171
|
+
*/
|
|
65
172
|
saveToFile(filePath: string): Promise<void>;
|
|
173
|
+
/**
|
|
174
|
+
* Save the markdown content to a file synchronously. If the directory doesn't exist it will be created.
|
|
175
|
+
* @param {string} filePath The file path to save the markdown content to.
|
|
176
|
+
* @returns {void}
|
|
177
|
+
*/
|
|
66
178
|
saveToFileSync(filePath: string): void;
|
|
67
179
|
private isCacheEnabled;
|
|
68
180
|
private createProcessor;
|
|
181
|
+
private mergeOptions;
|
|
182
|
+
private mergeRenderOptions;
|
|
69
183
|
}
|
|
70
184
|
|
|
71
185
|
export { type RenderOptions, Writr, type WritrOptions };
|
package/dist/writr.js
CHANGED
|
@@ -15,60 +15,31 @@ import remarkEmoji from "remark-emoji";
|
|
|
15
15
|
import remarkMDX from "remark-mdx";
|
|
16
16
|
import parse from "html-react-parser";
|
|
17
17
|
import * as yaml from "js-yaml";
|
|
18
|
+
import { Hookified } from "hookified";
|
|
18
19
|
|
|
19
20
|
// src/writr-cache.ts
|
|
20
|
-
import {
|
|
21
|
+
import { CacheableMemory } from "cacheable";
|
|
21
22
|
var WritrCache = class {
|
|
22
|
-
|
|
23
|
-
_markdownStoreSync = new CacheableMemory();
|
|
23
|
+
_store = new CacheableMemory();
|
|
24
24
|
_hashStore = new CacheableMemory();
|
|
25
|
-
get
|
|
26
|
-
return this.
|
|
27
|
-
}
|
|
28
|
-
get markdownStoreSync() {
|
|
29
|
-
return this._markdownStoreSync;
|
|
25
|
+
get store() {
|
|
26
|
+
return this._store;
|
|
30
27
|
}
|
|
31
28
|
get hashStore() {
|
|
32
29
|
return this._hashStore;
|
|
33
30
|
}
|
|
34
|
-
|
|
35
|
-
const key = this.hash(markdown, options);
|
|
36
|
-
return this.get(key);
|
|
37
|
-
}
|
|
38
|
-
getMarkdownSync(markdown, options) {
|
|
31
|
+
get(markdown, options) {
|
|
39
32
|
const key = this.hash(markdown, options);
|
|
40
|
-
return this.
|
|
33
|
+
return this._store.get(key);
|
|
41
34
|
}
|
|
42
|
-
|
|
35
|
+
set(markdown, value, options) {
|
|
43
36
|
const key = this.hash(markdown, options);
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
setMarkdownSync(markdown, value, options) {
|
|
47
|
-
const key = this.hash(markdown, options);
|
|
48
|
-
this.setSync(key, value);
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
|
-
async get(key) {
|
|
52
|
-
return this._markdownStore.get(key);
|
|
37
|
+
this._store.set(key, value);
|
|
53
38
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
async set(key, value) {
|
|
58
|
-
return this._markdownStore.set(key, value);
|
|
59
|
-
}
|
|
60
|
-
setSync(key, value) {
|
|
61
|
-
this._markdownStoreSync.set(key, value);
|
|
62
|
-
return true;
|
|
63
|
-
}
|
|
64
|
-
async clear() {
|
|
65
|
-
await this._markdownStore.clear();
|
|
66
|
-
this._markdownStoreSync.clear();
|
|
39
|
+
clear() {
|
|
40
|
+
this._store.clear();
|
|
67
41
|
this._hashStore.clear();
|
|
68
42
|
}
|
|
69
|
-
setStorageAdapter(adapter) {
|
|
70
|
-
this._markdownStore = new Cacheable({ primary: adapter });
|
|
71
|
-
}
|
|
72
43
|
hash(markdown, options) {
|
|
73
44
|
const content = { markdown, options };
|
|
74
45
|
const key = JSON.stringify(content);
|
|
@@ -83,11 +54,11 @@ var WritrCache = class {
|
|
|
83
54
|
};
|
|
84
55
|
|
|
85
56
|
// src/writr.ts
|
|
86
|
-
var Writr = class {
|
|
57
|
+
var Writr = class extends Hookified {
|
|
87
58
|
engine = unified().use(remarkParse).use(remarkGfm).use(remarkToc).use(remarkEmoji).use(remarkRehype).use(rehypeSlug).use(remarkMath).use(rehypeKatex).use(rehypeHighlight).use(remarkMDX).use(rehypeStringify);
|
|
88
59
|
// Stringify HTML
|
|
89
60
|
_options = {
|
|
90
|
-
|
|
61
|
+
throwErrors: false,
|
|
91
62
|
renderOptions: {
|
|
92
63
|
emoji: true,
|
|
93
64
|
toc: true,
|
|
@@ -96,39 +67,68 @@ var Writr = class {
|
|
|
96
67
|
gfm: true,
|
|
97
68
|
math: true,
|
|
98
69
|
mdx: true,
|
|
99
|
-
caching:
|
|
70
|
+
caching: false
|
|
100
71
|
}
|
|
101
72
|
};
|
|
102
73
|
_content = "";
|
|
103
74
|
_cache = new WritrCache();
|
|
75
|
+
/**
|
|
76
|
+
* Initialize Writr. Accepts a string or options object.
|
|
77
|
+
* @param {string | WritrOptions} [arguments1] If you send in a string, it will be used as the markdown content. If you send in an object, it will be used as the options.
|
|
78
|
+
* @param {WritrOptions} [arguments2] This is if you send in the content in the first argument and also want to send in options.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* const writr = new Writr('Hello, world!', {caching: false});
|
|
82
|
+
*/
|
|
104
83
|
constructor(arguments1, arguments2) {
|
|
84
|
+
super();
|
|
105
85
|
if (typeof arguments1 === "string") {
|
|
106
86
|
this._content = arguments1;
|
|
107
87
|
} else if (arguments1) {
|
|
108
|
-
this._options =
|
|
88
|
+
this._options = this.mergeOptions(this._options, arguments1);
|
|
109
89
|
if (this._options.renderOptions) {
|
|
110
90
|
this.engine = this.createProcessor(this._options.renderOptions);
|
|
111
91
|
}
|
|
112
92
|
}
|
|
113
93
|
if (arguments2) {
|
|
114
|
-
this._options =
|
|
94
|
+
this._options = this.mergeOptions(this._options, arguments2);
|
|
115
95
|
if (this._options.renderOptions) {
|
|
116
96
|
this.engine = this.createProcessor(this._options.renderOptions);
|
|
117
97
|
}
|
|
118
98
|
}
|
|
119
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Get the options.
|
|
102
|
+
* @type {WritrOptions}
|
|
103
|
+
*/
|
|
120
104
|
get options() {
|
|
121
105
|
return this._options;
|
|
122
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Get the Content. This is the markdown content and front matter if it exists.
|
|
109
|
+
* @type {WritrOptions}
|
|
110
|
+
*/
|
|
123
111
|
get content() {
|
|
124
112
|
return this._content;
|
|
125
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Set the Content. This is the markdown content and front matter if it exists.
|
|
116
|
+
* @type {WritrOptions}
|
|
117
|
+
*/
|
|
126
118
|
set content(value) {
|
|
127
119
|
this._content = value;
|
|
128
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Get the cache.
|
|
123
|
+
* @type {WritrCache}
|
|
124
|
+
*/
|
|
129
125
|
get cache() {
|
|
130
126
|
return this._cache;
|
|
131
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Get the front matter raw content.
|
|
130
|
+
* @type {string} The front matter content including the delimiters.
|
|
131
|
+
*/
|
|
132
132
|
get frontMatterRaw() {
|
|
133
133
|
if (!this._content.trimStart().startsWith("---")) {
|
|
134
134
|
return "";
|
|
@@ -140,6 +140,10 @@ var Writr = class {
|
|
|
140
140
|
}
|
|
141
141
|
return this._content.slice(start, end + 5);
|
|
142
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Get the body content without the front matter.
|
|
145
|
+
* @type {string} The markdown content without the front matter.
|
|
146
|
+
*/
|
|
143
147
|
get body() {
|
|
144
148
|
if (this.frontMatterRaw === "") {
|
|
145
149
|
return this._content;
|
|
@@ -147,17 +151,33 @@ var Writr = class {
|
|
|
147
151
|
const end = this._content.indexOf("\n---\n");
|
|
148
152
|
return this._content.slice(Math.max(0, end + 5)).trim();
|
|
149
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* Get the markdown content. This is an alias for the body property.
|
|
156
|
+
* @type {string} The markdown content.
|
|
157
|
+
*/
|
|
150
158
|
get markdown() {
|
|
151
159
|
return this.body;
|
|
152
160
|
}
|
|
161
|
+
/**
|
|
162
|
+
* Get the front matter content as an object.
|
|
163
|
+
* @type {Record<string, any>} The front matter content as an object.
|
|
164
|
+
*/
|
|
153
165
|
get frontMatter() {
|
|
154
166
|
const frontMatter = this.frontMatterRaw;
|
|
155
167
|
const match = /^---\s*([\s\S]*?)\s*---\s*/.exec(frontMatter);
|
|
156
168
|
if (match) {
|
|
157
|
-
|
|
169
|
+
try {
|
|
170
|
+
return yaml.load(match[1].trim());
|
|
171
|
+
} catch (error) {
|
|
172
|
+
this.emit("error", error);
|
|
173
|
+
}
|
|
158
174
|
}
|
|
159
175
|
return {};
|
|
160
176
|
}
|
|
177
|
+
/**
|
|
178
|
+
* Set the front matter content as an object.
|
|
179
|
+
* @type {Record<string, any>} The front matter content as an object.
|
|
180
|
+
*/
|
|
161
181
|
set frontMatter(data) {
|
|
162
182
|
const frontMatter = this.frontMatterRaw;
|
|
163
183
|
const yamlString = yaml.dump(data);
|
|
@@ -166,14 +186,24 @@ ${yamlString}---
|
|
|
166
186
|
`;
|
|
167
187
|
this._content = this._content.replace(frontMatter, newFrontMatter);
|
|
168
188
|
}
|
|
189
|
+
/**
|
|
190
|
+
* Get the front matter value for a key.
|
|
191
|
+
* @param {string} key The key to get the value for.
|
|
192
|
+
* @returns {T} The value for the key.
|
|
193
|
+
*/
|
|
169
194
|
getFrontMatterValue(key) {
|
|
170
195
|
return this.frontMatter[key];
|
|
171
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* Render the markdown content to HTML.
|
|
199
|
+
* @param {RenderOptions} [options] The render options.
|
|
200
|
+
* @returns {Promise<string>} The rendered HTML content.
|
|
201
|
+
*/
|
|
172
202
|
async render(options) {
|
|
173
203
|
try {
|
|
174
204
|
let result = "";
|
|
175
205
|
if (this.isCacheEnabled(options)) {
|
|
176
|
-
const cached =
|
|
206
|
+
const cached = this._cache.get(this._content, options);
|
|
177
207
|
if (cached) {
|
|
178
208
|
return cached;
|
|
179
209
|
}
|
|
@@ -186,18 +216,23 @@ ${yamlString}---
|
|
|
186
216
|
const file = await engine.process(this.body);
|
|
187
217
|
result = String(file);
|
|
188
218
|
if (this.isCacheEnabled(options)) {
|
|
189
|
-
|
|
219
|
+
this._cache.set(this._content, result, options);
|
|
190
220
|
}
|
|
191
221
|
return result;
|
|
192
222
|
} catch (error) {
|
|
193
223
|
throw new Error(`Failed to render markdown: ${error.message}`);
|
|
194
224
|
}
|
|
195
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Render the markdown content to HTML synchronously.
|
|
228
|
+
* @param {RenderOptions} [options] The render options.
|
|
229
|
+
* @returns {string} The rendered HTML content.
|
|
230
|
+
*/
|
|
196
231
|
renderSync(options) {
|
|
197
232
|
try {
|
|
198
233
|
let result = "";
|
|
199
234
|
if (this.isCacheEnabled(options)) {
|
|
200
|
-
const cached = this._cache.
|
|
235
|
+
const cached = this._cache.get(this._content, options);
|
|
201
236
|
if (cached) {
|
|
202
237
|
return cached;
|
|
203
238
|
}
|
|
@@ -210,38 +245,121 @@ ${yamlString}---
|
|
|
210
245
|
const file = engine.processSync(this.body);
|
|
211
246
|
result = String(file);
|
|
212
247
|
if (this.isCacheEnabled(options)) {
|
|
213
|
-
this._cache.
|
|
248
|
+
this._cache.set(this._content, result, options);
|
|
214
249
|
}
|
|
215
250
|
return result;
|
|
216
251
|
} catch (error) {
|
|
217
252
|
throw new Error(`Failed to render markdown: ${error.message}`);
|
|
218
253
|
}
|
|
219
254
|
}
|
|
255
|
+
/**
|
|
256
|
+
* Render the markdown content and save it to a file. If the directory doesn't exist it will be created.
|
|
257
|
+
* @param {string} filePath The file path to save the rendered markdown content to.
|
|
258
|
+
* @param {RenderOptions} [options] the render options.
|
|
259
|
+
*/
|
|
260
|
+
async renderToFile(filePath, options) {
|
|
261
|
+
try {
|
|
262
|
+
const { writeFile, mkdir } = fs.promises;
|
|
263
|
+
const directoryPath = dirname(filePath);
|
|
264
|
+
const content = await this.render(options);
|
|
265
|
+
await mkdir(directoryPath, { recursive: true });
|
|
266
|
+
await writeFile(filePath, content, "utf8");
|
|
267
|
+
} catch (error) {
|
|
268
|
+
this.emit("error", error);
|
|
269
|
+
if (this._options.throwErrors) {
|
|
270
|
+
throw error;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Render the markdown content and save it to a file synchronously. If the directory doesn't exist it will be created.
|
|
276
|
+
* @param {string} filePath The file path to save the rendered markdown content to.
|
|
277
|
+
* @param {RenderOptions} [options] the render options.
|
|
278
|
+
*/
|
|
279
|
+
renderToFileSync(filePath, options) {
|
|
280
|
+
try {
|
|
281
|
+
const directoryPath = dirname(filePath);
|
|
282
|
+
const content = this.renderSync(options);
|
|
283
|
+
fs.mkdirSync(directoryPath, { recursive: true });
|
|
284
|
+
fs.writeFileSync(filePath, content, "utf8");
|
|
285
|
+
} catch (error) {
|
|
286
|
+
this.emit("error", error);
|
|
287
|
+
if (this._options.throwErrors) {
|
|
288
|
+
throw error;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Render the markdown content to React.
|
|
294
|
+
* @param {RenderOptions} [options] The render options.
|
|
295
|
+
* @param {HTMLReactParserOptions} [reactParseOptions] The HTML React parser options.
|
|
296
|
+
* @returns {Promise<string | React.JSX.Element | React.JSX.Element[]>} The rendered React content.
|
|
297
|
+
*/
|
|
220
298
|
async renderReact(options, reactParseOptions) {
|
|
221
299
|
const html = await this.render(options);
|
|
222
300
|
return parse(html, reactParseOptions);
|
|
223
301
|
}
|
|
302
|
+
/**
|
|
303
|
+
* Render the markdown content to React synchronously.
|
|
304
|
+
* @param {RenderOptions} [options] The render options.
|
|
305
|
+
* @param {HTMLReactParserOptions} [reactParseOptions] The HTML React parser options.
|
|
306
|
+
* @returns {string | React.JSX.Element | React.JSX.Element[]} The rendered React content.
|
|
307
|
+
*/
|
|
224
308
|
renderReactSync(options, reactParseOptions) {
|
|
225
309
|
const html = this.renderSync(options);
|
|
226
310
|
return parse(html, reactParseOptions);
|
|
227
311
|
}
|
|
312
|
+
/**
|
|
313
|
+
* Load markdown content from a file.
|
|
314
|
+
* @param {string} filePath The file path to load the markdown content from.
|
|
315
|
+
* @returns {Promise<void>}
|
|
316
|
+
*/
|
|
228
317
|
async loadFromFile(filePath) {
|
|
229
318
|
const { readFile } = fs.promises;
|
|
230
319
|
this._content = await readFile(filePath, "utf8");
|
|
231
320
|
}
|
|
321
|
+
/**
|
|
322
|
+
* Load markdown content from a file synchronously.
|
|
323
|
+
* @param {string} filePath The file path to load the markdown content from.
|
|
324
|
+
* @returns {void}
|
|
325
|
+
*/
|
|
232
326
|
loadFromFileSync(filePath) {
|
|
233
327
|
this._content = fs.readFileSync(filePath, "utf8");
|
|
234
328
|
}
|
|
329
|
+
/**
|
|
330
|
+
* Save the markdown content to a file. If the directory doesn't exist it will be created.
|
|
331
|
+
* @param {string} filePath The file path to save the markdown content to.
|
|
332
|
+
* @returns {Promise<void>}
|
|
333
|
+
*/
|
|
235
334
|
async saveToFile(filePath) {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
335
|
+
try {
|
|
336
|
+
const { writeFile, mkdir } = fs.promises;
|
|
337
|
+
const directoryPath = dirname(filePath);
|
|
338
|
+
await mkdir(directoryPath, { recursive: true });
|
|
339
|
+
await writeFile(filePath, this._content, "utf8");
|
|
340
|
+
} catch (error) {
|
|
341
|
+
this.emit("error", error);
|
|
342
|
+
if (this._options.throwErrors) {
|
|
343
|
+
throw error;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
240
346
|
}
|
|
347
|
+
/**
|
|
348
|
+
* Save the markdown content to a file synchronously. If the directory doesn't exist it will be created.
|
|
349
|
+
* @param {string} filePath The file path to save the markdown content to.
|
|
350
|
+
* @returns {void}
|
|
351
|
+
*/
|
|
241
352
|
saveToFileSync(filePath) {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
353
|
+
try {
|
|
354
|
+
const directoryPath = dirname(filePath);
|
|
355
|
+
fs.mkdirSync(directoryPath, { recursive: true });
|
|
356
|
+
fs.writeFileSync(filePath, this._content, "utf8");
|
|
357
|
+
} catch (error) {
|
|
358
|
+
this.emit("error", error);
|
|
359
|
+
if (this._options.throwErrors) {
|
|
360
|
+
throw error;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
245
363
|
}
|
|
246
364
|
isCacheEnabled(options) {
|
|
247
365
|
if (options?.caching !== void 0) {
|
|
@@ -276,6 +394,43 @@ ${yamlString}---
|
|
|
276
394
|
processor.use(rehypeStringify);
|
|
277
395
|
return processor;
|
|
278
396
|
}
|
|
397
|
+
mergeOptions(current, options) {
|
|
398
|
+
if (options.throwErrors !== void 0) {
|
|
399
|
+
current.throwErrors = options.throwErrors;
|
|
400
|
+
}
|
|
401
|
+
if (options.renderOptions) {
|
|
402
|
+
current.renderOptions ??= {};
|
|
403
|
+
this.mergeRenderOptions(current.renderOptions, options.renderOptions);
|
|
404
|
+
}
|
|
405
|
+
return current;
|
|
406
|
+
}
|
|
407
|
+
mergeRenderOptions(current, options) {
|
|
408
|
+
if (options.emoji !== void 0) {
|
|
409
|
+
current.emoji = options.emoji;
|
|
410
|
+
}
|
|
411
|
+
if (options.toc !== void 0) {
|
|
412
|
+
current.toc = options.toc;
|
|
413
|
+
}
|
|
414
|
+
if (options.slug !== void 0) {
|
|
415
|
+
current.slug = options.slug;
|
|
416
|
+
}
|
|
417
|
+
if (options.highlight !== void 0) {
|
|
418
|
+
current.highlight = options.highlight;
|
|
419
|
+
}
|
|
420
|
+
if (options.gfm !== void 0) {
|
|
421
|
+
current.gfm = options.gfm;
|
|
422
|
+
}
|
|
423
|
+
if (options.math !== void 0) {
|
|
424
|
+
current.math = options.math;
|
|
425
|
+
}
|
|
426
|
+
if (options.mdx !== void 0) {
|
|
427
|
+
current.mdx = options.mdx;
|
|
428
|
+
}
|
|
429
|
+
if (options.caching !== void 0) {
|
|
430
|
+
current.caching = options.caching;
|
|
431
|
+
}
|
|
432
|
+
return current;
|
|
433
|
+
}
|
|
279
434
|
};
|
|
280
435
|
export {
|
|
281
436
|
Writr
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "writr",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"description": "Markdown Rendering Simplified",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/writr.js",
|
|
@@ -53,37 +53,36 @@
|
|
|
53
53
|
"website:serve": "rimraf ./site/README.md ./site/dist && npx docula serve -s ./site -o ./site/dist"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"cacheable": "^1.8.
|
|
56
|
+
"cacheable": "^1.8.5",
|
|
57
|
+
"hookified": "^1.5.1",
|
|
57
58
|
"html-react-parser": "^5.1.18",
|
|
58
59
|
"js-yaml": "^4.1.0",
|
|
59
|
-
"keyv": "^5.1.0",
|
|
60
60
|
"react": "^18.3.1",
|
|
61
|
-
"rehype-highlight": "^7.0.
|
|
61
|
+
"rehype-highlight": "^7.0.1",
|
|
62
62
|
"rehype-katex": "^7.0.1",
|
|
63
63
|
"rehype-slug": "^6.0.0",
|
|
64
64
|
"rehype-stringify": "^10.0.1",
|
|
65
65
|
"remark-emoji": "^5.0.1",
|
|
66
66
|
"remark-gfm": "^4.0.0",
|
|
67
67
|
"remark-math": "^6.0.0",
|
|
68
|
-
"remark-mdx": "^3.0
|
|
68
|
+
"remark-mdx": "^3.1.0",
|
|
69
69
|
"remark-parse": "^11.0.0",
|
|
70
70
|
"remark-rehype": "^11.1.1",
|
|
71
71
|
"remark-toc": "^9.0.0",
|
|
72
72
|
"unified": "^11.0.5"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
|
-
"@keyv/sqlite": "^4.0.1",
|
|
76
75
|
"@types/js-yaml": "^4.0.9",
|
|
77
|
-
"@types/node": "^22.
|
|
78
|
-
"@types/react": "^18.3.
|
|
79
|
-
"@vitest/coverage-v8": "^2.1.
|
|
80
|
-
"docula": "^0.9.
|
|
76
|
+
"@types/node": "^22.10.1",
|
|
77
|
+
"@types/react": "^18.3.12",
|
|
78
|
+
"@vitest/coverage-v8": "^2.1.6",
|
|
79
|
+
"docula": "^0.9.5",
|
|
81
80
|
"rimraf": "^6.0.1",
|
|
82
81
|
"ts-node": "^10.9.2",
|
|
83
|
-
"tsup": "^8.3.
|
|
84
|
-
"typescript": "^5.
|
|
85
|
-
"vitest": "^2.1.
|
|
86
|
-
"webpack": "^5.
|
|
82
|
+
"tsup": "^8.3.5",
|
|
83
|
+
"typescript": "^5.7.2",
|
|
84
|
+
"vitest": "^2.1.6",
|
|
85
|
+
"webpack": "^5.96.1",
|
|
87
86
|
"xo": "^0.59.3"
|
|
88
87
|
},
|
|
89
88
|
"xo": {
|