writr 4.2.0 → 4.4.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 +58 -3
- package/dist/writr.d.ts +9 -1
- package/dist/writr.js +77 -29
- package/package.json +14 -14
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
- [`.engine`](#engine)
|
|
23
23
|
- [`.render(options?: RenderOptions): Promise<string>`](#renderoptions-renderoptions-promisestring)
|
|
24
24
|
- [`.renderSync(options?: RenderOptions): string`](#rendersyncoptions-renderoptions-string)
|
|
25
|
-
- [`.renderToFile(filePath: string, options?: RenderOptions)
|
|
25
|
+
- [`.renderToFile(filePath: string, options?: RenderOptions)`](#rendertofilefilepath-string-options-renderoptions)
|
|
26
26
|
- [`.renderToFileSync(filePath: string, options?: RenderOptions): void`](#rendertofilesyncfilepath-string-options-renderoptions-void)
|
|
27
27
|
- [`.renderReact(options?: RenderOptions, reactOptions?: HTMLReactParserOptions): Promise<React.JSX.Element />`](#renderreactoptions-renderoptions-reactoptions-htmlreactparseroptions-promise-reactjsxelement-)
|
|
28
28
|
- [`.renderReactSync( options?: RenderOptions, reactOptions?: HTMLReactParserOptions): React.JSX.Element`](#renderreactsync-options-renderoptions-reactoptions-htmlreactparseroptions-reactjsxelement)
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
- [`.loadFromFileSync(filePath: string): void`](#loadfromfilesyncfilepath-string-void)
|
|
31
31
|
- [`.saveToFile(filePath: string): Promise<void>`](#savetofilefilepath-string-promisevoid)
|
|
32
32
|
- [`.saveToFileSync(filePath: string): void`](#savetofilesyncfilepath-string-void)
|
|
33
|
+
- [Hooks](#hooks)
|
|
33
34
|
- [Code of Conduct and Contributing](#code-of-conduct-and-contributing)
|
|
34
35
|
- [License](#license)
|
|
35
36
|
|
|
@@ -47,6 +48,7 @@
|
|
|
47
48
|
* Github Flavor Markdown (remark-gfm).
|
|
48
49
|
* Emoji Support (remark-emoji).
|
|
49
50
|
* MDX Support (remark-mdx).
|
|
51
|
+
* Built in Hooks for adding code to render pipeline.
|
|
50
52
|
|
|
51
53
|
# ESM and Node Version Support
|
|
52
54
|
|
|
@@ -252,7 +254,7 @@ const writr = new Writr(`# Hello World ::-):\n\n This is a test.`);
|
|
|
252
254
|
const html = writr.renderSync(); // <h1>Hello World 🙂</h1><p>This is a test.</p>
|
|
253
255
|
```
|
|
254
256
|
|
|
255
|
-
## '.renderToFile(filePath: string, options?: RenderOptions)
|
|
257
|
+
## '.renderToFile(filePath: string, options?: RenderOptions)'
|
|
256
258
|
|
|
257
259
|
Rendering markdown to a file. The options are based on RenderOptions.
|
|
258
260
|
|
|
@@ -347,9 +349,62 @@ writr.cache.store.lruSize = 100;
|
|
|
347
349
|
writr.cache.store.ttl = '5m'; // setting it to 5 minutes
|
|
348
350
|
```
|
|
349
351
|
|
|
352
|
+
# Hooks
|
|
353
|
+
|
|
354
|
+
Hooks are a way to add additional parsing to the render pipeline. You can add hooks to the the Writr instance. Here is an example of adding a hook to the instance of Writr:
|
|
355
|
+
|
|
356
|
+
```javascript
|
|
357
|
+
import { Writr, WritrHooks } from 'writr';
|
|
358
|
+
const writr = new Writr(`# Hello World ::-):\n\n This is a test.`);
|
|
359
|
+
writr.onHook(WritrHooks.beforeRender, data => {
|
|
360
|
+
data.body = 'Hello, Universe!';
|
|
361
|
+
});
|
|
362
|
+
const result = await writr.render();
|
|
363
|
+
console.log(result); // Hello, Universe!
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
For `beforeRender` the data object is a `renderData` object. Here is the interface for `renderData`:
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
export type renderData = {
|
|
370
|
+
body: string
|
|
371
|
+
options: RenderOptions;
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
For `afterRender` the data object is a `resultData` object. Here is the interface for `resultData`:
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
export type resultData = {
|
|
379
|
+
result: string;
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
For `beforeSaveToFile` the data object is an object with the `filePath` and `content`. Here is the interface for `saveToFileData`:
|
|
384
|
+
|
|
385
|
+
```typescript
|
|
386
|
+
export type saveToFileData = {
|
|
387
|
+
filePath: string;
|
|
388
|
+
content: string;
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
This is called when you call `saveToFile`, `saveToFileSync`.
|
|
393
|
+
|
|
394
|
+
For `beforeRenderToFile` the data object is an object with the `filePath` and `content`. Here is the interface for `renderToFileData`:
|
|
395
|
+
|
|
396
|
+
```typescript
|
|
397
|
+
export type renderToFileData = {
|
|
398
|
+
filePath: string;
|
|
399
|
+
content: string;
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
This is called when you call `renderToFile`, `renderToFileSync`.
|
|
404
|
+
|
|
350
405
|
# Code of Conduct and Contributing
|
|
351
406
|
[Code of Conduct](CODE_OF_CONDUCT.md) and [Contributing](CONTRIBUTING.md) guidelines.
|
|
352
407
|
|
|
353
408
|
# License
|
|
354
409
|
|
|
355
|
-
MIT © [Jared Wray](https://jaredwray.com)
|
|
410
|
+
[MIT](LICENSE) & © [Jared Wray](https://jaredwray.com)
|
package/dist/writr.d.ts
CHANGED
|
@@ -49,6 +49,14 @@ type RenderOptions = {
|
|
|
49
49
|
mdx?: boolean;
|
|
50
50
|
caching?: boolean;
|
|
51
51
|
};
|
|
52
|
+
declare enum WritrHooks {
|
|
53
|
+
beforeRender = "beforeRender",
|
|
54
|
+
afterRender = "afterRender",
|
|
55
|
+
beforeSaveToFile = "beforeSaveToFile",
|
|
56
|
+
beforeRenderToFile = "beforeRenderToFile",
|
|
57
|
+
beforeLoadFromFile = "beforeLoadFromFile",
|
|
58
|
+
afterLoadFromFile = "afterLoadFromFile"
|
|
59
|
+
}
|
|
52
60
|
declare class Writr extends Hookified {
|
|
53
61
|
engine: unified.Processor<mdast.Root, mdast.Root, hast.Root, hast.Root, string>;
|
|
54
62
|
private readonly _options;
|
|
@@ -182,4 +190,4 @@ declare class Writr extends Hookified {
|
|
|
182
190
|
private mergeRenderOptions;
|
|
183
191
|
}
|
|
184
192
|
|
|
185
|
-
export { type RenderOptions, Writr, type WritrOptions };
|
|
193
|
+
export { type RenderOptions, Writr, WritrHooks, type WritrOptions };
|
package/dist/writr.js
CHANGED
|
@@ -54,6 +54,15 @@ var WritrCache = class {
|
|
|
54
54
|
};
|
|
55
55
|
|
|
56
56
|
// src/writr.ts
|
|
57
|
+
var WritrHooks = /* @__PURE__ */ ((WritrHooks2) => {
|
|
58
|
+
WritrHooks2["beforeRender"] = "beforeRender";
|
|
59
|
+
WritrHooks2["afterRender"] = "afterRender";
|
|
60
|
+
WritrHooks2["beforeSaveToFile"] = "beforeSaveToFile";
|
|
61
|
+
WritrHooks2["beforeRenderToFile"] = "beforeRenderToFile";
|
|
62
|
+
WritrHooks2["beforeLoadFromFile"] = "beforeLoadFromFile";
|
|
63
|
+
WritrHooks2["afterLoadFromFile"] = "afterLoadFromFile";
|
|
64
|
+
return WritrHooks2;
|
|
65
|
+
})(WritrHooks || {});
|
|
57
66
|
var Writr = class extends Hookified {
|
|
58
67
|
engine = unified().use(remarkParse).use(remarkGfm).use(remarkToc).use(remarkEmoji).use(remarkRehype).use(rehypeSlug).use(remarkMath).use(rehypeKatex).use(rehypeHighlight).use(remarkMDX).use(rehypeStringify);
|
|
59
68
|
// Stringify HTML
|
|
@@ -201,24 +210,33 @@ ${yamlString}---
|
|
|
201
210
|
*/
|
|
202
211
|
async render(options) {
|
|
203
212
|
try {
|
|
204
|
-
let result = "";
|
|
205
|
-
if (this.isCacheEnabled(options)) {
|
|
206
|
-
const cached = this._cache.get(this._content, options);
|
|
207
|
-
if (cached) {
|
|
208
|
-
return cached;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
213
|
let { engine } = this;
|
|
212
214
|
if (options) {
|
|
213
215
|
options = { ...this._options.renderOptions, ...options };
|
|
214
216
|
engine = this.createProcessor(options);
|
|
215
217
|
}
|
|
216
|
-
const
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
218
|
+
const renderData = {
|
|
219
|
+
content: this._content,
|
|
220
|
+
body: this.body,
|
|
221
|
+
options
|
|
222
|
+
};
|
|
223
|
+
await this.hook("beforeRender" /* beforeRender */, renderData);
|
|
224
|
+
const resultData = {
|
|
225
|
+
result: ""
|
|
226
|
+
};
|
|
227
|
+
if (this.isCacheEnabled(renderData.options)) {
|
|
228
|
+
const cached = this._cache.get(renderData.content, renderData.options);
|
|
229
|
+
if (cached) {
|
|
230
|
+
return cached;
|
|
231
|
+
}
|
|
220
232
|
}
|
|
221
|
-
|
|
233
|
+
const file = await engine.process(renderData.body);
|
|
234
|
+
resultData.result = String(file);
|
|
235
|
+
if (this.isCacheEnabled(renderData.options)) {
|
|
236
|
+
this._cache.set(renderData.content, resultData.result, renderData.options);
|
|
237
|
+
}
|
|
238
|
+
await this.hook("afterRender" /* afterRender */, resultData);
|
|
239
|
+
return resultData.result;
|
|
222
240
|
} catch (error) {
|
|
223
241
|
throw new Error(`Failed to render markdown: ${error.message}`);
|
|
224
242
|
}
|
|
@@ -230,24 +248,33 @@ ${yamlString}---
|
|
|
230
248
|
*/
|
|
231
249
|
renderSync(options) {
|
|
232
250
|
try {
|
|
233
|
-
let result = "";
|
|
234
|
-
if (this.isCacheEnabled(options)) {
|
|
235
|
-
const cached = this._cache.get(this._content, options);
|
|
236
|
-
if (cached) {
|
|
237
|
-
return cached;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
251
|
let { engine } = this;
|
|
241
252
|
if (options) {
|
|
242
253
|
options = { ...this._options.renderOptions, ...options };
|
|
243
254
|
engine = this.createProcessor(options);
|
|
244
255
|
}
|
|
245
|
-
const
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
256
|
+
const renderData = {
|
|
257
|
+
content: this._content,
|
|
258
|
+
body: this.body,
|
|
259
|
+
options
|
|
260
|
+
};
|
|
261
|
+
this.hook("beforeRender" /* beforeRender */, renderData);
|
|
262
|
+
const resultData = {
|
|
263
|
+
result: ""
|
|
264
|
+
};
|
|
265
|
+
if (this.isCacheEnabled(renderData.options)) {
|
|
266
|
+
const cached = this._cache.get(renderData.content, renderData.options);
|
|
267
|
+
if (cached) {
|
|
268
|
+
return cached;
|
|
269
|
+
}
|
|
249
270
|
}
|
|
250
|
-
|
|
271
|
+
const file = engine.processSync(renderData.body);
|
|
272
|
+
resultData.result = String(file);
|
|
273
|
+
if (this.isCacheEnabled(renderData.options)) {
|
|
274
|
+
this._cache.set(renderData.content, resultData.result, renderData.options);
|
|
275
|
+
}
|
|
276
|
+
this.hook("afterRender" /* afterRender */, resultData);
|
|
277
|
+
return resultData.result;
|
|
251
278
|
} catch (error) {
|
|
252
279
|
throw new Error(`Failed to render markdown: ${error.message}`);
|
|
253
280
|
}
|
|
@@ -263,7 +290,12 @@ ${yamlString}---
|
|
|
263
290
|
const directoryPath = dirname(filePath);
|
|
264
291
|
const content = await this.render(options);
|
|
265
292
|
await mkdir(directoryPath, { recursive: true });
|
|
266
|
-
|
|
293
|
+
const data = {
|
|
294
|
+
filePath,
|
|
295
|
+
content
|
|
296
|
+
};
|
|
297
|
+
await this.hook("beforeRenderToFile" /* beforeRenderToFile */, data);
|
|
298
|
+
await writeFile(data.filePath, data.content);
|
|
267
299
|
} catch (error) {
|
|
268
300
|
this.emit("error", error);
|
|
269
301
|
if (this._options.throwErrors) {
|
|
@@ -281,7 +313,12 @@ ${yamlString}---
|
|
|
281
313
|
const directoryPath = dirname(filePath);
|
|
282
314
|
const content = this.renderSync(options);
|
|
283
315
|
fs.mkdirSync(directoryPath, { recursive: true });
|
|
284
|
-
|
|
316
|
+
const data = {
|
|
317
|
+
filePath,
|
|
318
|
+
content
|
|
319
|
+
};
|
|
320
|
+
this.hook("beforeRenderToFile" /* beforeRenderToFile */, data);
|
|
321
|
+
fs.writeFileSync(data.filePath, data.content);
|
|
285
322
|
} catch (error) {
|
|
286
323
|
this.emit("error", error);
|
|
287
324
|
if (this._options.throwErrors) {
|
|
@@ -336,7 +373,12 @@ ${yamlString}---
|
|
|
336
373
|
const { writeFile, mkdir } = fs.promises;
|
|
337
374
|
const directoryPath = dirname(filePath);
|
|
338
375
|
await mkdir(directoryPath, { recursive: true });
|
|
339
|
-
|
|
376
|
+
const data = {
|
|
377
|
+
filePath,
|
|
378
|
+
content: this._content
|
|
379
|
+
};
|
|
380
|
+
await this.hook("beforeSaveToFile" /* beforeSaveToFile */, data);
|
|
381
|
+
await writeFile(data.filePath, data.content);
|
|
340
382
|
} catch (error) {
|
|
341
383
|
this.emit("error", error);
|
|
342
384
|
if (this._options.throwErrors) {
|
|
@@ -353,7 +395,12 @@ ${yamlString}---
|
|
|
353
395
|
try {
|
|
354
396
|
const directoryPath = dirname(filePath);
|
|
355
397
|
fs.mkdirSync(directoryPath, { recursive: true });
|
|
356
|
-
|
|
398
|
+
const data = {
|
|
399
|
+
filePath,
|
|
400
|
+
content: this._content
|
|
401
|
+
};
|
|
402
|
+
this.hook("beforeSaveToFile" /* beforeSaveToFile */, data);
|
|
403
|
+
fs.writeFileSync(data.filePath, data.content);
|
|
357
404
|
} catch (error) {
|
|
358
405
|
this.emit("error", error);
|
|
359
406
|
if (this._options.throwErrors) {
|
|
@@ -433,5 +480,6 @@ ${yamlString}---
|
|
|
433
480
|
}
|
|
434
481
|
};
|
|
435
482
|
export {
|
|
436
|
-
Writr
|
|
483
|
+
Writr,
|
|
484
|
+
WritrHooks
|
|
437
485
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "writr",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.0",
|
|
4
4
|
"description": "Markdown Rendering Simplified",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/writr.js",
|
|
@@ -53,11 +53,11 @@
|
|
|
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.
|
|
57
|
-
"hookified": "^1.
|
|
58
|
-
"html-react-parser": "^5.
|
|
56
|
+
"cacheable": "^1.8.8",
|
|
57
|
+
"hookified": "^1.7.0",
|
|
58
|
+
"html-react-parser": "^5.2.2",
|
|
59
59
|
"js-yaml": "^4.1.0",
|
|
60
|
-
"react": "^
|
|
60
|
+
"react": "^19.0.0",
|
|
61
61
|
"rehype-highlight": "^7.0.1",
|
|
62
62
|
"rehype-katex": "^7.0.1",
|
|
63
63
|
"rehype-slug": "^6.0.0",
|
|
@@ -73,17 +73,17 @@
|
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
75
|
"@types/js-yaml": "^4.0.9",
|
|
76
|
-
"@types/node": "^22.
|
|
77
|
-
"@types/react": "^
|
|
78
|
-
"@vitest/coverage-v8": "^
|
|
79
|
-
"docula": "^0.
|
|
76
|
+
"@types/node": "^22.12.0",
|
|
77
|
+
"@types/react": "^19.0.8",
|
|
78
|
+
"@vitest/coverage-v8": "^3.0.4",
|
|
79
|
+
"docula": "^0.10.0",
|
|
80
80
|
"rimraf": "^6.0.1",
|
|
81
81
|
"ts-node": "^10.9.2",
|
|
82
|
-
"tsup": "^8.3.
|
|
83
|
-
"typescript": "^5.7.
|
|
84
|
-
"vitest": "^
|
|
85
|
-
"webpack": "^5.
|
|
86
|
-
"xo": "^0.
|
|
82
|
+
"tsup": "^8.3.6",
|
|
83
|
+
"typescript": "^5.7.3",
|
|
84
|
+
"vitest": "^3.0.4",
|
|
85
|
+
"webpack": "^5.97.1",
|
|
86
|
+
"xo": "^0.60.0"
|
|
87
87
|
},
|
|
88
88
|
"xo": {
|
|
89
89
|
"ignores": [
|